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;
}
封装了下PeTool-v0.512
最新推荐文章于 2024-04-09 22:06:36 发布