大家好,我是吾爱破解论坛的风吹屁屁凉同学,相信一些老朋友还记得我,去年吾爱视频大赛上我也有参加比赛,而且还得了个奖章

吾爱破解论坛———第二届动画教程大赛 (参赛时间:2010年6月1日-2010年7月15日) 
http://www.52pojie.cn/thread-47949-1-1.html
奖品丰厚啊,经不住诱惑,我又来参加了,今天要做的这个教程是一个关于TMD/WL脱壳的.

本板块CM等附件,下载不扣CB,不要钱就可以下载,大家可以来这里下演示程序,我已经发布了
Themida / Winlicense v1.8x - v2.x UnPackMe
http://www.52pojie.cn/thread-50439-1-1.html

此教程演示说明:
Delphi写的程序,加壳只有使用了一个加密选项,就是VM了入口代码,常规的方法是脱壳修复OEP代码才可以运行,特别是Delphi的程序,入口十几行代码,补代码会补死人的,做这个的目的是为了演示另一种未公开的不用修复OEP就可以直接脱壳的方法,做下这个脱壳教程参加动画大赛,听说有奖品拿,哈哈!

很多大牛都跟帖了,有我偶像Hmily还有小生我怕怕同学还有猥琐的ximo妞,强大的当红小生版主已经脱壳了,他使用的方法就是修复OEP原始代码,我记得好像有十来行,太有毅力了,我这个教程的重点就是,不用修复OEP的代码,直接dump修复iat就可以运行,和脱常规压缩壳差不多,不用考虑OEP代码被偷,好了,废话结束,开始正式进入教程

首先,要想调试TMD的程序,你就要能过它的反调试.吾爱上有很多大牛已经给出现成的东西,比如:

如果你的OD被Anti了 By Nooby
http://www.52pojie.cn/thread-31095-1-1.html

吾爱破解专用版ollydbg[2010.5.4更新] by 小生我怕怕
http://www.52pojie.cn/thread-14986-1-1.html

StrongOD.v0.3.4.By.海风月影[CUG][2010.06.13]
http://www.52pojie.cn/thread-37759-1-1.html

这些是调试的前提,这么多大牛给出的好东西,目前可以调试所有的加密壳,包括VMP啊TMD啊ZP啊这些,肯定是没有问题的,先载入OD吧

可以看到,我是加的WL2.1.0.1的最新版,老版本的区段是这样的:
            //1
.rsrc       //2         
.idata      //3      
.Themida    //4
新版是OD里面那种了,其实,他只是在入口前面加了点垃圾而已,这里
005B5000就是.Themida    //4
我们可以单步走一下就知道了,这个教程我会做的很慢很详细,很多大牛会觉得太简单可以拉着看,我尽量不用快捷键,使用鼠标点击给大家看.
005B5000    B8 00000000          mov eax,0                        ; 这里明显可以看出来是TMD的入口了吧,代码都还原了,前面写错了,没什么太大关系,继续走.
由于我演示的是另外的一种脱壳方法,所以你看教程之前应该有补OEP的脱壳经验才好.


TMD/WL入口点查找方法
1. .text段下内存写入断点,shift+F9,取消内存断点.
2. bp GetProcessHeap+C,F9,取消断点.
3. .text段下F2断点,F9到oep或者oep的第一个call里面的位置.

这里补充下,去OEP的思路,壳先填充数据,然后填充IAT,然后开始模拟OEP代码,这样下去的.

这是我自己总结的经验,我们先到OEP去看看,这里大家熟悉吧,Delphi 第一个call里面的内容,我不说这么来的了,这个以前很多教程说过,可以搜索下,吾爱有很多.我们看下IAT的情况,IAT被变形了，为了节省时间可以直接用UIF修复IAT。我们现在先修复下IAT,然后Dump一份修复IAT保存下来,IAT修复好了,我们来Dump,入口点我们先修复成这个第一个call的地方.好,dump修复完了,下面就开始关键了,我们继续F8走


005A097E    68 0B4A5D0A          push 0A5D4A0B                    ; 2.key
005A0983  ^ E9 AD3EF7FF          jmp Themida_.00514835            ; jmp Vm_Start
005A0988    68 694A5D0A          push 0A5D4A69                    ; 3.key
005A098D  ^ E9 A33EF7FF          jmp Themida_.00514835            ; jmp Vm_Start
005A0992    68 084B5D0A          push 0A5D4B08                    ; 4.key
005A0997  ^ E9 993EF7FF          jmp Themida_.00514835            ; jmp Vm_Start
005A099C    68 664B5D0A          push 0A5D4B66                    ; 5.key
005A09A1  ^ E9 8F3EF7FF          jmp Themida_.00514835            ; jmp Vm_Start
005A09A6    68 A84B5D0A          push 0A5D4BA8                    ; 6.key
005A09AB  ^ E9 853EF7FF          jmp Themida_.00514835            ; jmp Vm_Start


不知道你们有这样注意过,TMD/WL/CV的VM入口就是上面这个样子的,Vm_Start和Vm_Retn包括Vm_Oep都在.idata下面这个区段里。

push key
Jmp Vm_Start   进入虚拟机

00514835    9C                 pushfd                          ; Vm_Start  虚拟机入口


00519518    311C24             xor dword ptr ss:[esp],ebx
0051951B    331C24             xor ebx,dword ptr ss:[esp]
0051951E    8B2424             mov esp,dword ptr ss:[esp]
00519521    61                 popad
00519522    9D                 popfd
00519523    C3                 retn                            ;Vm_Retn    虚拟机出口
 
我们继续走,看会怎么样,这个过程类似找丢失的OEP值,其实不用找,我这只是演示为什么,方便大家理解,由于IAT修复后会导致出错,直接重来下,前面的我直接过了,硬件断点过来
0044DA04    53                   push ebx                         ; 第二个call里面的值
刚有没有注意到,常规的方法是在.text段上下F2断点找代码入口,其实虚拟机的出口就是跳向原始的call里面的值了,也就是从虚拟机出来就进入原始没有加密的代码里.我们只要在出口下好断点就能看到返回地址了,我们看看原始的入口点代码.代码我贴出来:


1.004D7210 > $  55               push ebp
  004D7211   .  8BEC             mov ebp,esp
  004D7213   .  83C4 F0          add esp,-10
  004D7216   .  B8 886F4D00      mov eax,UnPackMe.004D6F88
  004D721B   .  E8 18F1F2FF      call UnPackMe.00406338
2.004D7220   .  A1 B09F4D00      mov eax,dword ptr ds:[4D9FB0]
  004D7225   .  8B00             mov eax,dword ptr ds:[eax]
  004D7227   .  E8 D867F7FF      call UnPackMe.0044DA04
3.004D722C   .  8B0D A0A04D00    mov ecx,dword ptr ds:[4DA0A0]   
  004D7232   .  A1 B09F4D00      mov eax,dword ptr ds:[4D9FB0]
  004D7237   .  8B00             mov eax,dword ptr ds:[eax]
  004D7239   .  8B15 B06C4D00    mov edx,dword ptr ds:[4D6CB0]   
  004D723F   .  E8 D867F7FF      call UnPackMe.0044DA1C
4.004D7244   .  A1 B09F4D00      mov eax,dword ptr ds:[4D9FB0]
  004D7249   .  8B00             mov eax,dword ptr ds:[eax]
  004D724B   .  E8 4C68F7FF      call UnPackMe.0044DA9C
5.004D7250   .  E8 27CFF2FF      call UnPackMe.0040417C          //这里是Delphi的ExitProcess
6.004D7255   .  8D40 00          lea eax,dword ptr ds:[eax]


2.005A097E    68 0B4A5D0A        push 0A5D4A0B                   ; 2.key
  005A0983  ^ E9 AD3EF7FF        jmp Themida_.00514835           ; jmp Vm_Start
3.005A0988    68 694A5D0A        push 0A5D4A69                   ; 3.key
  005A098D  ^ E9 A33EF7FF        jmp Themida_.00514835           ; jmp Vm_Start
4.005A0992    68 084B5D0A        push 0A5D4B08                   ; 4.key
  005A0997  ^ E9 993EF7FF        jmp Themida_.00514835           ; jmp Vm_Start
5.005A099C    68 664B5D0A        push 0A5D4B66                   ; 5.key
  005A09A1  ^ E9 8F3EF7FF        jmp Themida_.00514835           ; jmp Vm_Start
6.005A09A6    68 A84B5D0A        push 0A5D4BA8                   ; 6.key
  005A09AB  ^ E9 853EF7FF        jmp Themida_.00514835           ; jmp Vm_Start

这是加壳后VM入口的地方,你发现上面规律没?他VM就是模拟了上面对应的部分,我再贴出来对应的是上面:


1.004D7210 > $  55               push ebp
  004D7211   .  8BEC             mov ebp,esp
  004D7213   .  83C4 F0          add esp,-10
  004D7216   .  B8 886F4D00      mov eax,UnPackMe.004D6F88
  004D721B   .  E8 18F1F2FF      call UnPackMe.00406338
=
1.push xxxxxxxx          //这里就是我们所要找的1.key值,这里就是Vm_Oep
  jmp Vm_start


2.004D7220   .  A1 B09F4D00      mov eax,dword ptr ds:[4D9FB0]
  004D7225   .  8B00             mov eax,dword ptr ds:[eax]
  004D7227   .  E8 D867F7FF      call UnPackMe.0044DA04
=
2.005A097E    68 0B4A5D0A        push 0A5D4A0B                   ; 2.key
  005A0983  ^ E9 AD3EF7FF        jmp Themida_.00514835           ; jmp Vm_Start


3.004D722C   .  8B0D A0A04D00    mov ecx,dword ptr ds:[4DA0A0]   
  004D7232   .  A1 B09F4D00      mov eax,dword ptr ds:[4D9FB0]
  004D7237   .  8B00             mov eax,dword ptr ds:[eax]
  004D7239   .  8B15 B06C4D00    mov edx,dword ptr ds:[4D6CB0]   
  004D723F   .  E8 D867F7FF      call UnPackMe.0044DA1C
=
3.005A0988    68 694A5D0A        push 0A5D4A69                   ; 3.key
  005A098D  ^ E9 A33EF7FF        jmp Themida_.00514835           ; jmp Vm_Start


4.004D7244   .  A1 B09F4D00      mov eax,dword ptr ds:[4D9FB0]
  004D7249   .  8B00             mov eax,dword ptr ds:[eax]
  004D724B   .  E8 4C68F7FF      call UnPackMe.0044DA9C
=
4.005A0992    68 084B5D0A        push 0A5D4B08                   ; 4.key
  005A0997  ^ E9 993EF7FF        jmp Themida_.00514835           ; jmp Vm_Start

5.004D7250   .  E8 27CFF2FF      call UnPackMe.0040417C          //这里是Delphi的ExitProcess
=
5.005A099C    68 664B5D0A        push 0A5D4B66                   ; 5.key
  005A09A1  ^ E9 8F3EF7FF        jmp Themida_.00514835           ; jmp Vm_Start

可能我这写的这么多,你应该能看懂,平时大家修复OEP就是修复这些VM模拟的代码,我的做教程的思路是不修复OEP代码,直接修复OEP在VM里面,这样让VM还是模拟代码跑,类似以前脱壳的以壳解壳,这里是用VM去跑OEP,但是TMD做了个处理,他把第一个VM模拟的key单独挪走了,后面的他会放一起,我们的思路找到第一处的key在哪.我们重新载入,下面看这么找第一处执行的VM地址,也就是Vm_Oep,先解码壳,和到OEP差不多,我们要做的是解码完了,还没执行OEP的地方

push xxxxxxxx          //这里就是我们所要找的1.key值
jmp Vm_start
Vm_start               //当代码执行到这里的时候,看堆栈窗口的压栈值就是上面的key了,所以我们在Vm_start的地方下好断点.

直接F9,然后F7步出,我们这么判断哪个是第一个模拟的地方,直接在
00406338    53                   push ebx                         ; Delphi 第一个call里面的内容
下好断点,然后F9去记录KEY吧,执行到上面代码的地方,前面一个肯定就是key了,刚按多了,不管他,那前面都是无用的.
0012FF78   0A5D97D3
0012FF78   0A5D99E1
0012FF78   0A5D9A89
0012FF78   0A5DA2D4
0012FF78   0A5DB6D8
0012FF78   0A5DBD39
0012FF98   0A5D499C   这个就是我们要找的key了


我前面说过,Vm_Oep就是这样的代码了
push 0A5D499C
jmp  00514835
对吧,我们搜索下
005A0C56    68 9C495D0A          push 0A5D499C                    ; Vm_Oep
005A0C5B  ^ E9 D53BF7FF          jmp Themida_.00514835            ; jmp Vm_start
你会只能搜到这一个,现在要做上面?改OEP啊

Vm_Oep RVA=005A0C56-400000=001A0C56

修复之前脱好壳的程序OEP,保存就可以运行吧,说的应该还算详细,如果你熟练的话,有很多种方法找,也可以不找代码,直接写前面几行,后面还可以用VM去跑,你直接修复
1.004D7210 > $  55               push ebp
  004D7211   .  8BEC             mov ebp,esp
  004D7213   .  83C4 F0          add esp,-10
  004D7216   .  B8 886F4D00      mov eax,UnPackMe.004D6F88
  004D721B   .  E8 18F1F2FF      call UnPackMe.00406338
然后跳到
2.005A097E    68 0B4A5D0A        push 0A5D4A0B                   ; 2.key
  005A0983  ^ E9 AD3EF7FF        jmp Themida_.00514835           ; jmp Vm_Start

一样可以运行,你可以试试,VM模拟的代码都是对应的,这种脱壳思路就是用VM自己去跑代码,差不多了,估计有一个小时了吧,明天还要上班,今天差不多就到这里了,本来有冲动想做语音教程,最后因为没有麦所以做不成,马上就世界杯开始了,巴西哦,可以看了上半场再去睡觉,最后欢迎大家来吾爱破解进行交流学习,这里有很多资料还有牛人,可以学到很多东西


LCG就是我的梦想,好强大的组织,听说里面有很多内部东西,好奇...哦,对了,差点忘了,大家记得给我投票,我要拿大奖,哈哈!大家晚安,下次再见.拜拜...




    风吹屁屁凉
        LCG
     2010.6.29
   吾爱破解论坛
http://www.52pojie.cn