OEP找壳和UPX脱壳的方法

admin 2025年1月13日10:23:23评论12 views字数 5331阅读17分46秒阅读模式
 

0x00  OEP介绍

EPEntry Point),意即程序的入口点。而OEP是程序的原始入口点,一个正常的程序只有一个EP,只有入口点被修改的程序(加壳等),才会拥有OEP

OEPOriginal Entry Point),程序的原始入口点,软件加壳就是隐藏了EP,只要我们找到程序的OEP,就可以立刻脱壳。

PUSHAD(压栈)代表程序的入口点

POPAD(出栈)代表程序的出口点,与PUSHAD相对应,一般找到这个OEP就在附近。

OEP找壳和UPX脱壳的方法
0x01  脱壳方法

寻找OEP脱壳的方法

方法一:

1.OD载入,不分析代码!

2.单步向下跟踪F8,是向下跳的让它实现

3.遇到程序往回跳的(包括循环),我们在下一句代码处按F4(或者右健单击代码,选择断点——运行到所选)

4.绿色线条表示跳转没实现,不用理会,红色线条表示跳转已经实现!

5.如果刚载入程序,在附近就有一个CALL的,我们就F7跟进去,这样很快就能到程序的OEP

6.在跟踪的时候,如果运行到某个CALL程序就运行的,就在这个CALLF7进入

7.一般有很大的跳转,比如 jmp XXXXXX 或者 JE XXXXXX 或者有RETE的一般很快就会到程序的OEP

方法二:

ESP定理脱壳(ESPOD的寄存器中,我们只要在命令行下ESP的硬件访问断点,就会一下来到程序的OEP了!)

1.开始就点F8,注意观察OD右上角的寄存器中ESP有没出现。

2.在命令行下:dd 0012FFA4(指在当前代码中的ESP地址),按回车!

3.选种下断的地址,下硬件访问WORD断点。

4.按一下F9运行程序,直接来到了跳转处,按下F8,到达程序OEP,脱壳

方法三:

内存跟踪:

1:用OD打开软件!

2:点击选项——调试选项——异常,把里面的忽略全部上!CTRL+F2重载下程序!

3:按ALT+M,DA 打开内存镜象,找到第一个。rsrc.F2下断点,

然后按SHIFT+F9运行到断点,接着再按ALT+M,DA 打开内存镜象,找到。RSRC上面的CODE,按

F2下断点!然后按SHIFT+F9,直接到达程序OEP,脱壳!

方法四:

一步到达OEP(前辈们总结的经验)

1.开始按Ctrl+F,输入:popad(只适合少数壳,包括ASPACK壳),然后按下F2F9运行到此处

2.来到大跳转处,点下F8,脱壳之!

方法五:

1:用OD打开软件!

2:点击选项——调试选项——异常,把里面的全部去掉!CTRL+F2重载下程序!

3:一开是程序就是一个跳转,在这里我们按SHIFT+F9,直到程序运行,记下从开始按F9到程序

运行的次数!

4CTRL+F2重载程序,按SHIFT+F9(次数为程序运行的次数-1

5:在OD的右下角我们看见有一个SE 句柄,这时我们按CTRL+G,输入SE句柄前的地址!

6:按F2下断点!然后按SHIFT+F9来到断点处!

7:去掉断点,按F8慢慢向下走!

8:到达程序的OEP,脱壳!

OEP找壳和UPX脱壳的方法
0x02  ESP定理

1、前置知识

ESP

esp:堆栈指针寄存器,主要用于存放堆栈内存储单元的偏移量,用它可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。

栈(stack)是内存中分配的一段空间。向一个栈插入新元素又称作入(push)放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈(pop),它把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

OEP找壳和UPX脱壳的方法

call

相当于高级语言中的函数调用。当执行call指令时,进行两步操作:将下一条的指令的地址压入栈中,再跳转到该地址处。相当于:

push ipjmp near ptr 地址

ref && retf

call指令相对应,将当前的ESP中指向的地址出栈,然后跳转到这个地址。相当于:

pop ip#ret
pop IPpop CS#retf

2ESP定理

为什么要保证堆栈平衡(保证数据环境)

程序在读写数据的时候是通过地址查找的,如果函数调用之前的堆栈与函数调用之后的堆栈不一致,就可能导致找不到数据或找到的数据错误,那么久有可能导致程序崩溃.

为什么要使用EBP寻址

EBP在程序的运行过程中有着特定的作用,保存数据的基址,根据这个特性,EBP一般不会被更改

但是在汇编中,函数需要用到的数据都会在运行前入栈,函数可以通过栈顶找到这些数据,所以在函数运行时,EBP就暂时失去了意义,所以我们就用它来临时保存开辟的栈底

也就是说,如果有一个数据(全局变量等)能够存储要索引的位置并且在函数运行时不会被改变,那么在函数运行时就可以用它来替代ESP去索引

如下图所示,EBP前后的值相同

OEP找壳和UPX脱壳的方法

OEP找壳和UPX脱壳的方法

OEP找壳和UPX脱壳的方法
0x03  UPX脱壳

找到OEP之后,右键,选择【用OllyDump脱壳调试进程】

OEP找壳和UPX脱壳的方法

将新PE程序保存为aaa.exe

OEP找壳和UPX脱壳的方法

然后运行aaa.exe

OEP找壳和UPX脱壳的方法

OEP找壳和UPX脱壳的方法
0x04  OEP特殊分析

Borland Delphi 6.0 - 7.0

00509CB0 > $  55            PUSH EBP 00509CB1  .  8BEC          MOV EBP,ESP 00509CB3  .  83C4 EC       ADD ESP,-14 00509CB6  .  53            PUSH EBX 00509CB7  .  56            PUSH ESI 00509CB8  .  57            PUSH EDI 00509CB9  .  33C0          XOR EAX,EAX 00509CBB  .  8945 EC       MOV DWORD PTR SS:[EBP-14],EAX 00509CBE  .  B8 20975000   MOV EAX,unpack.00509720 00509CC3  .  E8 84CCEFFF   CALL unpack.0040694C

Microsoft Visual C++ 6.0

00496EB8 >/$  55            PUSH EBP                                 ;  (初始 cpu 选择)00496EB9 |.  8BEC          MOV EBP,ESP00496EBB |.  6A FF         PUSH -100496EBD |.  68 40375600   PUSH Screensh.0056374000496EC2 |.  68 8CC74900   PUSH Screensh.0049C78C                   ;  SE 处理程序安装00496EC7 |.  64:A1 0000000>MOV EAX,DWORD PTR FS:[0]00496ECD |. 50            PUSH EAX00496ECE |.  64:8925 00000>MOV DWORD PTR FS:[0],ESP00496ED5 |.  83EC 58       SUB ESP,58

Microsoft Visual C++ 6.0 [Overlay] E语言

00403831 >/$  55            PUSH EBP00403832 |.  8BEC          MOV EBP,ESP00403834 |.  6A FF         PUSH -100403836 |.  68 F0624000   PUSH Nisy521.004062F00040383B |.  68 A44C4000   PUSH Nisy521.00404CA4                    ;  SE 处理程序安装00403840 |.  64:A1 0000000>MOV EAX,DWORD PTR FS:[0]00403846 |. 50            PUSH EAX00403847 |.  64:8925 00000>MOV DWORD PTR FS:[0],ESP

Microsoft Visual Basic 5.0 / 6.0

00401166  - FF25 6C104000   JMP DWORD PTR DS:[<&MSVBVM60.#100>]      ;MSVBVM60.ThunRTMain0040116C >  68 147C4000     PUSH PACKME.00407C1400401171   E8 F0FFFFFF     CALL<JMP.&MSVBVM60.#100>00401176   0000            ADD BYTE PTR DS:[EAX],AL00401178   0000            ADD BYTE PTR DS:[EAX],AL0040117A   0000            ADD BYTE PTR DS:[EAX],AL0040117C   3000            XOR BYTE PTR DS:[EAX],AL

或省略第一行的JMP

 00401FBC >  68 D0D44000        push dumped_.0040D4D0 00401FC1   E8 EEFFFFFF        call<jmp.&msvbvm60.ThunRTMain> 00401FC6   0000               add byte ptr ds:[eax],al 00401FC8   0000               add byte ptr ds:[eax],al 00401FCA   0000               add byte ptr ds:[eax],al 00401FCC   3000               xor byte ptr ds:[eax],al 00401FCE   0000               add byte ptr ds:[eax],al

BC++

0040163C > $ /EB 10         JMP SHORT BCLOCK.0040164E 0040163E    |66            DB 66                                    ;  CHAR 'f' 0040163F    |62            DB 62                                    ;  CHAR 'b' 00401640    |3A            DB 3A                                    ;  CHAR ':' 00401641    |43            DB 43                                    ;  CHAR 'C' 00401642    |2B            DB 2B                                    ;  CHAR '+' 00401643    |2B            DB 2B                                    ;  CHAR '+' 00401644    |48            DB 48                                    ;  CHAR 'H' 00401645    |4F            DB 4F                                    ;  CHAR 'O' 00401646    |4F            DB 4F                                    ;  CHAR 'O' 00401647     |4B            DB 4B                                    ;  CHAR 'K' 00401648    |90            NOP 00401649    |E9            DB E9 0040164A  . |98E04E00      DD OFFSET BCLOCK.___CPPdebugHook 0040164E  > A1 8BE04E00   MOV EAX,DWORD PTR DS:[4EE08B]00401653 . C1E0 02       SHL EAX,2 00401656  .  A3 8FE04E00   MOV DWORD PTR DS:[4EE08F],EAX 0040165B  .  52            PUSH EDX 0040165C  .  6A 00         PUSH 0                                   ; /pModule = NULL 0040165E  .  E8 DFBC0E00   CALL <JMP.&KERNEL32.GetModuleHandleA>    ; GetModuleHandleA 00401663  .  8BD0          MOV EDX,EAX

Dasm:

00401000 >/$6A 00         PUSH 0                                   ; /pModule =NULL 00401002 |.  E8 C50A0000   CALL<JMP.&KERNEL32.GetModuleHandleA>   ; GetModuleHandleA 00401007 |.  A3 0C354000   MOV DWORD PTR DS:[40350C],EAX 0040100C |.  E8 B50A0000   CALL <JMP.&KERNEL32.GetCommandLineA>     ; [GetCommandLineA 00401011 |.  A3 10354000   MOV DWORD PTR DS:[403510],EAX 00401016 |.  6A 0A         PUSH 0A                                  ; /Arg4 =0000000A 00401018 |.  FF35 10354000 PUSH DWORD PTR DS:[403510]               ; |Arg3 =00000000 0040101E |.  6A 00         PUSH 0                                   ; |Arg2 = 00000000 00401020 |.  FF35 0C354000 PUSH DWORD PTR DS:[40350C]               ; |Arg1 =00000000
声明

    由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,戟星安全实验室及文章作者不为此承担任何责任。

戟星安全实验室拥有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经戟星安全实验室允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。

OEP找壳和UPX脱壳的方法

戟星安全实验室

# 长按二维码 关注我们 #

原文始发于微信公众号(戟星安全实验室):OEP找壳和UPX脱壳的方法,赶紧收藏吧

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年1月13日10:23:23
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   OEP找壳和UPX脱壳的方法https://cn-sec.com/archives/1110129.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息