PE格式之千里追踪输入表
高数考完了,终于可以轻松的写代码了。哈哈
终于开始写输入表了。输入表是我们项目的重头戏。首先还是先介绍下输入表的基本知识。
自己写的话有点麻烦,还是copy一下小甲鱼辛辛苦苦打出来的课件吧
输入表结构
PE文件头的 IMAGE_OPTIONAL_HEADER 结构中的 DataDirectory(数据目录表) 的第二个成员就是指向输入表的。而输入表是以一个 IMAGE_IMPORT_DESCRIPTOR(简称IID) 的数组开始。每个被 PE文件链接进来的 DLL文件都分别对应一个 IID数组结构。在这个 IID数组中,并没有指出有多少个项(就是没有明确指明有多少个链接文件),但它最后是以一个全为NULL(0) 的 IID 作为结束的标志。
我们首先来找到这个输入表的地址:还是首先附上上次的那张图片:
如果看不清楚的话,这里给个链接,是我自己的博客里面的,放大应该就看的清楚了
http://miibotree.com/?p=226
在PE头那里我们可以看到数据目录表,(用红框框圈起来的那里) IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
接着红色的箭头指向了我们的数据目录表的数据结构
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory (输入表,我们所需要的)
#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory
#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory
#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table
#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory
// IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // (X86 usage)
#defi ne IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP
#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers
#define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor
然后每个数据目录表的结构成员有两个
typedef struct _IMAGE_DATA_DIRECTORY {DWORD VirtualAddress; //输入表的RVADWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
这里的VirtualAddress就是我们的输入表的RVA了
得到RVA只是第一步,我们接下来要判断输入表在哪个区块里面。
当然这个时候我们必须要做的就是读取区块的信息了。区块的数据结构如下(可以在图里面找到哦)
typedef struct _IMAGE_SECTION_HEADER {BYTE Name[IMAGE_SIZEOF_SHORT_NAME];union {DWORD PhysicalAddress;DWORD VirtualSize;} Misc;DWORD VirtualAddress; //区块的RVADWORD SizeOfRawData;DWORD PointerToRawData;DWORD PointerToRelocations;DWORD PointerToLinenumbers;WORD NumberOfRelocations;WORD NumberOfLinenumbers;DWORD Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
通过输入表的RVA与区块的RVA比较,我们就能知道输入表在哪个区块里面。
好,第二步已经完成了。
现在是最关键的第三步:
这里必须明确掌握RVA, VA, offset。因为这个是PE文件的最重点。下面再引用一下小甲鱼的课件:
RVA 和文件偏移的转换
在前边我们探讨过RVA 这个词,但对于初次接触PE 文件的朋友来说,显得尤其陌生和无奈。中国人不喜欢老外的缩写,但总要**着接受……不过,在有了前边知识的铺垫之后,现在来谈这个概念大家伙应该能够得心应手了。起码不用显得那么的费解和无奈~
RVA 是相对虚拟地址(Relative Virtual Address)的缩写,顾名思义,它是一个“相对地址”。PE 文件中的各种数据结构中涉及地址的字段大部分都是以 RVA 表示的,有木有??
更为准确的说,RVA 是当PE 文件被装载到内存中后,某个数据位置相对于文件头的偏移量。举个例子,如果 Windows 装载器将一个PE 文件装入到 00400000h 处的内存中,而某个区块中的某个数据被装入 0040**xh 处,那么这个数据的 RVA 就是(0040**xh - 00400000h )= **xh,反过来说,将 RVA 的值加上文件被装载的基地址,就可以找到数据在内存中的实际地址。
看图说话:
很明显,我们发现,DOS 文件头、PE 文件头和区块表的偏移位置与大小均没有变化。而各个区块映射到内存后,其偏移位置就发生了变化。
RVA 使得文件装入内存后的数据定位变得方便,然而却给我们要定位位于磁盘上的静态PE 文件带来了麻烦。举个例子说话:……由于例子在视频中,这里争取时间我就不写啦,大伙看参考视频演示吧。
如何换算 RVA 和文件偏移呢?
当处理PE 文件时候,任何的 RVA 必须经过到文件偏移的换算,才能用来定位并访问文件中的数据,但换算却无法用一个简单的公式来完成,事实上,唯一可用的方法就是最土最笨的方法:
步骤一:循环扫描区块表得出每个区块在内存中的起始 RVA(根据IMAGE_SECTION_HEADER 中的VirtualAddress 字段),并根据区块的大小(根据IMAGE_SECTION_HEADER 中的SizeOfRawData 字段)算出区块的结束 RVA(两者相加即可),最后判断目标 RVA 是否落在该区块内。
步骤二:通过步骤一定位了目标 RVA 处于具体的某个区块中后,那么用目标 RVA 减去该区块的起始 RVA ,这样就能得到目标 RVA 相对于起始地址的偏移量 RVA2.
步骤三:在区块表中获取该区块在文件中所处的偏移地址(根据IMAGE_SECTION_HEADER 中的PointerToRawData 字段这个字段是物理偏移地址 将这个偏移值加上步骤二得到的 RVA2 值,就得到了真正的文件偏移地址。
当然这里理解起来可能比较困难,大家可以看看小甲鱼的视频然后看看加密与解密的那本书最后动手实践来慢慢理解的。
将这个 真正的文件偏移地址加上基地址就是输入表的地址了。
如此一来,我们千里迢迢终于追踪到了输入表的地址了。
PE格式之千里追踪输入表相关推荐
- PE格式第七讲,重定位表
PE格式第七讲,重定位表 作者:IBinary 出处:http://www.cnblogs.com/iBinary/ 版权所有,欢迎保留原文链接进行转载:) 一丶何为重定位(注意,不是重定位表格) 首 ...
- 认识Import表-PE输入表说明
认识Import表-PE输入表说明 有很多介绍PE文件的文章,但是我打算写一篇关于输入表的文章,因为它对于破解很有用. 我想解释它的最好的方法是举一个例子,你可以跟着我逐步深入,一步一步的思考 ...
- PE格式系列_0x03:输入表原理+IAT填充流程
文章目录 Q1:函数真实地址? Q2:函数调用和真实地址之间桥梁? Q3:PE文件记录DLL信息? 1.数据结构 part 1.整体分析 part 2.局部分析 2.数据结构总结 3. 加载流程 Q4 ...
- 写一个PE的壳_Part 2:ASLR+修复输入表(IAT)+重定位表支持(.reloc)
系列汇总 写一个PE的壳_Part 1:加载PE文件到内存 写一个PE的壳_Part 2:ASLR+修复输入表(IAT)+重定位表支持(.reloc) 写一个PE的壳_Part 3:Section里实 ...
- 22. PE结构-PE详解之输入表(导入表)、屠龙刀W32Dasm(静态)、LordPE(动态)工具入门(查找dll、调用函数)
我们知道PE 文件中的数据被载入内存后根据不同页面属性被划分成很多区块(节),并有区块表(节表)的数据来描述这些区块.这里我们需要注意的问题是:一个区块中的数据仅仅只是由于属性相同而放在一起,并不一定 ...
- [导入]VB PE导出/输入表演示(读文件版)
VB PE导出/输入表演示(读文件版) 文章来源:http://blog.csdn.net/chenhui530/archive/2007/12/31/2006109.aspx 转载于:https:/ ...
- 华为澄清:公司副总裁未发表中美技术还差两万五千里表述
近日,自媒体文章<华为副总裁:我们与美国技术还差两万五千里>传出,文中提到华为公司董事.高级副总裁陈黎芳,近日在华为新员工座谈会上讲话说到"经过我们这30年奋力追赶,我们与美国距 ...
- PE格式:导入表与IAT内存修正
本章教程中,使用的工具是上次制作的PE结构解析器,如果还不会使用请先看前一篇文章中对该工具的介绍,本章节内容主要复习导入表结构的基础知识点,并通过前面编写的一些小案例,实现对内存的转储与导入表的脱壳修 ...
- PE文件输入表获取过程
1. 首先给出这个PE文件的一些16进制代码 dos头的最后一个变量给出PE头的地址:000000E0,由于import table 的数据目录项相对PE头的偏移为80h,故输入表的数据目录项在文件中 ...
- 获得PE文件输入表和输出表
#include <windows.h> #include <iostream> #include<ImageHlp.h> #pragma comment(lib, ...
最新文章
- [转载] 七龙珠第一部——第110话 加油 孙悟空
- Django框架(十二)-- Djang与Ajax
- 一级计算机考试修改信息书面申请表,医院信息科修改数据库申请单.doc
- JVM Class 类加载机制(系列号3)
- iOS 开发之几个 Demo 分享网站
- no talloc stackframe at ../source3/param/loadparm.c:4864, leaking memory
- 计算电磁学MoM学习启动篇
- java实习报告_Java实习报告总结3篇
- python django面试题_django面试题(21道)
- 无线网的dhcp服务器是什么意思,DHCP是什么意思
- 【干货】Dialog的高冷用法
- 清默网络——我的CCIE考试经验与心得(2)
- Asp.net Core 自带DI依赖注入
- python3.7.3安装教程windows 10_WIN10系统如何完全卸载Python 3.7.0软件? | 我爱分享网...
- VK第三方登录(JavaScript SDK)
- 树莓派从零开始快速入门第8讲——单总线(以DS18B20为例)
- 计算机网络实验-验证性实验
- 基于FPGA音乐播放器硬件电路设计
- 【PX4 二次开发】QGC使用以及仿真姿态环联动
- 自动取片机EMC测试,电磁兼容EMC整改,YY0505预测测试报告