Linux逆向之加壳&脱壳
字数 1042 2025-08-24 20:49:31

Linux逆向之加壳与脱壳技术详解

一、加壳技术概述

加壳是一种保护可执行文件的技术,通过对原始程序进行压缩或加密,并在程序运行时进行解压/解密,从而达到保护程序的目的。在Linux系统中,UPX是最常见的开源加壳工具。

UPX壳特点

  • 开源免费
  • 支持多种平台
  • 压缩率高
  • 执行速度快
  • 易于使用

二、环境准备与示例程序

1. 示例程序

#include <stdio.h>

void fun1() {
    puts("fun1:hello,world!");
    sleep(1);
}

void fun2() {
    puts("fun2:hello,world!");
    sleep(1);
}

int main(int argc, char const *argv[]) {
    puts("main:hello,world!");
    fun1();
    fun2();
    return 0;
}

2. 编译要求

使用静态编译以确保文件大小足够(UPX要求大于40KB):

gcc ./test.c -o test --static

三、UPX基本操作

1. 加壳操作

./upx test

常用参数:

  • -d:脱壳
  • -1~-9:压缩等级(1最快压缩率最低,9最慢压缩率最高)
  • -k:保留原程序备份

2. 加壳效果验证

加壳后程序应能正常运行:

./test

四、加壳原理分析

1. ELF文件结构变化

使用readelf工具查看加壳前后变化:

readelf -hlS --w test

加壳后:

  • ELF头部信息被修改
  • 段表信息被大幅简化
  • 仅保留UPX自定义的程序入口执行地址

2. 壳识别方法

常用检测工具:

  • checksec:检查安全属性
  • strings:查看可打印字符串

UPX壳特征:

  • 包含"UPX"等特征字符串
  • 特定的段名和入口点特征

五、UPX壳隐藏技术

1. 手动修改特征

使用二进制编辑器(如010 Editor):

  • 修改UPX相关字符串
  • 替换UPX关键词

效果:

  • 避免被检测工具识别
  • UPX工具无法自动脱壳

六、手动脱壳技术

1. 脱壳原理

加壳程序运行时会在内存中解压原始代码,手动脱壳的关键是:

  1. 找到原始入口点(OEP)
  2. 从内存中dump出解压后的程序

2. 脱壳步骤

准备工作

  1. 准备IDA调试环境
  2. linux_server64复制到目标系统并运行

IDA远程调试

  1. 选择调试器:Remote Linux Debugger
  2. 配置远程文件路径和IP地址
  3. 在start函数设置断点
  4. 开始调试

跟踪执行流程

  1. 按F8步过执行
  2. 遇到跳转循环时坚持向下执行原则
  3. 关键点:
    • 注意jmp r13跳转
    • 进入新段后的第一个call
    • 跳过三个向上循环
    • 最终回到OEP(如0x400890)

内存dump脚本

使用IDC脚本dump内存:

#include <idc.idc>
#define PT_LOAD 1
#define PT_DYNAMIC 2

static main(void) {
    auto ImageBase, StartImg, EndImg;
    auto e_phoff;
    auto e_phnum, p_offset;
    auto i, dumpfile;
    
    ImageBase = 0x400000;
    StartImg = 0x400000;
    EndImg = 0x0;
    
    if(Dword(ImageBase) == 0x7f454c46 || Dword(ImageBase) == 0x464c457f) {
        if(dumpfile = fopen("dumpfile", "wb")) {
            e_phoff = ImageBase + Qword(ImageBase + 0x20);
            Message("e_phoff = 0x%x\n", e_phoff);
            
            e_phnum = Word(ImageBase + 0x38);
            Message("e_phnum = 0x%x\n", e_phnum);
            
            for(i = 0; i < e_phnum; i++) {
                if(Dword(e_phoff) == PT_LOAD || Dword(e_phoff) == PT_DYNAMIC) {
                    p_offset = Qword(e_phoff + 0x8);
                    StartImg = Qword(e_phoff + 0x10);
                    EndImg = StartImg + Qword(e_phoff + 0x28);
                    Message("start = 0x%x, end = 0x%x, offset = 0x%x\n", StartImg, EndImg, p_offset);
                    dump(dumpfile, StartImg, EndImg, p_offset);
                    Message("dump segment %d ok.\n", i);
                }
                e_phoff = e_phoff + 0x38;
            }
            
            fseek(dumpfile, 0x3c, 0);
            fputc(0x00, dumpfile); fputc(0x00, dumpfile); fputc(0x00, dumpfile); fputc(0x00, dumpfile);
            
            fseek(dumpfile, 0x28, 0);
            fputc(0x00, dumpfile); fputc(0x00, dumpfile); fputc(0x00, dumpfile); fputc(0x00, dumpfile);
            fputc(0x00, dumpfile); fputc(0x00, dumpfile); fputc(0x00, dumpfile); fputc(0x00, dumpfile);
            
            fclose(dumpfile);
        } else Message("dump err.");
    }
}

static dump(dumpfile, startimg, endimg, offset) {
    auto i;
    auto size;
    size = endimg - startimg;
    fseek(dumpfile, offset, 0);
    for(i = 0; i < size; i = i + 1) {
        fputc(Byte(startimg + i), dumpfile);
    }
}

验证脱壳结果

  1. 用IDA分析dumpfile
  2. 检查反编译逻辑是否清晰
  3. 在Ubuntu中运行验证功能

七、进阶研究建议

  1. 研究UPX源码实现
  2. 分析不同压缩等级的效果差异
  3. 探索其他加壳工具和技术
  4. 研究反调试和反脱壳技术

八、参考资源

  1. UPX官方源码和文档
  2. ELF文件格式规范
  3. IDA Pro高级调试技术
  4. Linux二进制分析相关书籍
Linux逆向之加壳与脱壳技术详解 一、加壳技术概述 加壳是一种保护可执行文件的技术,通过对原始程序进行压缩或加密,并在程序运行时进行解压/解密,从而达到保护程序的目的。在Linux系统中,UPX是最常见的开源加壳工具。 UPX壳特点 开源免费 支持多种平台 压缩率高 执行速度快 易于使用 二、环境准备与示例程序 1. 示例程序 2. 编译要求 使用静态编译以确保文件大小足够(UPX要求大于40KB): 三、UPX基本操作 1. 加壳操作 常用参数: -d :脱壳 -1 ~ -9 :压缩等级(1最快压缩率最低,9最慢压缩率最高) -k :保留原程序备份 2. 加壳效果验证 加壳后程序应能正常运行: 四、加壳原理分析 1. ELF文件结构变化 使用 readelf 工具查看加壳前后变化: 加壳后: ELF头部信息被修改 段表信息被大幅简化 仅保留UPX自定义的程序入口执行地址 2. 壳识别方法 常用检测工具: checksec :检查安全属性 strings :查看可打印字符串 UPX壳特征: 包含"UPX"等特征字符串 特定的段名和入口点特征 五、UPX壳隐藏技术 1. 手动修改特征 使用二进制编辑器(如010 Editor): 修改UPX相关字符串 替换UPX关键词 效果: 避免被检测工具识别 UPX工具无法自动脱壳 六、手动脱壳技术 1. 脱壳原理 加壳程序运行时会在内存中解压原始代码,手动脱壳的关键是: 找到原始入口点(OEP) 从内存中dump出解压后的程序 2. 脱壳步骤 准备工作 准备IDA调试环境 将 linux_server64 复制到目标系统并运行 IDA远程调试 选择调试器:Remote Linux Debugger 配置远程文件路径和IP地址 在start函数设置断点 开始调试 跟踪执行流程 按F8步过执行 遇到跳转循环时坚持向下执行原则 关键点: 注意 jmp r13 跳转 进入新段后的第一个call 跳过三个向上循环 最终回到OEP(如0x400890) 内存dump脚本 使用IDC脚本dump内存: 验证脱壳结果 用IDA分析dumpfile 检查反编译逻辑是否清晰 在Ubuntu中运行验证功能 七、进阶研究建议 研究UPX源码实现 分析不同压缩等级的效果差异 探索其他加壳工具和技术 研究反调试和反脱壳技术 八、参考资源 UPX官方源码和文档 ELF文件格式规范 IDA Pro高级调试技术 Linux二进制分析相关书籍