细讲UPX壳

admin 2024年12月17日10:50:46评论72 views字数 2947阅读9分49秒阅读模式
细讲UPX壳
细讲UPX壳
 鼎新安全
持续关注
细讲UPX壳

UPX是一个压缩壳,在CTF中的应用大部分也仅仅是对程序套个壳,增加一下对反编译的时间,有时还会魔改一下但问题也不是很大改回来就行。

魔改标志位

细讲UPX壳
对于正常的UPX壳来说这几个位置应该都是UPX当它被改了之后就会导致自动化脱壳脚本失败,那我们就要改回来,改第一个就够了,全改回来也行,之后就可以用脚本进行脱壳了
细讲UPX壳
但这种魔改只会影响自动化脱壳脚本的定位,从而导致脱壳失败,但也仅仅会影响这种自动化脚本,如果是手工脱壳就不会,因为是我们自己找到压缩点与解压点,这里先说一下UPX的压缩原理。
1.什么是壳
简单来理解就是在自己的PE文件中加入了一段代码,但不影响PE文件的执行,壳又分加密壳和压缩壳,这里只讲压缩壳,压缩壳是对源程序代码进行压缩后,重新封装并生成可执行文件的一种壳,压缩壳的主要目的是减小文件大小,通过调用压缩引擎对文件进行压缩,在CTF壳中这个壳的作用仅仅只是让我们不能直接看到它的伪代码仅此而已。
2.压缩壳的原理
细讲UPX壳

这是一个正常壳映射到内存中的示意图

再来看看压缩壳的思路

细讲UPX壳
就是说PE文件经过经过压缩后减少了文件的大小,但在程序运行开始时会先进行解压然后映射到内存中   这里详细说一下UPX壳的执行流程:
1. 原始PE文件结构

+------------------------+

  |       PE头            |   

+------------------------+

   |      .text节          | <- 程序代码   

+------------------------+

   |      .data节          | <- 数据   

+------------------------+

   |      .rdata节         | <- 只读数据   

+------------------------+

   |      其他节           |  

 +------------------------+

2. 加壳后的PE文件结构

+------------------------+

   |     新PE头            |   

+------------------------+

   |     UPX0节            | <- 压缩后的数据   +------------------------+

   |     UPX1节            | <- 解压代码   

+------------------------+

   |     预留节            | <- 解压目标空间   

+------------------------+

3. 执行流程图

graph TD

       A[程序启动] --> B[进入壳入口点]

       B --> C[获取关键数据结构]

       C --> D[定位压缩数据]

       D --> E[申请内存空间]

       E --> F[解压数据]

       F --> G[修复PE结构]

       G --> H[修复重定位]

       H --> I[修复导入表]

       I --> J[跳转到OEP]

4. 详细执行步骤:

1.初始化阶段

  • 获取当前进程信息

  • 定位关键数据结构

  • 初始化解压环境

2.内存准备   

[申请内存]

VirtualAlloc(NULL,需要的大小,MEM_COMMIT | 

MEM_RESERVE,PAGE_EXECUTE_READWRITE)

[设置内存属性]

VirtualProtect(内存地址, 大小, 新属性, &旧属性) 

3.解压过程

源数据(压缩) -> 解压算法 -> 目标位置(解压)

   +----------------+     +----------+     +----------------+

   | UPX0节压缩数据 | --> | 解压算法  | --> | 预留节解压空间  |

   +----------------+     +----------+     +----------------+

4.修复阶段   

[PE头修复]

  • 修正SizeOfImage

  • 修正SectionAlignment

  • 修正FileAlignment

[重定位修复]

for each 重定位项:    if 类型 == IMAGE_REL_BASED_HIGHLOW:        *(DWORD*)重定位地址 = 新基址 + (*(DWORD*)重定位地址 - 旧基址)

[导入表修复]

for each 导入DLL:    LoadLibrary(DLL名)    for each 导入函数:        GetProcAddress(函数名)        填写IAT

5.执行转换

[跳转到OEP]push OEP地址ret

5.内存布局变化   

加壳前:

高地址   

+------------------+

   |    其他节       |   

+------------------+

   |    .data        |   

+------------------+

   |    .text        |   

+------------------+

   |    PE头         |   

+------------------+

低地址

加壳后:

高地址   

+------------------+

   |    预留节       | <- 解压目标   

+------------------+

   |    UPX1         | <- 解压代码   

+------------------+

   |    UPX0         | <- 压缩数据   

+------------------+

   |    PE头         |   

+------------------+   

低地址

解压后:

高地址   

+------------------+

   |    原始程序     | <- 已解压   

+------------------+

   |    UPX1         |   

+------------------+

   |    UPX0         |   

+------------------+

   |    PE头         |   

+------------------+

低地址

6.关键数据结构

typedef struct {    DWORD OEP;              // 原始入口点    DWORD ImageBase;        // 映像基址    DWORD ImportTable;      // 导入表RVA    DWORD RelocationTable;  // 重定位表RVA    DWORD CompressedData;   // 压缩数据位置    DWORD CompressedSize;   // 压缩数据大小    DWORD UncompressedSize; // 解压后大小} UPX_SHELL_DATA;

这是UPX壳的完整工作流程,实际实现时还需要考虑:反调试保护,代码混淆,异常处理,资源处理,内存对齐,安全性检查。   脱壳步骤:ESP定律脱壳,本质就是利用堆栈平衡,当子程序结束时要返回父程序时会ESP要在保证在RET这条指令之前,ESP指向的是我们压入栈中的地址,也就是说当UPX在自解压完成后我们只要找到这个地址就行,   示例:   压栈地址

细讲UPX壳

当自解压完成后也会到达这里所以在这下个内存断点

细讲UPX壳

在内存窗口中转到

细讲UPX壳

运行到这,之后只要dump出来就行

细讲UPX壳

细讲UPX壳细讲UPX壳

这就完成了手工脱壳了,比较简单。

细讲UPX壳
END
细讲UPX壳

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

原文始发于微信公众号(鼎新安全):细讲UPX壳

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

发表评论

匿名网友 填写信息