一、流程
1、File-> FileBuffer
2、添加节
3、定位导出表
4、将导出函数名称表、导出函数地址表、导出函数序号表Rva转Foa
5、定位导出函数名称表、导出函数地址表、导出函数序号表
6、移动导出函数名称表、导出函数地址表、导出函数序号表
7、复制导出函数名称表中的名称
8、获取函数名称的偏移
9、移动函数名称,并修复导出函数名称表
10、移动导出表结构体
11、修复导出函数名称表、导出函数地址表、导出函数序号表(Foa转Rva)
12、修复导出表的地址
二、演示
1、File-> FileBuffer
DWORD Size = 0;
BOOL isok = FALSE;
LPVOID pFileBuffer = NULL;
//File-> FileBuffer
Size = ReadPEFile(FILEPATH_IN,&pFileBuffer); //调用函数读取文件数据
if(!pFileBuffer || !Size)
{
printf("File-> FileBuffer失败");
return;
}
2、添加节
PIMAGE_DOS_HEADER pDosHeader = NULL;//DOS头
PIMAGE_NT_HEADERS pNtHeader = NULL;//NT头
PIMAGE_FILE_HEADER pFileHeader = NULL;//标准PE头
PIMAGE_OPTIONAL_HEADER pOptionalHeader = NULL;//拓展PE头
PIMAGE_SECTION_HEADER pSectionHeader = NULL;//节表
PIMAGE_SECTION_HEADER pNewSec = NULL;//新节表结构
PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL; //导出表结构体
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNtHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
//判断是否有足够的空间添加节表
if((DWORD)pNtHeader - (DWORD)pDosHeader - 0x40 < sizeof(IMAGE_SECTION_HEADER))
{
printf("没有多余空间");
free(pFileBuffer);
return;
}
memcpy((void*)((DWORD)pDosHeader + 0x40),
pNtHeader,
(DWORD)(pSectionHeader + pFileHeader->NumberOfSections) - (DWORD)pNtHeader);
pDosHeader->e_lfanew = 0x40;
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNtHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
//新增节表结构
pNewSec = (PIMAGE_SECTION_HEADER)(pSectionHeader + pFileHeader->NumberOfSections);
memset(pNewSec, 0, (DWORD)(pSectionHeader + pFileHeader->NumberOfSections) - (DWORD)pNtHeader);
//修改节表内容
memcpy(pNewSec->Name,".export",8);//修改节表名
PIMAGE_SECTION_HEADER upSecHeader = (PIMAGE_SECTION_HEADER)(pSectionHeader + pFileHeader->NumberOfSections-1);
if(upSecHeader->Misc.VirtualSize > upSecHeader->SizeOfRawData)//修改节表VrituallAddress
{
pNewSec->VirtualAddress = upSecHeader->VirtualAddress + upSecHeader->Misc.VirtualSize;
}else{
pNewSec->VirtualAddress = upSecHeader->VirtualAddress + upSecHeader->SizeOfRawData;
}
pNewSec->SizeOfRawData = 0x1000;//新增的节区的大小
pNewSec->PointerToRawData = upSecHeader->PointerToRawData + upSecHeader->SizeOfRawData;//文件中的偏移
pNewSec->Characteristics = 0x60000020;//修改属性(可执行)
3、定位导出表
//修改NT头属性
pFileHeader->NumberOfSections += 1;//修改NumberOfSection数量
pOptionalHeader->SizeOfImage += 0x1000;//修改SizeOfImage大小
LPVOID NewBuffer = malloc(pOptionalHeader->SizeOfImage);//申请内存
memset(NewBuffer, 0, pOptionalHeader->SizeOfImage);//初始化内存
memcpy(NewBuffer, pFileBuffer,Size);//复制内存
4、将导出函数名称表、导出函数地址表、导出函数序号表Rva转Foa
//定位导出表
DWORD ExportFoa = NULL;//导出表FOA
PDWORD AddressOfNames = NULL;//导出函数名称表
LPVOID AddressOfFunctions = NULL;//导出函数地址表
PWORD AddressOfNameOrdinals = NULL;//导出函数序号表
DWORD AddressOfNamesFOA = NULL;//导出函数名称表FOA
DWORD AddressOfFunctionsFOA = NULL;//导出函数地址表FOA
DWORD AddressOfNameOrdinalsFOA = NULL;//导出函数序号表FOA
ExportFoa = RvaToFoa(pOptionalHeader->DataDirectory[0].VirtualAddress,pFileBuffer);//获取导出表的地址FOA
pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + ExportFoa);//定位导出表
5、定位导出函数名称表、导出函数地址表、导出函数序号表
AddressOfNamesFOA = RvaToFoa(pExportDirectory->AddressOfNames,pFileBuffer);//获取导出函数名称表FOA
AddressOfFunctionsFOA = RvaToFoa(pExportDirectory->AddressOfFunctions,pFileBuffer);//获取到处函数地址表FOA
AddressOfNameOrdinalsFOA = RvaToFoa(pExportDirectory->AddressOfNameOrdinals,pFileBuffer);//获取导出函数序号表FOA
AddressOfNames = (PDWORD)((DWORD)pFileBuffer + AddressOfNamesFOA);//定位导出函数名称表
AddressOfFunctions = (LPVOID)((DWORD)pFileBuffer + AddressOfFunctionsFOA);//定位导出函数地址表
AddressOfNameOrdinals = (PWORD)((DWORD)pFileBuffer + AddressOfNameOrdinalsFOA);//定位导出函数序号表
6、移动导出函数名称表、导出函数地址表、导出函数序号表
//复制AddressOfFunctions表
LPVOID pNewSecAddr = (LPVOID)((DWORD)NewBuffer+pNewSec->PointerToRawData);//定位新节表的地址
memcpy(pNewSecAddr,AddressOfFunctions,(pExportDirectory->NumberOfFunctions * 4));
//复制AddressOfNameOrdinals表
pNewSecAddr =(LPVOID)((DWORD)pNewSecAddr + (pExportDirectory->NumberOfFunctions * 4));
memcpy(pNewSecAddr,AddressOfNameOrdinals,(pExportDirectory->NumberOfNames * 2));
//复制AddressOfNames
pNewSecAddr =(LPVOID)((DWORD)pNewSecAddr + (pExportDirectory->NumberOfNames * 2));
PDWORD NameAddr = (PDWORD)pNewSecAddr;//这里存储一下函数地址名称表的地址,以便后边移动名称的时候修改相应地址
memcpy(pNewSecAddr,AddressOfNames,(pExportDirectory->NumberOfNames * 4));
7、复制导出函数名称表中的名称
//复制函数名称表中的名称
pNewSecAddr =(LPVOID)((DWORD)pNewSecAddr + (pExportDirectory->NumberOfNames * 4));
8、获取函数名称的偏移
DWORD NameAddOffset = (DWORD)pNewSecAddr - (DWORD)NewBuffer;//函数名称偏移
9、移动函数名称,并修复导出函数名称表
for(size_t i=0;i < pExportDirectory->NumberOfNames;i++,AddressOfNames++)
{
DWORD NameOffset = (DWORD)*AddressOfNames;
PCHAR FName = (PCHAR)((DWORD)pFileBuffer + NameOffset);
size_t l = 0;
*NameAddr = FoaToRva(NameAddOffset,NewBuffer);//复制函数名称偏移到地址中
NameAddr = (PDWORD)((DWORD)NameAddr + 0x4);
while(FName[l] != '\0')
{
l += 1;
}
NameAddOffset += (l+1);
memcpy(pNewSecAddr,FName,(l+1));//复制函数名字符串到地址中
pNewSecAddr =(LPVOID)((DWORD)pNewSecAddr + l+1);
}
10、移动导出表结构体
//复制IMAGE_EXPORT_DIRECTORY结构体
memcpy(pNewSecAddr,pExportDirectory,pOptionalHeader->DataDirectory[0].Size);
PIMAGE_EXPORT_DIRECTORY pNewExportDirectory = (PIMAGE_EXPORT_DIRECTORY)pNewSecAddr;//地址赋值给新的导出表结构体
11、修复导出函数名称表、导出函数地址表、导出函数序号表(Foa转Rva)
//复制IMAGE_EXPORT_DIRECTORY结构体
memcpy(pNewSecAddr,pExportDirectory,pOptionalHeader->DataDirectory[0].Size);
PIMAGE_EXPORT_DIRECTORY pNewExportDirectory = (PIMAGE_EXPORT_DIRECTORY)pNewSecAddr;//地址赋值给新的导出表结构体
12、修复导出表的地址
//修复目录项中的值,指向新的导出表的地址RVA
pDosHeader = (PIMAGE_DOS_HEADER)NewBuffer;
pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNtHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
pOptionalHeader->DataDirectory[0].VirtualAddress = FoaToRva((DWORD)pNewExportDirectory - (DWORD)NewBuffer,NewBuffer);
13、存盘
isok = MemeryTOFile(NewBuffer,Size+1000,FILEPATH_OUT);
if(isok)
{
printf("存盘成功");
return;
}
//释放内存
free(pFileBuffer);
free(NewBuffer);
return;
三、完整代码
#include "stdafx.h"
#include <windows.h>
#include "stdlib.h"
#define FILEPATH_IN "C:/testdll.dll"
#define FILEPATH_OUT "C:/copyxx.dll"
DWORD ReadPEFile(IN LPSTR lpszFile,OUT LPVOID* pFileBuffer )
{
FILE *pFile = NULL;
DWORD fileSize = 0; //文件大小
LPVOID pTempFileBuffer = NULL; //缓冲区首地址
pFile = fopen(lpszFile,"rb"); //打开文件
if(!pFile)
{
printf("打开文件失败");
return NULL;
}
//读取文件大小
fseek(pFile,0,SEEK_END); //将指针从开始的位置移动到末尾
fileSize = ftell(pFile); //获取数据大小
//分配缓冲区(申请内存)
pTempFileBuffer = malloc(fileSize);
if(!pTempFileBuffer)
{
printf("分配空间失败");
fclose(pFile);
return NULL;
}
//将文件数据读取到缓冲区
fseek(pFile,0,SEEK_SET); //将指针指向开始
size_t n = fread(pTempFileBuffer,fileSize,1,pFile); //将数据读取到缓冲区中
if(!n)
{
printf("读取数据失败");
free(pTempFileBuffer); //释放内存
fclose(pFile); //关闭文件
return NULL;
}
//关闭文件
*pFileBuffer = pTempFileBuffer;
pTempFileBuffer = NULL;
fclose(pFile); //关闭文件
return fileSize;
}
BOOL MemeryTOFile(LPVOID pMemBuffer,size_t size,LPSTR lpszFile)
{
FILE *fp = NULL;
fp = fopen(lpszFile,"wb+");
if(!fp)
{
printf("存盘失败");
return FALSE;
}
fwrite(pMemBuffer,size,1,fp); //向磁盘写入数据
fclose(fp); //关闭文件
fp = NULL;
return TRUE;
}
//**********************************************************************
DWORD RvaToFoa(DWORD RVA,LPVOID pFileBuffer)
{
DWORD FOA = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNtHeader = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
PIMAGE_OPTIONAL_HEADER pOptionalHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNtHeader + 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->VirtualAddress + pSectionHeader->Misc.VirtualSize);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 pNtHeader = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
PIMAGE_OPTIONAL_HEADER pOptionalHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNtHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
if(FOA <= pOptionalHeader->SizeOfHeaders)
return FOA;
for(;FOA > (pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize);pSectionHeader++);//定位到所在节
RVA = FOA - pSectionHeader->PointerToRawData + pSectionHeader->VirtualAddress ;
return RVA;
}
VOID MoveExport()
{
DWORD Size = 0;
BOOL isok = FALSE;
LPVOID pFileBuffer = NULL;
//File-> FileBuffer
Size = ReadPEFile(FILEPATH_IN,&pFileBuffer); //调用函数读取文件数据
if(!pFileBuffer || !Size)
{
printf("File-> FileBuffer失败");
return;
}
PIMAGE_DOS_HEADER pDosHeader = NULL;//DOS头
PIMAGE_NT_HEADERS pNtHeader = NULL;//NT头
PIMAGE_FILE_HEADER pFileHeader = NULL;//标准PE头
PIMAGE_OPTIONAL_HEADER pOptionalHeader = NULL;//拓展PE头
PIMAGE_SECTION_HEADER pSectionHeader = NULL;//节表
PIMAGE_SECTION_HEADER pNewSec = NULL;//新节表结构
PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL; //导出表结构体
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNtHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
//判断是否有足够的空间添加节表
if((DWORD)pNtHeader - (DWORD)pDosHeader - 0x40 < sizeof(IMAGE_SECTION_HEADER))
{
printf("没有多余空间");
free(pFileBuffer);
return;
}
memcpy((void*)((DWORD)pDosHeader + 0x40),
pNtHeader,
(DWORD)(pSectionHeader + pFileHeader->NumberOfSections) - (DWORD)pNtHeader);
pDosHeader->e_lfanew = 0x40;
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNtHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
//新增节表结构
pNewSec = (PIMAGE_SECTION_HEADER)(pSectionHeader + pFileHeader->NumberOfSections);
memset(pNewSec, 0, (DWORD)(pSectionHeader + pFileHeader->NumberOfSections) - (DWORD)pNtHeader);
//修改节表内容
memcpy(pNewSec->Name,".export",8);//修改节表名
PIMAGE_SECTION_HEADER upSecHeader = (PIMAGE_SECTION_HEADER)(pSectionHeader + pFileHeader->NumberOfSections-1);
if(upSecHeader->Misc.VirtualSize > upSecHeader->SizeOfRawData)//修改节表VrituallAddress
{
pNewSec->VirtualAddress = upSecHeader->VirtualAddress + upSecHeader->Misc.VirtualSize;
}else{
pNewSec->VirtualAddress = upSecHeader->VirtualAddress + upSecHeader->SizeOfRawData;
}
pNewSec->SizeOfRawData = 0x1000;//新增的节区的大小
pNewSec->PointerToRawData = upSecHeader->PointerToRawData + upSecHeader->SizeOfRawData;//文件中的偏移
pNewSec->Characteristics = 0x60000020;//修改属性(可执行)
//在新增节表后增加40个字节的空白区
//memset(pNewSec+1, 0, 40);
//修改NT头属性
pFileHeader->NumberOfSections += 1;//修改NumberOfSection数量
pOptionalHeader->SizeOfImage += 0x1000;//修改SizeOfImage大小
LPVOID NewBuffer = malloc(Size+0x1000);//申请内存
memset(NewBuffer, 0, Size+0x1000);//初始化内存
memcpy(NewBuffer, pFileBuffer,Size);//复制内存
//定位导出表
DWORD ExportFoa = NULL;//导出表FOA
PDWORD AddressOfNames = NULL;//导出函数名称表
LPVOID AddressOfFunctions = NULL;//导出函数地址表
PWORD AddressOfNameOrdinals = NULL;//导出函数序号表
DWORD AddressOfNamesFOA = NULL;//导出函数名称表FOA
DWORD AddressOfFunctionsFOA = NULL;//导出函数地址表FOA
DWORD AddressOfNameOrdinalsFOA = NULL;//导出函数序号表FOA
ExportFoa = RvaToFoa(pOptionalHeader->DataDirectory[0].VirtualAddress,pFileBuffer);//获取导出表的地址FOA
pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + ExportFoa);//定位导出表
AddressOfNamesFOA = RvaToFoa(pExportDirectory->AddressOfNames,pFileBuffer);//获取导出函数名称表FOA
AddressOfFunctionsFOA = RvaToFoa(pExportDirectory->AddressOfFunctions,pFileBuffer);//获取到处函数地址表FOA
AddressOfNameOrdinalsFOA = RvaToFoa(pExportDirectory->AddressOfNameOrdinals,pFileBuffer);//获取导出函数序号表FOA
AddressOfNames = (PDWORD)((DWORD)pFileBuffer + AddressOfNamesFOA);//定位导出函数名称表
AddressOfFunctions = (LPVOID)((DWORD)pFileBuffer + AddressOfFunctionsFOA);//定位导出函数地址表
AddressOfNameOrdinals = (PWORD)((DWORD)pFileBuffer + AddressOfNameOrdinalsFOA);//定位导出函数序号表
//复制AddressOfFunctions表
LPVOID pNewSecAddr = (LPVOID)((DWORD)NewBuffer+pNewSec->PointerToRawData);//定位新节表的地址
memcpy(pNewSecAddr,AddressOfFunctions,(pExportDirectory->NumberOfFunctions * 4));
//复制AddressOfNameOrdinals表
pNewSecAddr =(LPVOID)((DWORD)pNewSecAddr + (pExportDirectory->NumberOfFunctions * 4));
memcpy(pNewSecAddr,AddressOfNameOrdinals,(pExportDirectory->NumberOfNames * 2));
//复制AddressOfNames
pNewSecAddr =(LPVOID)((DWORD)pNewSecAddr + (pExportDirectory->NumberOfNames * 2));
PDWORD NameAddr = (PDWORD)pNewSecAddr;//这里存储一下函数地址名称表的地址,以便后边移动名称的时候修改相应地址
memcpy(pNewSecAddr,AddressOfNames,(pExportDirectory->NumberOfNames * 4));
//复制函数名称表中的名称
pNewSecAddr =(LPVOID)((DWORD)pNewSecAddr + (pExportDirectory->NumberOfNames * 4));
//每复制一个函数名就要计算偏移添加到名字表的地址里
DWORD NameAddOffset = (DWORD)pNewSecAddr - (DWORD)NewBuffer;//函数名称偏移
for(size_t i=0;i < pExportDirectory->NumberOfNames;i++,AddressOfNames++)
{
DWORD NameOffset = (DWORD)*AddressOfNames;
PCHAR FName = (PCHAR)((DWORD)pFileBuffer + NameOffset);
size_t l = 0;
*NameAddr = FoaToRva(NameAddOffset,NewBuffer);//复制函数名称偏移到地址中
NameAddr = (PDWORD)((DWORD)NameAddr + 0x4);
while(FName[l] != '\0')
{
l += 1;
}
NameAddOffset += (l+1);
memcpy(pNewSecAddr,FName,(l+1));//复制函数名字符串到地址中
pNewSecAddr =(LPVOID)((DWORD)pNewSecAddr + l+1);
}
//复制IMAGE_EXPORT_DIRECTORY结构体
memcpy(pNewSecAddr,pExportDirectory,pOptionalHeader->DataDirectory[0].Size);
PIMAGE_EXPORT_DIRECTORY pNewExportDirectory = (PIMAGE_EXPORT_DIRECTORY)pNewSecAddr;//地址赋值给新的导出表结构体
//修改新的导出表的AddressOfFunctions、AddressOfNameOrdinals、AddressOfNames地址,这里需要FOA->RVA
pNewExportDirectory->AddressOfFunctions = FoaToRva(pNewSec->PointerToRawData,NewBuffer);
pNewExportDirectory->AddressOfNameOrdinals = FoaToRva(pNewSec->PointerToRawData + pExportDirectory->NumberOfFunctions * 4,NewBuffer);
pNewExportDirectory->AddressOfNames = FoaToRva(pNewSec->PointerToRawData + pExportDirectory->NumberOfFunctions * 4 + pExportDirectory->NumberOfNames * 2,NewBuffer);
//修复目录项中的值,指向新的导出表的地址RVA
pDosHeader = (PIMAGE_DOS_HEADER)NewBuffer;
pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNtHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
pOptionalHeader->DataDirectory[0].VirtualAddress = FoaToRva((DWORD)pNewExportDirectory - (DWORD)NewBuffer,NewBuffer);
//存盘
isok = MemeryTOFile(NewBuffer,Size+1000,FILEPATH_OUT);
if(isok)
{
printf("存盘成功");
return;
}
//释放内存
free(pFileBuffer);
free(NewBuffer);
return;
}
//**********************************************************************
int main(int argc, char* argv[])
{
MoveExport();
getchar();
return 0;
}