写一个PE的壳_Part 4:修复对ASLR支持+lief构建新PE


系列汇总


Part 3中遗留了一个隐患,MinGW无法生成重定位表,因此无法产生可移动的二进制文件;Part 4中要处理MinGW生成的可执行文件(不能移动的,即不支持ASLR的二进制文件)的打包问题

1.解决思路

step 1:当前现状

寻找解决办法前,先回顾一个Part 3中packed.exe是怎么处理支持ASLR的二进制文件(用calc.exe举例)的?

  • 1.packed.exe里面新增一个名称为.packed的区段,区段的内容被加载为calc.exe
  • 2.packed.exe负责解析.packed,放到一块我们申请的内存中,用参数是NULL的VirtualAlloc来申请一块随机内存来达到对ASLR的支持
  • 3.修复完calc.exe的输入表和重定位表,找到calc.exe的入口EP,执行calc.exe

下面是Part 3中unpacker.exe(或者叫packed.exe也可以)的内存布局示意图

VA RVA CONTENT
0x00400000 0 unpacker PE header
0x00401000 0x1000 unpacker .text section
0x00402000 0x2000 unpacker .rdata section
0x00403000 0x3000 unpacker .idata section
0x00404000 0x4000 unpacker .packed section

下面给出了Part 3中问题的原因

  • 问题:为什么Part 3中对不支持ASLR的二进制不支持呢?

  • 假设:part 3中最后生成的壳(或者叫打包)文件名为:packed.exe;不支持ASLR的测试程序名为:test.exe,源码如下:

    //test.exe的源码
    #include <stdio.h>
    #include <stdlib.h>
    int main() {
         
         
    	printf("this is a test for compil with MinGW, no reloc\n");
        return 0;
    }
    
  • 冲突:packed.exe默认是加载在0x400000的,test.exe因为不能移动(即不支持ASLR),导致也需要加载在0x400000上,产生冲突

  • 原因:packed.exe先运行,把坑占用了,test.exe没有重定位表,没法重定位,因此不能运行

step 2:解决思路

test.exe的重定位表没有,在packed.exe内存里拷贝一份不就解决了

问题1:那拷贝在哪里才能生效?

当然是不支持ASLR的程序(如test.exe)加载在0x00400000位置时,test.exe的重定位表应该放的位置(感觉像废话)

也从侧面看出来,测试整个进程packed.exe的加载基址应该是0x00400000,而不能是NULL的VirtualAlloc来申请一块随机内存,这部分后面后看到区别

问题2:packed.exe的重定位表已经把坑占了怎么办?

那就将packed.exe的重定位表整理后移呗,反正它也不用重定位表,下面是思路:

  • 1.packed.exe的重定位表都是在section里,先算好test.exe的重定位表的大小sizeof_alloc
  • 2.在packe.exe的第一个section的位置预留出sizeof_alloc大小的空间,后续load_PE函数会处理这里
  • 3.packed.exe的所有section整体向后平移sizeof_alloc就可以了

问题3:上面修改就解决问题了?

当然,先将test.exe加载在packe.exe的Image Base算出(是否支持ASLR处理方式不同),然后不破坏packed.exe的PE header,解析.packed开始执行test.exe;但是已经巧妙的将test.exe的section放入packed.exe区段的起始位置,这样test.exe就不需要重定位了,巧妙的解决了没有重定位表的问题

step 3:内存布局

如果我们想打包一个二进制文件,希望放在VA 0x00400000开始的内存中,下面是unpacker.exe修改后(文件名改成了packe.exe)的内存布局示意图

VA RVA CONTENT
image base of the packed binary 0 unpacker PE header
0x1000 .alloc section, for the packed binary loading
0x1000 + size of the packed binary in memory sections of the unpacker
sections of the unpacker
0x4000 + size of the packed binary in memory .packed section, with the packed PE file

2.修改unpack部分

相对于Part 3中的unpack部分,改的很少,主要是改动load_PE函数,c文件名是unpack_part4.c;整体修改前后对比,如果看不清楚也没有关系,后面会有详细的介绍

在这里插入图片描述

Part 3中支持ASLR是通过VirtualAlloc来申请一块内存来实现的,Part 4中要解决不支持ASLR的情况;几处改动说明:

Image Base

首先要检查PE文件的头中的DLLCharacteristics,看一下是否支持ASLR?

  • 不支持:也就没有重定位表什么事了,PE文件的加载位置就应该是默认的基址,使用当前模块地址作为基址
  • 支持:VirtualAlloc新申请一块内存,用于放被加载的程序(如test.exe)
char* ImageBase = NULL;
if(p_NT_HDR->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) {
   
   
    ImageBase = 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值