-
-
WindowsPE文件格式入门09.RadAsm的bug和重定位表
-
发表于: 2025-5-1 13:36 3533
-
RadAsm的bug
创建程序
1、创建程序1:C++工程:
●项目选项:控制台"hello,World"程序,不使用预编译头
2、创建程序2:汇编工程:
●radasm工程选项:控制台
●将程序1中的obj拷贝至本工程中并添加至工程连接选项,用程序2调用程序1中的TestFunc函数
获取并解决BUG
1.非预期BUG:提示缺少lib,"LIBCD.LIB"、"OLDNAMES.lib"。
●解决办法:从VC库中获取并拷贝过来。
2.预期BUG1:LIBCD.lib BUG:LNK2001:无法处理的外部符号 _main。
●原因:虽然汇编当中未使用此库,但是在C++程序中使用到了C库PI"printf"。而程序2汇编没有main函数,所以就会在连接时报预期BUG。
●解决方案:增加"main",即把汇编程序的入口标号替换为main。
●效果:报错消失,但程序依然报其他错误。
3.预期BUG2:指定函数未定义
●BUG探究:查找GetEnvironmentStrings函数定义(kernel32.lib),将lib包含后仍出现指定BUG。
●BUG再探究:从kernel32.lib中查询报错API,发现对应接口不分A/W,而是将GetEnvironmentStrings作为定义,GetEnvironmentStringA作为宏,违反了我们过往对于微软命名风格的认知习惯。所以造成了预期bug2。
●解决方案
○(1)手动修改radasm的kernel32.inc文件;
此时点击否就可以
F9
F8 入口点
解决办法:使用x32dbg重建导入表。
可以看到代码被改了
一般32位程序在32位系统中修复
inc2l.exe里面编译和链接用的绝对路径,换成相对路径就可以了,还有改字符串对应长度
修改编译选项
修改链接选项
定义:记录需要绝对地址修正的表,大多数绝对地址如果imagebase变化的话就无法使用,需要修正程序所调用的那些绝对地址。
我们现在都是玩固定基址的PE,随机基址涉及到要修代码,如果有重定位信息,就可以在内存中随便申请一块内存,把代码放进去跑。
我们知道随机基址需要重定位表来修代码, 那么是修什么代码呢。
实际上我们修的是使用绝对地址的代码,例如API的调用,通过IAT调用,这里就是使用的绝对地址,当模块基址改变时,原VA地址并没有保存API函数地址,所以就需要修正到正确的位置去获取API地址。
假设以下 RVA 地址需要进行修正,最简单的方法是把下面的地址都记录下来,加载的时候直接去修正
00001023
00001028
00001128
00001228
00001328
00001428
但是直接保存所有地址,那么数组的体积就会变得很大,那么如何减少体积呢
可以按照 分页地址 +分页偏移 的方式记录,因为分页偏移只需要 2个字节就可以了
00001000 分页基址
0000014 总大小
0023 分页偏移
0028
0128
0228
0328
0428
IMAGE_BASE_RELOCATION
1F000 对应文件偏移 9200
所有分页的数据大小合计就是 3B0 跟 结构体里面的总大小一致
便宜的最高位是 3 表示需要被重定位 , 0表示不需要,代表要对齐