2011-06-18 46 views
1

我目前正在将其中一个游戏培训师作为一个小型项目。我已经遇到了一个问题;当你“进入一个不同的层次”时,诸如燃料,现金,子弹,地址等地址会改变。如果您要重新启动应用程序,也会发生这种情况。进程间内存编辑 - 查找已更改的地址

如何重新定位这些地址?

我觉得这是一个相当基本的问题,但它是其中一个“它是或不是”可能的问题给我。我应该停止观察并完全忘记这个概念吗? “太难?”

+0

您如何在第一个实例中找到它们? –

+0

“重新定位地址”是什么意思? – foxy

+0

您可以从其他人那里找到地址(有点难度,因为这是动态的..),或者您在内存中搜索该值。你的钱是50,000?认为这是一个无符号的int?在内存中搜索50000,然后找到合适的一个。通过重新定位它们,我正在谈论地址更改。指向钱的指针会改变每个级别,并且每次启动程序时它都会改变。 –

回答

1

要描述如何做到这一点有点难,因为它严重依赖于你正在学习的程序,以及作者是否会让自己的生活变得艰难。请注意,我只做过一次,但即使我只知道一个小程序集,它的工作也相当好。

可能发生的情况是,通过调用malloc/new将值分配在堆上,每次更改级别时,都会清理并重新分配给别处。所以我们的想法是查看程序的汇编代码以找到malloc返回的指针的存储位置,并找出一种方法可靠地读取指针的内容并找到要查找的值。

你要做的第一件事就是像OllyDbg这样的调试器和一个装配的基本知识。之后,首先在要检查的变量上设置读取和写入断点。既然你说过你不能确切地知道变量的位置,你将不得不暂停进程,并在程序的内存中搜索该值。希望你最终只能得到几个筛选结果,但对堆栈中的任何东西都有疑问,因为它可能只是函数调用或本地使用的副本。

一旦设置了断点,只需运行该程序,直到发生断点。现在你所要做的就是查看代码并检查变量是如何被访问的。如果它作为参数传递,请检查函数的调用位置。如果通过指针访问它,记下它并开始检查指针。如果将它作为指针的偏移量进行访问,这意味着它是数据结构的一部分,因此请记下它并开始检查其他变量。等等。

把注意力集中在你的变量,只是保持在检查代码,直到你最终会发现它可以是两件事情之一根:

  • 具有静态地址的全局变量。这是最简单的情况,因为您有一个静态地址直接写入代码,您可以使用它来可靠地遍历数据结构。

  • 堆栈分配变量。这很棘手,我不完全确定如何可靠地处理这种情况。大多数情况下,它的地址可能与栈的开始位置有相同的偏移量,但可能不会。你也可以通过走栈来找到相应的函数及其参数,但这样做有点棘手。

一旦你有一个地址,所有剩下要做的就是使用ReadProcessMemory使用您找到的信息来查找您的变量。例如,如果您拥有的地址代表一个指向数据结构的指针,该数据结构的偏移量为0x40,则您的燃料值将被存储,然后您必须读取该地址处的值,向其中添加0x40,然后再对结果进行读取。

请注意,只要可执行文件不以任何方式更改,地址就是有效的。如果它重新编译或修补,那么你必须重新开始。我相信你还必须小心Windows的'ASLR这可能会改变你每次启动程序时的地址。


评论框太小,不适合这个,所以我会把它放在这里。

如果它是esp加上一个常量,那么我相信这是一个参数而不是局部变量(通过检查调用约定的布局来确认)。如果是这样的话,那么你应该继续执行程序,直到它返回给调用者,确定如何设置参数(在调用指令之前查找推送指令)并继续从那里进行探索。当我这样做时,我不得不在放置一次或两次堆栈之前找到指向数据结构的全局指针。

此外,esi寄存器与堆栈无关(我必须look it up),所以我会检查它是如何设置的。它可能是它包含数据结构的地址,常量是变量的偏移量。如果你知道寄存器是如何设置的,你会更接近指针。

+0

嘿,我做了一些更多的研究,不幸的是堆栈分配。根本没有**静态指针。 (并没有指针指针) - 是的;我之前也做过,但没有使用堆栈分配的变量。我知道,钱是[esi + a30](a30是**静态**),所以我知道指向我想编辑的内容 - 但不能要求用户将地址提取出来他们的屁股。我也对内存做了一些讨论,看来这个函数只占用堆栈的4个字节(mov eax,[esp + 04])。这就是我所知道的。 –

+0

@Saustin微小的评论框不会允许我回复,所以我更新了答案。希望这会有所帮助。 –

+0

感谢您的回复。如果有线程和什么不是,调试游戏决不是件容易的事,但我会尽我所能。感谢您的回应,我会继续研究。 –