wuqing1501 发表于 2010-1-11 01:20

Delphi程序脱TMD修复OEP

【文章标题】: 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:,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:
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:,eax
004061EE   6A 00            push 0
004061F0   E8 2BFFFFFF      call XX.00406120                      ; jmp 到 kernel32.GetModuleHandleA
004061F5   A3 68464B00      mov dword ptr ds:,eax
004061FA   A1 68464B00      mov eax,dword ptr ds:
004061FF   A3 AC104B00      mov dword ptr ds:,eax
00406204   33C0               xor eax,eax
00406206   A3 B0104B00      mov dword ptr ds:,eax
0040620B   33C0               xor eax,eax
0040620D   A3 B4104B00      mov dword ptr ds:,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:
00478CE6   8338 00            cmp dword ptr ds:,0
00478CE9   74 0A            je short XX.00478CF5
00478CEB   8B1D 64304B00      mov ebx,dword ptr ds:         ; XX.004B4044
00478CF1   8B1B               mov ebx,dword ptr ds:
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://如果找不到的话可以直接写成mov eax,004B1484
mov eax,dword ptr ds:
CALL00478CE0


然后我们继续按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:
0040642E   50               push eax
0040642F   837D 0C 01         cmp dword ptr ss:,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:
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://如果找不到的话可以直接写成mov eax,004B1484
mov eax,dword ptr ds:
CALL00478CE0
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:,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:
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:

走到这里我们可以直到已经运行到程序的部分了,这里就是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://如果找不到的话可以直接写成mov eax,004B1484
mov eax,dword ptr ds:
CALL00478CE0
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:,ah
004B0E0D    ?094B 00          or dword ptr ds:,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,菜鸟一个没有版权,欢迎转载,转载请注明作者并保持文章的完整, 谢谢!
                                                       2010年01月11日 AM 01:09:54

mantoou 发表于 2010-1-11 08:45

能提供个试练品就好了

hezhaoyang 发表于 2010-1-11 08:55

能就好了
mantoou 发表于 2010-1-11 08:45 http://bbs.52pojie.cn/images/common/back.gif

提供个试练品,让大家跟着学习才好

wuqing1501 发表于 2010-1-11 09:17

回复 2# mantoou
回复 3# hezhaoyang


    不好意思啊这个软件不方便提供 想学习的话还是自己加壳 自己脱就可以了

mantoou 发表于 2010-1-11 09:39

没加壳工具,晕死,LZ提供下不,嘿嘿

mantoou 发表于 2010-1-11 09:40

没加壳工具,晕死,LZ提供下不,嘿嘿

wuqing1501 发表于 2010-1-11 11:15

回复 6# mantoou


    汗 可以告诉你 想找加壳工具 太容易 了你可以用迅雷VAGAA 或者电驴什么的 能搜资源的软件 搜一下肯定能找到 好多加壳软件而且都不用 任何论坛币的这个东西看你有没有心去找了实在不行 就GOOGLE看看有多少免费的资源 包括加壳工具 希望多去搜索一下 或者 在论坛下载

石头学破解 发表于 2010-1-11 14:06

学习了。那天也来试下。

djxjg 发表于 2010-1-13 01:10

这个讲得真好。 谢。

gry8686 发表于 2010-1-13 01:22

进来学习一下
页: [1] 2
查看完整版本: Delphi程序脱TMD修复OEP