我第一次在StackOverflow问题“C# Theoretical: Write a JMP to a codecave in asm”中遇到过这个词。我看到根据Wiktionary,代码洞穴是:
一个未使用的内存块,有人,通常是软件破解程序,可以用来注入 自定义编程代码,用于修改程序的行为。
我找到了正确的定义吗?如果是这样,代码洞穴是否有合法用途?
答案 0 :(得分:17)
有人可能希望故意创建代码洞穴作为使用self-modifying code的一部分。
当然,假设一个人疯了。
答案 1 :(得分:13)
代码洞穴通常由alignment的编译器创建,并且通常位于函数之间。结构和跳转之间也应该有代码洞穴(在某些架构中),但通常没有任何大量的代码洞穴。
您也可以搜索一个归零内存块,但不能保证程序不会使用它们。
我认为理论上,如果您丢失了源代码,可以使用它们修补您的错误程序,并且您的程序不会增大。
修改强>
对于那些建议代码洞穴仅适用于运行时生成的代码的人:这是一个不完整的定义。很多时候我在“代码洞穴”中编写了一个数据结构,并更新了指向那里的指针,我怀疑我不是唯一这样做的人。
答案 2 :(得分:11)
我已经使用过它们,虽然直到今天我都没有听过代码洞穴这个词。维基词典定义表明,代码洞穴是破解者在他或她试图破解的可执行文件中发现的东西。你引用的问题不是那样使用它。相反,它建议使用VirtualAllocEx
分配代码洞穴,以在目标进程中创建一个全新的内存块。这样就无需在目标中搜索未使用的空间,并且它可以保证您有足够的空间放置所有新代码。
最终,我认为“代码洞穴”只是存储运行时生成代码的地方。该代码不必有任何邪恶的目的。在这一点上,代码洞穴的问题变得完全无趣。有趣的部分是在运行时生成代码的原因,以及确保新代码在您需要时运行的技术。
答案 3 :(得分:8)
一些合法用途:在没有重启的情况下修补实时操作系统二进制文件(MS执行此操作),为防火墙和防病毒程序挂钩低级操作系统功能(文件系统,网络),在不执行此操作时扩展应用程序有源代码(比如刮取低级操作系统调用DrawText,这样你就可以为盲人大声朗读)
答案 4 :(得分:6)
它描述的方式here让我想起了patchpoints - 合法使用。
答案 5 :(得分:4)
不熟悉术语,但热补丁机制可以使用保留空间来存储代码补丁。您挂钩有缺陷的功能并将其重定向到新改进的功能。它可以在不关键设备(大型电信交换机)的情况下即时完成。
答案 6 :(得分:3)
它可以用于在运行时注入代码。它可用于在静态语言中编写自修改代码,假设操作系统允许您(NX位未设置等)。有它的用途,但它不是你应该在典型的商业应用程序中考虑的事情。
答案 7 :(得分:3)
这对我来说听起来是正确的定义。
至于合法使用,请允许我这样说:除非你只是为了试验而尝试,并且愿意接受后果,否则不要这样做。
这种类型的东西不应该永远进入生产代码:
答案 8 :(得分:2)
自修改代码不应该被认为是轻微的,但有时可以带来很大的性能提升。如果你已经编程了很长时间,你可能在没有意识到的情况下使用它。
在广泛使用486及更高版本之前,许多PC都没有包含硬件浮动支持。这使得人们编写涉及浮点的程序陷入两难境地。如果他们编译程序以使用内联浮点指令,它将在具有浮点处理器的机器上快速运行,而在没有浮点处理器的机器上则不会。如果他们使用软件浮点仿真编译程序,它将在所有机器上运行,但在具有硬件浮点的机器上也会慢慢运行。
许多编译器库使用了一个有趣的技巧和自修改代码。默认行为是将陷阱指令放在需要浮点运算的位置。陷阱处理程序将模拟软件中的指令,或者如果检测到它在具有浮点硬件的机器上运行,它将通过用适当的硬件浮点指令替换陷阱指令来修改代码并执行它。结果是在所有机器上运行的软件,并且在具有浮点硬件的机器上运行几乎同样快,就好像代码已被编译为直接使用浮点硬件一样(因为大多数浮点密集型操作发生在多次执行的循环中) )。