模拟Loader装载输入函数的RVA地址至FirstThunk

本文详细介绍了在程序加载过程中,如何模拟系统处理导入表中ImportByName的部分,将RVA地址替换到FirstThunk,以理解PE文件结构和加载过程。
摘要由CSDN通过智能技术生成

这次模拟了系统在加载程序到内存时,程序的导入表中的FirstThunk被替换的过程。这里只演示了ImportByName的情形,仅供自娱自乐,233333。

#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma warning(disable:4996)
#pragma warning(disable: 4018)

DWORD CalcFileOffset(PIMAGE_SECTION_HEADER pSectionHeader, DWORD dwVirtualAddr);
BOOL IsPeFormat(UCHAR *data);
bool FindCorrespondingDll(UCHAR *pImportTable, UCHAR *data);
BOOL FindCorrespondingDllFunction(PIMAGE_IMPORT_DESCRIPTOR pImageDescriptor, UCHAR *data);
DWORD FindCorrespondingImportFunctionByName(char *importedFunctionName, char * DllName);
UCHAR *GetFileData(char *fileName);
DWORD GetExportTableRVA(UCHAR *data);

DWORD numberOfSections = 0;//区块表数目

BOOL IsPeFormat(UCHAR *data)//check 是否是pe文件格式
{
   
	PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)data;
	PIMAGE_NT_HEADERS pFileHeader = NULL;

	if (pDosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
   
		pFileHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader+pDosHeader->e_lfanew);
		if (pFileHeader->Signature == IMAGE_NT_SIGNATURE)//若这两个签名都满足 说明是PE格式文件
			return TRUE;
	}

	return FALSE;
}


bool FindCorrespondingDll(UCHAR *pImportTable, UCHAR *data)//找到给定pe文件的依赖dll,即导入的各项的dll,然后再分发给子函数 
{
   
	PIMAGE_IMPORT_DESCRIPTOR pImageDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)pImportTable;//输入表以一个全0的PIMAGE_IMPORT_DESCRIPTOR作为结束条件
	UCHAR *zeroBuf = (UCHAR *)malloc(sizeof(IMAGE_IMPORT_DESCRIPTOR));
	memset(zeroBuf, 0, sizeof(IMAGE_IMPORT_DESCRIPTOR));

	while (memcmp(pImageDescriptor, zeroBuf, sizeof(IMAGE_IMPORT_DESCRIPTOR)) != 0) {
   //当输入表描述符不为全0时
		//每个输入表描述符描述一个DLL的信息,送入相应的处理函数处理每一个DLL
		FindCorrespondingDllFunction(pImageDescriptor, data);//送入一个DLL描述符
		pImageDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pImageDescriptor + sizeof(IMAGE_IMPORT_DESCRIPTOR));//获取下一个输入表描述符
	}
	return TRUE;
}

BOOL FindCorrespondingDllFunction(PIMAGE_IMPORT_DESCRIPTOR pImageDescriptor, UCHAR *data)//用于获得每个DLL的相应的函数的函数名用于二进制比较 函数名都是ASCII字符串
{
   
	PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)data;
	PIMAGE_NT_HEADERS pFileHeader = (PIMAGE_NT_HEADERS)((DWORD)data + pDosHeader->e_lfanew);
	PIMAGE_FILE_HEADER pHeader = (PIMAGE_FILE_HEADER)(&pFileHeader->FileHeader);//获取fileHeader
	PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(&pFileHeader->OptionalHeader);//获得可选头地址
	PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)IMAGE_FIRST_SECTION(pFileHeader);//获取区块表地址
	DWORD offsetOfDllName = CalcFileOffset(pSectionHeader
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值