// 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;
}