PE导出表、重定位详解
来源:互联网 发布:csgom4a1皮肤知乎 编辑:程序博客网 时间:2024/05/17 06:47
此文档主要讲解导出表,重定位信息:
使用例子为: Windows.UI.Xaml.dll、010editor
1、导出表,重定位表的地址存放在哪里
DOS头-àPE头文件(_IMAGE_NT_HEADERS)-à扩展头(IMAGE_OPTIONAL_HEADER32)-à数据目录表
数据目录表中的内容:
structIMAGE_DATA_DIRECTORY Export (1)
……
StructIMAGE_DATA_DIRECTORY BaseRelocationTable (6)
Typedef struct IMAGE_DATA_DIRECTORY {
DWORDVirtualAddress ; //此处地址为在内存中的地址
DWORD size ;
}
如下图信息:
2、这里是VirtualAddress,如何转变成相对文件地址:
根据pe文件的区段表进行转换:
去段表的结构:
Typedefstruct _IMAGE_SECTION_HEADER{
BYTEName[0x8];
Union{
DWORDPhysicalAddress;
DWORDVirtualSize ;
}
DWORDVirualAddress ;
DWORDSzieOfRawData;
DWORDPointerToRawData;
DWORDPointerToRelocations;
DWORDPointerToLinenumbers;
WORDNumberOfRelocations;
WORDNumberOfLinenumbers;
DWORDCharacteristics;
}
查看需要转换的RVA在哪一个区段中。比如:VirualAddress (比如:此地址为第一个模块地址)<RVA <VirualAddres(第二个模块地址),那么RVA应该依据第一个模块进行转换:RVA-VirualAddress+PointerToRawData=offset(相对文件偏移)
1、 导出表地址指向一个数据结构,该结构为:
Typedef struct _IMAGE_EXPROT_DIRECTORY{
DWORD Characteristics; //0x0
DWORD TimeDataStamp; //0x4
WORD MajorVersion; //0x8
WORD MinorVersion; //0xA
DWORD Name; //0xC
DWORD Base; //0x10
DWORD NumberOfFuncions; //0x14
DWORD NumberOfName; //0x18
DWORD AddressOfFunctions; //0x1c 导出地址表
DWORD AddressOfName; //0x20 导出名称表
DWORD AddressOfNameOrdinals; //0x24 指向导出序列号数组
}
如何利用导出名称表中的名称找到函数导出的地址:
导出名称表与导出序列号数组是相互对应的,序号与导出地址表的数组索引对应。
从AddressOfName 找出你需要的函数名,从AddressOfNameOrdinals;中找出与之对应的序列号,根据序列号找到导出地址。比如:序列号为5,那么就找导出地址表中的第六个数据(导出地址表从0开始)。
实战:
根据PEID我们可以看到我们看到到处函数信息:(依据此信息验证手工寻找)
第一步:
第二步:
第三步:
计算offset: BC2D40-1000+400 = BC2140
第四部:
第五步:计算:
Offset‘s AddressOfFunctions: 00BC2D68-1000+400 = BC2168
Offset‘s AddressOfName:00BC2DA0-1000+400 = BC21A0
Offset‘s AddressOfNameOrdinals:00BC2DD8-1000+400 = BC21D8
第六步寻找createString RVA地址:
寻找字符串:
00BC2E08-1000+400 = BC2208
寻找Oridinal:
寻找0号索引地址:
地址:00864ac0
2、 重定位表的信息。
根据扩展表找到重定位表的RVA,通过段表将RVA转换成offset.
Offset指向的位置为一个数据结构:
typedef struct _IMAGE_BASE_RELOCATION{
DWORD VirtualAddress; //0x0 重定位页的起始地址
DWORD SizeOfBlock; //0x4 本结构+重定位数组
}
此数据结构之后是:
Struct {
WORD Offset:12; //重定位偏移
WORD Type:4; //重定位类型
}
Type == 0x3 (大部分重定位都是该值):重定位偏移指向的整个4字节大小的地址都需要修正。
如何计算重定位位置:
VirtualAddress +offset+ImageBase(PE结构中的数据)-ImageBase(实际装入的地址) = 需要重定位的RVA
下一步:
DWORD PTR [需要重定位的RVA] = DWORD PTR(需要重定位的RVA) -ImageBase(PE结构中的数据)+ImageBase(实际装入的地址)
循环多少次此分页重定位结束:
N = (SizeOfBlock-Sizeof(_IMAGE_BASE_RELOCATION))/sizeof(struct{WORD Offset:12,WORD Type:4})
N次之后,开启下一个分页的重定位信息。
实战:
第一步:
第二步:
第三步计算:
BFA000-BFA000+BF5000 = BF5000
第四步:
VirtualAddress = 00001000;
SizeOfBlock = 00000808
重定位的个数:
N = (00000808-8)/2 =0x400;
第五步:
00 30 的意思是:
imagebase+重定位00001000+0地址处的四个字节。
Windows.UI.Xaml加载基址默认为10000000,第一个需要重定位的数据为:10B377A0.
我们手动改变dll的加载基址,变成707A0000.需要重定位的位置为:707A0000+1000.
原来数据为:10B377A0,重定位后的数据:
10B377A0-10000000+707A0000 = 712D77A0
- PE导出表、重定位详解
- PE重定位表
- PE--重定位表
- PE详解之 基址重定位
- PE文件结构详解--重定位
- PE文件结构详解--PE导出表
- PE总结 – 重定位表
- PE重定位表学习笔记
- PE文件重定位
- PE加载重定位
- PE格式详解9 基址重定位详解
- PE结构导出表详解
- 小甲鱼PE详解之基址重定位详解(PE详解10)
- 小甲鱼PE详解之基址重定位详解(PE详解10)
- 小甲鱼PE详解之基址重定位详解(PE详解10)
- 小甲鱼PE详解之基址重定位详解(PE详解10)
- 小甲鱼PE详解之基址重定位详解(PE详解10)
- 小甲鱼PE详解之基址重定位详解(PE详解10)
- CentOS修改mysql 用户root的密码并允许远程登录
- 深入解读Spring Framework事务管理(第五弹:同时执行事务通知和自定义的分析通知)
- 简易动态进度条实现
- iOS开发怎么获取本地数据和把数据存储到本地
- 开始用FairyGUI和KBEngine重写uMMORPG
- PE导出表、重定位详解
- android获取json数据异常
- 【english】New Year message
- 【Hibernate】——使用连接表的单向关联映射
- cppcheck的简单介绍
- [实用代码片段] web分页之 智能10页
- 2016年终总结
- Centos6.4下Yum命令安装Mysql数据库及配置
- CSS学习笔记:选择器