-
-
[原创]算法分析初步
-
发表于:
2006-8-6 18:20
6589
-
【破文标题】算法分析初步
【破文作者】逍遥风
【破解工具】OD,计算器
【破解平台】WINXP
【破解声明】由于这个CRACKME的算法的关键只有一步加法运算,所以只需分析出加法就可以了
----------------------------------------------------------------------
今天的任务就是让大家大概了解一下简单的算法分析是如何得来的。
首先用OD载入这个CRACKME,发现加了壳。根据经验判断应该是UPX的壳,脱壳很简单,几下就脱掉了
它的马甲。这不用关心因为重点不是脱壳所以这部分一笔带过。用OD载入脱壳后的CRACKME。
根据错误提示很容易找到关键代码。
1)整体感知:
先看一下整个的流程:
00447EAC |. 8BF0 mov esi, eax
00447EAE |. 33C0 xor eax, eax
00447EB0 |. 55 push ebp
00447EB1 |. 68 A17F4400 push 00447FA1
00447EB6 |. 64:FF30 push dword ptr fs:[eax]
00447EB9 |. 64:8920 mov fs:[eax], esp
00447EBC |> 8D55 F0 /lea edx, [ebp-10]
00447EBF |. 8B86 D0020000 |mov eax, [esi+2D0]
00447EC5 |. E8 36C2FDFF |call 00424100 ; 取注册名进行计算
00447ECA |. 8B55 F0 |mov edx, [ebp-10] ; 使EDX等于注册名
00447ECD |. 8D45 FC |lea eax, [ebp-4]
00447ED0 |. E8 EFBCFBFF |call 00403BC4
00447ED5 |. 8B45 FC |mov eax, [ebp-4] ; 使EAX等于注册名
00447ED8 |. E8 DFBCFBFF |call 00403BBC ; 取注册名位数
00447EDD |. 83F8 06 |cmp eax, 6 ; 注册名位数与6比较
00447EE0 |.^ 7C DA \jl short 00447EBC
00447EE2 |. 8D45 F8 lea eax, [ebp-8]
00447EE5 |. BA B87F4400 mov edx, 00447FB8 ; xxxxxx
00447EEA |. E8 E5BAFBFF call 004039D4
00447EEF |. BB 01000000 mov ebx, 1 ; 使EBX等于1,开始算法计算
00447EF4 |> 8D45 F8 /lea eax, [ebp-8]
00447EF7 |. E8 90BEFBFF |call 00403D8C ; 用计算结果替换固定字符串中的X
00447EFC |. 8B55 FC |mov edx, [ebp-4]
00447EFF |. 8A541A FF |mov dl, [edx+ebx-1] ; 取注册名每一位的ASCII码
00447F03 |. 80C2 05 |add dl, 5 ; 注册名每一位的ASCII码加上5
00447F06 |. 885418 FF |mov [eax+ebx-1], dl ; 将计算的结果保存,并转换成对应的字母
00447F0A |. 43 |inc ebx ; 每计算一次EBX+1
00447F0B |. 83FB 07 |cmp ebx, 7 ; 计算次数与7比较
00447F0E |.^ 75 E4 \jnz short 00447EF4 ; 循环计算
00447F10 |. 8D45 F4 lea eax, [ebp-C] ; 使EAX等于循环计算的结果
00447F13 |. BA C87F4400 mov edx, 00447FC8 ; hey, u r realy good!\n\nsend ur solution to moon.86@gmx.de!
00447F18 |. E8 B7BAFBFF call 004039D4
00447F1D |. 8D55 EC lea edx, [ebp-14]
00447F20 |. 8B86 EC020000 mov eax, [esi+2EC]
00447F26 |. E8 F9C4FFFF call 00444424 ; 取输入的注册码
00447F2B |. 8B55 EC mov edx, [ebp-14] ; 使EDX等于输入的注册码
00447F2E |. 8B45 F8 mov eax, [ebp-8] ; 使EAX等于真正的注册码
00447F31 |. E8 96BDFBFF call 00403CCC ; 真假注册码比较。
00447F36 |. 75 26 jnz short 00447F5E ; 不相等就跳向失败
----------------------------------------------------------------------
2)各个击破
以下面这段简单的代码进行说明:(省略了一些无关的代码和操作,直接来到算法的核心部分:)
00447EE2 |. 8D45 F8 lea eax, [ebp-8]
00447EE5 |. BA B87F4400 mov edx, 00447FB8 ; xxxxxx(固定字符串)
00447EEA |. E8 E5BAFBFF call 004039D4
00447EEF |. BB 01000000 mov ebx, 1 ; 使EBX等于1,开始算法计算
00447EF4 |> 8D45 F8 /lea eax, [ebp-8]
00447EF7 |. E8 90BEFBFF |call 00403D8C ; 用计算结果替换固定字符串中的X
00447EFC |. 8B55 FC |mov edx, [ebp-4]
00447EFF |. 8A541A FF |mov dl, [edx+ebx-1] ; 取注册名每一位的ASCII码
00447F03 |. 80C2 05 |add dl, 5 ; 注册名每一位的ASCII码加上5
00447F06 |. 885418 FF |mov [eax+ebx-1], dl ; 将计算的结果保存,并转换成对应的字母
00447F0A |. 43 |inc ebx ; 每计算一次EBX+1
00447F0B |. 83FB 07 |cmp ebx, 7 ; 计算次数与7比较
00447F0E |.^ 75 E4 \jnz short 00447EF4 ; 循环计算
00447F10 |. 8D45 F4 lea eax, [ebp-C] ; 使EAX等于循环计算的结果
现在、就简单说说这个算法的分析过程是如何得来的。
----------------------------------------------------------------------
这个算法的可以归结为3个问题:
1)取注册名的ASCII码
2)注册名ASCII码加5,并将计算结果转换成对应的字符
3)用计算得到的字符替换固定字符串中的X
下面开始详细说说,上面的计算过程是怎样得来的:
问题1:
为什么00447EFF处的代码的作用是“取注册名每一位的ASCII码”
我们先运行到这段代码上,这时注意OD中各个窗口的情况,尤其是寄存器窗口(如图1)
再用F8单步走过这里,注意寄存器窗口的值变化了,信息窗口也出现了提示(如图2,3)
在这里实验用的注册名是lovetc,l对应的ASCII码就是6C。当步过这句代码时寄存器EDX中的值变为了******6C
信息窗口也出现"dl=6C('l')"的字样。
所以就可以确定这句代码的作用就是取注册名第一位的ASCII码。
注意:现在只能确定是取注册名第一位的ASCII码,还不能确定是取注册码每一位的ASCII码。
问题2:
为什么00447F03处的代码的作用是“注册名每一位的ASCII码加上5”
这句代码"add dl 5",结合上一个问题中信息窗口的提示:dl=6C('l')
也就是说:将DL中的值与5相加 ,而DL中的值等于6C,6C又是注册名第一位的ASCII码。
那么就可以猜测一下,打开WINDOWS自带的计算器。计算6C+5=71。
结合这句代码,可以猜测得出经过计算DL中的值应该等于71。现在F8步过这句代码,
注意信息窗口和寄存器窗口的情况(如图4,5)
寄存器窗口中的EDX中的值变成了******71,信息窗口的内容也提示"dl=71('q')"
所以就可以得出结论:这句代码作用是注册名第一位的ASCII码加上5。
问题3:
为什么00447EF7处的代码的作用是“用计算结果替换固定字符串中的X”
首先:还是运行到00447EF7这个位置,注意各个窗口的情况以寄存器窗口为例(如图6)。
再F8步过这个CALL,再以次观察寄存器窗口(如图7)
字符串“XXXXXX”现在变成了“qXXXXX”。结合上个问题的结论,71既是加法计算的结果
又是字母q对应的ASCII码。
所以可以确定这个CALL的作用就是用计算的结果对应的字符替换字符串中的X。
解决完了这3个问题,还有一点需要注意,现在得出得结论都是对于单个字符而言的,是否适用
于整个循环过程呢?也就是说:“取注册名第一位的ASCII码”
是否可以推广成“取注册码每一位的ASCII码”
这个时候就要做进一步的跟踪分析,注意各个窗口值的变化。方法和上文中提到的一样。
----------------------------------------------------------------------
现在经过了算法的计算,就该进行真假注册码的比较了,这里又提供了依次巩固练习的机会
00447F26 |. E8 F9C4FFFF call 00444424 ; 取输入的注册码
00447F2B |. 8B55 EC mov edx, [ebp-14] ; 使EDX等于输入的注册码
00447F2E |. 8B45 F8 mov eax, [ebp-8] ; 使EAX等于真正的注册码
00447F31 |. E8 96BDFBFF call 00403CCC ; 真假注册码比较。
00447F36 |. 75 26 jnz short 00447F5E ; 不相等就跳向失败
。。。
00447F65 |. BA 1C804400 mov edx, 0044801C ; u fuckin noob!
问题1
1)为什么说00447F2B处代码的作用是“使EDX等于输入的注册码”
2)为什么说00447F2E处代码的作用是“使EAX等于真正的注册码”
这两个问题现在已经可以自己动手,轻松解决了。
----------------------------------------------------------------------
一篇班门弄斧的文章,大家见笑了。
----------------------------------------------------------------------
【版权声明】本文只为交流,转载请保留作者及文章完整性
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课