#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>
int main() {
FILE* fp = NULL;
FILE* new_fp = NULL;
long file_size;
char* file_buffer;
char* image_buffer;
char* new_buffer;
fp = fopen("NOTEPAD-xp.EXE", "rb");
fseek(fp, 0, SEEK_END);
file_size = ftell(fp);
fseek(fp, 0, SEEK_SET);
printf("文件大小:%d字节\n", file_size);
//申请内存空间存放PE文件
file_buffer = (char*)malloc(file_size);
memset(file_buffer, 0, file_size);
//往file——buffer读PE
fread(file_buffer, file_size, 1, fp);
PIMAGE_DOS_HEADER pDos_Header = (PIMAGE_DOS_HEADER)file_buffer;
printf("打印dos头\n");
printf("打印DOS头起始位置:%x\n", pDos_Header);
printf("打印pDos_Header->e_magic:%x\n",pDos_Header->e_magic);
printf("打印pDos_Header->e_lfanew:%x\n", pDos_Header->e_lfanew);
printf("打印NT头\n");
PIMAGE_NT_HEADERS pNT_Header = (PIMAGE_NT_HEADERS)(file_buffer + pDos_Header->e_lfanew);
printf("打印NT头起始位置:%x\n", pNT_Header);
printf("打印pNT_Header->Signature:%.8x\n", pNT_Header->Signature);
printf("打印pNT_Header->FileHeader:%.8x\n", pNT_Header->FileHeader);
printf("打印pNT_Header->OptionalHeader:%.8x\n", pNT_Header->OptionalHeader);
printf("打印标准PE头\n");
printf("打印pNT_Header->FileHeader.Machine:%.8x\n", pNT_Header->FileHeader.Machine);
printf("打印pNT_Header->FileHeader.NumberOfSections:%.8x\n", pNT_Header->FileHeader.NumberOfSections);
printf("打印pNT_Header->FileHeader.SizeOfOptionalHeader:%.8x\n", pNT_Header->FileHeader.SizeOfOptionalHeader);
printf("打印拓展PE头\n");
printf("打印pNT_Header->OptionalHeader.Magic:%.8x\n", pNT_Header->OptionalHeader.Magic);
printf("打印pNT_Header->OptionalHeader.AddressOfEntryPoint:%.8x\n", pNT_Header->OptionalHeader.AddressOfEntryPoint);
printf("打印pNT_Header->OptionalHeader.ImageBase:%.8x\n", pNT_Header->OptionalHeader.ImageBase);
printf("打印pNT_Header->OptionalHeader.SectionAlignment:%.8x\n", pNT_Header->OptionalHeader.SectionAlignment);
printf("打印 pNT_Header->OptionalHeader.FileAlignment:%.8x\n", pNT_Header->OptionalHeader.FileAlignment);
printf("打印 pNT_Header->OptionalHeader.SizeOfImage:%.8x\n", pNT_Header->OptionalHeader.SizeOfImage);
printf("打印 pNT_Header->OptionalHeader.SizeOfHeaders:%.8x\n", pNT_Header->OptionalHeader.SizeOfHeaders);
//打印节表或者说是区段
PIMAGE_SECTION_HEADER pSction_Header = IMAGE_FIRST_SECTION(pNT_Header);
printf("\t****************打印节表****************\t\n");
for (size_t i = 0; i < pNT_Header->FileHeader.NumberOfSections; i++)
{
printf("打印节表%d\n", i+1);
printf("pSction_Header[%d].Name(区段、节名称):%s\n",i+1, pSction_Header[i].Name);
printf("pSction_Header[%d].VirtualAddress(内存中的偏移Voffset,需要加imagebase获得真实地址):%.8x\n", i + 1, pSction_Header[i].VirtualAddress);
printf("pSction_Header[%d].Misc(内存中的大小):%.8x\n", i + 1, pSction_Header[i].Misc);
printf("(文件中的偏移)pSction_Header[%d].PointerToRawData(文件中的偏移Roffset):%.8x\n", i + 1, pSction_Header[i].PointerToRawData);
printf("pSction_Header[%d].SizeOfRawData(文件中大小Vsize):%.8x\n", i + 1, pSction_Header[i].SizeOfRawData);
printf("pSction_Header[%d].Misc.VirtualSize:%.8x\n", i + 1, pSction_Header[i].Misc.VirtualSize);
printf("pSction_Header[%d].Characteristics(节的属性):%.8x\n", i + 1, pSction_Header[i].Characteristics);
printf("****************************************************************\t\n");
}
//filebuffer----imagebuffer
//创建一个imagebuffer空间大小为sizeofimage大小
image_buffer = (char*)malloc(pNT_Header->OptionalHeader.SizeOfImage);
memset(image_buffer, 0, pNT_Header->OptionalHeader.SizeOfImage);
//往里面拷贝头内容OptionalHeader.SizeOfHeaders400,在可选头里
memcpy(image_buffer, pDos_Header, pNT_Header->OptionalHeader.SizeOfHeaders);
//往里面拷贝节内容
for (size_t i = 0; i < pNT_Header->FileHeader.NumberOfSections; i++)
{
memcpy(image_buffer + pSction_Header[i].VirtualAddress, file_buffer + pSction_Header[i].PointerToRawData, pSction_Header[i].SizeOfRawData);
}
printf("\tPE文件已在内存中模拟完毕\t\n");
printf("\tPE文件已在内存中模拟完毕\t\n");
printf("\tPE文件已在内存中模拟完毕\t\n");
printf("\tPE文件已在内存中模拟完毕\t\n");
//image_buffer-->new_buffer
//从image_buffer 获取头的内容DOS头+NT头+PE标准头+PE可选头+节表
PIMAGE_DOS_HEADER new_DOS_Header = (PIMAGE_DOS_HEADER)(image_buffer);
//NT头
PIMAGE_NT_HEADERS new_NT_Header = (PIMAGE_NT_HEADERS)(image_buffer + new_DOS_Header->e_lfanew);
//标准PE头//这里必须进行强制类型转换
PIMAGE_FILE_HEADER new_File_Header = (PIMAGE_FILE_HEADER)((DWORD)new_NT_Header + 4);
//PIMAGE_FILE_HEADER new_File_Header = (PIMAGE_FILE_HEADER)(new_NT_Header + 4);(这条是错误的)
//可选PE头
printf("%x\n", new_File_Header->Machine);
PIMAGE_OPTIONAL_HEADER new_Option_Header = (PIMAGE_OPTIONAL_HEADER)((DWORD)new_NT_Header + 4 + 20);
printf("%x\n", new_Option_Header->ImageBase);
//节表
PIMAGE_SECTION_HEADER new_Section_Header = IMAGE_FIRST_SECTION(new_NT_Header);
//这里获取下头+节表的大小
int new_buffer_size = new_Option_Header->SizeOfHeaders;
//获取下所有节内容大小
for (size_t i = 0; i < new_File_Header->NumberOfSections; i++)
{
new_buffer_size += new_Section_Header[i].SizeOfRawData;
}
//开辟空间
new_buffer = (char*)malloc(new_buffer_size);
memset(new_buffer, 0, new_buffer_size);
//拷贝头部加上节表
memcpy(new_buffer, new_DOS_Header,new_Option_Header->SizeOfHeaders);
//拷贝节内容
PIMAGE_SECTION_HEADER Temp_Section_Header = new_Section_Header;
for (size_t i = 0; i < new_File_Header->NumberOfSections; i++, Temp_Section_Header++)
{
memcpy((PDWORD)((DWORD)new_buffer + Temp_Section_Header->PointerToRawData), (PDWORD)((DWORD)image_buffer + Temp_Section_Header->VirtualAddress), Temp_Section_Header->SizeOfRawData);
}
printf("拷贝文件大小为:%d字节\n", new_buffer);
//new_buffer---->存盘
new_fp = fopen("new_notepad.exe", "wb");
fwrite(new_buffer, new_buffer_size, 1, new_fp);
fclose(new_fp);
free(new_buffer);
free(image_buffer);
free(file_buffer);
return 0;
}