好友
阅读权限25
听众
最后登录1970-1-1
|
【文章标题】: Delphi程序脱TMD修复OEP
【文章作者】: wuqing1501
【软件名称】: 某软件
【下载地址】: 不便提供
【使用工具】: 老三样
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
朋友给的软件让我破解,因为我是菜鸟不会破,所以就没有破解但是看到加壳是TMD的 而且是Delphi的,就想学习一下怎么脱TMD并修复OEP 于是就有了下文,基本上操作多是参看的 KISSY的视频的。
我们这里只是学习OEP的修复,至于IAT处理就使用脚本吧!此文仅为了那些和我一样在黑暗中慢慢摸索的菜鸟,大牛们就飘过吧!
好了,进入正题吧!
首先查壳
ThemIDA/WinLicense V1.8.X-V2.X -> Oreans Technologies * Sign.By.fly * 20080131 *
OD载入
009E0014 X> B8 00000000 mov eax,0 ; OD载入后停在这里
009E0019 60 pushad
009E001A 0BC0 or eax,eax
009E001C 74 68 je short XX.009E0086
009E001E E8 00000000 call XX.009E0023
009E0023 58 pop eax
009E0024 05 53000000 add eax,53
009E0029 8038 E9 cmp byte ptr ds:[eax],0E9
009E002C 75 13 jnz short XX.009E0041
009E002E 61 popad
009E002F EB 45 jmp short XX.009E0076
009E0031 DB2D 37009E00 fld tbyte ptr ds:[9E0037]
009E0037 FFFF ??? ; 未知命令
009E0039 FFFF ??? ; 未知命令
009E003B FFFF ??? ; 未知命令
009E003D FFFF ??? ; 未知命令
009E003F 3D 40E80000 cmp eax,0E840
很明显的TMD入口
好了我们使用这个脚本跑吧
TMDScript-1.9.1+_1.0 final_修正集成版.osc
OD载入脚本 运行完后停在这里
004061E4 53 push ebx ; 脚本运行完 停在这里
004061E5 8BD8 mov ebx,eax
004061E7 33C0 xor eax,eax
004061E9 A3 A0104B00 mov dword ptr ds:[4B10A0],eax
004061EE 6A 00 push 0
004061F0 E8 2BFFFFFF call XX.00406120 ; jmp 到 kernel32.GetModuleHandleA
004061F5 A3 68464B00 mov dword ptr ds:[4B4668],eax
004061FA A1 68464B00 mov eax,dword ptr ds:[4B4668]
004061FF A3 AC104B00 mov dword ptr ds:[4B10AC],eax
00406204 33C0 xor eax,eax
00406206 A3 B0104B00 mov dword ptr ds:[4B10B0],eax
0040620B 33C0 xor eax,eax
0040620D A3 B4104B00 mov dword ptr ds:[4B10B4],eax
00406212 E8 C1FFFFFF call XX.004061D8
00406217 BA A8104B00 mov edx,XX.004B10A8
0040621C 8BC3 mov eax,ebx
0040621E E8 D1DBFFFF call XX.00403DF4
00406223 5B pop ebx
00406224 C3 retn
这个就是程序的第一个CALL
此时 EAX的值为004B09D0
有这些我们可以写出OEP的前几句
push ebp
mov ebp,esp
add esp,-10
mov eax,004B09D0//第一个call时 EAX的值
call 004061E4//第一个CALL的地址
好了 我们按 F8 一直运行到
00406224 C3 retn
此时记下寄存器的数值
EAX 00000000
ECX 0012FF70
EDX 0012FF88
EBX 0012FF9C
ESP 0012FF80
EBP 0012FF94
ESI 5E0000BA
EDI FFFAAF8C
然后继续按F8将进入到TMD的VM中
00C2AD4A 68 E266860C push 0C8666E2
然后再按F8几次 走过第一个JMP后 在CODE段 00401000处F2断点,F9运行 然后再在在CODE段 00401000处F2断点再运行 直到停在第二个CALL内
00478CE0 53 push ebx ; 第二个CALL
00478CE1 A1 64304B00 mov eax,dword ptr ds:[4B3064]
00478CE6 8338 00 cmp dword ptr ds:[eax],0
00478CE9 74 0A je short XX.00478CF5
00478CEB 8B1D 64304B00 mov ebx,dword ptr ds:[4B3064] ; XX.004B4044
00478CF1 8B1B mov ebx,dword ptr ds:[ebx]
00478CF3 FFD3 call ebx
00478CF5 5B pop ebx
00478CF6 C3 retn
此时我们记下第二个CALL的地址 和寄存器的内容
EAX 03181804
ECX 0012FF70
EDX 0012FF88
EBX 0012FF9C
ESP 0012FF80
EBP 0012FF94
ESI 5E0000BA
EDI FFFAAF8C
然后我们与第一次记录的寄存器比较,发现只有EAX发生了变化 ,我们按CTRL+B搜索二进制 04 18 18 03 找到了地址004B1484,这时我们可以补充OEP为
push ebp
mov ebp,esp
add esp,-10
mov eax,004B09D0//第一个call时 EAX的值
call 004061E4//第一个CALL的地址
mov eax,dword ptr ds:[4B1484]//如果找不到的话可以直接写成mov eax,004B1484
mov eax,dword ptr ds:[eax]
CALL 00478CE0
然后我们继续按F8直到走完第二个CALL
00478CF6 C3 retn
此时我们再记录下寄存器的数据
EAX 00000001
ECX 76AB67F0 ole32.76AB67F0
EDX 76AB67F0 ole32.76AB67F0
EBX 0012FF9C
ESP 0012FF80
EBP 0012FF94
ESI 5E0000BA
EDI FFFAAF8C
然后我们继续安装上面的步骤执行 直到程序运行到第三个CALL
00406428 55 push ebp ; 第三个call
00406429 8BEC mov ebp,esp
0040642B 8B45 10 mov eax,dword ptr ss:[ebp+10]
0040642E 50 push eax
0040642F 837D 0C 01 cmp dword ptr ss:[ebp+C],1
00406433 1BC0 sbb eax,eax
00406435 40 inc eax
00406436 83E0 7F and eax,7F
00406439 50 push eax
0040643A 8B45 08 mov eax,dword ptr ss:[ebp+8]
0040643D 50 push eax
0040643E E8 DDFFFFFF call XX.00406420 ; jmp 到 kernel32.CreateMutexA
00406443 5D pop ebp
00406444 C2 0C00 retn 0C
此时我们记下 第三个CALL的地址和寄存器的数据
EAX 00000001
ECX 76AB67F0 ole32.76AB67F0
EDX 76AB67F0 ole32.76AB67F0
EBX 0012FF9C
ESP 0012FF74
EBP 0012FF94
ESI 5E0000BA
EDI FFFAAF8C
此时寄存器与我们上次记录的数据相比 只有ESP发生了变换 变化值为:0012FF74-0012FF80=-c 这时我们可以修复OEP为
push ebp
mov ebp,esp
add esp,-10
mov eax,004B09D0//第一个call时 EAX的值
call 004061E4//第一个CALL的地址
mov eax,dword ptr ds:[4B1484]//如果找不到的话可以直接写成mov eax,004B1484
mov eax,dword ptr ds:[eax]
CALL 00478CE0
add esp,-c
call 00406428
然后我们继续F8做完第三个CALL 记下寄存器的数据
EAX 00000208
ECX 0012FEF8
EDX 7C92E514 ntdll.KiFastSystemCallRet
EBX 0012FF9C
ESP 0012FF74
EBP 0012FF94
ESI 5E0000BA
EDI FFFAAF8C
然后继续按F8走到VM中,然后和上面一样继续CODE段下断点,直到程序停在非VM 中,中间遇到 012214DE F3:A4 rep movs byte ptr es:[edi],byte ptr d> 这样的可以 F7一次,然后再F8一次走过去,然后继续下断点运
行
运行几次后发现程序停在了这里
004B0E50 E8 D356F5FF call XX.00406528 ; jmp 到 ntdll.RtlGetLastWin32Error 最后停在这里了
004B0E55 3D B7000000 cmp eax,0B7
004B0E5A 75 10 jnz short XX.004B0E6C
004B0E5C A1 48534B00 mov eax,dword ptr ds:[4B5348]
004B0E61 50 push eax
004B0E62 E8 9955F5FF call XX.00406400 ; jmp 到 kernel32.CloseHandle
004B0E67 E9 C2000000 jmp XX.004B0F2E
004B0E6C A1 78314B00 mov eax,dword ptr ds:[4B3178]
走到这里我们可以直到已经运行到程序的部分了,这里就是OEP的附近了
此时我们记下寄存器中的数据
EAX 00000208
ECX 0012FEF8
EDX 7C92E514 ntdll.KiFastSystemCallRet
EBX 0012FF9C
ESP 0012FF84
EBP 0012FF94
ESI 5E0000BA
EDI FFFAAF8C
此时与上面的寄存器比较一下 还是只有 ESP发生变化 变化值为 0012FF84-0012FF74=10
好了我们可以把OEP修复为
push ebp
mov ebp,esp
add esp,-10
mov eax,004B09D0//第一个call时 EAX的值
call 004061E4//第一个CALL的地址
mov eax,dword ptr ds:[4B1484]//如果找不到的话可以直接写成mov eax,004B1484
mov eax,dword ptr ds:[eax]
CALL 00478CE0
add esp,-c
call 00406428
add esp,10
这样我们就找到了所有被VM的的OEP了,其实整个过程就是 看每次寄存器那些数据发生了变化 我们把相应的变化写出来就可以了
此时我们分析一下数据 看看OEP的具体位置在哪里?
根据Delphi程序的入口 OEP一般位于
0044CA7C . \4C364200 dd delphi7.0042364C
0044CA80 . ACC64400 dd delphi7.0044C6AC
0044CA84 . 50C64400 dd delphi7.0044C650
0044CA88 . 88C84400 dd delphi7.0044C888
0044CA8C . 58C84400 dd delphi7.0044C858
0044CA90 00 db 00
0044CA91 00 db 00
0044CA92 00 db 00
0044CA93 00 db 00
0044CA94 . 90C84400 dd delphi7.0044C890//根据Delphi程序的入口 OEP一般位于这个下面
看我们分析后的代码
004B0E02 ? 4A dec edx
004B0E03 ? 00CC add ah,cl
004B0E05 ? F7 ??? ; 未知命令
004B0E06 ? 4A dec edx
004B0E07 ? 00A0 094B0064 add byte ptr ds:[eax+64004B09],ah
004B0E0D ? 094B 00 or dword ptr ds:[ebx],ecx
004B0E10 00 db 00
004B0E11 00 db 00
004B0E12 00 db 00
004B0E13 00 db 00
004B0E14 A8094B00 dd XX.004B09A8
004B0E18 77 db 77 ; CHAR 'w'
004B0E19 3D db 3D ; CHAR '='
004B0E1A D6 db D6
那我们的OEP地址应该就是004B0E18 了
好我们把我们修复好的代码从这里开始写上去 发现写好后
004B0E50 E8 D356F5FF call XX.00406528这个代码与我们写的代码之间还有些数据,我们可以直接用个跳转跳到这里也可以直接把中间的代码都NOP掉,我就直接NOP掉了
好了 到了这里我们的工作基本上就算完成了
恩 在004B0E18 新建EIP吧,
然后用LordPE DUMP出来,再用ImportREC修复一下就可以了,看看怎么样软件运行了吧!
再此,多谢GUC大牛的帮助,帮我大半个晚上,刚开始一直是DUMP修复好的文件不能运行一直有错误提示,后来发现是系统的问题,经过重新启动电脑后,DUMP修复好的文件可以正常运行了。
其实这个壳的低版本是可以用OKDODO的脱壳机脱掉的,但是脱掉的 带了太多的VM 那样我们破解的时候就发现好多字符串是看不到的,但是我们还原了OEP以后 在搜下字符串吧,有了新的发现了吧!
好了就到这里吧 太晚 了 要休息了!
写下此文,以作纪念!
软件我就不提供了想学习的可以自己用TMD加壳自己再脱!
--------------------------------------------------------------------------------
【经验总结】
1,自己动手脱一边壳,比看上百遍的视屏和教程都有用!
2,通过脱这个过程熟悉了被TMD VM 了的OEP 的还原,很重要的一点就是要熟悉常见程序的OEP特征!
3,由于水平有限,小菜鸟一个,不知道怎么处理IAT的,这个还要以后多学习了!
--------------------------------------------------------------------------------
【版权声明】: 本文原创于wuqing1501[Upk], 菜鸟一个没有版权,欢迎转载,转载请注明作者并保持文章的完整, 谢谢!
2010年01月11日 AM 01:09:54 |
免费评分
-
查看全部评分
|