移动导出表

本文介绍了移动导出表的技术实现,包括添加节、RVA与FOA转化、导出表操作等步骤。首先,通过fopen()和fclose()函数处理文件流,接着详细阐述了RVA到FOA及反之的转化过程。然后,详细说明了如何添加新的节,以及移动导出表的具体步骤,涉及到函数地址和名称的更新。最后,提到了相关代码实现和实验对比。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

移动导出表:

思路:

添加节之后新建一个句柄用来重新安排结构情况,然后将的句柄的内容写入读入的数据流中。

前期知识:

fopen()和 fclose()

两个函数都是文件操作函数,对数据流进行操作
fopen将文件读入一个文件流,文件流就是文件原本的形式。
fclose()将文件流关闭。
fwrite():fwrite(NewBuffer,pOptionalHeader->SizeOfImage,1,fp);
可以直接将内存写入数据流中

RVA 和 FOA的转化:

FOA->RVA:修改新的导出表的AddressOfFunctions、AddressOfNameOrdinals、AddressOfNames地址,需要转化成RVA
RVA->FOA:定位导出地址表、导出名称表、导出序号表需要将内容转化成FOA

添加节:

1.判断节表空间是否够2个节表的长度(最后一个节表需要全部为0)
2.对节表进行赋值
3.FileHeader的节区数量+1
4.OptionalHeader的ImageBase的大小+0x1000

移动导出表:

1.申请一个新的内存NewBuffer,将原来内存复制。
2.定位三个表的位置(需要RVA -> FOA)
3.复制三个表的内容到新的句柄
4.复制函数名称(每复制一个函数名就要计算偏移RVA添加到函数名称表的地址中)
5.复制IMAGE_EXPORT_DIRECTORY结构体
6.修改新的导出表的AddressOfFunctions、AddressOfNameOrdinals、AddressOfNames地址
7.修改VirtualAddress值,指向新的导出表地址
8.读取文件,将修改后的新的句柄写入文件流中

代码

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

DWORD RVATOFOA(DWORD RVA,LPVOID pFileBuffer)
{
   
    DWORD FOA = NULL;
    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNtHeaders = NULL;
    PIMAGE_FILE_HEADER pFileHeader = NULL;
    PIMAGE_OPTIONAL_HEADER pOptionalHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;

    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
    pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNtHeaders + 4);
    pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
    if(RVA <= pOptionalHeader->SizeOfHeaders)
        return RVA;
    for(;RVA >(pSectionHeader->Misc.VirtualSize  + pSectionHeader->VirtualAddress);pSectionHeader++);//定位到所在的节
    FOA = RVA - pSectionHeader->VirtualAddress + pSectionHeader->PointerToRawData;
    return FOA;
}
DWORD FOATORVA(DWORD FOA,LPVOID pFileBuffer)
{
   
    DWORD RVA = NULL;
    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNtHeaders = NULL;
    PIMAGE_FILE_HEADER pFileHeader = NULL;
    PIMAGE_OPTIONAL_HEADER pOptionalHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;

    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
    pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNtHeaders + 4);
    pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
    if(FOA <= pOptionalHeader->SizeOfHeaders)
        return RVA;
    for
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值