gpt4 book ai didi

windows - OllyDbg 中的地址在程序重新加载时发生变化

转载 作者:可可西里 更新时间:2023-11-01 09:57:53 34 4
gpt4 key购买 nike

这是我的第一篇文章,我是汇编和调试的新手,所以请多多包涵。

我试图将一些代码(对 MessageBoxA 的一点调用)注入(inject)到 Windows 7 记事本可执行文件中。但是,我遇到了地址问题。首先,我在 OllyDbg 中打开 exe,然后找到包含“notepad.pdb”的 ASCII 文本的行。然后我在下面放了一个 ASCII 字符串(例如,“INJECTED NOTEPAD”)。接下来,在其下方,我输入了这个 asm 代码:​​

PUSH 0
PUSH address_of_ASCII_string ; In this case, 00A6B668C
PUSH address_of_ASCII_string ; In this case, 00A6B668C
PUSH 0
CALL MessageBoxA

接下来,我转到程序中的第一行代码(只需右键单击并按 Go to Origin(或者只需按数字键盘上的 *))然后我用 JMP 指令替换第一行到地址我注入(inject)的代码中的第一个 PUSH 0。然后,我将替换的指令放在注入(inject)代码的末尾。之后,我将 JMP 指令放入跳转到注入(inject)代码的 JMP 指令之后的代码行(是的,我只是描述了一个代码洞穴或类似代码)。当我运行它时一切正常。但是,当我将修改后的代码保存到一个新的可执行文件中并再次使用 OllyDbg 运行它时,它不起作用。当我尝试引用我输入的 ASCII 字符串时,地址完全错误。示例如下图所示:

如您所见,我将字符串压入堆栈,但是当我再次将修改后的程序重新加载到调试器中时,字符串的地址发生了变化,但我的代码没有。因此,当我调用 MessageBoxA 函数时,它出错了,因为我为 Text 和 Caption 参数加载了错误的地址。我该如何解决这个问题?

最佳答案

您遇到的是 ASLR 的影响.简而言之,这意味着在操作系统(在此示例中为 Windows)上运行的可执行文件在多次执行时不会具有相同的基地址。

所以有几种方法可以将您的代码注入(inject)另一个二进制文件,我将在此处解决 2 并且我还会猜测(在阅读评论后)您正在尝试修补磁盘上的二进制文件。

  1. 修补磁盘上的二进制文件:

    一个。解决此问题的第一种方法是从 PE 中删除重定位表。 .我绝对不会推荐这种方式,因为如果它没有被加载到它喜欢的基地址(OptionalHeader.ImageBase),它可能会在未来崩溃可执行文件,这是默认的所有需要​​重定位的指令都将用作添加的基础一个偏移量。

    假设您在偏移量 0x600 处有一个字符串来自镜像库,如果可执行文件映射到其首选基地址(通常为 0x00400000 ),则字符串将保存在地址 0x00400000 中.您的编译器链接文件的方式将是地址 0x00400000 + 0x600所以0x00400600 .那么当可执行文件加载到不同的基地址时会发生什么?在这种情况下,Windows 可执行加载程序会将基地址的偏移量(实际上是映射减去首选基地址)添加到每个重定位条目(上面的示例将需要一个)。因此,万一可执行文件将被加载到 0x00500000加载程序将添加 0x00100000到导致绝对地址 0x00500600 的重定位条目.

    第二种方法是向二进制文件添加重定位条目。这样,与 (a) 中描述的方式相反,您不会损害二进制文件,只会添加一个重定位条目,在加载可执行文件时,加载程序会将地址更改为正确的地址(如果您添加了正确的地址)输入)。

    编写与位置无关的代码并使用此代码修补二进制文件。示例:

    sub     esp, 10*4
    mov byte [esp], 0x68 ; 'h'
    mov byte [esp + 1], 0x69 ; 'i'
    mov byte [esp + 2], 0x00 ; null byte
    mov byte [esp + 3], 0x79 ; 'y'
    mov byte [esp + 4], 0x6f ; 'o'
    mov byte [esp + 5], 0x75 ; 'u'
    mov byte [esp + 6], 0x00 ; null byte
    mov eax, esp
    push 0
    push eax
    add eax, 3
    push eax
    push 0
    call [MessageBoxA]

    此代码会将 2 个需要的字符串写入堆栈并将指针推送到堆栈上的字符串,这样代码不需要任何重定位,因为它是一段与位置无关的代码。

    <
  2. 修补内存中的二进制文件:

    一个。位置无关代码(见上)

    使用 VirtualAllocEx ,此 API 将在调用它之后返回一个您可以写入的地址,这样您只需在内存中拥有映射地址并且知道在何处以及如何注入(inject)您的代码。

关于windows - OllyDbg 中的地址在程序重新加载时发生变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41304436/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com