PE_导入表

参考:Revival_S
头文件:

// toolfunc.h
DWORD toLoardPE(PVOID* pFileBuffer, PSTR file_path){
	FILE *fp;
	DWORD FileSize;
	PVOID pFileBufferTemp;

	fp = fopen(file_path, "rb");
	if(!fp){
		printf("读取文件失败!\n");
		return 0;
	}
	fseek(fp, 0, SEEK_END);
	FileSize = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	
	pFileBufferTemp = malloc(FileSize);
	if(!pFileBufferTemp){
		printf("读取文件开辟内存失败\n");
		return 0;
	}

	DWORD n = fread(pFileBufferTemp, FileSize, 1, fp);

	*pFileBuffer = pFileBufferTemp;
	pFileBufferTemp = NULL;
	fclose(fp);

	return FileSize;
}

DWORD Align(int add, int alignment){
	if(add % alignment == 0){
		return add;
	}
	return ((add / alignment) + 1) * alignment;
}

DWORD Rva2Foa(PVOID pFileBuffer, DWORD dwRva){
	PIMAGE_DOS_HEADER pDosHeader = NULL;
	PIMAGE_NT_HEADERS pNTHeader = NULL;
	PIMAGE_FILE_HEADER pPEHeader = NULL;
	PIMAGE_OPTIONAL_HEADER pOptionHeader = NULL;
	PIMAGE_SECTION_HEADER pSectionHeader = NULL;

	if(!pFileBuffer){
		printf("从磁盘读取文件为空!\n");
		return 0;
	}

	if(*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE){
		printf("(Rva2Foa)没有MZ标志!\n");
		return 0;
	}

	pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
	if(*(PDWORD)((DWORD)pDosHeader + pDosHeader->e_lfanew) != IMAGE_NT_SIGNATURE){
		printf("(Rva2Foa)没有PE标志!\n");
		return 0;
	}

	pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
	pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
	pOptionHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
	pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);

	PIMAGE_SECTION_HEADER pSectionHeaderTemp = pSectionHeader;
	PIMAGE_SECTION_HEADER pNextSectionHeaderTemp = pSectionHeader + 1;


	if(dwRva <= pOptionHeader->SizeOfHeaders){
		return dwRva;
	}else{
		for(int n=1; n < pPEHeader->NumberOfSections; n++, pSectionHeaderTemp++, pNextSectionHeaderTemp++){
			if((dwRva >= pSectionHeaderTemp->VirtualAddress) && (dwRva < (pNextSectionHeaderTemp->VirtualAddress)))
				return dwRva - pSectionHeaderTemp->VirtualAddress + pSectionHeaderTemp->PointerToRawData;
		}
	}
	if (dwRva >= pSectionHeaderTemp->VirtualAddress && dwRva < pOptionHeader->SizeOfImage)
	{
		return pSectionHeaderTemp->PointerToRawData + dwRva - pSectionHeaderTemp->VirtualAddress;
	}
	printf("RVA TO FOA Failed!\n");

	return 0;
}

主程序:

#include<stdio.h>
#include<windows.h>
#include "toolfunc.h"

PSTR file_path = "C:\\Users\\lolol\\Desktop\\3.exe";

int main(){
	PIMAGE_DOS_HEADER pDosHeader = NULL;
	PIMAGE_FILE_HEADER pPEHeader = NULL;
	PIMAGE_OPTIONAL_HEADER pOptionHeader = NULL;
	PIMAGE_SECTION_HEADER pSectionHeader = NULL;
	PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
	PIMAGE_BASE_RELOCATION pRelocationTable = NULL;
	PIMAGE_IMPORT_DESCRIPTOR pImportTable = NULL;

	PIMAGE_IMPORT_BY_NAME pImportByName = NULL;

	PVOID pFileBuffer = NULL;
	BYTE zero[sizeof(IMAGE_IMPORT_DESCRIPTOR)] = {0};

	DWORD FileSize = toLoardPE(&pFileBuffer, file_path);
	printf("读入文件大小:%x\n",FileSize);

	pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
	pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pFileBuffer + pDosHeader->e_lfanew + 4);
	pOptionHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);

	pDataDirectory = pOptionHeader->DataDirectory;
	

	pDataDirectory = pDataDirectory + 1; // 重定位表的目录表
	printf("导入表的地址:%#x\n",pDataDirectory->VirtualAddress);
	if(!pDataDirectory->VirtualAddress){
		printf("没有导入表\n");
		return 0;
	}
	pImportTable = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pFileBuffer + Rva2Foa(pFileBuffer, pDataDirectory->VirtualAddress));	

	// 遍历所有导入表
	for(size_t i=0; memcmp(zero, pImportTable, sizeof(zero)); i++){
		printf("==========第%2d个导入表==========\n",i);
		printf("被使用的DLL的名字:%s\n", (char*)((DWORD)pFileBuffer + Rva2Foa(pFileBuffer, pImportTable->Name)));
		printf("INT地址:%#x\n", pImportTable->OriginalFirstThunk);
		printf("时间戳:%#x\n", pImportTable->TimeDateStamp);
		printf("IAT地址:%#x\n", pImportTable->FirstThunk);

		// INT

		printf("===============INT==============\n");
		PDWORD pINTItem = NULL;
		pINTItem = (PDWORD)((DWORD)pFileBuffer + Rva2Foa(pFileBuffer, pImportTable->OriginalFirstThunk));
		for(int numINT = 0; *pINTItem; numINT++){ // 遍历每个IMAGE_THUNK_DATA			
			if((*pINTItem) & 0x80000000){// 存的是序号
				//printf("1\n");
				printf("第%d个函数的序号%#x\n", numINT, *pINTItem & 0x7fffffff);
			}else{// 存的是RVA,指向IMAGE_IMPORT_BY_NAME				
				pImportByName = (PIMAGE_IMPORT_BY_NAME)((DWORD)pFileBuffer + Rva2Foa(pFileBuffer, *pINTItem));				
				printf("第%d个函数的名字%#x-%s\n", numINT, pImportByName->Hint, pImportByName->Name);
			}

			pINTItem++;
		}

		// IAT
		printf("===============IAT==============\n");
		PDWORD pIATItem = NULL;
		pIATItem = (PDWORD)((DWORD)pFileBuffer + Rva2Foa(pFileBuffer, pImportTable->FirstThunk));
		for(int numIAT = 0; *pIATItem; numIAT++){ // 遍历每个IMAGE_THUNK_DATA			
			if((*pIATItem) & 0x80000000){// 存的是序号
				//printf("1\n");
				printf("第%d个函数的序号%#x\n", numIAT, *pIATItem & 0x7fffffff);
			}else{// 存的是RVA,指向IMAGE_IMPORT_BY_NAME				
				pImportByName = (PIMAGE_IMPORT_BY_NAME)((DWORD)pFileBuffer + Rva2Foa(pFileBuffer, *pIATItem));				
				printf("第%d个函数的名字%#x-%s\n", numIAT, pImportByName->Hint, pImportByName->Name);
			}

			pIATItem++;
		}

		pImportTable++;
	}

	

	return 0;
}

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值