封装了下PeTool-v0.512

eTool.cpp

#include <stdlib.h>

#include "stdafx.h"

#include <iostream>

#include <iomanip>

#include <fstream>

#include <string>

#include <windows.h>

#include <malloc.h>

using namespace std;

#define MessageBox_Add 0x74D61E80

//功能:通过文件路径获得文件指针,并返回其指针地址

//参数:一个指针类型的返回的pFileBuffer指针地址

int Return_FileBuffer(OUT LPVOID* pFileBuffer,IN char* FilePath)

{

FILE* File = ReadFile(FilePath, "rb");

int File_size = compute_file_len(File);

*pFileBuffer = File_to_FileBuffer(File_size, File);

return File_size;

}

//功能:打印PE信息

void Print_Pe(IN char* FilePath)

{

FILE* File_Address;

File_Address = ReadFile(FilePath, "rb");

int file_size = compute_file_len(File_Address);

char* FileBuffer = (char*)File_to_FileBuffer(file_size, File_Address);

Read_Pe_info(FileBuffer);

}

//读取文件,并返回文件流

//参数1:文件路径

//参数2:读取类型

FILE* ReadFile(LPSTR FilePath,char* Type)

{

FILE* FileAddress;//定义文件流

if (!(FileAddress = fopen(FilePath,Type)))

{

printf("没有读取文件失败,错误01");

fclose(FileAddress);

return 0;

}

return FileAddress;

}

//获得读取的文件流大小,返回文件流大小

//参数:文件流地址

int SizeOfFile(FILE* FileAddress)

{

int size;

//定位到文件末尾

fseek(FileAddress, NULL, SEEK_END);

//得到大小

size = ftell(FileAddress);

//重定位文件头到最开始的位置

fseek(FileAddress, NULL, SEEK_SET);

return size;

}

//申请动态内存,从文件流读取数据,并返回动态内存的文件指针

//参数1:文件流大小,字节

//参数2:文件流指针

//返回值:动态内存的文件指针

LPVOID File_to_FileBuffer(int size, FILE* FileAddress)

{

if (!size)

{

printf("没有获得需要申请的内存大小");

fclose(FileAddress);

return 0;

}

LPVOID MalcMem = NULL;

MalcMem = (char*)malloc(size);

memset(MalcMem, 0, size);

fread(MalcMem, 1,size, FileAddress);

return MalcMem;

}

//把文件数据写内存中

//参数1:文件流地址,

//参数2:申请的Filebuffer动态内存地址,

//参数3:Filebuffer大小

LPVOID ReadFileMem(FILE* File_address, LPVOID pFilebuffer, int pFilebuffer_size)

{

if (!(fread(pFilebuffer, 1, pFilebuffer_size, File_address)))

{

printf("错误,请查看代码1000");

return 0;

}

return pFilebuffer;

}

//动态分配内存,并刷新分配的内存空间

//参数1:文件大小

char* Malloc(int buffer_size)

{

char* buffer_address = (char*)malloc(buffer_size);

if (!buffer_address)

{

printf("内存分配失败,检查代码1001");

return 0;

}

memset(buffer_address, 0, buffer_size);

return buffer_address;

}

//读取Filebuffer的信息,并打印出来

//参数1:buffer地址

void Read_Pe_info(IN LPVOID buffer_address)

{

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)buffer_address;

// 获取PE头部偏移

if (*((PDWORD)((DWORD)pDosHeader + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)

{

printf("不是有效的PE标志!\n");

free(buffer_address);

}

printf("pDosHeader:%x\n", pDosHeader->e_magic);

pNTHeader = PIMAGE_NT_HEADERS((DWORD)pDosHeader + pDosHeader->e_lfanew);

printf("=====================开始查找NT头中信息=============================\n\n");

printf("pNTHeader:%08x\n", pNTHeader->Signature);

//强制类型转化,指向标准PE头

pPEHeader = PIMAGE_FILE_HEADER((DWORD)pNTHeader + 4);

printf("=====================开始查找标准PE头中信息=========================\n");

printf("pPEHeader:%x\n", pPEHeader->Machine);

printf("节的数量:%d\n", pPEHeader->NumberOfSections);

printf("SizeOfOptionalHeader(可选PE头的大小):%x\n", pPEHeader->SizeOfOptionalHeader);

int NumberOfSections = pPEHeader->NumberOfSections;

// 强制类型转换,指向可选PE头

pOptionHeader = PIMAGE_OPTIONAL_HEADER32((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);

printf("====================开始查找可选PE头中信息==========================\n");

printf("SizeOfImage:%x\n", pOptionHeader->SizeOfImage);

printf("SizeOfHeaders:%x\n", pOptionHeader->SizeOfHeaders);

printf("SectionAlignment:%x\n", pOptionHeader->SectionAlignment);

DWORD SizeOfHeaders = pOptionHeader->SizeOfHeaders;

DWORD SizeOfImage = pOptionHeader->SizeOfImage;

DWORD SectionAlignment = pOptionHeader->SectionAlignment;

// 强制类型转换,指向节表中的信息

printf("====================查找到节表中信息%d个==========================\n",pPEHeader->NumberOfSections);

pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);

for (int i = 0; i<NumberOfSections; i++,pSectionHeader++)

{

printf("Section_Name:%s\n", pSectionHeader->Name);

printf("VirtualAddress:%08X\n", pSectionHeader->VirtualAddress);

printf("SizeOfRawData:%08X\n", pSectionHeader->SizeOfRawData);

printf("PointerToRawData:%08X\n", pSectionHeader->PointerToRawData);

printf("==============================================\n");

//info_Address[i] = pSectionHeader->VirtualAddress;

//info_RawData[i] = pSectionHeader->SizeOfRawData;

//info_PointerToRawData[i] = pSectionHeader->PointerToRawData;

}

printf("打印PE信息结束!!\n");

}

//FileBuffer拉伸到Imagebuffer

//参数1:FileBuffer指针

void FileBufferToImagebuffer(IN LPVOID* pFileBuffer,OUT LPVOID* pImagebuffer)

{

LPVOID pTempImageBuffer = NULL;

if (!pFileBuffer)

{

printf("没有获取到FileBuffer指针,请检查代码");

}

PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)*pFileBuffer;

if (*(PWORD)pDos!=IMAGE_DOS_SIGNATURE)

{

printf("不是有效的MZ标志,请检查代码或者是否为EXE程序");

}

PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)((DWORD)pDos+pDos->e_lfanew);

if (*(PWORD)pNt != IMAGE_NT_SIGNATURE)

{

printf("不是有效的PE标志,请检查代码或者是否为EXE程序");

}

PIMAGE_FILE_HEADER pFile = (PIMAGE_FILE_HEADER)((DWORD)pNt + 4);

PIMAGE_OPTIONAL_HEADER pOption = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFile + IMAGE_SIZEOF_FILE_HEADER);

PIMAGE_SECTION_HEADER pSetion = (PIMAGE_SECTION_HEADER)((DWORD)pOption + pFile->SizeOfOptionalHeader);

//将sizeofimage的值扩展为SectionAlignment的整数倍(在内存中一般是0x1000的整数倍)

int Sizeofimage_Alignment = pOption->SizeOfImage;

int iTemp = pOption->SizeOfImage % pOption->SectionAlignment;

if (iTemp!= 0)

{

Sizeofimage_Alignment = pOption->SizeOfImage + pOption->SectionAlignment - iTemp;

pOption->SizeOfImage = (DWORD)Sizeofimage_Alignment;

}

//申请动态内存

pTempImageBuffer = (LPVOID)malloc(Sizeofimage_Alignment);

//刷新内存

memset(pTempImageBuffer, 0, pOption->SizeOfImage);

//复制头到动态内存

if (!pTempImageBuffer)

{

printf("内存分配失败,代码0009");

}

memcpy(pTempImageBuffer, *pFileBuffer, pOption->SizeOfHeaders);

//复制节表

int CountSection = pFile->NumberOfSections;

for (int i = 0; i < CountSection; i++, pSetion++)

{

memcpy((LPVOID)((DWORD)pTempImageBuffer + pSetion->VirtualAddress), (LPVOID)((DWORD)pDos+pSetion->PointerToRawData), pSetion->SizeOfRawData);

}

*pImagebuffer = pTempImageBuffer;

}

//保存内存缓存为文件

//参数1:pNewFileBuffer指针

//参数2:缓存大小

//参数3:文件保存路径,建议使用#define 进行定义,例如:#define NewFilePath "D:\\XXXXX.exe";

void Save_pNewFileBufferTo_EXE(IN LPVOID* pNewFileBuffer,IN char* NewFilePath,int FileSize)

{

//char Save_exe[] = "D:\\ipmsg_NewSection.exe";

FILE* Save_file = fopen(NewFilePath, "wb+");

fwrite(*pNewFileBuffer, FileSize, 1, Save_file);

if (!Save_file)

{

printf("拷贝失败了,错误代码22\n");

fclose(Save_file);

return ;

}

fclose(Save_file);

return ;

}

//功能:在代码节空白区添加代码

//参数1:一个指针类型的pImgeBuffer指针地址

//参数2:一个指针类型的pNewImageBuffer指针地址(添加代码后的内存映像)

//参数3,:返回被插入代码后的sizeofimage大小

void CodeSection_InsertCode(IN LPVOID* pImageBuffer, OUT LPVOID* pNewImageBuffer, DWORD* SizeOfImage)

{

char ShellCode[] =

{

0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00,//MessgeBoxA(0,0,0,0)  四个参数,在堆中压如堆栈,

0xE8, 0x00, 0x00, 0x00, 0x00,//E8  就是call

0xE9, 0x00, 0x00, 0x00, 0x00  //E9   就是JMP

};

PIMAGE_DOS_HEADER pNewDos = (PIMAGE_DOS_HEADER)*pImageBuffer;

PIMAGE_NT_HEADERS pNewNt = (PIMAGE_NT_HEADERS)((DWORD)pNewDos + (DWORD)(pNewDos->e_lfanew));

PIMAGE_FILE_HEADER pNewFile = (PIMAGE_FILE_HEADER)((DWORD)pNewNt + 4);

PIMAGE_OPTIONAL_HEADER pNewOptional = (PIMAGE_OPTIONAL_HEADER)((DWORD)pNewFile + IMAGE_SIZEOF_FILE_HEADER);

PIMAGE_SECTION_HEADER pNewSection = (PIMAGE_SECTION_HEADER)((DWORD)pNewOptional + pNewFile->SizeOfOptionalHeader);

if (!(pNewSection->SizeOfRawData - pNewSection->Misc.VirtualSize > 18))

{

printf("第一个节区内存空间不够,请查看SizeOfRawData和Misc.VirtualSize");

free(*pImageBuffer);

}

//计算从第一节的哪个位置开始添加代码

DWORD ImageBase_ = pNewOptional->ImageBase;

char* InsertCode_Pos = (char*)(DWORD)*pImageBuffer + pNewSection->VirtualAddress + pNewSection->Misc.VirtualSize;

//把ShellCode复制到InsertCode_Pos

memcpy(InsertCode_Pos, ShellCode, sizeof(ShellCode));

int E8_Code = MessageBox_Add - (DWORD)(ImageBase_ + ((DWORD)InsertCode_Pos+0xd - (DWORD)*pImageBuffer));

*(PDWORD)(InsertCode_Pos + 0x9) = E8_Code;

int E9_Code = (ImageBase_ + pNewOptional->AddressOfEntryPoint) - (DWORD)(ImageBase_ + ((DWORD)InsertCode_Pos+ 0x12 - (DWORD)*pImageBuffer ));

*(PDWORD)(InsertCode_Pos + 0xe) = E9_Code;

pNewOptional->AddressOfEntryPoint = (DWORD)InsertCode_Pos - (DWORD)*pImageBuffer;//重新定位程序入口处

//pNewOptional->SizeOfImage = pNewOptional->SizeOfImage + sizeof(ShellCode);//把Shellcode代码大小添加进SizeofImage

//*SizeOfImage = pNewOptional->SizeOfImage;

//申请一块动态内存,大小为加了18个字节后的sizeofimage

*pNewImageBuffer = malloc(pNewOptional->SizeOfImage);

//把pImageBuffer复制到pNewImagebuffer

int Sizeofimage_Alignment = pNewOptional->SizeOfImage;

int iTemp = pNewOptional->SizeOfImage % pNewOptional->SectionAlignment;

if (iTemp != 0)

{

Sizeofimage_Alignment = pNewOptional->SizeOfImage + pNewOptional->SectionAlignment - iTemp;

pNewOptional->SizeOfImage = Sizeofimage_Alignment;

}

memcpy(*pNewImageBuffer, *pImageBuffer, pNewOptional->SizeOfImage);

*SizeOfImage = pNewOptional->SizeOfImage;

}

//ImageBuffer压缩到FileBuffer

//参数1:ImageBuffer指针

//参数2:pNewFileBuffer指针

void ImageBufferToFileBuffer(IN LPVOID* pImageBuffer,IN LPVOID* TempFileBuffer2,OUT LPVOID* pNewFileBuffer)

{

if (!TempFileBuffer2)

{

printf("临时指针TempFileBuffer没有被分配地址");

}

if (!*pImageBuffer)

{

printf("没有获取到FileBuffer指针,请检查代码");

}

PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)*pImageBuffer;

if (*(PWORD)pDos != IMAGE_DOS_SIGNATURE)

{

printf("不是有效的MZ标志,请检查代码或者是否为EXE程序");

}

PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)((DWORD)pDos + pDos->e_lfanew);

if (*(PWORD)pNt != IMAGE_NT_SIGNATURE)

{

printf("不是有效的PE标志,请检查代码或者是否为EXE程序");

}

PIMAGE_FILE_HEADER pFile = (PIMAGE_FILE_HEADER)((DWORD)pNt + 4);

PIMAGE_OPTIONAL_HEADER pOption = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFile + IMAGE_SIZEOF_FILE_HEADER);

PIMAGE_SECTION_HEADER pSetion = (PIMAGE_SECTION_HEADER)((DWORD)pOption + pFile->SizeOfOptionalHeader);

//将sizeofimage的值扩展为SectionAlignment的整数倍(在内存中一般是0x1000的整数倍)

int Sizeofimage_Alignment = pOption->SizeOfImage;

int iTemp = pOption->SizeOfImage % pOption->SectionAlignment;

if (iTemp != 0)

{

Sizeofimage_Alignment = pOption->SizeOfImage + pOption->SectionAlignment - iTemp;

pOption->SizeOfImage = Sizeofimage_Alignment;

}

//申请动态内存

*TempFileBuffer2 = malloc(pOption->SizeOfImage);///这里有问题,应该是前面的程序出现了内存越界访问造成的。

//刷新内存

memset(*TempFileBuffer2, 0, pOption->SizeOfImage);

//复制头到动态内存

if (!*TempFileBuffer2)

{

printf("内存分配失败,代码0009");

}

memcpy(*TempFileBuffer2, *pImageBuffer, pOption->SizeOfHeaders);

//复制节表

int CountSection = pFile->NumberOfSections;

for (int i = 0; i < CountSection; i++, pSetion++)

{

memcpy((LPVOID)((DWORD)*TempFileBuffer2 + pSetion->PointerToRawData), (LPVOID)((DWORD)pDos + pSetion->VirtualAddress), pSetion->SizeOfRawData);

}

*pNewFileBuffer = *TempFileBuffer2;

//free(*TempFileBuffer2);

}

//计算文件大小

//参数:文件指针

//int返回值:文件大小

int compute_file_len(FILE* pfile)

{

int len = 0;

fseek(pfile, 0, SEEK_END);

len = ftell(pfile);

fseek(pfile, 0, SEEK_SET);

return len;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值