// mem.cpp : 定義控制台應用程序的入口點。 //PE文件從文件加載到內存,再從內存讀取,然后存盤到文件 #include "stdafx.h" #include <windows.h> #include <winnt.h> #define PATH "C:\\Users\\Administrator\\Desktop\\MSG.exe" int Filelength(FILE *fp); int _tmain(int argc, _TCHAR* argv[]) { FILE *Fp; fopen_s(&Fp, PATH, "rb"); int FileSize = Filelength(Fp);//獲取文件大小 char * FileBuffer = (char *)malloc(FileSize);//申請存放文件的內存空間 if (FileBuffer == NULL) { printf("申請iImageBuffer失敗"); } fread_s(FileBuffer, FileSize, 1, FileSize, Fp); //將文件復制到內存中 //定位一下內存中的數據 各個頭表 //定位標准PE頭 PIMAGE_FILE_HEADER MyFileHeader; MyFileHeader = (PIMAGE_FILE_HEADER)(char *)(FileBuffer + *(int *)(FileBuffer + 0x3c) + 0x4); //定位可選PE頭 PIMAGE_OPTIONAL_HEADER MyOptionalHeader; MyOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((char *)MyFileHeader + 0x14); //定位節表 PIMAGE_SECTION_HEADER MySectionHeader; MySectionHeader = (PIMAGE_SECTION_HEADER)((char *)MyOptionalHeader + MyFileHeader->SizeOfOptionalHeader); //拉伸,也就是讀到內存中的狀態 char * ImageBuffer = (char *)malloc(MyOptionalHeader->SizeOfImage);//給拉伸申請內存空間 //ZeroMemory(ImageBuffer, MyOptionalHeader->SizeOfImage); if (ImageBuffer == NULL) { printf("申請iImageBuffer失敗"); } memcpy(ImageBuffer, FileBuffer, MyOptionalHeader->SizeOfHeaders); for (int i = 0; i < MyFileHeader->NumberOfSections ; i++) { memcpy(ImageBuffer + MySectionHeader->VirtualAddress, FileBuffer + MySectionHeader->PointerToRawData, MySectionHeader->SizeOfRawData);// MySectionHeader++; } //壓縮,為存盤做准備 char * NewBuffer = (char *)malloc(FileSize);//給壓縮申請內存空間 if (NewBuffer == NULL) { printf("申請iImageBuffer失敗"); } memcpy(NewBuffer, ImageBuffer, MyOptionalHeader->SizeOfHeaders); MySectionHeader = (PIMAGE_SECTION_HEADER)((char *)MyOptionalHeader + MyFileHeader->SizeOfOptionalHeader);//重新指一下,前面動過了 for (int i = 0; i < MyFileHeader->NumberOfSections; i++) { memcpy(NewBuffer + MySectionHeader->PointerToRawData, ImageBuffer + MySectionHeader->VirtualAddress, MySectionHeader->SizeOfRawData); MySectionHeader++; } FILE *nFp; fopen_s(&nFp, "C:\\Users\\Administrator\\Desktop\\CYP.exe", "wb"); fwrite(NewBuffer, FileSize, 1, nFp); //getchar(); fclose(nFp); free(FileBuffer); free(ImageBuffer); free(NewBuffer); return 0; } //獲取文件大小 int Filelength(FILE *fp) { int num; fseek(fp, 0, SEEK_END); num = ftell(fp); fseek(fp, 0, SEEK_SET); return num; }