PE里新增了一个节,但没有导出表的EXE里新增可以成功运行,有导出表的EXE就出错。(求助)

liangfei1983 2018-06-30 11:34:45



代码如下:
#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
DWORD GetFileBuff(char* FileName);
DWORD GetSizeOfExport(DWORD FileBuff);
DWORD RvaToFoa(DWORD FileBuff,DWORD Rva);
DWORD AddSection(DWORD FileBuff,DWORD SizeOfExport,DWORD SizeOfFile);
DWORD SizeOfFile;
int main(int argc, char* argv[])
{
char* FileName="exeExport.exe";
DWORD FileBuff=GetFileBuff(FileName);
DWORD SizeOfExport=GetSizeOfExport(FileBuff);
if(NULL==SizeOfExport)
{
SizeOfExport=0x1000;
printf("NO EXPORT!\n");
}

DWORD NewBuffFo=AddSection(FileBuff,SizeOfExport,SizeOfFile);

//

return 0;
}

DWORD GetFileBuff(char* FileName)
{
HANDLE hFile=CreateFile(FileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
DWORD NumberOfBytesRead=0;
if(INVALID_HANDLE_VALUE==hFile)
{
printf("CreateFile ERROR:GetLastError()=%d\n",GetLastError());
}
SizeOfFile=GetFileSize(hFile,NULL);
if(INVALID_FILE_SIZE==SizeOfFile)
{
printf("GetFileSize ERROR:GetLastError()=%d\n",GetLastError());
}
LPVOID FileBuff=VirtualAlloc(NULL,SizeOfFile,0x1000,PAGE_READWRITE);
if(NULL==FileBuff)
{
printf("VirtualAlloc ERROR:GetLastError()=%d\n",GetLastError());
}

BOOL bRead=ReadFile(hFile,FileBuff,SizeOfFile,&NumberOfBytesRead,NULL);
if(FALSE==bRead)
{
printf("ReadFile ERROR:GetLastError()=%d\n",GetLastError());
}
return (DWORD)FileBuff;

}
DWORD GetSizeOfExport(DWORD FileBuff)
{
PIMAGE_DOS_HEADER pImageDosHeader;
PIMAGE_NT_HEADERS pImageNtHeaders;
PIMAGE_FILE_HEADER pImageFileHeader;
PIMAGE_OPTIONAL_HEADER pImageOptionalHeader;
PIMAGE_SECTION_HEADER pImageSectionHeader;
PIMAGE_EXPORT_DIRECTORY pImageExportDirectory;

pImageDosHeader=(PIMAGE_DOS_HEADER)FileBuff;
pImageNtHeaders=(PIMAGE_NT_HEADERS)(FileBuff+pImageDosHeader->e_lfanew);
pImageFileHeader=(PIMAGE_FILE_HEADER)((DWORD)pImageNtHeaders+sizeof(pImageNtHeaders->Signature));
pImageOptionalHeader=(PIMAGE_OPTIONAL_HEADER)((DWORD)pImageFileHeader+sizeof(IMAGE_FILE_HEADER));
pImageSectionHeader=(PIMAGE_SECTION_HEADER)((DWORD)pImageOptionalHeader+pImageFileHeader->SizeOfOptionalHeader);
//--------------------------------------------------------------------------
DWORD dwExport=pImageOptionalHeader->DataDirectory[0].VirtualAddress;
DWORD Foa=RvaToFoa(FileBuff,pImageOptionalHeader->DataDirectory[0].VirtualAddress);
pImageExportDirectory=(PIMAGE_EXPORT_DIRECTORY)((DWORD)FileBuff+Foa);
DWORD SizeOfExport=0;
if(dwExport!=0)
{
//得到头的大小
SizeOfExport+=sizeof(IMAGE_EXPORT_DIRECTORY);
//再加函数数组地址的大小
SizeOfExport+=pImageExportDirectory->NumberOfFunctions*sizeof(DWORD);
//再加函数名字数组地址的大小
SizeOfExport+=pImageExportDirectory->NumberOfNames*sizeof(DWORD);
//再加函数序号数组地址的大小
SizeOfExport+=pImageExportDirectory->NumberOfNames*sizeof(WORD);
////再加所有函数名字的大小
DWORD* pNameAddress=(DWORD*)(FileBuff+RvaToFoa(FileBuff,pImageExportDirectory->AddressOfNames));

for(DWORD i=0;i<pImageExportDirectory->NumberOfNames;i++)
{
SizeOfExport+=strlen((char*)(FileBuff+RvaToFoa(FileBuff,pNameAddress[i])))+1;

}
return SizeOfExport;
}
return 0;
}
DWORD RvaToFoa(DWORD FileBuff,DWORD Rva)
{
PIMAGE_DOS_HEADER pImageDosHeader;
PIMAGE_NT_HEADERS pImageNtHeaders;
PIMAGE_FILE_HEADER pImageFileHeader;
PIMAGE_OPTIONAL_HEADER pImageOptionalHeader;
PIMAGE_SECTION_HEADER pImageSectionHeader;

pImageDosHeader=(PIMAGE_DOS_HEADER)FileBuff;
pImageNtHeaders=(PIMAGE_NT_HEADERS)(FileBuff+pImageDosHeader->e_lfanew);
pImageFileHeader=(PIMAGE_FILE_HEADER)((DWORD)pImageNtHeaders+sizeof(pImageNtHeaders->Signature));
pImageOptionalHeader=(PIMAGE_OPTIONAL_HEADER)((DWORD)pImageFileHeader+sizeof(IMAGE_FILE_HEADER));
pImageSectionHeader=(PIMAGE_SECTION_HEADER)((DWORD)pImageOptionalHeader+pImageFileHeader->SizeOfOptionalHeader);
DWORD SectionAlignment=pImageOptionalHeader->SectionAlignment;

for(DWORD i=0;i<pImageFileHeader->NumberOfSections;i++)
{
DWORD SizeOfSection=pImageSectionHeader[i].VirtualAddress+pImageSectionHeader[i].Misc.VirtualSize;

if(SizeOfSection%SectionAlignment)
{
SizeOfSection=(SizeOfSection+SectionAlignment)&(0-SectionAlignment);
}
if(Rva<SizeOfSection)
{
Rva=Rva-pImageSectionHeader[i].VirtualAddress+pImageSectionHeader[i].PointerToRawData;
return Rva;
}

}

return Rva;
}
DWORD AddSection(DWORD FileBuff,DWORD SizeOfExport,DWORD SizeOfFile)
{
char* SectionName=".New";
DWORD NumberOfBytesWrite=0;
PIMAGE_DOS_HEADER pImageDosHeader;
PIMAGE_NT_HEADERS pImageNtHeaders;
PIMAGE_FILE_HEADER pImageFileHeader;
PIMAGE_OPTIONAL_HEADER pImageOptionalHeader;
PIMAGE_SECTION_HEADER pImageSectionHeader;

pImageDosHeader=(PIMAGE_DOS_HEADER)FileBuff;
pImageNtHeaders=(PIMAGE_NT_HEADERS)(FileBuff+pImageDosHeader->e_lfanew);
pImageFileHeader=(PIMAGE_FILE_HEADER)((DWORD)pImageNtHeaders+sizeof(pImageNtHeaders->Signature));
pImageOptionalHeader=(PIMAGE_OPTIONAL_HEADER)((DWORD)pImageFileHeader+sizeof(IMAGE_FILE_HEADER));
pImageSectionHeader=(PIMAGE_SECTION_HEADER)((DWORD)pImageOptionalHeader+pImageFileHeader->SizeOfOptionalHeader);
//---------------------------------------------------------------------------------------------------------
DWORD dwNewSize=SizeOfExport;
if(dwNewSize%pImageOptionalHeader->SectionAlignment)
{
dwNewSize=(dwNewSize+pImageOptionalHeader->SectionAlignment)&(0-pImageOptionalHeader->SectionAlignment);
}

DWORD SizeOfImage=pImageOptionalHeader->SizeOfImage+dwNewSize;
pImageOptionalHeader->SizeOfImage=SizeOfImage;
//将新节表头写进去
DWORD NumberOfSection=pImageFileHeader->NumberOfSections;
pImageFileHeader->NumberOfSections+=1;
pImageSectionHeader[NumberOfSection].Misc.VirtualSize=SizeOfExport;
pImageSectionHeader[NumberOfSection].SizeOfRawData=dwNewSize;
pImageSectionHeader[NumberOfSection].PointerToRawData=pImageSectionHeader[NumberOfSection-1].PointerToRawData
+pImageSectionHeader[NumberOfSection-1].SizeOfRawData;
DWORD dwNewSectionVirtualSize=pImageSectionHeader[NumberOfSection-1].Misc.VirtualSize;
if(dwNewSectionVirtualSize%pImageOptionalHeader->SectionAlignment)
{
dwNewSectionVirtualSize=(dwNewSectionVirtualSize+pImageOptionalHeader->SectionAlignment)
&(0-pImageOptionalHeader->SectionAlignment);
}

pImageSectionHeader[NumberOfSection].VirtualAddress=pImageSectionHeader[NumberOfSection-1].VirtualAddress
+dwNewSectionVirtualSize;
pImageSectionHeader[NumberOfSection].Characteristics=0xffffffff;
strcpy((char*)(pImageSectionHeader[NumberOfSection].Name),SectionName);

LPVOID NewBuff=VirtualAlloc(NULL,SizeOfImage,0x1000,PAGE_READWRITE);
if(NULL==NewBuff)
{
printf("VirtualAlloc ERROR:GetLastError()=%d\n",GetLastError());
}
//将原节表头复制进去
memcpy(NewBuff,(void*)FileBuff,pImageOptionalHeader->SizeOfHeaders);


for(DWORD i=0;i<NumberOfSection;i++)
{
memcpy((void*)((DWORD)NewBuff+pImageSectionHeader[i].PointerToRawData),
(void*)((DWORD)FileBuff+pImageSectionHeader[i].PointerToRawData),
pImageSectionHeader[i].SizeOfRawData);
}






HANDLE hNewFile=CreateFile("NewexeExport.exe",GENERIC_ALL,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);

BOOL bWriteFile=WriteFile(hNewFile,NewBuff,SizeOfFile+SizeOfExport
,&NumberOfBytesWrite,NULL);
if(false==bWriteFile)
{
printf("MemeryToFile WriteFile error=%d\n",GetLastError());
}


return 0;
}



下面这个是exeExport.exe的代码:
#include "stdafx.h"
#include <stdio.h>
extern "C" _declspec(dllexport) int Print(int a);
int Print(int a)
{
printf("%d\n",a);
return 0;
}
int main(int argc, char* argv[])
{
printf("TEST\n");
return 0;
}


下面是错误的显示:



但如果我不用带有导出表的EXE测试就没有问题,请教错误出在哪里?
...全文
108 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
liangfei1983 2018-07-01
  • 打赏
  • 举报
回复
找到错误了!花了足足一天的时间,各种调试,知识明显巩固多了!
liangfei1983 2018-07-01
  • 打赏
  • 举报
回复
看了那本书,还是没有找出错误来!
赵4老师 2018-06-30
  • 打赏
  • 举报
回复
《Windows PE权威指南》
赵4老师 2018-06-30
  • 打赏
  • 举报
回复
《Windows PE权威指南》

64,439

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧