PE练习:
#include<Windows.h>
#include"resource.h"
#include<iostream>
#pragma comment(lib,"Msimg32.lib")
#define FILEBUFF "C:/LenovoSoftstore/Install/xxx/xxx.exe"
#define fileBuff "C:/LenovoSoftstore/Install/xxx/副本xxx.exe"
#define DEBUG 1
#include<objidl.h>
#include<gdiplus.h>
#include<gdiplusgraphics.h>
using namespace Gdiplus;
#pragma comment(lib,"Gdiplus.lib")
#define CLASSNAME "Mode"
#define WINDOW_NAME "小模块"
#define WINDOW_W 960
#define WINDOW_H 580
static HMENU g_mwnu = NULL;
class ModuleTraversal {
private:
const int m_mistake = 0xFFFFFFFF;
PVOID m_Buffer = NULL;
unsigned int m_ModeSize;
private:
PIMAGE_DOS_HEADER pDosMode;
PIMAGE_NT_HEADERS32 pNtMode;
PIMAGE_FILE_HEADER pFileHeaderMode;
PIMAGE_OPTIONAL_HEADER32 pOptionalMode;
PIMAGE_DATA_DIRECTORY pDataDirectoryMode;
PIMAGE_SECTION_HEADER pSectionMode;
private:
public:
PVOID OpenFile(HWND hwnd,const char*nam);
VOID DosMode();
VOID FileMode();
VOID OptionalHeaderMode();
VOID SectionHeaderMode();
VOID UnfoldStretch();
};
#include "modepe.h"
PVOID ModuleTraversal::OpenFile(HWND hwnd,const char*name){
FILE* pFile = NULL;
DWORD FileSize = 0;
PVOID pFileBuffer = NULL;
pFile = fopen(name, "rb");
if (pFile == NULL) {
if (DEBUG) {
MessageBox(hwnd, "打开文件失败", "提示", MB_OK);
}
return (PVOID)this->m_mistake;
}
fseek(pFile, 0, SEEK_END);
FileSize = ftell(pFile);
fseek(pFile, 0, SEEK_SET);
pFileBuffer = malloc(FileSize);
if (pFileBuffer == NULL) {
if (DEBUG) {
MessageBox(hwnd, "内存申请失败", "提示", MB_OK);
}
fclose(pFile);
return (PVOID)this->m_mistake;
}
memset(pFileBuffer, 0, FileSize);
size_t internalBuffer = fread(pFileBuffer, FileSize, 1, pFile);
if (internalBuffer == NULL) {
if (DEBUG) {
MessageBox(hwnd, "读取到缓冲区失败", "提示", MB_OK);
}
free(pFileBuffer);
fclose(pFile);
pFileBuffer = NULL;
return (PVOID)this->m_mistake;
}
fclose(pFile);
return (PVOID)pFileBuffer;
}
DWORD ModuleTraversal::ModeSize(){
this->m_Buffer = this->OpenFile(nullptr, FILEBUFF);
if (this->m_Buffer == NULL) {
return this->m_mistake;
}
this->pDosMode = (PIMAGE_DOS_HEADER)this->m_Buffer;
if (*((PWORD)this->pDosMode )!= IMAGE_DOS_SIGNATURE) {
free(this->m_Buffer);
return this->m_mistake;
}
this->pNtMode = PIMAGE_NT_HEADERS32(DWORD(this->m_Buffer )+ this->pDosMode->e_lfanew);
if (this->pNtMode->Signature != 0x00004550) {
free(this->m_Buffer);
return this->m_mistake;
}
this->m_ModeSize = sizeof(IMAGE_DOS_HEADER);
this->m_ModeSize += sizeof(IMAGE_NT_HEADERS32);
this->m_ModeSize += sizeof(IMAGE_SECTION_HEADER)*this->pNtMode->FileHeader.NumberOfSections;
return this->m_ModeSize;
}
VOID ModuleTraversal::DosMode(){
DWORD DosSize = 0;
this->m_Buffer = OpenFile(nullptr, FILEBUFF);
printf("---------------------------------------------------------------------\n");
if (this->m_Buffer == NULL) {
if (DEBUG) {
MessageBox(NULL, "文件缓冲区获取失败", "提示", MB_OK);
}
return;
}
if (*(PWORD)this->m_Buffer!= IMAGE_DOS_SIGNATURE) {
if (DEBUG) {
MessageBox(NULL, "获取到文件开始字节数不匹配", "提示", MB_OK);
}
free(this->m_Buffer);
return ;
}
pDosMode = (PIMAGE_DOS_HEADER)m_Buffer;
printf("%x\tMZ标志:e_magic\n", pDosMode->e_magic);
printf("%x\tPE标记:e_lfanew\n", pDosMode->e_lfanew);
pNtMode = PIMAGE_NT_HEADERS32((DWORD)m_Buffer + pDosMode->e_lfanew);
printf("跳转PE标志\t%x\tNT开始处:Signature\n", pNtMode->Signature);
printf("---------------------------------------------------------------------\n");
free(this->m_Buffer);
return ;
}
VOID ModuleTraversal::FileMode(){
this->m_Buffer = this->OpenFile(nullptr, FILEBUFF);
if (this->m_Buffer == NULL) {
return VOID();
}
if (*(PWORD)this->m_Buffer != IMAGE_DOS_SIGNATURE) {
free(this->m_Buffer);
return VOID();
}
pDosMode = (PIMAGE_DOS_HEADER)m_Buffer;
pNtMode = PIMAGE_NT_HEADERS32((DWORD)m_Buffer + pDosMode->e_lfanew);
printf("%x\tCPU型号:Machine\n", pNtMode->FileHeader.Machine);
printf("%x\t节的总数:NumberOfSections\n", pNtMode->FileHeader.NumberOfSections);
printf("%x\t时间轴:TimeDateStamp\n", pNtMode->FileHeader.TimeDateStamp);
printf("%x\t可选PE头的大小:SizeOfOptionalHeader\n", pNtMode->FileHeader.SizeOfOptionalHeader);
printf("%x\t属性:Characteristics\n", pNtMode->FileHeader.Characteristics);
printf("----------------------------------------------------------------------\n");
free(this->m_Buffer);
return VOID();
}
VOID ModuleTraversal::OptionalHeaderMode(){
this->m_Buffer = this->OpenFile(nullptr, FILEBUFF);
if (this->m_Buffer == NULL) {
return VOID();
}
pDosMode = (PIMAGE_DOS_HEADER)this->m_Buffer;
if (*(PWORD)this->m_Buffer != IMAGE_DOS_SIGNATURE) {
free(this->m_Buffer);
return VOID();
}
pNtMode = PIMAGE_NT_HEADERS32((DWORD)this->m_Buffer + pDosMode->e_lfanew);
if (pNtMode->OptionalHeader.Magic == 0x10B) {
printf("%x\t文件的类型:32位的PE格式的文件:Magic\n", pNtMode->OptionalHeader.Magic);
}
else if (pNtMode->OptionalHeader.Magic == 0x20B) {
printf("%x\t文件的类型:64位的PE格式的文件:Magic\n", pNtMode->OptionalHeader.Magic);
}
else{
printf("%x\t文件的类型:Magic\n", pNtMode->OptionalHeader.Magic);
}
printf("%x\t所有代码节的和:SizeOfCode\n", pNtMode->OptionalHeader.SizeOfCode);
printf("%x\t程序入口(OEP):AddressOfEntryPoint\n", pNtMode->OptionalHeader.AddressOfEntryPoint);
printf("%x\t代码开始的基址:BaseOfCode\n", pNtMode->OptionalHeader.BaseOfCode);
printf("%x\t数据开始的基址:BaseOfDat\n", pNtMode->OptionalHeader.BaseOfData);
printf("%x\t内存镜像:ImageBase\n", pNtMode->OptionalHeader.ImageBase);
printf("%x\t内存对齐:SectionAlignment\n", pNtMode->OptionalHeader.SectionAlignment);
printf("%x\t文件对齐:FileAlignment\n", pNtMode->OptionalHeader.FileAlignment);
printf("%x\t整个文件在内存中拉伸后的大小:SizeOfImage\n", pNtMode->OptionalHeader.SizeOfImage);
printf("%x\t所有头加上所有节表的总和(头的部分):SizeOfHeaders\n", pNtMode->OptionalHeader.SizeOfHeaders);
printf("%x\t目录项数目(包含多少个表):NumberOfRvaAndSizes\n", pNtMode->OptionalHeader.NumberOfRvaAndSizes);
printf("----------------------------------------------------------------------\n");
free(this->m_Buffer);
return VOID();
}
VOID ModuleTraversal::SectionHeaderMode(){
this->m_Buffer = this->OpenFile(nullptr, FILEBUFF);
if (this->m_Buffer == NULL) {
return;
}
this->pDosMode = PIMAGE_DOS_HEADER(this->m_Buffer);
if ((*(PWORD)this->m_Buffer) != IMAGE_DOS_SIGNATURE) {
free(this->m_Buffer);
return;
}
this->pNtMode = PIMAGE_NT_HEADERS32((DWORD)this->m_Buffer + this->pDosMode->e_lfanew);
this->pSectionMode = PIMAGE_SECTION_HEADER(((DWORD)this->m_Buffer) + this->pDosMode->e_lfanew + 0x4 + sizeof(IMAGE_FILE_HEADER) + sizeof(IMAGE_OPTIONAL_HEADER32));
for (int traversalSection = 0; traversalSection < pNtMode->FileHeader.NumberOfSections; traversalSection++) {
char arr[9] = { 0 };
strcpy(arr, (char*)this->pSectionMode->Name);
for (int arrByte = 0; arrByte < 8; arrByte++) {
printf("%c", arr[arrByte]);
}
printf("\t节的名字\n");
printf("%x\t内存中的偏移地址:VirtualAddress\n", this->pSectionMode->VirtualAddress);
printf("%x\t内存中的大小:Misc.VirtualSize\n", this->pSectionMode->Misc.VirtualSize);
printf("%x\t文件中的偏移:PointerToRawData\n", this->pSectionMode->PointerToRawData);
printf("%x\t文件中大小:SizeOfRawData\n", this->pSectionMode->SizeOfRawData);
printf("%x\t节的属性:Characteristics\n", this->pSectionMode->Characteristics);
this->pSectionMode++;
printf("----------------------------------------------\n");
}
free(this->m_Buffer);
return VOID();
}
VOID ModuleTraversal::UnfoldStretch(){
PVOID FileBuff = NULL;
PVOID ImageBuff = NULL;
DWORD FileCalculateSize = 0;
FILE* pFile = fopen(FILEBUFF, "rb");
if (pFile == NULL) {
return VOID();
}
fseek(pFile, 0, SEEK_END);
FileCalculateSize = ftell(pFile);
fseek(pFile, 0, SEEK_SET);
if (FileCalculateSize == -1) {
fclose(pFile);
return VOID();
}
FileBuff = malloc(FileCalculateSize);
memset(FileBuff, 0, FileCalculateSize);
fread(FileBuff, FileCalculateSize, 1, pFile);
this->m_Buffer = FileBuff;
if (this->m_Buffer == NULL) {
fclose(pFile);
return VOID();
}
if (*(PWORD)(this->m_Buffer) != IMAGE_DOS_SIGNATURE) {
free(this->m_Buffer);
return VOID();
}
this->pDosMode = PIMAGE_DOS_HEADER(this->m_Buffer);
this->pNtMode = PIMAGE_NT_HEADERS32(DWORD(this->m_Buffer) + this->pDosMode->e_lfanew);
this->pSectionMode = PIMAGE_SECTION_HEADER(DWORD(this->m_Buffer) + this->pDosMode->e_lfanew + sizeof(IMAGE_NT_HEADERS32));
PIMAGE_SECTION_HEADER pSectionMode1 = PIMAGE_SECTION_HEADER(DWORD(this->m_Buffer) + this->pDosMode->e_lfanew + sizeof(IMAGE_NT_HEADERS32));
DWORD sizeByte = (sizeof(IMAGE_DOS_HEADER)+this->pDosMode->e_lfanew + sizeof(IMAGE_NT_HEADERS32) + (sizeof(IMAGE_SECTION_HEADER)*this->pNtMode->FileHeader.NumberOfSections));
ImageBuff = malloc(this->pNtMode->OptionalHeader.SizeOfImage);
memset(ImageBuff, 0, this->pNtMode->OptionalHeader.SizeOfImage);
memcpy(ImageBuff, FileBuff, this->pNtMode->OptionalHeader.SizeOfHeaders);
for (int fileBuff_ImageBuff = 0; fileBuff_ImageBuff < this->pNtMode->FileHeader.NumberOfSections; fileBuff_ImageBuff++) {
memcpy(PVOID((DWORD)ImageBuff + (this->pNtMode->OptionalHeader.SizeOfHeaders + this->pSectionMode->VirtualAddress)),
PVOID((DWORD)FileBuff + (this->pNtMode->OptionalHeader.SizeOfHeaders + this->pSectionMode->SizeOfRawData)), this->pSectionMode->Misc.VirtualSize);
this->pSectionMode++;
}
PVOID BackTo = NULL;
BackTo = malloc(FileCalculateSize);
memset(BackTo, 0, FileCalculateSize);
memcpy(BackTo, ImageBuff, sizeByte);
for (int backto = 0; backto < this->pNtMode->FileHeader.NumberOfSections; backto++) {
memcpy(
PVOID((DWORD)BackTo + this->pNtMode->OptionalHeader.SizeOfHeaders + pSectionMode1->PointerToRawData),
PVOID((DWORD)ImageBuff + this->pNtMode->OptionalHeader.SizeOfHeaders + pSectionMode1->VirtualAddress),
pSectionMode1->Misc.VirtualSize);
pSectionMode1++;
}
FILE* shrinkFile = NULL;
shrinkFile = fopen(fileBuff, "wb+");
fwrite(BackTo, FileCalculateSize, 1, shrinkFile);
fclose(shrinkFile);
free(this->m_Buffer);
shrinkFile = NULL;
this->m_Buffer = NULL;
FileBuff = NULL;
ImageBuff = NULL;
return VOID();
}