实现功能:
代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
LPVOID ToLeaderPE(IN LPSTR lpszFile);
LPVOID ReadPEFile(IN LPVOID pFileBuffer);
LPVOID CopyFileBufferToImageBuffer(IN LPVOID pFileBuffe, OUT LPVOID* pImageBuffer);
LPVOID CopyImageBufferToNewBuffer(IN LPVOID pImageBuffer, OUT LPVOID* pNewBuffer);
BOOL MemeryTOFile(IN LPVOID pMemBuffer, IN size_t size, OUT LPSTR lpszFile);
//DWORD RvaToFileOffset(IN LPVOID pFileBuffer, IN DWORD dwRva);
LPVOID ToLeaderPE(IN LPSTR lpszFile)
{
FILE *pFile = NULL;
DWORD fileSize = 0;
LPVOID pFileBuffer = NULL;
pFile = fopen(lpszFile, "rb");
if (!pFile)
{
printf("can't open file\n");
return 0;
}
fseek(pFile, 0, SEEK_END);
fileSize = ftell(pFile);
printf("FileBuffer: %x\n", fileSize);
fseek(pFile, 0, SEEK_SET);
pFileBuffer = malloc(fileSize);
if (!pFileBuffer)
{
printf("apply memory failed\n");
fclose(pFile);
return 0;
}
size_t n = fread(pFileBuffer, fileSize, 1, pFile);
if (!n)
{
printf("read data filed\n");
free(pFileBuffer);
fclose(pFile);
return 0;
}
fclose(pFile);
return pFileBuffer;
}
LPVOID ReadPEFile(IN LPVOID pFileBuffer)
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
if (!pFileBuffer)
{
printf("文件读取失败\n");
return;
}
//判断是否是有效的MZ标志
if (*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE)
{
printf("不是有效的MZ标志\n");
free(pFileBuffer);
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
//打印DOC头
printf("\n********************DOS头********************\n");
printf("MZ标志:%x\n", pDosHeader->e_magic);
printf("PE偏移:%x\n", pDosHeader->e_lfanew);
//判断是否是有效的PE标志
if (*((PDWORD)((DWORD)pFileBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("不是有效的PE标志\n");
free(pFileBuffer);
return;
}
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew);
//打印NT头
printf("********************NT头********************\n");
printf("NT:%x\n", pNTHeader->Signature);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 4);
int NumberOfSections = pPEHeader->NumberOfSections;
int SizeOfOptionalHeader = pPEHeader->SizeOfOptionalHeader;
printf("********************PE头********************\n");
printf("PE:%x\n", pPEHeader->Machine);
printf("节的数量:%x\n", pPEHeader->NumberOfSections);
printf("SizeOfOptionalHeader:%x\n", pPEHeader->SizeOfOptionalHeader);
//可选PE头
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
printf("********************OPTIOIN_PE头********************\n");
printf("OPTION_PE:%x\n", pOptionHeader->Magic);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + SizeOfOptionalHeader);
for (int n = 0; n < NumberOfSections; n++)
{
printf("********************SECTION %d********************\n", n + 1);
char name[9] = { 0 };
memcpy(name, pSectionHeader->Name, 8);
printf("SECTION NAME: %s\n", name);
printf("VirtualAddress: %x\n", pSectionHeader->VirtualAddress);
printf("SizeOfRawData: %x\n", pSectionHeader->SizeOfRawData);
printf("PointerToRawData: %x\n", pSectionHeader->PointerToRawData);
printf("Characteristics: %x\n", pSectionHeader->Characteristics);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader + IMAGE_SIZEOF_SECTION_HEADER);
}
//free(pFileBuffer);
}
LPVOID CopyFileBufferToImageBuffer(IN LPVOID pFileBuffer, OUT LPVOID* pImageBuffer)
{
LPVOID pImageTemp = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
int SizeOfImage = pOptionHeader->SizeOfImage;
pImageTemp = malloc(SizeOfImage);
printf("ImageBuffe base: %x\n", pImageTemp);
printf("FileBuffe base: %x\n", pFileBuffer);
if (!pImageTemp)
{
printf("apply ImageBuffer failed\n");
return 0;
}
int SizeOfHeaders = pOptionHeader->SizeOfHeaders;
memset(pImageTemp, 0, SizeOfImage);
printf("SizeOfImage: %x\n", SizeOfImage);
memcpy(pImageTemp, pFileBuffer, SizeOfHeaders);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);
for (int n = 0; n < pPEHeader->NumberOfSections; n++)
{
memcpy((DWORD)pImageTemp + pSectionHeader->VirtualAddress, (DWORD)pFileBuffer+ pSectionHeader->PointerToRawData, pSectionHeader->SizeOfRawData);
printf("VirtualAddress%d: %10x PointerToRawData%d: %10x\n", n,(DWORD)pImageTemp + pSectionHeader->VirtualAddress, n,(DWORD)pFileBuffer + pSectionHeader->PointerToRawData);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader + IMAGE_SIZEOF_SECTION_HEADER);
}
*pImageBuffer = pImageTemp;
pImageTemp = NULL;
}
LPVOID CopyImageBufferToNewBuffer(IN LPVOID pImageBuffer, OUT LPVOID* pNewBuffer)
{
LPVOID pNewTemp = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pImageBuffer + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
DWORD NewBuffer = pOptionHeader->SizeOfHeaders;
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);
for (int n = 0; n < pPEHeader->NumberOfSections; n++)
{
NewBuffer += pSectionHeader[n].SizeOfRawData;
//pSectionHeader += IMAGE_SIZEOF_SECTION_HEADER;
}
pNewTemp = malloc(NewBuffer);
if (!pNewTemp)
{
printf("apply memory failed\n");
return 0;
}
memset(pNewTemp, 0, NewBuffer);
memcpy(pNewTemp, pImageBuffer, pOptionHeader->SizeOfHeaders);
PIMAGE_SECTION_HEADER pTempSectionHeader = pSectionHeader;
for (DWORD n = 0; n < pPEHeader->NumberOfSections; n++, pTempSectionHeader++)
{
memcpy((PDWORD)((DWORD)pNewTemp + pTempSectionHeader->PointerToRawData), (PDWORD)((DWORD)pImageBuffer + pTempSectionHeader->VirtualAddress), pTempSectionHeader->SizeOfRawData);
}
printf("pNewBuffer base: %x\n", pNewTemp);
*pNewBuffer = pNewTemp;
pNewTemp = NULL;
printf("NewBuffer: %x\n", NewBuffer);
return NewBuffer;
}
BOOL MemeryTOFile(IN LPVOID pMemBuffer, IN size_t size, OUT LPSTR lpszFile)
{
FILE *fp;
fp = fopen(lpszFile, "wb");
if (fp!=NULL)
{
fwrite(pMemBuffer, size, 1, fp);
}
fclose(fp);
return 1;
}
int main()
{
char PATH[] = "C:\\Windows\\System32\\notepad.exe";
char cpPATH[] = "D:\\copyXX.exe";
LPVOID pFileBuffer= ToLeaderPE(PATH);
LPVOID SectionINFOFile= ReadPEFile(pFileBuffer);
LPVOID pImageBuffer = NULL;
LPVOID pNewBuffer = NULL;
CopyFileBufferToImageBuffer(pFileBuffer, &pImageBuffer);
size_t NewBuffer = CopyImageBufferToNewBuffer(pImageBuffer, &pNewBuffer);
MemeryTOFile(pNewBuffer, NewBuffer, cpPATH);
return 0;
}
结果展示: