合适初学者学习的算法破解
在看雪上的时间也不算短了。不断的学习各位大侠的文章,很感谢他们的努力写出那么多那么好的文章来。获取了那么多自己觉得应该对论坛也贡献一些
只是水平有限,实在是拿不出手,昨天朋友给我一个CreckMer我觉得适合,像我这样初哥学习。所就写一篇文章出来显一下眼。给像我一样初们学习一下。共同
努力变大侠吧。程序我没法上传要的话留EMAIL我发给你吧。破解时我是OD和IDA一起用的。文章中大部分都是IDA的代码。你也可以这样做,用一个程序
学两样工具值。
朋友给我一个可执行文件,让我把他破解出来。目的是找出可以打印出OK的字符串。
打开程序要求输入字符串,输入“123789”之后出现:
3959846171
274934722
输入密码:
123789
err!
请按任意键继续. . .
看来程序是要我们输入一个合适的字符串然后才会打印出OK来了。
用PEID检察没有加壳,是VC的程序。
那么我们从哪里开始呢?如何找到我们找的字符串呢?题目是要我们找到OK字符那我们就从找OK字符开始。
OD打开程序。停在
00424E10 >/$ 55 PUSH EBP
右键->查找->所有字符串。第一个就是OK。双击到达调用他的代码处:
.text:0040179E push offset s_Ok ; "OK!\n"
.text:004017A3 call _printf
看来这里就是输出OK的地方了。
下面是我们所要处理的程序代码:
.text:00401725 push offset loc_4010F5
.text:0040172A push offset s_FIIg ; "输入密码:"
.text:0040172F push offset unk_47A840
.text:00401734 call sub_401302
.text:00401734
.text:00401739 add esp, 8
.text:0040173C mov ecx, eax
.text:0040173E call sub_401253
.text:0040173E
.text:00401743 lea eax, [ebp+var_18]
.text:00401746 push eax
.text:00401747 push offset dword_47A8D0
.text:0040174C call sub_401073
.text:0040174C
.text:00401751 add esp, 8
.text:00401754 lea ecx, [ebp+var_18]
.text:00401757 push ecx ; char *
.text:00401758 call _atoi
.text:00401758
.text:0040175D add esp, 4
.text:00401760 mov [ebp+var_4], eax
.text:00401763 mov eax, [ebp+var_4]
.text:00401766 xor edx, edx
.text:00401768 mov ecx, 64711753h
.text:0040176D div ecx
.text:0040176F mov ecx, edx
.text:00401771 mov eax, [ebp+var_4]
.text:00401774 xor edx, edx
.text:00401776 mov esi, 3DB6C49h
.text:0040177B div esi
.text:0040177D mov esi, edx
.text:0040177F add esi, [ebp+var_4]
.text:00401782 mov eax, [ebp+var_4]
.text:00401785 xor edx, edx
.text:00401787 mov edi, 0D393EBh
.text:0040178C div edi
.text:0040178E add esi, ecx
.text:00401790 add edx, esi
.text:00401792 mov [ebp+var_4], edx
.text:00401795 cmp [ebp+var_4], 10632BC2h
.text:0040179C jnz short loc_4017AD
.text:0040179C
.text:0040179E push offset s_Ok ; "OK!\n"
.text:004017A3 call _printf
.text:004017A3
.text:004017A8 add esp, 4
.text:004017AB jmp short loc_4017BA
.text:004017AB
.text:004017AD ; ---------------------------------------------------------------------------
.text:004017AD
.text:004017AD loc_4017AD: ; CODE XREF: sub_4016A0+FC j
.text:004017AD push offset s_Err ; "err!\n"
.text:004017B2 call _printf
找到了输出的地方我想输入的地方离的也不远了。向上看看
在IDA中这个指针被显示为字符串"输入密码:"
.text:0040172A push offset s_FIIg ; "输入密码:"
也就是说输入字符用的函数,应该就在他在下面不过的地方,单步走下去。
.text:0040174C call sub_401073
果然运行到这个CALL的时候程序停住等待我们输入正确的数值。
输入:123789
程序停在.text:00401739这时堆栈窗口中出现了我们输入的字符“123789”。而指向他的指针是[ebp+var_18]。
接下来程序把字符串放堆栈调用_atoi函数,目的是把字符串转换成整数,然后由eax返回。
.text:00401754 lea ecx, [ebp+var_18]
.text:00401757 push ecx ; char *
.text:00401758 call _atoi
.text:0040175D add esp, 4
.text:00401760 mov [ebp+var_4], eax
之后我们就进入我们要找的领域,算法开始了。
.text:0040175D add esp, 4
.text:00401760 mov [ebp+var_4], eax
.text:00401766 xor edx, edx
.text:00401768 mov ecx, 64711753h
.text:0040176D div ecx ;edx = eax %ecx
.text:0040176F mov ecx, edx ; ecx = [ebp+var_4]%64711753h
.text:00401771 mov eax, [ebp+var_4] ;
.text:00401774 xor edx, edx
.text:00401776 mov esi, 3DB6C49h
.text:0040177B div esi ;edx = eax%esi
.text:0040177D mov esi, edx ;
.text:0040177F add esi, [ebp+var_4] ;esi = eax%esi+[ebp+var_4] == [ebp+var_4]% 3DB6C49h+[ebp+var_4]
.text:00401782 mov eax, [ebp+var_4]
.text:00401785 xor edx, edx
.text:00401787 mov edi, 0D393EBh
.text:0040178C div edi ;edx = eax%edi == [ebp+var_4]% 0D393EBh
.text:0040178E add esi, ecx ;
.text:00401790 add edx, esi ;edx += esi == edx = edx+esi+ecx 这里把上面所有的做的结果相加
;这是前面我所记录的数值
;edx =[ebp+var_4]% 0D393EBh
;esi = [ebp+var_4]% 3DB6C49h+[ebp+var_4]
;ecx = [ebp+var_4]%64711753h
;综合起来就是
;edx =[ebp+var_4]%0D393EB+[ebp+var_4]% 3DB6C49h+[ebp+var_4]+[ebp+var_4]%64711753h
; 用C语言的代码就是
;var4%0x0d393eb + var4%0x3db6c49 + var4 + var4%0x64711753
.text:00401792 mov [ebp+var_4], edx ;这句就这么翻sum = (var1%0x0d393eb + var1%0x3db6c49 + var1 + var1%0x64711753);
好了大功告成了,双儿呢?
顺便说一下,面对这么多的算法代码,我唯一的办法只能是反汇编了,如果你能不列出算式就看出这段代码的意思,那请把的QQ或EMAIL留下我正想
学呢教教我。
我们现在完成了,对算法代码的反汇编。如何才能找到正确的值呢?。往下看这段代码
.text:00401795 cmp [ebp+var_4], 10632BC2h
.text:0040179C jnz short loc_4017AD
.text:0040179C
.text:0040179E push offset s_Ok ; "OK!\n"
.text:004017A3 call _printf
这不就是我最初找的字符串“OK”吗!合起来的代码意思就是我们输入的数据,经过我们上面分析的算法,计算之后不等于10632BC2h 就跳到printf error的代码去。跟据这个我们可以列出下列公式:
0x10632bc2 = (var1%0x0d393eb + var1%0x3db6c49 + var1 + var1%0x64711753);
这个好象用数学的方法可以解决。但我们不懂数学。只能用计算机的方法来解决他了。再说计算机最初始设计的目的就是计算密码,我这也算是一次野性
回归吧。虽然笨了点。谁让我不会数学呢!用这段C代码去算得到最后的得数:
int var1 = 0,sum;
for(; 0x10632bc2 > (var1%0x0d393eb + var1%0x3db6c49 + var1 + var1%0x64711753);var1++);
printf("out:%d\n" ,var1);
打印结果如下:
out:109177054
运行要破解的程序输入109177054结果如下:
3959846171
274934722
输入密码:
109177054
OK!
请按任意键继续. . .
最上面的两行数字没用。显示OK了。成功。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课