打开软件
PEID检查一下
用汇编写的,难怪这么小。
输入1234566 点击Check It, 没反应,输入别的数字 没反应、 不能输入字母。
看来问题出在了输入的数据上。而且输入的应该就是一串数字。
没有关键字搜索。但是可以从windows API来考虑。
GetDlgItemText 和 GetWindowText 都是常用来获取数据的。
查看一下当前程序使用到的API
找到了。GetWindowTextA
分别查看各自的汇编代码 显然第一个是我们要找的断点。
00401316 |. 6A 28 push 0x28 ; /Count = 28 (40.)
00401318 |. 68 C4334000 push CrackHea.004033C4 ; |Buffer = CrackHea.004033C4
0040131D |. FF35 90314000 push dword ptr ds:[0x403190] ; |hWnd = NULL
00401323 |. E8 4C010000 call <jmp.&USER32.GetWindowTextA> ; \GetWindowTextA
00401328 |. E8 A5000000 call CrackHea.004013D2 ; 这是干嘛的
0040132D |. 3BC6 cmp eax,esi ; 这个地方要返回zf=0 也就是eax=esi
0040132F |. 75 42 jnz short CrackHea.00401373
00401331 |. EB 2C jmp short CrackHea.0040135F
00401333 |. 4E 6F 77 20 7>ascii "Now write a keyg"
00401343 |. 65 6E 20 61 6>ascii "en and tut and y"
00401353 |. 6F 75 27 72 6>ascii "ou're done.",0
0040135F |> 6A 00 push 0x0 ; /Style = MB_OK|MB_APPLMODAL
00401361 |. 68 0F304000 push CrackHea.0040300F ; |Title = "Crudd's Crack Head"
00401366 |. 68 33134000 push CrackHea.00401333 ; |Text = "Now write a keygen and tut and you're done."
0040136B |. FF75 08 push [arg.1] ; |hOwner = 7FFDF000
0040136E |. E8 19010000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
同时我们也发现了可疑call
0040132D |. 3BC6 cmp eax,esi ; 这个地方要返回zf=0 也就是eax=esi
此处下断 输入1234566,运行跟进。
004013D2 /$ 56 push esi
004013D3 |. 33C0 xor eax,eax
004013D5 |. 8D35 C4334000 lea esi,dword ptr ds:[0x4033C4] ; 这个地方存的是输入的数据
004013DB |. 33C9 xor ecx,ecx ; user32.75AE714E
004013DD |. 33D2 xor edx,edx
004013DF |. 8A06 mov al,byte ptr ds:[esi] ; 取第一位
004013E1 |. 46 inc esi ; 指针+1
004013E2 |. 3C 2D cmp al,0x2D ; 和-比较 不是- 跳
004013E4 |. 75 08 jnz short CrackHea.004013EE
004013E6 |. BA FFFFFFFF mov edx,-0x1
004013EB |. 8A06 mov al,byte ptr ds:[esi]
004013ED |. 46 inc esi
004013EE |> EB 0B jmp short CrackHea.004013FB
004013F0 |> 2C 30 /sub al,0x30 ; al减去0x30 其实就是取数字的值
004013F2 |. 8D0C89 |lea ecx,dword ptr ds:[ecx+ecx*4] ; ecx=ecx*5
004013F5 |. 8D0C48 |lea ecx,dword ptr ds:[eax+ecx*2] ; ecx=eax+ecx*2
004013F8 |. 8A06 |mov al,byte ptr ds:[esi] ; 取下一位数据
004013FA |. 46 |inc esi ; 指针后移
004013FB |> 0AC0 or al,al
004013FD |.^ 75 F1 \jnz short CrackHea.004013F0 ; al 不是 0 就跳转,是0就继续向下执行
004013FF |. 8D040A lea eax,dword ptr ds:[edx+ecx]
00401402 |. 33C2 xor eax,edx
00401404 |. 5E pop esi ; CrackHea.0040132D
00401405 |. 81F6 53757A79 xor esi,0x797A7553
0040140B \. C3 retn
看到这个函数就明白了。
它首先检查是正数还是负数,然后依次从我们输入的数字字符串 从高位遍历到最低位。每次用ecx来存储累计的值。 ecx=10*ecx+eax; 一直循环到最低位。
其实这个循环的作用就是把我们输入的数字字符串转成对应的数值。、
如果我们输入的是正数的话,edx就是0,经过xor后还是eax本身,
然后pop esi,此时esi是0,然后对esi进行xor,esi的值就是0x797A7553
最后我们retn返回后,比较eax和esi的值是否相等,esi值到最后得出是固定的,eax的值就是我们输入的数字字符串的数值形式,所以只要输入 0x797A7553 的数值形式即可,
所以我们输入的数字应该是 2038068563