我正在玩一些测试应用程序来尝试修补其代码。
此处是IDA pro的原始代码
movzx eax, byte ptr word_F3BB4A
and eax, 2
jz short loc_62300F
这是我的补丁
push ax
xor ax, ax
mov byte ptr word_F3BB4A, al
nop
pop ax
jmp short loc_62300F
问题是启动应用程序后,我的代码中的地址不会改变基础。我正在获取访问F3BB4A的异常。
答案 0 :(得分:3)
在您正在修补的代码中,即
movzx eax, byte ptr word_F3BB4A
and eax, 2
jz short loc_62300F
有两条引用内存的说明:movzx
和jz
在二者中只有后者与位置无关(它的目的地被编码为相对偏移量),前者使用绝对地址。
加载器根据链接器生成的元数据修复(重定位)绝对地址。这些元数据按指令地址工作。
例如,如果我们修补此程序
012C1000 | A1 00 20 2C 01 | mov eax,dword ptr ds:[12C2000] |
012C1005 | 90 | nop |
012C1006 | 90 | nop |
012C1007 | 90 | nop |
012C1008 | 90 | nop |
012C1009 | 90 | nop |
012C100A | 90 | nop |
012C100B | 90 | nop |
012C100C | 90 | nop |
012C100D | 90 | nop |
012C100E | C3 | ret |
将移动向下移动8个字节(这是我使用的所有nop
的原因)并再次执行我们的可执行文件:
010C1000 | 90 | nop |
010C1001 | 90 | nop |
010C1002 | 90 | nop |
010C1003 | 5C | pop esp |
010C1004 | 91 | xchg eax,ecx |
010C1005 | 90 | nop |
010C1006 | 90 | nop |
010C1007 | 90 | nop |
010C1008 | A1 00 20 40 00 | mov eax,dword ptr ds:[402000] |
010C100D | 90 | nop |
010C100E | C3 | ret |
我们在哪里看到:
nop
代替原始移动。如果要修补原始代码,使其在执行原始工作之前用零覆盖移动的位置,则替换
0F B6 05 XX XX XX XX | movzx eax,byte ptr ds:[XXXXXXXXh]
83 E0 02 | and eax,2
与
90 | nop
C6 05 XX XX XX XX 00 | mov byte ptr ds:[XXXXXXXXh], 0
31 C0 | xor eax,eax
请注意两个动作的主要内容如何具有相同的地址,结尾eax
的结果如何为零。