首页
社区
课程
招聘
[原创]分析算法的思路(只给新新新手)
发表于: 2011-5-10 12:43 4580

[原创]分析算法的思路(只给新新新手)

2011-5-10 12:43
4580

本文只是对只会玩爆破但想学算法的新手看的,高手飘过,第一次作品,错误请指出。
算法都少不了call,但是稍复杂一点的程序里面会有很多call(在关键部分附近),我们怎么知道哪个是关键call?而且进入关键call后我们要关注哪些数据?这些大牛们都讨论了N多遍,但他们的水平非我等小辈可比,他们会根据步过call后的寄存器变化就可以判断出它的作用,我们就茫然,所以看他们的文章就有点郁闷(是我太菜吧,反正我是不懂)。今天就来说说哪些call对结果有用,应关注哪些数据。说的只是一个思路(大牛们把这个当作一个当然,所以他们把这一步省了),具体的算法没写,但你可以从简单的入手。
首先找一个目标:我找的就是看雪大哥(他不认识我,我就厚着脸叫一声)的解密教学的“序列号保护方式习题的第九个”。
这个没加壳,我们就直接按字符串参考定位到关键跳转(只截一部分):
0042DB95  |> \8D55 FC        lea     edx, dword ptr [ebp-4]
0042DB98  |.  8B83 E4010000  mov     eax, dword ptr [ebx+1E4]
0042DB9E  |.  E8 85C6FEFF   call    0041A228
0042DBA3  |.  837D FC 00     cmp     dword ptr [ebp-4], 0
0042DBA7  |.  75 1A          jnz     short 0042DBC3           //判断输入是否为空,否则跑到相应处
0042DBA9  |.  6A 00          push    0
0042DBAB  |.  66:8B0D 1CDD4> mov     cx, word ptr [42DD1C]
0042DBB2  |.  B2 02          mov     dl, 2
0042DBB4  |.  B8 7CDD4200   mov     eax, 0042DD7C                    ;  please enter your serial !
0042DBB9  |.  E8 82F2FFFF   call    0042CE40
0042DBBE  |.  E9 2D010000   jmp     0042DCF0
0042DBC3  |>  8BC7          mov     eax, edi           //跑到这里,算法一定在这下面,在这里下断
0042DBC5  |.  E8 7A59FDFF   call    00403544
0042DBCA  |.  C706 02000000  mov     dword ptr [esi], 2
0042DBD0  |>  8D55 FC       /lea     edx, dword ptr [ebp-4]
0042DBD3  |.  8B83 E0010000  |mov     eax, dword ptr [ebx+1E0]
0042DBD9  |.  E8 4AC6FEFF   |call    0041A228
0042DBDE  |.  8B45 FC       |mov     eax, dword ptr [ebp-4]
0042DBE1  |.  8B16          |mov     edx, dword ptr [esi]
0042DBE3  |.  0FB64410 FF   |movzx   eax, byte ptr [eax+edx-1]
0042DBE8  |.  8D55 F8       |lea     edx, dword ptr [ebp-8]
0042DBEB  |.  E8 8889FDFF   |call    00406578
0042DBF0  |.  8B55 F8       |mov     edx, dword ptr [ebp-8]
0042DBF3  |.  8BC7          |mov     eax, edi
0042DBF5  |.  E8 CE5BFDFF   |call    004037C8
0042DBFA  |.  FF06          |inc     dword ptr [esi]
0042DBFC  |.  833E 07       |cmp     dword ptr [esi], 7
0042DBFF  |.^ 75 CF         \jnz     short 0042DBD0
0042DC01  |.  8D45 F8       lea     eax, dword ptr [ebp-8]
0042DC04  |.  50            push    eax
0042DC05  |.  B9 03000000   mov     ecx, 3
0042DC0A  |.  BA 01000000   mov     edx, 1
0042DC0F  |.  8B07          mov     eax, dword ptr [edi]
0042DC11  |.  E8 AE5DFDFF   call    004039C4                         ;  步过后两个数据都没变化
0042DC16  |.  8B45 F8       mov     eax, dword ptr [ebp-8]
0042DC19  |.  E8 8A89FDFF   call    004065A8                         ;  虽然步过后没改变,但下一条指令它的返回值改变第一个
0042DC1E  |.  A3 58F74200   mov     dword ptr [42F758], eax
0042DC23  |.  8BC7          mov     eax, edi
0042DC25  |.  E8 1A59FDFF   call    00403544             ;没改变
0042DC2A  |.  8BC3          mov     eax, ebx
0042DC2C  |.  E8 B3FCFFFF   call    0042D8E4                         ;  改变第一个
0042DC31  |.  A1 50F74200   mov     eax, dword ptr [42F750]
0042DC36  |.  A3 50F74200   mov     dword ptr [42F750], eax
0042DC3B  |.  8BC3          mov     eax, ebx
0042DC3D  |.  E8 F2FCFFFF   call    0042D934                         ;  改变第一个
0042DC42  |.  A1 58F74200   mov     eax, dword ptr [42F758]
0042DC47  |.  A3 58F74200   mov     dword ptr [42F758], eax
0042DC4C  |.  8BC3          mov     eax, ebx
0042DC4E  |.  E8 35FDFFFF   call    0042D988                         ;  改变第一个
0042DC53  |.  8BC3          mov     eax, ebx
0042DC55  |.  E8 7EFDFFFF   call    0042D9D8                         ;  改变第一个
0042DC5A  |.  A1 58F74200   mov     eax, dword ptr [42F758]
0042DC5F  |.  A3 58F74200   mov     dword ptr [42F758], eax
0042DC64  |.  8BC3          mov     eax, ebx
0042DC66  |.  E8 B1FDFFFF   call    0042DA1C                         ;  没改变,暂时没用
0042DC6B  |.  8BC3          mov     eax, ebx
0042DC6D  |.  E8 B6FDFFFF   call    0042DA28                         ;  没改变
0042DC72  |.  A1 58F74200   mov     eax, dword ptr [42F758]
0042DC77  |.  A3 58F74200   mov     dword ptr [42F758], eax
0042DC7C  |.  8BC3          mov     eax, ebx
0042DC7E  |.  E8 B1FDFFFF   call    0042DA34                         ;  变第一个
0042DC83  |.  8BC3          mov     eax, ebx
0042DC85  |.  E8 F2FDFFFF   call    0042DA7C
0042DC8A  |.  8BC3          mov     eax, ebx
0042DC8C  |.  E8 0BFEFFFF   call    0042DA9C                         ;  变第一个
0042DC91  |.  A1 50F74200   mov     eax, dword ptr [42F750]
0042DC96  |.  0105 58F74200 add     dword ptr [42F758], eax          ;  操作,这里我们下一步可就多了一个关注对象( eax也就是42f750)了,这是下一步的关注对象,我们先关注当前的对象(一个一个先后关注),所以这里就先不管了
0042DC9C  |.  8D55 FC       lea     edx, dword ptr [ebp-4]
0042DC9F  |.  8B83 E4010000 mov     eax, dword ptr [ebx+1E4]
0042DCA5  |.  E8 7EC5FEFF   call    0041A228                         ;  没改变
0042DCAA  |.  8B45 FC       mov     eax, dword ptr [ebp-4]
0042DCAD  |.  E8 F688FDFF   call    004065A8
0042DCB2  |.  A3 60F74200   mov     dword ptr [42F760], eax          ;  返回值赋给第二个
0042DCB7  |.  A1 58F74200   mov     eax, dword ptr [42F758]
0042DCBC  |.  3B05 60F74200 cmp     eax, dword ptr [42F760]
0042DCC2  |.  75 17         jnz     short 0042DCDB                   ;  关键跳!!!
0042DCC4  |.  6A 00         push    0
0042DCC6  |.  66:8B0D 1CDD4>mov     cx, word ptr [42DD1C]
0042DCCD  |.  B2 02         mov     dl, 2
0042DCCF  |.  B8 A0DD4200   mov     eax, 0042DDA0                    ;  good serial, thanks for trying this crackme by niabi !
0042DCD4  |.  E8 67F1FFFF   call    0042CE40
0042DCD9  |.  EB 15         jmp     short 0042DCF0
0042DCDB  |>  6A 00         push    0
0042DCDD  |.  66:8B0D 1CDD4>mov     cx, word ptr [42DD1C]
0042DCE4  |.  B2 02         mov     dl, 2
0042DCE6  |.  B8 E0DD4200   mov     eax, 0042DDE0                    ;  bad name or serial number !!!!!
0042DCEB  |.  E8 50F1FFFF   call    0042CE40
首先看关键跳处(关键跳我已标明),我们看它成功的条件是什么?要成功就必须0042DCBC处的eax和42f760地址里的(四个字节)数要相等,而看上面知道eax又等于42f758处的数,所以我们知道,成功的条件就是42f758(记为第一个地址)和42f760(记为第二个)处的数值相等!爆破的哥们当然就改这个地方就行,但是我们得弄算法啊!那么这两个地方的数是怎么来的?我们当然得往上看了。可以看到这里有好多call!思路不要乱,现在我们关注的就是(只是)那两处的数据(此为关注对象,现在知道该关注什么了吧)。那么我们可以想当然的认为,如果步过一个call我们那两处的数据不变,且下面也没有其返回结果传给这两处的话,那么这个call就没用(这里要想明白)。
我们把程序加载后,在我指示的地方下好断,然后把数据窗口打开,找到我们要关注的两处地址,接着就死死的盯着这两处!

然后我们F9运行,输入abcdef和123456( 至少6位),点cheak!程序断下,可以看到这两处都为0。盯着那两处,我们按F2单步,如果有地方执行过后这两处数据有变我们就注一下。我已做好注了,大家可以参考,可以定出对结果有影响的call来!

定出关键call后我们就可以进入其中分析算法,当然我们的关注对象还是那两处(中间可能会增加要关注的对象)。当把这两个对象的算法弄明白之后,我们再来关注下一个对象(像上面0042DC96处的eax,它影响到我们的对象了)。一个一个弄明白之后,呵呵,这个算法也就浮出水面。这个方法如果配合内存断点就完美了(ccdebuger大可的教程里已经说明了这个思路)。
我没时间弄算法了,就这样吧,只是给新手一个思路,有时间的话再自己写个简单的程序作例详细分析。
总结:
1.看成功的条件(条件有多个就一个一个分析) 2.根据条件定出关注对象  3.单步测试是不是关键的  4.进入关键call弄懂算法,再关注下一个对象  (下一个,再下一个。。。。)  5.完成!
(很抱歉,本来有图的,但不知道怎么插入,对不住了)


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (3)
雪    币: 24
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
不错,只要是原创的就支持,鼓励鼓励!
2011-5-10 13:46
0
雪    币: 20
活跃值: (42)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
3
不错的东西,谢谢分享。
2011-5-11 08:35
0
雪    币: 129
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
顶顶  嘿嘿
2011-5-11 08:52
0
游客
登录 | 注册 方可回帖
返回
//