获取特定值的正确内存地址

逆向工程 ollydbg C++
2021-06-25 08:04:25

我在看这一系列视频时,我注意到他每次重新启动游戏和/或 olly 时,他的内存地址都没有改变。此外,他的评论似乎一直存在,他能够轻松找到他以前工作过的地方。https://www.youtube.com/watch?v=BHYjxsDROn4&t=8s

我还试图获取特定的内存地址并编写一个基本程序,该程序允许我通过从外部写入它们来更改它们,但是每次我尝试这样做时,内存地址都会发生变化。我意识到记忆是动态的,这应该发生,但我不明白为什么它没有发生在他身上。仅仅是因为它是一个较旧的视频,这就是它过去的工作方式,还是我遗漏了什么。此外,现在为了做到这一点,我假设我需要以某种方式从基地址获取偏移量。我观看的每个关于这样做的视频都是指找到指针的偏移量。只有指针保持静态偏移量吗?如果是这样,我如何在 ollydbg 中找到它?

2个回答

您的帖子包含多个问题,我建议将它们分开,并向它们提供更多详细信息。由于这个原因,我的回答将是模糊的。

关于不变的内存地址,我假设您正在寻找的是ASLR阅读这个这个主题。据我所知,您可以使用EMET或直接修补可执行文件来禁用 ASLR,因此地址不会改变。

或者,您可以使用其他技术来查找您的地址,即使地址发生变化。

至于偏移量,它们通常被添加到一个静态地址,以访问对象字段/属性。具体的地址和偏移量显然取决于您要做什么,并且应该通过在调试器中观察它从您的可执行文件中获取。

例如:

  • 让我们假设您发现游戏player在内存中有一个对象(位置可能会在每次运行时改变)。

  • 比方说,你找到了一个静态指针的实例player名为“pPlayer”的对象,在这个内存地址:0xAB1234

  • 还可以说您知道(因为您对对象结构进行了逆向工程)player对象有一个字段,其中包含游戏中角色的健康点数,以整数形式存储在0x16偏移量处。

  • 通过将找到的偏移量与player对象地址(对象的基地址)相加,您将获得包含角色当前 HP 的内存地址。你可以在你的程序或作弊引擎中像这样从外部读取它:[[0xAB1234]+0x16]在伪代码中,这意味着:

    AddressOfPlayerObject = memory.Read(0xAB1234)

    AddressOfHP = AddressOfPlayerObject + 0x16

    PlayerHP = memory.Read(AddressOfHP)

在那种情况下他的内存地址没有改变的原因是因为游戏是 32 位的,并且按照这个这个按惯例加载到内存中(对 0x400000 执行 CTRL + F 并阅读前 2 个结果所在的段落)。

您可能还会看到由符号名称引用的地址,例如 ac_client.exe+5B2C0,其中 ac_client.exe 引用的基址为 0x400000 加上偏移量 0x5B2C0。

至于您要在 C++ 中完成的工作,您可以使用 Windows 函数来识别进程,然后获取其基址。然后你可以以此为基础进行偏移。如果每次开始游戏时您的地址都在更改,那么正如 Dominik 建议的那样,ASLR 可能就是您要处理的问题。或者像 Denuvo 这样的反作弊/混淆实现。或者使用 JVM 之类的东西的游戏,它可以在每次重新启动时更改地址子程序指令。

您的选择通常是引用符号名称、找到要引用的基地址 + 偏移量,或识别可以扫描的字节签名(又名“字节数组”)——然后您获取一个地址以在 和本身,或作为偏移量的基准点。

所有这些内容还有很多,但我强烈建议您阅读游戏黑客一书对于您想要做的事情,它将为您提供相当多的智慧,否则您将花费​​数小时数小时试图通过帖子和视频拼凑起来。它还提供了获取正在运行的进程的 PID 等所需的代码片段。