#include "iostream"
#include <windows.h>
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"
);
return
0;
}
fseek
(pfile ,0,SEEK_END);
file_size=
ftell
(pfile);
fseek
(pfile ,0,SEEK_SET);
pTempFilebuffer=
malloc
(file_size);
if
(!pTempFilebuffer)
{
printf
(
"分配空间失败!\n"
);
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;
}
DWORD
CopyFileBufferToImageBuffer(
PVOID
pFileBuffer,
PVOID
* pImageBuffer)
{
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;
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
)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
pTempImagebuffer =
malloc
(pOptionHeader->SizeOfImage);
if
(!pTempImagebuffer)
{
printf
(
"分配空间失败!\n"
);
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)
{
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"
);
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"
);
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;
}
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[] =
"C:\\Windows\\System32\\notepad.exe"
;
char
write_file_path[] =
"c:\\1111.exe"
;
int
ret1 = ReadPEFile(file_path,&pFileBuffer);
printf
(
"exe->filebuffer 返回值为计算所得文件大小:%#x\n"
,ret1);
int
ret2 = CopyFileBufferToImageBuffer(pFileBuffer,&pImageBuffer);
printf
(
"filebuffer -> imagebuffer返回值为计算所得文件大小:%#x\n"
,ret2);
int
FileSize = CopyImageBufferToNewBuffer(pImageBuffer,&pNewFileBuffer);
printf
(
"imagebuffer->newbuffer返回值为计算所得文件大小:%#x\n"
,FileSize);
int
ret4 = newbuffer_write2_exe(pNewFileBuffer,FileSize, write_file_path);
printf
(
"newbuffer->存盘返回值为:%d\n"
,ret4);
}
int
main()
{
operate_pe();
return
0;
}