【转载】秒到oep,支持所有壳,包括vmp

from:http://www.52pojie.cn/forum.php?mod=viewthread&tid=120450

你可以怀疑这个方法,真的假的一试就知道,如果不知道怎么找,可以把你的试验品传到网盘,有空我把针对你试验品的步骤帖给你。
有的OEP被抽了代码的只能找到伪OEP,也就是被抽掉之后剩下的头部地址。

你也可以直接无视这个方法,对你少一个选择,对我没有任何损失。

       首先讲一下方法的原理。
       每一个程序都是由无数个CALL加其参数组成了,在程序里,每一个CALL都是有返回地址的。当在程序领空的时候,返回到不能返回的时候。这个返回地址就是在程序的main函数里。
       所以只要找到了最终程序领空的返回地址,也就找到了main函数的地方。main函数的起始位置也就是oep了。而OD是会记录每一个返回地址的。我们用OD就可以迅速找到OEP了,而且适合所有壳(除了有注册框的壳,因为你不过掉注册框就到不了程序的领空)。
       下面以一个加ZP的壳为例(无注册框),来说明如何操作。

1. OD载入程序,入口点为

 

1 004711DA >  E8 01000000     call 演示程序.004711E0
2 004711DF    5C              pop esp
3 004711E0    872C24          xchg dword ptr ss:[esp],ebp
4 004711E3    8DAD 9CFEFFFF   lea ebp,dword ptr ss:[ebp-164]
5 004711E9    872C24          xchg dword ptr ss:[esp],ebp
6 004711EC  ^ E9 8AFEFFFF     jmp 演示程序.0047107B
7 004711F1    B0 1D           mov al,1D
8 004711F3  ^ 7C E8           jl short 演示程序.004711DD

2.直接shift+F9让程序跑起来,然后来到OD的堆栈窗口。直接拉到最下面。

 1 0012FF54   0012FFA8
 2 0012FF58   0044D294  演示程序.0044D294
 3 0012FF5C   00010264  UNICODE "nclude=D:\Program Files\Microsoft Visual Studio\VC98\atl\include;D:\Program Files\Microsoft Visual S"
 4 0012FF60   00000113
 5 0012FF64   00000001
 6 0012FF68   00000000
 7 0012FF6C   000743DC
 8 0012FF70   00000265
 9 0012FF74   000002F8
10 0012FF78   7FFD7000
11 0012FF7C   0044D4A7  演示程序.0044D4A7
12 0012FF80   0012FF8C  指向下一个 SEH 记录的指针
13 0012FF84   0044D4B1  SE处理程序
14 0012FF88   0012FFA8
15 0012FF8C   0012FFB4  指向下一个 SEH 记录的指针
16 0012FF90   0044D4EA  SE处理程序
17 0012FF94   0012FFA8
18 0012FF98   7C930208  ntdll.7C930208
19 0012FF9C   FFFFFFFF
20 0012FFA0   7FFD7000
21 0012FFA4   00B817C0
22 0012FFA8   0012FFC0
23 0012FFAC   0044EDA0  演示程序.0044EDA0
24 0012FFB0   7FFD7000
25 0012FFB4   0012FFE0  指向下一个 SEH 记录的指针
26 0012FFB8   004039B0  SE处理程序
27 0012FFBC   0012FFC0
28 0012FFC0   0012FFF0
29 0012FFC4   7C817067  返回到 kernel32.7C817067
30 0012FFC8   7C930208  ntdll.7C930208
31 0012FFCC   FFFFFFFF
32 0012FFD0   7FFD7000
33 0012FFD4   8054C6B8
34 0012FFD8   0012FFC8
35 0012FFDC   895C0020
36 0012FFE0   FFFFFFFF  SEH 链尾部
37 0012FFE4   7C839AC0  SE处理程序
38 0012FFE8   7C817070  kernel32.7C817070
39 0012FFEC   00000000
40 0012FFF0   00000000
41 0012FFF4   00000000
42 0012FFF8   004711DA  offset 演示程序.
43 0012FFFC   00000000

从下往上,找到第一个返回到程序领空的地址。

0012FFAC 0044EDA0 演示程序.0044EDA0

然后汇编窗口中跟随,来到这里:

1 0044EDA0      E8            db E8
2 0044EDA1      7B            db 7B                                    ;  CHAR '{'
3 0044EDA2      4F            db 4F                                    ;  CHAR 'O'
4 0044EDA3      FB            db FB
5 0044EDA4      FF            db FF

3. 点右键,选择分析-->从模块中删除分析,变成这样:

 1 0044ED6B    E8 586EFBFF     call 演示程序.00405BC8
 2 0044ED70    A1 D0FF4400     mov eax,dword ptr ds:[44FFD0]
 3 0044ED75    8B00            mov eax,dword ptr ds:[eax]
 4 0044ED77    E8 F8E5FFFF     call 演示程序.0044D374
 5 0044ED7C    8B0D AC004500   mov ecx,dword ptr ds:[4500AC]            ; 演示程序.00451BD0
 6 0044ED82    A1 D0FF4400     mov eax,dword ptr ds:[44FFD0]
 7 0044ED87    8B00            mov eax,dword ptr ds:[eax]
 8 0044ED89    8B15 14E94400   mov edx,dword ptr ds:[44E914]            ; 演示程序.0044E960
 9 0044ED8F    E8 F8E5FFFF     call 演示程序.0044D38C
10 0044ED94    A1 D0FF4400     mov eax,dword ptr ds:[44FFD0]
11 0044ED99    8B00            mov eax,dword ptr ds:[eax]
12 0044ED9B    E8 6CE6FFFF     call 演示程序.0044D40C
13 0044EDA0    E8 7B4FFBFF     call 演示程序.00403D20                       ; 刚才的位置

4.我们往上找

 1 0044ED5B    0058 EB         add byte ptr ds:[eax-15],bl
 2 0044ED5E    44              inc esp
 3 0044ED5F    0055 8B         add byte ptr ss:[ebp-75],dl
 4 0044ED62    EC              in al,dx
 5 0044ED63    83C4 F0         add esp,-10
 6 0044ED66    B8 80EB4400     mov eax,演示程序.0044EB80
 7 0044ED6B    E8 586EFBFF     call 演示程序.00405BC8
 8 0044ED70    A1 D0FF4400     mov eax,dword ptr ds:[44FFD0]
 9 0044ED75    8B00            mov eax,dword ptr ds:[eax]
10 0044ED77    E8 F8E5FFFF     call 演示程序.0044D374
11 0044ED7C    8B0D AC004500   mov ecx,dword ptr ds:[4500AC]            ; 演示程序.00451BD0
12 0044ED82    A1 D0FF4400     mov eax,dword ptr ds:[44FFD0]
13 0044ED87    8B00            mov eax,dword ptr ds:[eax]
14 0044ED89    8B15 14E94400   mov edx,dword ptr ds:[44E914]            ; 演示程序.0044E960
15 0044ED8F    E8 F8E5FFFF     call 演示程序.0044D38C
16 0044ED94    A1 D0FF4400     mov eax,dword ptr ds:[44FFD0]
17 0044ED99    8B00            mov eax,dword ptr ds:[eax]
18 0044ED9B    E8 6CE6FFFF     call 演示程序.0044D40C
19 0044EDA0    E8 7B4FFBFF     call 演示程序.00403D20                       ; 刚才的位置

这里就是OEP的头部了。如果你熟悉各种语言的入口特征的话,马上就应该知道OEP的位置了。
看这里

1 0044ED5F    0055 8B         add byte ptr ss:[ebp-75],dl
2 0044ED62    EC              in al,dx

其实这个就是被混淆了的OEP。他只是在558B的前面加了个00,  我们想办法把00去掉。

00的地址是0044ED5F,那么55的地址是0044ED60(即是加1),我们CTRL+G,输入0044ED60,回车。我们的OEP就回来了,如下:

 1 0044ED60    55              push    ebp                              ; oep
 2 0044ED61    8BEC            mov     ebp, esp
 3 0044ED63    83C4 F0         add     esp, -10
 4 0044ED66    B8 80EB4400     mov     eax, 0044EB80
 5 0044ED6B    E8 586EFBFF     call    00405BC8
 6 0044ED70    A1 D0FF4400     mov     eax, dword ptr [44FFD0]
 7 0044ED75    8B00            mov     eax, dword ptr [eax]
 8 0044ED77    E8 F8E5FFFF     call    0044D374
 9 0044ED7C    8B0D AC004500   mov     ecx, dword ptr [4500AC]          ; 演示程序.00451BD0
10 0044ED82    A1 D0FF4400     mov     eax, dword ptr [44FFD0]
11 0044ED87    8B00            mov     eax, dword ptr [eax]
12 0044ED89    8B15 14E94400   mov     edx, dword ptr [44E914]          ; 演示程序.0044E960
13 0044ED8F    E8 F8E5FFFF     call    0044D38C
14 0044ED94    A1 D0FF4400     mov     eax, dword ptr [44FFD0]
15 0044ED99    8B00            mov     eax, dword ptr [eax]
16 0044ED9B    E8 6CE6FFFF     call    0044D40C
17 0044EDA0    E8 7B4FFBFF     call    00403D20

 

文中所用程序的下载地址:http://files.cnblogs.com/tk091/test3.zp.rar

 

至于找到oep后如何脱壳,这个就难说了,下面是我的脱壳过程。

对oep下硬件断点,重新载入后运行,删除分析模块。

od插件dump分别两个。

运行实际的程序,打开pe修复工具,填入oep,

显示无效的函数,全部无效,选择等级三修复即可,要几个几个的修复,如果一起修复则会死掉。

你可能感兴趣的:(【转载】秒到oep,支持所有壳,包括vmp)