PE Loader

摘要:
");free;return-1;}//检测是否是'PE'标志pNTHeader=;if(pNTHeader-˃Signature!

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!
");
		free(pFileBuffer);
		return -1;
	}

	
	//检测是否是'PE'标志
	pNTHeader = (PIMAGE_NT_HEADERS32)((DWORD)pFileBuffer + pDosHeader->e_lfanew);
	if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
	{
		printf("Not 'PE' signature
");
		free(pFileBuffer);
		return -1;
	}

	//检测是否存在重定位表
	DWORD dwFlagRelocation = 0;
	if (pOptionHeader->DataDirectory[5].VirtualAddress == 0)
	{
		dwFlagRelocation = 1;
		printf("EXE Have Not Base Relocation Table!
");
	}

	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.
", GetLastError());
		if(dwFlagRelocation){
			printf("No Base Relocation Table, And Pe's ImageBase VirtualAlloc Fail.
");
			free(pImageBuffer);
			return -1;
		}

		pAllocAddr = VirtualAlloc(NULL, (SIZE_T)dwSizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
		printf("Start Second VirtualAlloc....
");
		if(pAllocAddr == NULL){
			printf("Second VirtualAlloc Fail, The Error is %d.
", GetLastError());
			free(pImageBuffer);
			return -1;
		}
		printf("Second VirtualAlloc: %x
", pAllocAddr);
	}

	printf("Fina VirtualAlloc: %x
", 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
", GetOep(pAllocAddr));
	printf("pAllocAddr: %x
", pAllocAddr);
	printf("oep+pAllocAddr: %x
", (DWORD)dwOep);
	printf("=================PE Loader=================
");
	((void(*)())((DWORD)pDosHeader + pOptionHeader->AddressOfEntryPoint))();
	
	system("pause");

	return 0;
}

PE Loader第1张

免责声明:文章转载自《PE Loader》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇利用Kettle转储接口数据如何通俗的解释仿射变换?下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

解决xcode打开时loading假死的问题

出现这个问题就真得崩溃了,有些小伙伴甚至还重装了Xcode,这里给大家推荐一个行之有效的方法。...

高斯键盘设置指南

高斯键盘设置指南如何打开蓝牙模式电源:蓝牙需要电源。高斯GS87-D有两种通电方式:将键盘背面的开关转到on;使用USBType-C电源切换模式:Fn+P用于在有线模式和无线模式之间切换。按下Fn+P,Fn+PP右上角的键盘灯闪烁3次。有线模式和蓝牙模式相互切换。但是,没有指示灯指示当前模式是有线模式还是蓝牙模式如何连接蓝牙代码匹配:长按Fn+P,直到P键快...

(二)Jenkins配置主从节点实例

4.从节点配置和相关配置中从节点机创建jenkins用户,并从一些环境配置中创建jenkings用户的ssh密钥,用于指定上述配置界面的ssh启动模式;在配置启动模式和项目源代码管理中从远程仓库获取源代码;创建Jenkins用户并使用root登录到远程子节点计算机。#adduserjenkins#passwdjenkins生成Jenkins用户的ssh密钥。...

sqlserver 计算 百分比

selectltrim+'%'As百分比NUMERIC(P,S)P的默认值是:38S的默认值是:-84~127numeric(a,b)函数有两个参数,前面一个为总的位数,后面一个参数是小数点后的位数,例如numeric(5,2)是总位数为5,小数点后为2位的数,也就是说这个字段的整数位最大是3位。...

Python-正则

,三:量词*重复0次或多次{0,}+重复一次或多次{1,}?重复0或1次{1,0}{n}重复n次{n}{n,}重复n次,或更多次{n,m}将n次重复到m次Escape:如果字符串中有特殊字符要匹配,请在常规字符和字符串前面添加r。如果特殊字符在字符组中,则它们是匹配的特殊字符,但为了记忆,匹配时会转义所有特殊字符。...

uniapp之页面间传递和接收数组

uni-app如何在页面之前发送和传递数组?如果阵列是直接发送和传递的,则收到的消息如下所示。无法获取更多的对象值。接收数组对象的参数。您可以首先将数组转换为JSON字符串,然后在将其传递到页面后将其解析为JavaScript对象。...