逆向 计算用户输入长度

 

title: “维吉尼亚密码的破解” key: 2019-03-10-Vigenere-Cipher tags: crypto pageview: true modify_date: shraring: true show_author_profile: true show_subscribe: true


逆向-计算用户输入长度

or ecx 0FFFFFFFFh
xor eax eax
add esp 10h
repne scasb
not ecx 
dec ecx

首先前两步,第一步用来把ecx的值置成0xFFFFFFFF

第二步用来将eax清零,而之所以这样写,不用mov eax,0,是因为这种方法要比mov eax,0效率高(硬件内的原因)。

接下来repne scasb,其实就是repne scas byte ptr es:[edi],是最经典的求字符串长度的代码,strlen()在VC优化编译模式是这段代码。 参考博文here,(参考了很多。。。)

scasb是串扫描指令,repne(或者也可以写成repnz,作用是每执行一次串操作指令CX减1,并判断ZF标志是否为1,只要CX=0 或ZF=1,则重复执行结束)

举个例子,假设字符串是“kid57”,对于这个字符串来执行repne scasb的时候: 第一次: al-‘k’,di=di-1,即byte ptr es:[edi]指向’i’,并置相应的标志位 然后cx-1,则ecx=FFFFFFFE,判断是否cx=0或ZF=1,显然该处条件不成立,继续重复执行 第二次: al-‘i’,di=di-1,即byte ptr es:[edi]指向’d’,并置相应的标志位 然后cx-1,则ecx=FFFFFFFD,判断是否cx=0或ZF=1,显然该处条件不成立,继续重复执行 第三次: al-‘d’,di=di-1,即byte ptr es:[edi]指向’5’,并置相应的标志位 然后cx-1,则ecx=FFFFFFFC,判断是否cx=0或ZF=1,显然该处条件不成立,继续重复执行 第四次: al-‘5’,di=di-1,即byte ptr es:[edi]指向’7’,并置相应的标志位 然后cx-1,则ecx=FFFFFFFB,判断是否cx=0或ZF=1,显然该处条件不成立,继续重复执行 第五次:

al-‘7’,di=di-1,即byte ptr es:[edi]指向’0’,并置相应的标志位 然后cx-1,则ecx=FFFFFFFA,判断是否cx=0或ZF=1,这时候ZF = 1 成立。

更正…..

发现not ecx之后得到的不是00000006而是00000005,因为是按位取反的。

然后减一变成00000004,这时候跟实际的长度相比,就少了一位。

——–》其实是没有少的,因为上面就错了。di是从用户输入的第一位开始,然后逐渐往后移动,直到和eax相等——》移到最后一位为0的时候,这才停下来。

而scasb的真相:

scasb :

inc edi

dec ecx

je loopdone

cmp byte

[edi-1],al

jne scans

loopdone

这样可以看到,即使到达了’\0’,ecx也是还是减掉了1的。所以这就是dec ecx的作用(前面多减1,取反就要多出来1,把他减掉)