PE Loader

https://github.com/adezz/PeLoader

// 06_04_Inject_process.cpp : Defines the entry point for the console application.
//
#include "AAAA.h"
// 06_04_Inject_process.cpp : Defines the entry point for the console application.
//
int main(int argc, char* argv[])
{
LPVOID pFileBuffer = NULL;
DWORD dwBufferLength = 0;
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;
PIMAGE_IMPORT_DESCRIPTOR pIMPORT_DESCRIPTOR = NULL;
PIMAGE_IMPORT_BY_NAME pImage_IMPORT_BY_NAME = NULL;
MyReadFile(&pFileBuffer, &dwBufferLength, argv[1]);
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
//检测是否是'MZ'标志
if (*(PWORD)pFileBuffer != IMAGE_DOS_SIGNATURE)
{
printf("Not 'MZ' signature!\n");
free(pFileBuffer);
return -1;
}
//检测是否是'PE'标志
pNTHeader = (PIMAGE_NT_HEADERS32)((DWORD)pFileBuffer + pDosHeader->e_lfanew);
if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
{
printf("Not 'PE' signature\n");
free(pFileBuffer);
return -1;
}
//检测是否存在重定位表
DWORD dwFlagRelocation = 0;
if (pOptionHeader->DataDirectory[5].VirtualAddress == 0)
{
dwFlagRelocation = 1;
printf("EXE Have Not Base Relocation Table!\n");
}
LPVOID pImageBuffer = NULL;
CopyFileBufferToImageBuffer(pFileBuffer, &pImageBuffer); // free pFileBuffer
// get ImageBase
DWORD dwImageBase;
dwImageBase = GetImageBase(pImageBuffer);
// get SizeOfImage
DWORD dwSizeOfImage = 0;
dwSizeOfImage = GetSizeOfImage(pImageBuffer);
// to alloc memory
LPVOID pAllocAddr = NULL;
pAllocAddr = VirtualAlloc((PVOID)dwImageBase, (SIZE_T)dwSizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (pAllocAddr == NULL) {
printf("PE's ImageBase VirtualAlloc Fail, The Error is %d.\n", GetLastError());
if(dwFlagRelocation){
printf("No Base Relocation Table, And Pe's ImageBase VirtualAlloc Fail.\n");
free(pImageBuffer);
return -1;
}
pAllocAddr = VirtualAlloc(NULL, (SIZE_T)dwSizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
printf("Start Second VirtualAlloc....\n");
if(pAllocAddr == NULL){
printf("Second VirtualAlloc Fail, The Error is %d.\n", GetLastError());
free(pImageBuffer);
return -1;
}
printf("Second VirtualAlloc: %x\n", pAllocAddr);
}
printf("Fina VirtualAlloc: %x\n", pAllocAddr);
// memcpy
memcpy(pAllocAddr, pImageBuffer, dwSizeOfImage);
//CopyMemory(pAllocAddr, pImageBuffer, dwSizeOfImage);
// load pe
PDWORD pIAT = NULL;
DWORD Original = 0;
pDosHeader = (PIMAGE_DOS_HEADER)pAllocAddr;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pAllocAddr + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + sizeof(IMAGE_OPTIONAL_HEADER32));
// 修复重定位表
FixRelocation(pAllocAddr, (DWORD)pAllocAddr - dwImageBase);
//获取导入表的位置,每个导入表的相关信息占20个字节
pIMPORT_DESCRIPTOR = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pAllocAddr + (DWORD)pOptionHeader->DataDirectory[1].VirtualAddress);
HMODULE hModule;
//这里可以进行while操作,这里while的判断依据为pIMPORT_DESCRIPTOR个数
while (pIMPORT_DESCRIPTOR->FirstThunk && pIMPORT_DESCRIPTOR->OriginalFirstThunk) {
hModule = LoadLibrary((PCHAR)((DWORD)pAllocAddr + (DWORD)pIMPORT_DESCRIPTOR->Name));
pIAT = (PDWORD)((DWORD)pAllocAddr + (DWORD)pIMPORT_DESCRIPTOR->FirstThunk);
while (*pIAT) {
if (*pIAT & 0x80000000) {
//高位为1 则 除去最高位的值就是函数的导出序号
Original = *pIAT & 0x7FFFFFFF; //去除最高标志位。
*pIAT = (DWORD)GetProcAddress(hModule, (PCHAR)Original);
}
else
{
//高位不为1 则指向IMAGE_IMPORT_BY_NAME;
pImage_IMPORT_BY_NAME = (PIMAGE_IMPORT_BY_NAME)((DWORD)pAllocAddr + *pIAT);
*pIAT = (DWORD)GetProcAddress(hModule, (PCHAR)pImage_IMPORT_BY_NAME->Name);
}
pIAT++;
}
pIMPORT_DESCRIPTOR++;
}
LPVOID dwOep = (LPVOID)(GetOep(pAllocAddr) + (DWORD)pAllocAddr);
printf("oep: %x\n", GetOep(pAllocAddr));
printf("pAllocAddr: %x\n", pAllocAddr);
printf("oep+pAllocAddr: %x\n", (DWORD)dwOep);
printf("=================PE Loader=================\n");
((void(*)())((DWORD)pDosHeader + pOptionHeader->AddressOfEntryPoint))();
system("pause");
return 0;
}

posted @   zpchcbd  阅读(785)  评论(1编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示