• 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!
    ");
    		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;
    }
    

  • 相关阅读:
    判别式模型与生成式模型
    C#和Excel进行报表开发
    C# TreeView序列化、串行化、反序列化
    磁盘碎片整理后电脑盘损坏的修复过程
    用C#实现CS模式下软件自动在线升级
    win10家庭版更改为企业版和激活
    [原创]前端页面检查神器google chrome lighthouse
    [原创] PDMReaderSetup下载
    SpringBoot定时任务@EnableScheduling
    【spring bean】@Resource注解的自动注入策略 , 以 项目中注入多个线程池的Bean为例 附加自定义SpringBeanSupport
  • 原文地址:https://www.cnblogs.com/zpchcbd/p/14697035.html
Copyright © 2020-2023  润新知