修改已编译的可执行内存分配

时间:2011-07-31 18:27:45

标签: c++ windows memory-management compiled

我有一个编译后的可执行文件,无法访问源代码。每次运行时,变量都被分配给存储器地址0x7B008C。我试图让它每次使用不同的地址而不是那个地址。它不必是动态的,因为我的目的只是打破当前修改源程序行为的现有应用程序。

所以我的问题是,在不破坏程序行为的情况下实现这一目标的最简单方法是什么?

2 个答案:

答案 0 :(得分:4)

一般情况下,你不能。

编译可执行文件时,链接器在机器代码中将对静态变量的引用解析为变量的原始地址。没有任何迹象表明存在这样的引用,并且由于x86机器代码的性质,以后很难找到这些引用(你不一定能明确指出指令的位置)。

而且,你不知道那只是一个普通的变量。它可能是静态类或结构的一部分。这些区别在编译后会丢失,但是当尝试移动变量时,它会变得更加困难 - 可能是代码基于来自另一个变量的偏移量(即结构的开头)引用它。

你真的想在这里完成什么?可能有一种更好的方法,而不仅仅是搞乱虚拟内存布局。

如果您只是试图打破现有的培训师,一种方法(未经测试!)可能会改变进程ACL。在创建流程时,使用CreateProcess并传入lpProcessAttributeslpThreadAttributes的自定义安全描述符(对于已经运行的流程,您可以使用SetSecurityInfo执行此操作)。在安全描述符中设置DACL,以便仅授予SYNCHRONIZE | PROCESS_QUERY_INFORMATION | PROCESS_SUSPEND_RESUME | PROCESS_TERMINATE权限(即,撤销所有DACL条目的所有其他权限)。这种技术并非万无一失 - 训练师意识到你这样做可以简单地将DACL设置回默认状态;但是它应该通过拒绝调试访问来破坏现有的培训师。

答案 1 :(得分:0)

你可以通过使用BEAEngine完成整个可执行文件来完成它(我说可能因为我从来没有这样做过,以为我使用过BEAEngine并且它能够做到它),但它会非常复杂,可能非常复杂。

我不会浪费时间尝试这样做,因为,就像bdonlan一样,我不会关心在单人游戏中使用训练员的人。除了你所描述的,还有其他一些不太复杂的方法可以打破培训师。