jnad 发表于 2010-6-25 16:42

初学者脱破md5查密文

【文章标题】: 初学者md5脱破查密文
【文章作者】: jnad
【作者邮箱】:866664#163.com
【软件名称】: 我也不知道
【软件大小】: 22k
【下载地址】: 自己搜索下载
【保护方式】: 不知名软件保护
【使用工具】: od,peid
--------------------------------------------------------------------------------
【详细过程】
peid侦壳.UPX ->.upx.sourceforge.net *
od载入,弹出可黑框框,估计是被保护程序是个bat..
0040E340 >60            pushad
0040E341    BE 15A04000   mov esi,xxx.0040A015
0040E346    8DBE EB6FFFFF   lea edi,dword ptr ds:
0040E34C    57            push edi
0040E34D    89E5            mov ebp,esp
0040E34F    8D9C24 80C1FFFF lea ebx,dword ptr ss:
0040E356    31C0            xor eax,eax

看入口代码..直接esp定律上.
(单步f8,右键寄存器esp--在数据窗口跟随.在数据窗口拉4个字节右键断点-硬件访问-Wrod,f9运行,删除硬件断点)

0040EECC    8D4424 80       lea eax,dword ptr ss:
0040EED0    6A 00         push 0x0
0040EED2    39C4            cmp esp,eax
0040EED4^ 75 FA         jnz short xxx.0040EED0
0040EED6    83EC 80         sub esp,-0x80
0040EED9- E9 2221FFFF   jmp xxx.00401000


有个循环,f4打断.走.jmp跳.到达oep

00401000    68 CC000000   push 0xCC
00401005    68 00000000   push 0x0
0040100A    68 8CB14000   push xxx.0040B18C
0040100F    E8 7C210000   call xxx.00403190                        ; jmp 到 msvcrt.memset
00401014    83C4 0C         add esp,0xC
00401017    68 00000000   push 0x0
0040101C    E8 7B210000   call xxx.0040319C                        ; jmp 到 kernel32.GetModuleHandleA

ok开始脱壳.
运行lordPE 找到调试进程,修正镜像大小 (不进行这一步某些程序会无法运行的)
完整转储
Import rec 修正输入表
输入oep 1000
自动查找IAt
获取输入表.
显示无效函数.
没有,ok ,转储文件
看下我们脱壳的文件
运行,ok
继续





f9直接运行,他是直接弹出对话框,输入密码,错误,弹出对话框
重载,我们下GetWindowTextA断点.
BP GetWindowTextA.
f9 运行 输入我们的假码 jnad
   断下来了, ALT+f9 返回用户执行代码
00404B75    FF37            push dword ptr ds:
00404B77    FF15 D8A74000   call dword ptr ds:[<&user32.#376>]       ; USER32.GetWindowTextA
00404B7D    53            push ebx
00404B7E    E8 A3370000   call <jmp.&msvcrt.#774>
00404B83    59            pop ecx
00404B84    2BF0            sub esi,eax
00404B86    56            push esi
00404B87    E8 94310000   call Unpack1.00407D20
00404B8C    5E            pop esi

返回retn


00401601    50            push eax
00401602    50            push eax
00401603    68 02000000   push 0x2
00401608    E8 1F350000   call Unpack1.00404B2C                  ; 获取假码
0040160D    8D0D 28B24000   lea ecx,dword ptr ds:
00401613    5A            pop edx



由此可见这 这个call就是获取假码
一路走下去,逢call就进去看看...
004078C3    881401          mov byte ptr ds:,dl
004078C6    83C0 01         add eax,0x1                              ; 获取字节数
004078C9    3BC7            cmp eax,edi
004078CB^ 72 F3         jb short Unpack1.004078C0

又来到这里了
004078B9    8DA424 00000000 lea esp,dword ptr ss:
004078C0    8A1428          mov dl,byte ptr ds:
004078C3    881401          mov byte ptr ds:,dl
004078C6    83C0 01         add eax,0x1                              ; 获取字节数
004078C9    3BC7            cmp eax,edi
004078CB^ 72 F3         jb short Unpack1.004078C0

看来他还有别的功能,咱初学,先不管,继续
这里他需要循环0x34次
其实这段话
mov dl,byte ptr ds: //eax+ebp地址的数值赋值给dl寄存器
mov byte ptr ds:,dl //在ecx+eax的地方开辟00的空间, 为一会写数据做准备
大家可以在od里打d ecx+eax查看刚才清0的全过程
再这样逢call就进(系统的call就回来把...咱看他也没用)

走了很长时间,回头用peid插件发现他有md5+crc的加密,估计有很大的关系.
继续:
call跟完了,回到主地方了:
00406DAC    E8 5F0A0000   call Unpack1.00407810                  ; 获取字节数
00406DB1    8D4C24 20       lea ecx,dword ptr ss:
00406DB5    51            push ecx
00406DB6    8D5424 14       lea edx,dword ptr ss:
00406DBA    52            push edx
00406DBB    E8 200B0000   call Unpack1.004078E0                  ; 为一会md5准备
00406DC0    8B8424 8C000000 mov eax,dword ptr ss:
00406DC7    83C4 18         add esp,0x18
00406DCA    50            push eax
00406DCB    6A 20         push 0x20
00406DCD    E8 AE0E0000   call Unpack1.00407C80                  ; 再次获取假码
00406DD2    33C9            xor ecx,ecx
00406DD4    EB 0A         jmp short Unpack1.00406DE0
00406DD6    8DA424 00000000 lea esp,dword ptr ss:
00406DDD    8D49 00         lea ecx,dword ptr ds:


跟着上面的那个短jmp来到这里, 我们发下这段代码很古怪的:
00406DE0    0FB6140C      movzx edx,byte ptr ss:
00406DE4    C1EA 04         shr edx,0x4
00406DE7    0FB692 E0904000 movzx edx,byte ptr ds:
00406DEE    8810            mov byte ptr ds:,dl
00406DF0    0FB6140C      movzx edx,byte ptr ss:
00406DF4    83E2 0F         and edx,0xF
00406DF7    0FB692 E0904000 movzx edx,byte ptr ds:
00406DFE    8850 01         mov byte ptr ds:,dl
00406E01    0FB6540C 01   movzx edx,byte ptr ss:
00406E06    C1EA 04         shr edx,0x4
00406E09    0FB692 E0904000 movzx edx,byte ptr ds:
00406E10    8850 02         mov byte ptr ds:,dl
00406E13    0FB6540C 01   movzx edx,byte ptr ss:
00406E18    83E2 0F         and edx,0xF
00406E1B    0FB692 E0904000 movzx edx,byte ptr ds:
00406E22    8850 03         mov byte ptr ds:,dl
00406E25    0FB6540C 02   movzx edx,byte ptr ss:
00406E2A    C1EA 04         shr edx,0x4
00406E2D    0FB692 E0904000 movzx edx,byte ptr ds:
00406E34    8850 04         mov byte ptr ds:,dl
00406E37    0FB6540C 02   movzx edx,byte ptr ss:
00406E3C    83E2 0F         and edx,0xF
00406E3F    0FB692 E0904000 movzx edx,byte ptr ds:
00406E46    8850 05         mov byte ptr ds:,dl
00406E49    0FB6540C 03   movzx edx,byte ptr ss:
00406E4E    C1EA 04         shr edx,0x4
00406E51    0FB692 E0904000 movzx edx,byte ptr ds:
00406E58    8850 06         mov byte ptr ds:,dl
00406E5B    0FB6540C 03   movzx edx,byte ptr ss:
00406E60    83E2 0F         and edx,0xF
00406E63    0FB692 E0904000 movzx edx,byte ptr ds:
00406E6A    8850 07         mov byte ptr ds:,dl
00406E6D    83C1 04         add ecx,0x4
00406E70    83C0 08         add eax,0x8
00406E73    83F9 10         cmp ecx,0x10
00406E76^ 0F8C 64FFFFFF   jl Unpack1.00406DE0



我们发现在他都是一些传送指令和逻辑右移指令.莫非这就是算法部分?
我们来看下,在command 里跟下 :
d edx+0x4090e0
内存窗口显示:
004090E030 31 32 33 34 35 36 37 38 39 61 62 63 64 65 660123456789abcdef
不知道大家知道么? 在我印象里md5算法用到了0123456789abcdef这串数,
我们来验证一下,走走试试...
还有一个地址很可疑,esp+ecx 的地址, 我们在数据窗口看下(Command里输入 d esp+ecx)
他是在加密我们的假码.

004016A1    50            push eax
004016A2    50            push eax
004016A3    FF35 00B24000   push dword ptr ds:
004016A9    FF35 C4B14000   push dword ptr ds:             ; Unpack1.0040C210
004016AF    E8 5C2C0000   call Unpack1.00404310
004016B4    5A            pop edx

循环结束后retu跟出去以后,发现信息框里面一串很古怪的字符串.
ds:=0040C210 (Unpack1.0040C210), ASCII "253f7b5d921338af34da817c00f42753V"
这是什么呢? 莫非是真码的md5值?
00404335    8A01            mov al,byte ptr ds:               ;将ecx的地址数值赋给al
00404337    84C0            test al,al
00404339    74 0D         je short Unpack1.00404348
0040433B    8806            mov byte ptr ds:,al
0040433D    83C6 01         add esi,0x1                              ; esi+1
00404340    83C1 01         add ecx,0x1                              ; ecx+1
00404343    83EF 01         sub edi,0x1                              ; -1
00404346^ 75 ED         jnz short Unpack1.00404335

真码在进行某种运算?
先不管了,继续.本着逢call就进的原则,我们来的了这里:
004016B6    890D 50B44000   mov dword ptr ds:,ecx
004016BC    030D 8CA34000   add ecx,dword ptr ds:
004016C2    0315 8CA34000   add edx,dword ptr ds:
004016C8    E8 23630000   call Unpack1.004079F0
004016CD    75 2E         jnz short Unpack1.004016FD
004016CF    68 10000000   push 0x10
看下我们的寄存器的状态:
EAX 00000041
ECX 00910898 ASCII "1aedf102e293a0cbd59c8116939ea90a"
EDX 009108B9 ASCII "253f7b5d921338af34da817c00f42753"
EBX 00000004
ESP 0012FFC4
EBP 0000001A
载入了真码和假码,其实到这步,我们已经得到了密码的md5值,他的md5值,到查密的网站查密得1521
为了爆破他,我们继续....
进call 004016c8:
004079F9    09C9            or ecx,ecx                               ; 或
004079FB    75 05         jnz short Unpack1.00407A02
004079FD    B9 71A34000   mov ecx,Unpack1.0040A371
00407A02    8A22            mov ah,byte ptr ds:               ; 真码传送1字节给ah
00407A04    42            inc edx                                  ; edx自加1
00407A05    8A01            mov al,byte ptr ds:               ; 假码传送1字节给al
00407A07    41            inc ecx                                  ; ecx自加1
00407A08    38C4            cmp ah,al                              ; 真假各个位进行比较
00407A0A    75 0C         jnz short Unpack1.00407A18               ; 不相同跳走
00407A0C    08E4            or ah,ah                                 ; 或
00407A0E^ 75 F2         jnz short Unpack1.00407A02               ; 循环所有md5各个位
00407A10    B8 01000000   mov eax,0x1                              ; eax=1
00407A15    85C0            test eax,eax
00407A17    C3            retn
00407A18    31C0            xor eax,eax
00407A1A    85C0            test eax,eax
00407A1C    C3            retn

他是判断每一位,只要有一位不对,就跳走,跳到哪可想而知了..
最简单的解决办法,就是他狂任他狂,清风照大缸...

咱只要把
jnz short 00407A18
给nop掉   


就可以了,因为这只是段子程序,这只是负责验证是否正确,正确eax=1否则就是0
代码是死的,人是活的,懂了代码,他就变成鱼肉了...
也可以把
00407A18    31C0            xor eax,eax
变成
00407A18    31C0            or eax,eax
一样的道理.

本人才疏学浅,有些东西理解错误或者片面,希望大家能指出来 谢谢


--------------------------------------------------------------------------------
                                                       2010年06月25日 16:40:51

zyl3201 发表于 2010-6-25 17:22

哇,很不错的讲解支持下,学习下

kenljc 发表于 2010-6-26 02:50

学习,再学习

fenqingfj 发表于 2010-6-26 12:49

晕,这是怎么破解的,没看懂

Hmily 发表于 2010-6-26 19:28

第一篇技术贴加精鼓励,期待更多作品!

zhoudongzhou 发表于 2010-7-4 20:34

四位的MD5求值,一般的MD网站可以查出
如果大于8位+字符,楼主也就。。。

先学了

118114 发表于 2010-7-5 07:42

本人正努力的学习中,认真的看了,还是看不懂

boteli 发表于 2010-7-5 09:39

支持啊。。。虽然看不懂。但是还是要支持

mystery520 发表于 2010-7-7 21:01

很详细学习一下

0000000 发表于 2010-7-8 23:19

呵呵 不错。 不错。 鼓励一下
页: [1] 2
查看完整版本: 初学者脱破md5查密文