打开软件,一看是要输入 用户名和序列号,随便输一个。然后点击 register。 弹出错误。
关键字出现了: Wrong Serial,try again!
OD 载入 ,搜索字符串得到两处结果、
中文搜索引擎, 条目 593
地址=00440F79
反汇编=mov edx,CrackMe3.0044108C
文本字符串=Wrong Serial,try again!中文搜索引擎, 条目 595
地址=00440F93
反汇编=mov edx,CrackMe3.0044108C
文本字符串=Wrong Serial,try again!
发现两处地址较近,直接在反汇编窗口中查看。、
向上找,找到了两处关键call、
00440F2C |. 8B45 FC mov eax,[local.1]
00440F2F |. BA 14104400 mov edx,CrackMe3.00441014 ; Registered User
00440F34 |. E8 F32BFCFF call CrackMe3.00403B2C
00440F39 |. 75 51 jnz short CrackMe3.00440F8C ; 跳了就完蛋
另一处:
00440F49 |. 8B45 FC mov eax,[local.1]
00440F4C |. BA 2C104400 mov edx,CrackMe3.0044102C ; GFX-754-IER-954
00440F51 |. E8 D62BFCFF call CrackMe3.00403B2C
00440F56 |. 75 1A jnz short CrackMe3.00440F72 ; 跳了就完蛋
这两处call执行后如果 jnz发生了跳转就会产生失败。所以call函数要返回ZF=0
在第一处函数下断,F9运行,用户名为 testuser 序列号为 754-GFX-IER-954
压入两个参数,eax为 testuser ,edx为 Registered User
F7跳入函数内
00403B2C /$ 53 push ebx
00403B2D |. 56 push esi
00403B2E |. 57 push edi
00403B2F |. 89C6 mov esi,eax
00403B31 |. 89D7 mov edi,edx ; CrackMe3.00441014
00403B33 |. 39D0 cmp eax,edx ; CrackMe3.00441014
00403B35 |. 0F84 8F000000 je CrackMe3.00403BCA ; 地址 相同则跳 显然不同
00403B3B |. 85F6 test esi,esi ; 检查字符串a是否为空、
00403B3D |. 74 68 je short CrackMe3.00403BA7
00403B3F |. 85FF test edi,edi ; 检查字符串b是否为空
00403B41 |. 74 6B je short CrackMe3.00403BAE
00403B43 |. 8B46 FC mov eax,dword ptr ds:[esi-0x4] ; 输入 字符串长度
00403B46 |. 8B57 FC mov edx,dword ptr ds:[edi-0x4] ; 参考字符串
00403B49 |. 29D0 sub eax,edx ; 相减
00403B4B |. 77 02 ja short CrackMe3.00403B4F ; 输入字符串a长度比较长 则跳转 根据后文edx可以得出是取短值
00403B4D |. 01C2 add edx,eax ; 如果字符串a比较短的话就让edx为字符串a的长度
00403B4F |> 52 push edx ; 短值压入栈
00403B50 |. C1EA 02 shr edx,0x2 ; 右移两位 就是除4,因为要进行字符串比较 4个字符一起比较效率高
00403B53 |. 74 26 je short CrackMe3.00403B7B ; 如果字符串长度小于4就会变成0 然后就挂了、
00403B55 |> 8B0E /mov ecx,dword ptr ds:[esi] ; CrackMe3.0043EB70
00403B57 |. 8B1F |mov ebx,dword ptr ds:[edi] ; 比较esi edi所指向的四个字符
00403B59 |. 39D9 |cmp ecx,ebx
00403B5B |. 75 58 |jnz short CrackMe3.00403BB5 ; 比较字符串 前四个字符 不相等就完蛋
00403B5D |. 4A |dec edx ; 字符串长度减一
00403B5E |. 74 15 |je short CrackMe3.00403B75 ; 比完了 就跳出去 没比完继续
00403B60 |. 8B4E 04 |mov ecx,dword ptr ds:[esi+0x4]
00403B63 |. 8B5F 04 |mov ebx,dword ptr ds:[edi+0x4]
00403B66 |. 39D9 |cmp ecx,ebx
00403B68 |. 75 4B |jnz short CrackMe3.00403BB5 ; 不相等就滚出去
00403B6A |. 83C6 08 |add esi,0x8
00403B6D |. 83C7 08 |add edi,0x8
00403B70 |. 4A |dec edx ; 又比较了4个字符了 每次循环比较8个字符
00403B71 |.^ 75 E2 \jnz short CrackMe3.00403B55 ; 还有字符没比就继续
00403B73 |. EB 06 jmp short CrackMe3.00403B7B
00403B75 |> 83C6 04 add esi,0x4 ; 剩下不足4个字符了 不能在循环里面比了
00403B78 |. 83C7 04 add edi,0x4
00403B7B |> 5A pop edx ; CrackMe3.00440F39
00403B7C |. 83E2 03 and edx,0x3
00403B7F |. 74 22 je short CrackMe3.00403BA3
00403B81 |. 8B0E mov ecx,dword ptr ds:[esi] ; CrackMe3.0043EB70
00403B83 |. 8B1F mov ebx,dword ptr ds:[edi]
00403B85 |. 38D9 cmp cl,bl ; 比较剩下几个中的第一个
00403B87 |. 75 41 jnz short CrackMe3.00403BCA
00403B89 |. 4A dec edx ; -1
00403B8A |. 74 17 je short CrackMe3.00403BA3
00403B8C |. 38FD cmp ch,bh
00403B8E |. 75 3A jnz short CrackMe3.00403BCA ; -1
00403B90 |. 4A dec edx ; CrackMe3.00441014
00403B91 |. 74 10 je short CrackMe3.00403BA3
00403B93 |. 81E3 0000FF00 and ebx,0xFF0000
00403B99 |. 81E1 0000FF00 and ecx,0xFF0000
00403B9F |. 39D9 cmp ecx,ebx ; -1
00403BA1 |. 75 27 jnz short CrackMe3.00403BCA
00403BA3 |> 01C0 add eax,eax
00403BA5 |. EB 23 jmp short CrackMe3.00403BCA
00403BA7 |> 8B57 FC mov edx,dword ptr ds:[edi-0x4]
00403BAA |. 29D0 sub eax,edx ; CrackMe3.00441014
00403BAC |. EB 1C jmp short CrackMe3.00403BCA
00403BAE |> 8B46 FC mov eax,dword ptr ds:[esi-0x4]
00403BB1 |. 29D0 sub eax,edx ; CrackMe3.00441014
00403BB3 |. EB 15 jmp short CrackMe3.00403BCA
00403BB5 |> 5A pop edx ; CrackMe3.00440F39
00403BB6 |. 38D9 cmp cl,bl
00403BB8 |. 75 10 jnz short CrackMe3.00403BCA
00403BBA |. 38FD cmp ch,bh
00403BBC |. 75 0C jnz short CrackMe3.00403BCA
00403BBE |. C1E9 10 shr ecx,0x10
00403BC1 |. C1EB 10 shr ebx,0x10
00403BC4 |. 38D9 cmp cl,bl
00403BC6 |. 75 02 jnz short CrackMe3.00403BCA
00403BC8 |. 38FD cmp ch,bh
00403BCA |> 5F pop edi ; CrackMe3.00440F39
00403BCB |. 5E pop esi ; CrackMe3.00440F39
00403BCC |. 5B pop ebx ; CrackMe3.00440F39
00403BCD \. C3 retn
其实这个函数的功能是检查两个字符串是否相同,
它首先比较两个字符串的地址是否相同,如果相同就返回失败。
然后比较两个字符串的第一个字符是否为 \0, 也就是检查字符串长度,如果为空,返回失败
接下来就可以进行比较了。 因为一个字符是8位,而eax寄存器变量是32位,所以每次比较4个字符,
最后不足4个字符单个比,当然如果字符串不同的话,肯定最后也会返回失败的。。
所以这个函数的参数是两个字符串,功能是比较两个字符串是否相同,如果相同的话,就返回1.
这两处关键call用的是同一处函数,所以只要找到题目中检查的第二个参数就行了。分别为;
Registered User
GFX-754-IER-954