首页
社区
课程
招聘
[分享]合适初学者学习的算法破解
发表于: 2007-12-26 15:04 3172

[分享]合适初学者学习的算法破解

2007-12-26 15:04
3172
合适初学者学习的算法破解

在看雪上的时间也不算短了。不断的学习各位大侠的文章,很感谢他们的努力写出那么多那么好的文章来。获取了那么多自己觉得应该对论坛也贡献一些
只是水平有限,实在是拿不出手,昨天朋友给我一个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直播授课

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 50161
活跃值: (20620)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
谢谢你与大家分享心得
2007-12-26 17:39
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
不错不错,好好学习一下
2007-12-26 18:38
0
雪    币: 239
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
感谢坛主支持
2007-12-27 15:10
0
游客
登录 | 注册 方可回帖
返回
//