TA的每日心情 | 奋斗 2020-6-5 22:18 |
---|
签到天数: 22 天 [LV.4]偶尔看看III
|
原脱文参考:
【文章标题】: 手脱Tmd1950 unpackme
【文章作者】: a__p [CUG]
【作者邮箱】: a__p@163.com
【作者主页】: http://www.unpack.cn
【作者QQ号】: xxxxxxx
【软件名称】: test.exe
【软件大小】: 641 KB
【下载地址】: http://www.unpack.cn/viewthread.php?tid=18423&extra=page%3D2
【保护方式】: Themida/WinLicense V1.9.5.0
【使用工具】: OD修改版,LoadPE,ImportREC
【操作平台】: WINXP,WIN2003
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
脱壳大致流程:
1、代码段内存写入断点。
2、搜索代码:3985??????0?0F,改成JMP。
3、搜索代码:FFD3,上面4个JE改成NOP。
4、在ZwFreeVirtualMemory末尾下断。
5、在代码段下断就可以到OEP
废话不多说,配置好OD和插件,推荐用okdodo大侠的新版插件或者PhantOm plugin V1.20来隐藏。
0040C014 > B8 00000000 mov eax,0 ;载入点
0040C019 60 pushad
0040C01A 0BC0 or eax,eax
0040C01C 74 68 je short 0040C086
0040C01E E8 00000000 call 0040C023
0040C023 58 pop eax
0040C024 05 53000000 add eax,53
0040C029 8038 E9 cmp byte ptr ds:[eax],0E9
0040C02C 75 13 jnz short 0040C041
0040C02E 61 popad
0040C02F EB 45 jmp short 0040C076
0040C031 DB2D 37C04000 fld tbyte ptr ds:[40C037]
0040C037 FFFF ??? ; Unknown command
0040C039 FFFF ??? ; Unknown command
0040C03B FFFF ??? ; Unknown command
0040C03D FFFF ??? ; Unknown command
Alt+M在代码段下内存写入断点,Shift+F9运行,遇到 rep 代码时F7+F8步过
0054351A F3:A4 rep movs byte ptr es:[edi],byt> ;这里F7+F8
继续 shift+f9
00556B88 8F00 pop dword ptr ds:[eax] ;来到这里,取消代码段的内存断点
00556B8A 51 push ecx
00556B8B B9 00000000 mov ecx,0
00556B90 01C1 add ecx,eax
00556B92 8131 60585F23 xor dword ptr ds:[ecx],235F586>
00556B98 59 pop ecx
00556B99 E9 11000000 jmp 00556BAF
00556B9E 54 push esp
00556B9F 76 61 jbe short 00556C02
在这里我们先查看一下壳加密表的首地址和尾地址,方便后面修复IAT跨平台问题。
搜索代码(选上整个块):0000????????FFFFFFFFDDDDDDDD ,记下0054B4F8这个地址①。
0054B4F8 0000 add byte ptr ds:[eax],al ;加密表的首地址
0054B4FA 0000 add byte ptr ds:[eax],al
0054B4FC 0000 add byte ptr ds:[eax],al
0054B4FE FFFF ??? ; Unknown command
0054B500 FFFF ??? ; Unknown command
0054B502 DDDD fstp st(5)
0054B504 DDDD fstp st(5)
搜索代码(不选整个块):DDDDDDDD00000000 ,记下0054BA64这个地址②。
0054BA5E DDDD fstp st(5)
0054BA60 DDDD fstp st(5)
0054BA62 0000 add byte ptr ds:[eax],al
0054BA64 0000 add byte ptr ds:[eax],al ;加密表的尾地址
0054BA66 0000 add byte ptr ds:[eax],al
0054BA68 0000 add byte ptr ds:[eax],al
0054BA6A EB 40 jmp short 0054BAAC
接下来继续搜索代码(选上整个块):3985??????0?0F,把后面的JE改成JMP。(避开加密)
00554087 3985 752B4607 cmp dword ptr ss:[ebp+7462B75]> ;找到这里
0055408D 0F84 80000000 je 00554113
修改成
0055408D /E9 81000000 jmp 00554113
00554092 |90 nop
然后向下搜索代码(不选整个块):FFD3,找到它上面的4个JE改成NOP。(避开加密)
005548F5 /0F84 E9000000 je 005549E4 ;NOP
0055492C /0F84 B2000000 je 005549E4 ;NOP
00554955 /0F84 89000000 je 005549E4 ;NOP
00554991 /0F84 4D000000 je 005549E4 ;NOP
其中找第一个JE的时候,会有个花指令,可以在005548E9的JMP那里回车一下就可以看到了。
005548E9 /E9 06000000 jmp 005548F4 ;这里回车一下跟过去看看
做完上面以后,就可以Ctrl+G在ZwFreeVirtualMemory末尾下断了
7C92DA48 > B8 53000000 mov eax,53
7C92DA4D BA 0003FE7F mov edx,7FFE0300
7C92DA52 FF12 call dword ptr ds:[edx]
7C92DA54 C2 1000 retn 10 ;这里F2
OK,这时候可以按F9运行了,在ZwFreeVirtualMemory末尾断下后(不要取消断点),F8单步返回
00AD8F2F 8BF8 mov edi,eax ;返回在这
00AD8F31 85FF test edi,edi
00AD8F33 0F8C 68C60200 jl 00B055A1
00AD8F39 33C0 xor eax,eax
00AD8F3B 40 inc eax
00AD8F3C 5F pop edi
00AD8F3D 5E pop esi
00AD8F3E 5D pop ebp
00AD8F3F C2 1000 retn 10
断下后返回,循环在代码段下F2断点,这样可以查看到一些IAT和OEP信息(注意看寄存器信息),F9运行
00556B88 8F00 pop dword ptr ds:[eax] ;EAX=00407000 IAT开始③
00556B8A 51 push ecx
00556B8B B9 00000000 mov ecx,0
00556B90 01C1 add ecx,eax
00556B92 8131 60585F23 xor dword ptr ds:[ecx],235F586>
00556B98 59 pop ecx
...
004B6973 FF32 push dword ptr ds:[edx] ; kernel32.GetVersion ④
004B6975 ^ E9 F092FFFF jmp 004AFC6A
004B697A 81EE 344B114A sub esi,4A114B34
004B6980 8B3C24 mov edi,dword ptr ss:[esp]
断在004B6973的时候,把EDX的值记下,在代码段下F2断点就可以到OEP处了
00403897 33D2 xor edx,edx
00403899 8AD4 mov dl,ah
0040389B 8915 EC844000 mov dword ptr ds:[4084EC],edx
004038A1 8BC8 mov ecx,eax
004038A3 81E1 FF000000 and ecx,0FF
004038A9 890D E8844000 mov dword ptr ds:[4084E8],ecx
004038AF C1E1 08 shl ecx,8
004038B2 03CA add ecx,edx
004038B4 890D E4844000 mov dword ptr ds:[4084E4],ecx
004038BA C1E8 10 shr eax,10
004038BD A3 E0844000 mov dword ptr ds:[4084E0],eax
004038C2 33F6 xor esi,esi
004038C4 56 push esi
看到这些代码可以猜出是个VC++程序,OEP前面被偷了一小段代码,部分代码可以在堆栈区找回
来到堆栈区域,鼠标往下拉一点...
0012FF84 0012FFE0 Pointer to next SEH record
0012FF88 00404C64 SE handler ;补OEP用到的⑤
0012FF8C 00407100 test.00407100 ;补OEP用到的⑥
0012FF90 FFFFFFFF
找个VC++ 未加壳的程序,OD载入后把前面一段代码复制过来.
0040386B 55 push ebp
0040386C 8BEC mov ebp,esp
0040386E 6A FF push -1
00403870 68 00714000 push 00407100 ;这里看堆栈信息
00403875 68 644C4000 push 00404C64 ;这里看堆栈信息
0040387A 64:A1 00000000 mov eax,dword ptr fs:[0]
00403880 50 push eax
00403881 64:8925 00000000 mov dword ptr fs:[0],esp
00403888 83EC 58 sub esp,58
0040388B 53 push ebx
0040388C 56 push esi
0040388D 57 push edi
0040388E 8965 E8 mov dword ptr ss:[ebp-18],esp
00403891 FF15 6C704000 call dword ptr ds:[40706C] ; kernel32.GetVersion
00403891这个CALL的值就是刚才断在004B6973的时候EDX的值,补上即可
在0040386B新建EIP,现在打开LOADPE选择TEST.EXE修正镜像后DUMP下来,然后打开 ImportRE
OEP:0000386B 自动查找IAT
RVA:00006FFC 大小:000000F4
获取输入表CreateThread
发现有一个函数无效,这时候可以记住这个无效的地址,然后在OD中Ctrl+G 来到:
026E0000 8BFF mov edi,edi
026E0002 E9 0C000000 jmp 026E0013
026E0007 04 ED add al,0ED
这里都是些花指令,直接在JMP那里回车一路跟过去,到后面就会出现要找的函数.
026E017D E8 06000000 call 026E0188 ;到这的时候回车跟进去
026E0182 06 push es
026E01AE 61 popad
026E01AF E8 7802137A call kernel32.CreateRemoteThread
026E01B4 60 pushad
出来了....跟踪发现是CreateThread函数。
IAT修复转存DUMP的程序.
PEDI查壳:Microsoft Visual C++ 6.0
试运行正常.
脱壳后发现IAT地址都是绝对地址,这样是不能跨平台运行的,让我们来修复一下。
这里借用fxyang大侠的脱壳脚本部分代码来改装一下,达到修复IAT格式问题。再次拜模fxyang哥哥的脚本功力。。。
首先载入已脱壳修复的程序,依次输入脚本中用到的3个地址,脱壳过程中记录下来了。
//这里脚本开始
var cbase
var csize
var dllsize
var tmp
var temp
var iattop
var iatadd
var iatcalltop
var iatcallend
bphwcall
bpmc
exec
pushad
pushfd
ende
ask "请输入IAT基地址"
cmp $RESULT,0
je Over
mov iattop,$RESULT
ask "请输入加密表的首地址"
cmp $RESULT,0
je Over
mov iatcalltop,$RESULT
ask "请输入加密表的尾地址"
cmp $RESULT,0
je Over
mov iatcallend,$RESULT
gmi eip,CODEBASE
mov cbase,$RESULT
gmi eip,CODESIZE
mov csize,$RESULT
mov ecx,cbase
add csize,cbase
mov edx,csize
mov iatadd,iattop
loopiatadd:
sub iatadd,04
cmp [iatadd],0
je iataddbase
jmp loopiatadd
iataddbase:
mov iattop,iatadd
sub iattop,04
cmp [iattop],0
je findiatbase
jmp loopiatadd
findiatbase:
add iatadd,04
mov ebx,iatadd
log iatadd
mov [iatcalltop],#8A013CE89074273CE97423668B01663DFF157477663DFF257471833900907503419090413BCA0F8FDE000000EBD2909090909090909090909090909090909090909090909090909090908B690103E983C5058BF3AD83F800750A833E009074C3909090903BE87402EBEA8079FF9075218039E9750866C741FFFF25EB0666C741FFFF1583EE04897101EB2190EB269090908039E9750866C701FF2590EB0566C701FF159083EE04897102909083C104E96FFFFFFF908B690203E983C5068BF3AD83F800750A833E00900F8454FFFFFF3BE87402EBEA8079FF907521668139FF15750866C741FFFF15EB0866C741FFFF2583EE04897101EB0A0000000083EE0489710283C104E919FFFFFF909090#
mov tmp,eip
log tmp
mov eip,iatcalltop
sti
mov temp,iatcalltop
add temp,010c
bphws temp,"x"
esto
bphwcall
mov eip,tmp
bp eip
exec
popfd
popad
ende
bc eip
msg "脚本执行完成,iat表修复完成"
eval "IAT基地址在:{iatadd}"
msg $RESULT
ret
Over:
msg "用户已取消操作,脚本中断"
ret
//这里脚本结束
运行完脚本后,你会发现IAT调用格式已恢复正常了,特意还在WIN2003下测试通过。到此,脱壳修复完毕。
附文中用到的目标文件和插件,再次感谢 ^,^
Tmd1950 unpackme 新anti
http://www.unpack.cn/viewthread.php?tid=18423&extra=page%3D2
OD隐藏插件
http://www.unpack.cn/viewthread.php?tid=19109&extra=page%3D1
PhantOm plugin V1.20.by Hellsp@wn & Archer
http://www.unpack.cn/viewthread.php?tid=19261
--------------------------------------------------------------------------------
【版权声明】: 本文原创于一蓑烟雨技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2007年11月22日 10:17:14
[ 本帖最后由 a__p 于 2007-11-22 10:32 编辑 ] |
|