PE文件操作-动态加载

本文探讨了如何实现PELoader以动态加载DLL,重点在于处理IAT表的修正和重定位表的调整。在加载过程中,需要根据内存对齐读取节表,并填充IAT。重定位表的修正涉及到新基址与默认基址的偏移计算。最后,通过修改节内存属性并启动入口函数,完成PE文件的加载。对于没有ASLR的EXE文件,可能需要还原重定位表。
摘要由CSDN通过智能技术生成

有时会有这样的需求,要把一个dll加载到进程空间或者对付地址空间随机化技术,这就需要自己实现一个PELoader。在PE文件中,许多数据在内存中的位置已经以RVA的形式在链接时给出,我们只需要根据节表的描述准确的按位置加载,大部分程序就可以正确运行了,但有几个类型的数据还是需要loader来调整的:

  1. IAT
    在PE文件中,调用静态链接的DLL例程一般都是以call ds:[xxxxxxxxh]的形式,其中这个地址是指向了IAT表的对应项,而在文件中,IAT表的每一项是和INT表一样指向了一个IMAGE_IMPORT_BY_NAME或者是个Id,所以当加载到内存中时需要将表项修正为函数地址。
  2. 重定位表
    一般加载exe文件没有重定位的问题,因为exe文件会加载到默认的基址上,而在进程地址空间初始化后,这个基址几乎肯定是未分配的,但dll或者使用了地址空间随机化技术的exe就会使用到重定位表,因此我们需要根据加载的基址和OPTIONAL_HEADER中的基址来算出偏移

注:在这篇中主要写加载dll,至于exe调试时还有一些不稳定的情况,以后再说。
文章中的ctx是自己写的一个pe解析器,等完善后会放到开源网站上。
首先,为了避开CreateSection检测,我们直接用CreateFile:

    IMAGE_DOS_HEADER dos_header;
    IMAGE_NT_HEADERS32 nt_header;

    SetFilePointer(pe_file, 0, 0, FILE_BEGIN);
    ReadFile(pe_file, &dos_header, sizeof(IMAGE_DOS_HEADER), &ret, NULL);
    if (ret != sizeof(IMAGE_DOS_HEADER))
        return false;

    SetFilePointer(pe_file, dos_header.e_lfanew, NULL, FILE_BEGIN);
    ReadFile(pe_file, &nt_header, sizeof(IMAGE_NT_HEADERS32), &ret, NULL);
    if (ret != sizeof(IMAGE_NT_HEADERS32))
        return false;

    //在OptionalHeader中找到准确的印象大小
    PVOID map_ptr = VirtualAlloc(NULL, 
        nt_header.OptionalHeader.SizeOfImage, 
        MEM_COMMIT, PAGE_READWRITE);
    ZeroMemory(map_ptr, nt_header.OptionalHe
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值