【文章标题】: 初学者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:[esi-0x9015]
0040E34C 57 push edi
0040E34D 89E5 mov ebp,esp
0040E34F 8D9C24 80C1FFFF lea ebx,dword ptr ss:[esp-0x3E80]
0040E356 31C0 xor eax,eax
看入口代码..直接esp定律上.
(单步f8,右键寄存器esp--在数据窗口跟随.在数据窗口拉4个字节右键断点-硬件访问-Wrod,f9运行,删除硬件断点)
0040EECC 8D4424 80 lea eax,dword ptr ss:[esp-0x80]
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:[edi]
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:[0x40B228]
00401613 5A pop edx
由此可见这 这个call就是获取假码
一路走下去,逢call就进去看看... 004078C3 881401 mov byte ptr ds:[ecx+eax],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:[esp]
004078C0 8A1428 mov dl,byte ptr ds:[eax+ebp]
004078C3 881401 mov byte ptr ds:[ecx+eax],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] //eax+ebp地址的数值赋值给dl寄存器
mov byte ptr ds:[ecx+eax],dl //在ecx+eax的地方开辟00的空间, 为一会写数据做准备
大家可以在od里打d ecx+eax查看刚才清0的全过程
再这样逢call就进(系统的call就回来把...咱看他也没用)
走了很长时间,回头用peid插件发现他有md5+crc的加密,估计有很大的关系.
继续:
call跟完了,回到主地方了:
[code] 00406DAC E8 5F0A0000 call Unpack1.00407810 ; 获取字节数
00406DB1 8D4C24 20 lea ecx,dword ptr ss:[esp+0x20]
00406DB5 51 push ecx
00406DB6 8D5424 14 lea edx,dword ptr ss:[esp+0x14]
00406DBA 52 push edx
00406DBB E8 200B0000 call Unpack1.004078E0 ; 为一会md5准备
00406DC0 8B8424 8C000000 mov eax,dword ptr ss:[esp+0x8C]
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:[esp]
00406DDD 8D49 00 lea ecx,dword ptr ds:[ecx]
跟着上面的那个短jmp来到这里, 我们发下这段代码很古怪的: 00406DE0 0FB6140C movzx edx,byte ptr ss:[esp+ecx]
00406DE4 C1EA 04 shr edx,0x4
00406DE7 0FB692 E0904000 movzx edx,byte ptr ds:[edx+0x4090E0]
00406DEE 8810 mov byte ptr ds:[eax],dl
00406DF0 0FB6140C movzx edx,byte ptr ss:[esp+ecx]
00406DF4 83E2 0F and edx,0xF
00406DF7 0FB692 E0904000 movzx edx,byte ptr ds:[edx+0x4090E0]
00406DFE 8850 01 mov byte ptr ds:[eax+0x1],dl
00406E01 0FB6540C 01 movzx edx,byte ptr ss:[esp+ecx+0x1]
00406E06 C1EA 04 shr edx,0x4
00406E09 0FB692 E0904000 movzx edx,byte ptr ds:[edx+0x4090E0]
00406E10 8850 02 mov byte ptr ds:[eax+0x2],dl
00406E13 0FB6540C 01 movzx edx,byte ptr ss:[esp+ecx+0x1]
00406E18 83E2 0F and edx,0xF
00406E1B 0FB692 E0904000 movzx edx,byte ptr ds:[edx+0x4090E0]
00406E22 8850 03 mov byte ptr ds:[eax+0x3],dl
00406E25 0FB6540C 02 movzx edx,byte ptr ss:[esp+ecx+0x2]
00406E2A C1EA 04 shr edx,0x4
00406E2D 0FB692 E0904000 movzx edx,byte ptr ds:[edx+0x4090E0]
00406E34 8850 04 mov byte ptr ds:[eax+0x4],dl
00406E37 0FB6540C 02 movzx edx,byte ptr ss:[esp+ecx+0x2]
00406E3C 83E2 0F and edx,0xF
00406E3F 0FB692 E0904000 movzx edx,byte ptr ds:[edx+0x4090E0]
00406E46 8850 05 mov byte ptr ds:[eax+0x5],dl
00406E49 0FB6540C 03 movzx edx,byte ptr ss:[esp+ecx+0x3]
00406E4E C1EA 04 shr edx,0x4
00406E51 0FB692 E0904000 movzx edx,byte ptr ds:[edx+0x4090E0]
00406E58 8850 06 mov byte ptr ds:[eax+0x6],dl
00406E5B 0FB6540C 03 movzx edx,byte ptr ss:[esp+ecx+0x3]
00406E60 83E2 0F and edx,0xF
00406E63 0FB692 E0904000 movzx edx,byte ptr ds:[edx+0x4090E0]
00406E6A 8850 07 mov byte ptr ds:[eax+0x7],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
[/code]
我们发现在他都是一些传送指令和逻辑右移指令.莫非这就是算法部分?
我们来看下,在command 里跟下 :
d edx+0x4090e0
内存窗口显示: 004090E0 30 31 32 33 34 35 36 37 38 39 61 62 63 64 65 66 0123456789abcdef
不知道大家知道么? 在我印象里md5算法用到了0123456789abcdef这串数,
我们来验证一下,走走试试...
还有一个地址很可疑,esp+ecx 的地址, 我们在数据窗口看下(Command里输入 d esp+ecx)
他是在加密我们的假码.
004016A1 50 push eax
004016A2 50 push eax
004016A3 FF35 00B24000 push dword ptr ds:[0x40B200]
004016A9 FF35 C4B14000 push dword ptr ds:[0x40B1C4] ; Unpack1.0040C210
004016AF E8 5C2C0000 call Unpack1.00404310
004016B4 5A pop edx
循环结束后retu跟出去以后,发现信息框里面一串很古怪的字符串.
ds:[0040B1C4]=0040C210 (Unpack1.0040C210), ASCII "253f7b5d921338af34da817c00f42753V"
这是什么呢? 莫非是真码的md5值? 00404335 8A01 mov al,byte ptr ds:[ecx] ; 将ecx的地址数值赋给al
00404337 84C0 test al,al
00404339 74 0D je short Unpack1.00404348
0040433B 8806 mov byte ptr ds:[esi],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:[0x40B450],ecx
004016BC 030D 8CA34000 add ecx,dword ptr ds:[0x40A38C]
004016C2 0315 8CA34000 add edx,dword ptr ds:[0x40A38C]
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:[edx] ; 真码传送1字节给ah
00407A04 42 inc edx ; edx自加1
00407A05 8A01 mov al,byte ptr ds:[ecx] ; 假码传送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
他是判断每一位,只要有一位不对,就跳走,跳到哪可想而知了..
最简单的解决办法,就是他狂任他狂,清风照大缸...
咱只要把给nop掉
就可以了,因为这只是段子程序,这只是负责验证是否正确,正确eax=1否则就是0
代码是死的,人是活的,懂了代码,他就变成鱼肉了...
也可以把 00407A18 31C0 xor eax,eax
变成
00407A18 31C0 or eax,eax
一样的道理.
本人才疏学浅,有些东西理解错误或者片面,希望大家能指出来 谢谢
--------------------------------------------------------------------------------
2010年06月25日 16:40:51 |