#pragma warning(suppress : 4996)
#include "ImageBuffer.h"
char inputPath[] = "C:\\ipmsg\\Feige\\Feige.exe";
char outputPath[] = "C:\\ipmsg\\Feige\\Feige2.exe";
LPSTR FILEPATH = inputPath;
LPSTR OUT_FILEPATH = outputPath;
int main(void)
{
LPVOID pFileBuffer;
LPVOID pImageBuffer;
LPVOID pNewBuffer;
int size = 0;
ReadPEFile(FILEPATH,&pFileBuffer);
CopyFileBufferToImageBuffer(pFileBuffer,&pImageBuffer);
size = CopyImageBufferToNewBuffer(pImageBuffer,&pNewBuffer);
MemeryTOFile(pNewBuffer, size, OUT_FILEPATH);
free(pFileBuffer);
free(pImageBuffer);
free(pNewBuffer);
return 0;
}
//**************************************************************************
//ReadPEFile:将文件读取到缓冲区
//参数说明:
//lpszFile 文件路径 //pFileBuffer 缓冲区指针
//返回值说明:
//读取失败返回0 否则返回实际读取的大小
//**************************************************************************
DWORD ReadPEFile(IN LPSTR lpszFile, OUT LPVOID* pFileBuffer)
{
FILE* pFile = NULL;
DWORD fileSize = 0;
// LPVOID pFileBuf = 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;
char tableName[9] = { 0 };
//打开文件
pFile = fopen(lpszFile, "rb");
if (!pFile)
{
printf("无法打开EXE文件\n");
return NULL;
}
//读取文件大小
fseek(pFile, 0, SEEK_END);
fileSize = ftell(pFile);
fseek(pFile, 0, SEEK_SET);
//分配缓冲区
*pFileBuffer = (LPVOID)malloc(fileSize);
if (!(*pFileBuffer) )
{
printf("空间分配失败!\n");
fclose(pFile);
return NULL;
}
memset(*pFileBuffer,0, fileSize);
//讲文件数据读取到缓冲区
size_t n = fread(*pFileBuffer, fileSize, 1, pFile);
if (!n)
{
printf("读取数据失败!\n");
free(*pFileBuffer);
fclose(pFile);
return NULL;
}
//关闭文件
fclose(pFile);
if (*((PWORD)(*pFileBuffer)) != IMAGE_DOS_SIGNATURE)
{
printf("不是有效地MZ标志\n");
free(*pFileBuffer);
return 0;
}
pDosHeader = (PIMAGE_DOS_HEADER)(*pFileBuffer);
//打印dos头
//printf("--------------------------------------DOC------------------------------------------\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 0;
}
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);
//printf("--------------------------------------PE------------------------------------------\n");
//printf("PE类型10B→32位 20B→64位:%x\n", pPEHeader->Machine);
//printf("文件存在的节的总数:%x\n", pPEHeader->NumberOfSections);
//printf("可选PE头的大小,32位默认E0h 64位默认F0h:%x\n", pPEHeader->SizeOfOptionalHeader);
//printf("PE属性:%x\n", pPEHeader->Characteristics);
//可选PE头
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
//printf("********************OPTIOIN_PE头********************\n");
//printf("OPTION_PE 类型:10B→32位 20B→64位:%x\n", pOptionHeader->Magic);
//printf("所有代码节的和:%x\n", pOptionHeader->SizeOfCode);
//printf("已初始化数据大小的和:%x\n", pOptionHeader->SizeOfInitializedData);
//printf("未初始化数据大小的和:%x\n", pOptionHeader->SizeOfUninitializedData);
//printf("程序入口:%x\n", pOptionHeader->AddressOfEntryPoint);
//printf("代码开始的基址:%x\n", pOptionHeader->BaseOfCode);
//printf("数据开始的基址:%x\n", pOptionHeader->BaseOfData);
//printf("内存镜像基址:%x\n", pOptionHeader->ImageBase);
//printf("内存对齐:%x\n", pOptionHeader->SectionAlignment);
//printf("文件对齐:%x\n", pOptionHeader->FileAlignment);
//printf("内存中整个PE文件的映射的尺寸:%x\n", pOptionHeader->SizeOfImage);
//printf("所有头+节表按照文件对齐后的大小:%x\n", pOptionHeader->SizeOfHeaders);
//printf("初始化时保留的栈大小:%x\n", pOptionHeader->SizeOfStackReserve);
//printf("初始化时栈实际提交的大小:%x\n", pOptionHeader->SizeOfStackCommit);
//printf("初始化时保留的堆大小:%x\n", pOptionHeader->SizeOfHeapReserve);
//printf("初始化时堆实际提交的大小:%x\n", pOptionHeader->SizeOfHeapCommit);
//printf("目录项数目:%x\n", pOptionHeader->NumberOfRvaAndSizes);
//printf("+++++++++++++++++++++++++++++++++++++++\n");
//printf("pOptionHeader->SizeOfImage:%x\n", pOptionHeader->SizeOfImage);
//printf("+++++++++++++++++++++++++++++++++++++++\n");
pSectionHeader = (PIMAGE_SECTION_HEADER)((char*)pOptionHeader + (pPEHeader->SizeOfOptionalHeader));
for (int i = 0; i < (pPEHeader->NumberOfSections); i++)
{
char* c = (char*)pSectionHeader;
for (int n = 0; n < 8; n++)
{
tableName[n] = *c;
c++;
}
//printf("第%d个节的名字:%s\n", i, tableName);
//printf("第%d个节的大小:%x\n", i, pSectionHeader->Misc.VirtualSize);
//printf("第%d个节的内存偏移:%x\n", i, pSectionHeader->VirtualAddress);
//printf("第%d个节在文件中对齐的大小:%x\n", i, pSectionHeader->SizeOfRawData);
//printf("第%d个节的文件偏移:%x\n", i, pSectionHeader->PointerToRawData);
//printf("第%d个节的属性:%x\n", i, pSectionHeader->Characteristics);
pSectionHeader++;
}
printf("****************************************\n");
//printf("%x\n", fileSize);
return fileSize;
//return (pOptionHeader->SizeOfImage);
}
//**************************************************************************
//CopyFileBufferToImageBuffer:将文件从FileBuffer复制到ImageBuffer
//参数说明:
//pFileBuffer FileBuffer指针
//pImageBuffer ImageBuffer指针
//返回值说明: //读取失败返回0 否则返回复制的大小
//**************************************************************************
DWORD CopyFileBufferToImageBuffer(IN LPVOID pFileBuffer, OUT LPVOID* pImageBuffer)
{
DWORD ImageSize = 0;
char* dest = NULL;
char* src = 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);
pSectionHeader = (PIMAGE_SECTION_HEADER)((char*)pOptionHeader + (pPEHeader->SizeOfOptionalHeader));
ImageSize = (pOptionHeader->SizeOfImage);
//printf("+++++++++++++++++++++++++++++++++++++++\n");
//printf("CopyFileBufferToImageBuffer:%x\n", ImageSize);
//printf("pOptionHeader->SizeOfImage:%x\n", pOptionHeader->SizeOfImage);
//printf("+++++++++++++++++++++++++++++++++++++++\n");
//分配缓冲区
*pImageBuffer = malloc(ImageSize);
if (!(*pImageBuffer))
{
printf("空间分配失败!\n");
return 0;
}
memset(*pImageBuffer, 0, ImageSize);
//拷贝各个头
dest = (char*)*pImageBuffer;
src = (char*)pFileBuffer;
memcpy(dest,src,(pOptionHeader->SizeOfHeaders));
//拷贝各个节
for (int i = 0; i < (pPEHeader->NumberOfSections); i++)
{
dest = NULL;
src = NULL;
src = (char*)((char*)pFileBuffer + pSectionHeader->PointerToRawData);
dest = (char*)((char*)*pImageBuffer + pSectionHeader->VirtualAddress);
memcpy(dest, src, (pSectionHeader->SizeOfRawData));
pSectionHeader++;
}
printf("****************************************\n");
printf("%x\n", ImageSize);
return ImageSize;
}
//**************************************************************************
//CopyImageBufferToNewBuffer:将ImageBuffer中的数据复制到新的缓冲区
//参数说明:
//pImageBuffer ImageBuffer指针
//pNewBuffer NewBuffer指针
//返回值说明:
//读取失败返回0 否则返回复制的大小
//**************************************************************************
DWORD CopyImageBufferToNewBuffer(IN LPVOID pImageBuffer, OUT LPVOID* pNewBuffer)
{
DWORD NewSize = 0;
char* dest = NULL;
char* src = 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;
PIMAGE_SECTION_HEADER pLastSectionHeader = 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);
pSectionHeader = (PIMAGE_SECTION_HEADER)((char*)pOptionHeader + (pPEHeader->SizeOfOptionalHeader));
//计算NewBuffer要多少空间 = 最后一个节在文件中的偏移 + 在文件中对齐后的大小
pLastSectionHeader = pSectionHeader + ((pPEHeader->NumberOfSections) - 1);
NewSize = pLastSectionHeader->PointerToRawData + pLastSectionHeader->SizeOfRawData;
//分配缓冲区
*pNewBuffer = malloc(NewSize);
if (!(*pNewBuffer))
{
printf("空间分配失败!\n");
return 0;
}
memset(*pNewBuffer, 0, NewSize);
//拷贝各个头
dest = (char*)*pNewBuffer;
src = (char*)pImageBuffer;
memcpy(dest, src, (pOptionHeader->SizeOfHeaders));
//拷贝各个节
for (int i = 0; i < (pPEHeader->NumberOfSections); i++)
{
dest = NULL;
src = NULL;
src = (char*)((char*)pImageBuffer + pSectionHeader->VirtualAddress);
dest = (char*)((char*)*pNewBuffer + pSectionHeader->PointerToRawData);
memcpy(dest, src, (pSectionHeader->SizeOfRawData));
//printf("第%d个节的大小:%x\n", i, pSectionHeader->Misc.VirtualSize);
//printf("第%d个节的内存偏移:%x\n", i, pSectionHeader->VirtualAddress);
//printf("第%d个节在文件中对齐的大小:%x\n", i, pSectionHeader->SizeOfRawData);
//printf("第%d个节的文件偏移:%x\n", i, pSectionHeader->PointerToRawData);
pSectionHeader++;
}
printf("****************************************\n");
printf("%x\n", NewSize);
return NewSize;
}
//**************************************************************************
//MemeryTOFile:将内存中的数据复制到文件
//参数说明:
//pMemBuffer 内存中数据的指针
//size 要复制的大小
//lpszFile 要存储的文件路径
//返回值说明:
//失败返回0 否则返回1
//**************************************************************************
BOOL MemeryTOFile(IN LPVOID pMemBuffer, IN size_t size, OUT LPSTR lpszFile)
{
FILE* p = NULL;
int i = 0;
p = fopen(lpszFile,"wb+");
if (!p)
{
printf("无法创建文件\n");
return 0;
}
i = fwrite(pMemBuffer,size, 1,p);
printf("****************************************\n");
printf("%x\n", i);
fclose(p);
return i;
}
PE文件从硬盘到内存再到硬盘
最新推荐文章于 2022-05-02 13:49:32 发布