Win32应用程序MOV到内存地址无法正常工作

时间:2016-12-18 08:18:16

标签: assembly exe ida

我正在玩一些测试应用程序来尝试修补其代码。

此处是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的异常。

1 个答案:

答案 0 :(得分:3)

在您正在修补的代码中,即

movzx   eax, byte ptr word_F3BB4A
and     eax, 2
jz      short loc_62300F

有两条引用内存的说明:movzxjz 在二者中只有后者与位置无关(它的目的地被编码为相对偏移量),前者使用绝对地址。
加载器根据链接器生成的元数据修复(重定位)绝对地址。这些元数据按指令地址工作。

例如,如果我们修补此程序

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                                     |

我们在哪里看到:

  1. 移动指令使用地址402000h,因此最终会在运行时失败。它没有像预期的那样重新安置。
  2. 当执行重新定位(现在不存在的)原始移动时,加载程序已更改nop代替原始移动。
  3. 如果要修补原始代码,使其在执行原始工作之前用零覆盖移动的位置,则替换

    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的结果如何为零。