第3讲:导入表的定位和读取操作
2015-08-29 18:28
211 查看
// ImportFun.cpp : 完整代码如下
//
//
#include "stdafx.h" #include <stdio.h> #include <windows.h> //用来实现RVA到磁盘文件偏移的转换 DWORD RVAToOffset(LPVOID lpBase,DWORD VirtualAddress) { IMAGE_DOS_HEADER *dosHeader; IMAGE_NT_HEADERS *ntHeader; IMAGE_SECTION_HEADER *SectionHeader; int NumOfSections;//Section 的数量 //定位到PE head dosHeader=(IMAGE_DOS_HEADER*)lpBase; ntHeader=(IMAGE_NT_HEADERS*)((BYTE*)lpBase+dosHeader->e_lfanew); NumOfSections=ntHeader->FileHeader.NumberOfSections; for (int i=0;i<NumOfSections;i++) { SectionHeader=(IMAGE_SECTION_HEADER*)((BYTE*)lpBase+dosHeader->e_lfanew+sizeof(IMAGE_NT_HEADERS))+i; if(VirtualAddress>SectionHeader->VirtualAddress&&VirtualAddress<SectionHeader->VirtualAddress+SectionHeader->SizeOfRawData) { DWORD AposRAV=VirtualAddress-SectionHeader->VirtualAddress; DWORD Offset=SectionHeader->PointerToRawData+AposRAV; return Offset; } } return 0; } int main(int argc, char* argv[]) { //打开文件 HANDLE hFile=CreateFile("c:\\calc.exe",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(hFile==INVALID_HANDLE_VALUE) { printf("CreateFile Failed\n"); return 0; } //创建内存映射文件的内核对象 HANDLE hMap=CreateFileMapping(hFile,NULL,PAGE_READONLY,NULL,NULL,NULL); if(hMap==INVALID_HANDLE_VALUE) { printf("CreateFileMapping Failed\n"); return 0; } //把文件映射入内存 LPVOID lpBase=MapViewOfFile(hMap,FILE_MAP_READ,0,0,0);//返回内存文件映射句柄,lpBase if(lpBase==NULL) { printf("MapViewOfFile Failed\n"); return 0; } IMAGE_DOS_HEADER *dosHeader; IMAGE_NT_HEADERS *ntHeader; IMAGE_IMPORT_BY_NAME *ImportName; //lpBase由MapViewOfFile函数返回 dosHeader=(IMAGE_DOS_HEADER*)lpBase; //检测是否是有效的PE文件 if (dosHeader->e_magic!=IMAGE_DOS_SIGNATURE) { printf("This is not a windows file\n"); return 0; } //定位到PE header ntHeader=(IMAGE_NT_HEADERS*)((BYTE*)lpBase+dosHeader->e_lfanew);//e_lfanew成员定位到PE header //判断是否是一个有效的win32文件 if(ntHeader->Signature!=IMAGE_NT_SIGNATURE) { printf("This is not a win32 file\n"); return 0; } //定位到导入表 IMAGE_IMPORT_DESCRIPTOR *ImportDec=(IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)lpBase+RVAToOffset(lpBase,ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)); while(ImportDec->FirstThunk) { //得到DLL文件名 char *pDllName=(char*)((BYTE*)lpBase+RVAToOffset(lpBase,ImportDec->Name)); printf("\nDLL文件名:%s\n",pDllName); //通过OriginalFirstThunk定位到PIMAGE_THUNK_DATA结构数组 PIMAGE_THUNK_DATA pThunk=(PIMAGE_THUNK_DATA)((BYTE*)lpBase+RVAToOffset(lpBase,ImportDec->OriginalFirstThunk)); while(pThunk->u1.Function) { //判断函数是用函数名导入的还是序号导入的 if(pThunk->u1.Ordinal& IMAGE_ORDINAL_FLAG32)//高位为1 { //输出序号 printf("从此DLL模块导出的函数的序号:%x\n",pThunk->u1.Ordinal&0xFFFF); } else//高位为0 { //得到IMAGE_IMPORT_BY_NAME结构中的函数名 ImportName=(IMAGE_IMPORT_BY_NAME*)((BYTE*)lpBase+RVAToOffset(lpBase,(DWORD)pThunk->u1.AddressOfData)); printf("从此DLL模块导出的函数的函数名:%s\n",ImportName->Name); } pThunk++; } ImportDec++; } UnmapViewOfFile(lpBase); CloseHandle(hMap); CloseHandle(hFile); return 0; }
相关文章推荐
- HDU 1075 What Are You Talking About(map+字符串)
- Python 函数之参数、局部变量
- 求二叉树叶子节点的个数
- 如何确定一个数组中的最大值
- 关于安装JDK不当--找不到或无法加载主类 com.sun.tools.javac.Main问题
- 有关findviewbyid 一个错误用法
- 第2讲:搜索PEB结构获取kernel32.dll的基址暴力搜索内存空间获得 Api 的线性地址
- 项目总结---- imageLoder 的2个Bug解决方法、1.9.4如何选择性删除disk缓存和其它一些错误。
- oracle dblink创建
- 暑假-二分图-E - Girls and Boys
- 为好基友做了个豆瓣相册下载助手,在这里记录分享一下
- MYSQL的添加字段和修改字段
- 控制并发调用接口数
- MongoDB学习十--MongoDB的Replication Introduction
- 树莓派2代(RaspberryPi2)配合温度传感器DS18B20获取温度
- 友元函数
- 在linux下烧写exynos4412 SD卡启动的Supperboot(2)
- 关于iphone6适配
- POJ2528解题报告,区间离散化,线段树
- 求二叉树第K层的节点个数