修改已编译的可执行文件的内存分配
我有一个已编译的可执行文件,无法访问源代码。每次运行时都会将变量分配给内存地址0x7B008C。我试图让它每次使用不同的地址而不是那个地址。它不必是动态的,因为我的目的只是破坏当前存在的修改源程序行为的应用程序。
所以我的问题是,在不破坏程序行为的情况下实现这一目标的最简单方法是什么?
I have a compiled executable with no access to the source code. Every time it runs a variable is assigned to memory address 0x7B008C. I am trying to make it use a different address rather than that one each time. It does not have to be dynamic because my purpose is only to break currently existing applications that modify the behavior of the source program.
So my question is, what is the easiest way to achieve this without breaking the behavior of the program?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
一般来说,你不能。
编译可执行文件时,链接器在机器代码中将对静态变量的引用解析为变量的原始地址。没有留下任何表明存在此类引用的迹象,并且由于 x86 机器代码的性质,以后很难找到这些引用(您不一定能够明确地告诉指令从哪里开始)。
而且,你不知道这是否只是一个普通变量。它可能是静态类或结构的一部分。这些区别在编译后就会丢失,但是当尝试移动变量时,它会变得更加困难 - 代码可能是根据另一个变量的偏移量(即结构的开头)来引用它的。
你真正想在这里完成什么?可能有比仅仅搞乱虚拟内存布局更好的方法。
如果您只是想打破现有的训练器,一种方法(未经测试!)可能是更改进程 ACL。创建进程时,请使用
CreateProcess< /code>
并传入
权限(即撤销所有 DACL 条目的所有其他权限)。此技术并非万无一失 - 培训师知道您正在这样做,只需将 DACL 设置回默认值即可;然而,它应该通过拒绝现有培训师的调试访问来破坏他们。lpProcessAttributes
和lpThreadAttributes
的自定义安全描述符(对于已经运行的进程,您可以使用SetSecurityInfo
) 。在安全描述符中设置 DACL,以便仅同步 | PROCESS_QUERY_INFORMATION | 进程查询信息PROCESS_SUSPEND_RESUME | 进程暂停授予 PROCESS_TERMINATEIn general, you can't.
When executables are compiled, references to static variables are resolved by the linker, in the machine code, to the raw address of the variable. No indication that such a reference existed is left, and due to the nature of x86 machine code, it is very difficult to find these references later (you can't necessarily tell where instructions begin unambiguously).
Moreover, you don't know if that's just an ordinary variable. It might be part of a static class or structure. These distinctions are lost after compilation, but when trying to move variables, it makes it that much more difficult - it could be that code is referencing it based on an offset from another variable (ie, the start of the struct).
What are you really trying to accomplish here? There may be a better way than just messing with virtual memory layouts.
If you're just trying to break existing trainers, one approach (untested!) might be to alter the process ACL. When creating the process, use
CreateProcess
and pass in a custom security descriptor forlpProcessAttributes
andlpThreadAttributes
(for a process that's already running, you can do this withSetSecurityInfo
). Set the DACL in the security descriptor so that onlySYNCHRONIZE | PROCESS_QUERY_INFORMATION | PROCESS_SUSPEND_RESUME | PROCESS_TERMINATE
rights are granted (ie, revoke all other rights on all DACL entries). This technique is not foolproof - a trainer aware you're doing this can simply set the DACL back to default; however it should break existing trainers, by denying them debug access.您可能可以通过使用 BEAEngine 浏览整个可执行文件来完成此操作(我说可能因为我从来没有这样做过,以为我使用过 BEAEngine 并且它能够做到这一点),但它会非常复杂并且可能非常复杂。
不过,我不会浪费时间尝试这样做,因为,像 bdonlan 一样,我不会关心人们在单人游戏中使用训练器。还有其他比您所描述的更简单的破坏训练器的方法。
You could probably do it by going through the entire executable with BEAEngine (I say probably because I've never done it, thought I've used BEAEngine and it's capable of doing it), but it would be very involved and probably pretty complicated.
I wouldn't waste my time trying to do it though, because, like bdonlan, I wouldn't care about people using trainers on a single player game. And there are other, less complex ways of breaking trainers than what you describe.