experiment : EXE使用UPX加壳后, 用OD查找OEP

测试程序

#include "stdafx.h"
#include <windows.h>
#include <tchar.h>

int _tmain(int argc, _TCHAR* argv[])
{
    _tprintf(L">> tmain\r\n");

    do
    {
        _tprintf(L"loop here not need quit\r\n");
        ::Sleep(1000);
    } while (1);

    _tprintf(L"<< tmain\r\n");
	return 0;
}

用VS2008, 编译成默认的Release版, 输出PE为: forTest.exe

加壳

用 UPXv3.25 对 forTest.exe 加壳, 改名为 forTestAfterUpx.exe

查壳

用 Exeinfo_v0032work_658sign 对加壳后的 forTestAfterUpx.exe 查壳


寻找OEP

用OD加载 forTestAfterUpx.exe单步寻找OEP, OEP的标志为 E8, E9打头的两行汇编.
未加壳的Vs2008程序, 用OD载入后, 直接停在E8,E9打头的2行汇编上.

单步往下走, 直到找到和未加壳程序相同的OEP


在往小地址跳的语句后面按下F4, 运行到往上跳的语句后面, 便于快速向下走.






004079CC   .^\E2 D9         loopd   short 004079A7
004079CE   .  8DBE 00500000 lea     edi, dword ptr [esi+5000]        ;  F4
004079D4   >  8B07          mov     eax, dword ptr [edi]
004079D6   .  09C0          or      eax, eax
004079D8   .  74 3C         je      short 00407A16                   ;  解压完成后, 跳出
004079DA   .  8B5F 04       mov     ebx, dword ptr [edi+4]
004079DD   .  8D8430 B47200>lea     eax, dword ptr [eax+esi+72B4]
004079E4   .  01F3          add     ebx, esi
004079E6   .  50            push    eax
004079E7   .  83C7 08       add     edi, 8
004079EA   .  FF96 F0720000 call    dword ptr [esi+72F0]
004079F0   .  95            xchg    eax, ebp
004079F1   >  8A07          mov     al, byte ptr [edi]
004079F3   .  47            inc     edi
004079F4   .  08C0          or      al, al
004079F6   .^ 74 DC         je      short 004079D4
004079F8   .  89F9          mov     ecx, edi
004079FA   .  57            push    edi
004079FB   .  48            dec     eax
004079FC   .  F2:AE         repne   scas byte ptr es:[edi]
004079FE   .  55            push    ebp
004079FF   .  FF96 F4720000 call    dword ptr [esi+72F4]
00407A05   .  09C0          or      eax, eax
00407A07   .  74 07         je      short 00407A10
00407A09   .  8903          mov     dword ptr [ebx], eax
00407A0B   .  83C3 04       add     ebx, 4
00407A0E   .^ EB E1         jmp     short 004079F1                   ;  最后一轮解压循环
00407A10   >  FF96 04730000 call    dword ptr [esi+7304]
00407A16   >  8BAE F8720000 mov     ebp, dword ptr [esi+72F8]        ;  解压完成
00407A1C   .  8DBE 00F0FFFF lea     edi, dword ptr [esi-1000]
00407A22   .  BB 00100000   mov     ebx, 1000
00407A27   .  50            push    eax
00407A28   .  54            push    esp
00407A29   .  6A 04         push    4
00407A2B   .  53            push    ebx
00407A2C   .  57            push    edi
00407A2D   .  FFD5          call    ebp
00407A2F   .  8D87 07020000 lea     eax, dword ptr [edi+207]
00407A35   .  8020 7F       and     byte ptr [eax], 7F
00407A38   .  8060 28 7F    and     byte ptr [eax+28], 7F
00407A3C   .  58            pop     eax
00407A3D   .  50            push    eax
00407A3E   .  54            push    esp
00407A3F   .  50            push    eax
00407A40   .  53            push    ebx
00407A41   .  57            push    edi
00407A42   .  FFD5          call    ebp
00407A44   .  58            pop     eax
00407A45   .  61            popad                                    ;  解压完成后的 POPAD
00407A46   .  8D4424 80     lea     eax, dword ptr [esp-80]
00407A4A   >  6A 00         push    0
00407A4C   .  39C4          cmp     esp, eax
00407A4E   .^ 75 FA         jnz     short 00407A4A                   ;  调整堆栈呢
00407A50   .  83EC 80       sub     esp, -80
00407A53   .- E9 8498FFFF   jmp     004012DC                         ;  解压完成后, POPAD后的跨段跳转
可以看出, UPX解压完成的标志是POPAD, 加一句跨段跳转, 跑到OEP.
004012DC    E8 77040000     call    00401758                         ; E8E9两行是OEP~, 未加壳的原始程序EP也是E8E9, E8E9两行的OPCODE也和未加壳程序相同.
004012E1  ^ E9 9FFDFFFF     jmp     00401085
004012E6    8BFF            mov     edi, edi
004012E8    55              push    ebp
004012E9    8BEC            mov     ebp, esp
004012EB    81EC 28030000   sub     esp, 328

比对在加壳程序解压后找到的OEP和未加壳程序OEP

对照未加壳程序的EP
013D12DC > $  E8 77040000   call    013D1758
013D12E1   .^ E9 9FFDFFFF   jmp     013D1085
013D12E6   >  8BFF          mov     edi, edi
013D12E8  /.  55            push    ebp
013D12E9  |.  8BEC          mov     ebp, esp
013D12EB  |.  81EC 28030000 sub     esp, 328

经过对比, 程序基址 + 0x12DC, 就是OEP.






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值