[C] 纯文本查看 复制代码
#include "iostream"
#include <windows.h>
// exe->filebuffer 返回值为计算所得文件大小
int ReadPEFile(char* file_path,PVOID* pFileBuffer)
{
FILE* pfile =NULL;// 文件指针
DWORD file_size=0;
LPVOID pTempFilebuffer =NULL;
pfile =fopen(file_path,"rb");// 如果有新的指针,就要进行判断
if(!pfile )
{
printf("打开exe文件失败!\n");//如果分配失败就要关闭文件、释放动态内存、指针指向NULL
return 0;
}
fseek(pfile ,0,SEEK_END);
file_size=ftell(pfile);
fseek(pfile ,0,SEEK_SET);
pTempFilebuffer=malloc(file_size);
if(!pTempFilebuffer)
{
printf("分配空间失败!\n");//如果分配失败就要关闭文件、释放动态内存、指针指向NULL
fclose(pfile );
return 0;
}
size_t n=fread(pTempFilebuffer,file_size,1,pfile );
if(!n)
{
printf("分配空间失败!\n");
fclose(pfile);
free(pTempFilebuffer);
return 0;
}
*pFileBuffer=pTempFilebuffer;
pTempFilebuffer=NULL;
fclose(pfile);
return file_size;
}
// filebuffer -> imagebuffer
DWORD CopyFileBufferToImageBuffer(PVOID pFileBuffer,PVOID* pImageBuffer)
{
// 初始化PE头部结构体
PIMAGE_DOS_HEADER pDosHeader =NULL;
PIMAGE_NT_HEADERS pNTHeader =NULL;
PIMAGE_FILE_HEADER pPEHeader =NULL;
PIMAGE_OPTIONAL_HEADER pOptionHeader =NULL;
PIMAGE_SECTION_HEADER pSectionHeader =NULL;
// 初始化IMAGE_BUFFER指针(temparay)
LPVOID pTempImagebuffer = NULL;
if(!pFileBuffer)
{
printf("(2pimagebuffer阶段)读取到内存的pfilebuffer无效!\n");
return 0 ;
}
if(*((PWORD)pFileBuffer)!=IMAGE_DOS_SIGNATURE)
{
printf("(2pimagebuffer阶段)不含MZ标志,不是exe文件!\n");
return 0;
}
pDosHeader=PIMAGE_DOS_HEADER(pFileBuffer);
pNTHeader=(PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
pPEHeader=(PIMAGE_FILE_HEADER)((DWORD)pNTHeader+4);
pOptionHeader=(PIMAGE_OPTIONAL_HEADER)((DWORD)pNTHeader+0x18);
// pSectionHeader=(PIMAGE_SECTION_HEADER)((DWORD)pDosHeader+pOptionHeader->SizeOfHeaders);
//为什么这里不一样
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
// 分配动态内存
pTempImagebuffer =malloc(pOptionHeader->SizeOfImage);
if(!pTempImagebuffer)
{
printf("分配空间失败!\n");//如果分配失败就要关闭文件、释放动态内存、指针指向NULL
free(pTempImagebuffer);
return 0;
}
memset(pTempImagebuffer,0,pOptionHeader->SizeOfImage);
memcpy(pTempImagebuffer,pDosHeader,pOptionHeader->SizeOfHeaders);
PIMAGE_SECTION_HEADER pTempSectionHeader = pSectionHeader;
for(DWORD i=0;i<pPEHeader->NumberOfSections;i++,pTempSectionHeader++)
memcpy((void*)((DWORD)pTempImagebuffer+pTempSectionHeader->VirtualAddress)
,(void*)((DWORD)pDosHeader+pTempSectionHeader->PointerToRawData)
,pTempSectionHeader->SizeOfRawData);
*pImageBuffer=pTempImagebuffer;
pTempImagebuffer=NULL;
return pOptionHeader->SizeOfImage;
}
DWORD CopyImageBufferToNewBuffer(IN LPVOID pImageBuffer,OUT LPVOID* pNewBuffer)
{
// 初始化PE头部结构体
PIMAGE_DOS_HEADER pDosHeader =NULL;
PIMAGE_NT_HEADERS pNTHeader =NULL;
PIMAGE_FILE_HEADER pPEHeader =NULL;
PIMAGE_OPTIONAL_HEADER pOptionHeader =NULL;
PIMAGE_SECTION_HEADER pSectionHeader =NULL;
if(!pImageBuffer)
{
printf("分配空间失败!\n");//如果分配失败就要关闭文件、释放动态内存、指针指向NULL
free(pImageBuffer);
return 0;
}
if(*((PWORD)pImageBuffer)!=IMAGE_DOS_SIGNATURE)
{
printf("(2pimagebuffer阶段)不含MZ标志,不是exe文件!\n");
return 0;
}
pDosHeader=(PIMAGE_DOS_HEADER)pImageBuffer;
pNTHeader=(PIMAGE_NT_HEADERS)((DWORD)pDosHeader+pDosHeader->e_lfanew);
pPEHeader=(PIMAGE_FILE_HEADER)((DWORD)pNTHeader+4);
pOptionHeader=(PIMAGE_OPTIONAL_HEADER)((DWORD)pNTHeader+0x18);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
PIMAGE_SECTION_HEADER pSectionHeader1=pSectionHeader;
DWORD a=pOptionHeader->SizeOfHeaders;
for(DWORD q=0;q<pPEHeader->NumberOfSections;q++,pSectionHeader1++)
a+=pSectionHeader1->SizeOfRawData;
LPVOID pTempImagebuffer = NULL;
pTempImagebuffer=malloc(a);
if(!pTempImagebuffer)
{
printf("分配空间失败!\n");//如果分配失败就要关闭文件、释放动态内存、指针指向NULL
free(pTempImagebuffer);
return 0;
}
memset(pTempImagebuffer,0,a);
memcpy(pTempImagebuffer,pDosHeader,pOptionHeader->SizeOfHeaders);
pSectionHeader1=pSectionHeader;
for(int i=0;i<pPEHeader->NumberOfSections;i++,pSectionHeader1++)
memcpy((void*)((DWORD)pTempImagebuffer+pSectionHeader1->PointerToRawData),
(void*)((DWORD)pDosHeader+pSectionHeader1->VirtualAddress),
pSectionHeader1->SizeOfRawData);
*pNewBuffer=pTempImagebuffer;
pTempImagebuffer=NULL;
return a;
}
//newbuffer->存盘
int newbuffer_write2_exe(PVOID NewFileBuffer,DWORD FileSize, char* FilePath)
{
FILE* fp1 = fopen(FilePath,"wb");
if(fp1 != NULL)
{
fwrite(NewFileBuffer,FileSize,1,fp1);
}
fclose(fp1);
return 1;
}
void operate_pe()
{ // 初始化操作
PVOID pFileBuffer = NULL;
PVOID pImageBuffer = NULL;
PVOID pNewFileBuffer = NULL;
DWORD NewFileBufferSize = 0;
//char file_path[] = "D:\\Lib\\IPMSG2007.exe";
char file_path[] = "C:\\Windows\\System32\\notepad.exe";
char write_file_path[] = "c:\\1111.exe";
// exe->filebuffer
int ret1 = ReadPEFile(file_path,&pFileBuffer); // &pFileBuffer(void**类型) 传递地址对其值可以进行修改
printf("exe->filebuffer 返回值为计算所得文件大小:%#x\n",ret1);
// filebuffer -> imagebuffer
int ret2 = CopyFileBufferToImageBuffer(pFileBuffer,&pImageBuffer);
printf("filebuffer -> imagebuffer返回值为计算所得文件大小:%#x\n",ret2);
//imagebuffer->newbuffer
int FileSize = CopyImageBufferToNewBuffer(pImageBuffer,&pNewFileBuffer);
printf("imagebuffer->newbuffer返回值为计算所得文件大小:%#x\n",FileSize);
//newbuffer->存盘
int ret4 = newbuffer_write2_exe(pNewFileBuffer,FileSize, write_file_path);
printf("newbuffer->存盘返回值为:%d\n",ret4);
}
int main()
{
operate_pe();
return 0;
}