通常,当我在反转游戏后编写游戏黑客可执行文件时,会进行代码探查以找到可以在需要的地方注入代码的地方。好吧,在从其他人撤消了一些此类可执行文件的同时,我注意到他们选择始终将其代码注入Game.exe + 100。这让我想知道开始这样做并称其完成是否更容易。老实说,目前我的大脑在游动,试图将我的头缠在我已经搜索过的资源上。将PE映射到内存后,是否存在从文档库记录下来的和/或众所周知的偏移,几乎总是可以安全地对其进行覆盖/写入?如果是这样,它们可能是哪个偏移量?从那里,我将了解这些部分分别代表什么,以及每个偏移量可以使用多少个字节。将我指向正确的图表或详细说明特定偏移量的信息。我现在不知所措,对我所看到的一切感到困惑(例如看到相同的偏移量编号用于各个部分等)。谢谢!

#1 楼

在PE文件中,节通常映射到4kb倍数的地址(这是默认值,尽管可以覆盖)。这意味着即使是单个物理字节长的部分也将为其分配全部4kb的内存。第一部分映射到文件头之后的内存中,因此它将与文件头相距4kb。既然绑定导入表已被弃用,很少有文件头需要使用那么多空间,因此有很多可用空间。 0x100是一个不错的整数,超出了记录的标准标头大小,这就是使用它的原因。

评论


非常棒的解释。为了确保我理解正确,在进入任何其他部分之前,我实际上要使用0x100至0x1000的范围,对吗?最后,我假设我需要通过VirtualProtectEx()使该区域的RWX成为内存。我可以尝试一下,但是只是为了将它扔给以后可能在此线程上发生的任何人。

–dsasmblr
18年8月13日在17:51

是的,在一般情况下,您可以使用0x0100至0x0FFF;是的,在一般情况下,您需要VirtualProtectEx()使标头可写。

–彼得·弗里
18年8月27日在21:16

#2 楼

简短答案:因为您的普通程序将永远不会访问这些值。

长答案:彼得·费里(Peter Ferrie)的答案指出,在该偏移量处通常不存在任何东西。那是不对的。 Portable Executable的最短有效报头长度为0xc8。但这是针对具有单个节的程序,没有导入(或任何其他需要数据目录的东西),没有DOS存根和没有Rich标头(在不修补链接程序的情况下Visual Studio不可能的)。带有导入和两个部分的实际(但仍主要是学术性)程序的最短标头至少为0x160长。添加默认的DOS存根,您位于0x1a0。添加Rich Header,通常为另一个0x30-0x80字节。实际上,您很少会看到标头适合前512个字节的PE。因此,在0x100,您将覆盖数据,但是,一旦加载程序将映像加载到内存中,操作系统就不再使用该数据,因此只要程序也不使用该数据(例如加载资源),会没事的。

可能值得注意的是0x40之后的所有偏移量都是可变的,因此如果不先检查目标二进制文件,您甚至都不知道在0x100处要覆盖什么。由于无论如何都要调用VirtualProtectEx(无论是使数据段可执行还是使代码段可写),因此您最好调用VirtualAllocEx,而不必费心寻找代码陷阱。如果我不得不猜测为什么另一个人总是注入0x100,那是因为那是因为他是从一个已知地址运行的(除非启用了ASLR并且目标二进制文件是可重定位的),所以他不必重新定位注入/使其位置独立之前的代码。这是懒惰,草率和不安全的。