我正在寻找一种简单的方法来查找以内存结尾的函数。我正在开发一个项目,可以在其他代码中找到运行时问题,例如:代码注入,病毒等等。我的程序将使用将在运行时检查的代码运行,以便我可以访问内存。我无法访问源代码本身。我想只检查它的具体功能。我需要知道函数在堆栈中的起始和结束位置。我正在使用Windows 8.1 64位。
答案 0 :(得分:8)
一般情况下,你无法找到函数在内存中的结束位置,因为编译器可以有optimized,inlined,克隆或删除该函数,将它分成不同的部分等等。可能是某些system call主要在内核中实现,或者某些功能在外部shared library("在您的程序的外部" executable)...对于C11标准(参见n1570)的观点,您的问题毫无意义。该标准定义了语言的semantics,即生成程序行为的属性。另见this答案中的解释。
在某些计算机(Harvard architecture)上,代码将保留在不同的内存中,因此无需询问该函数的开始或结束位置。
如果您将问题限制为特定的C 实施(具有特定优化设置的特定compiler,则针对特定的operating system和instruction set architecture以及ABI)你可能(在一些情况下,而不是在所有情况下)能够找到函数的结尾" (但这不会很简单,并且不会失败)。例如,您可以对编译器生成的汇编代码和/或object file进行后处理,检查ELF可执行文件及其符号表,检查DWARF调试信息等。
你的问题很像一些XY problem,所以你应该激励它,而不是更多的解释和背景。
我需要知道函数在堆栈中的起始和结束位置。
函数不会位于堆栈中,但主要位于可执行文件(或库)的code segment中。 call stack上的内容是一系列调用帧。呼叫帧的组织特定于您的ABI。一些编译器options(例如-fomit-frame-pointer
)将难以探索调用堆栈(无需访问源代码和编译器的帮助)。
我无法访问源代码本身。我想只检查它的具体功能。
你的问题仍然是不明确的,可能是undecidable,比你所认为的要复杂得多(因为与halting problem有关),并且有相关的大量文献(阅读{{ 3}},decompiler,static code analysis& anti-virus)。我建议花几个月或几年时间学习更多关于编译器的知识(从malware analysis开始),Dragon Book,指令集架构,ABI。然后查看与ACM相关的几个会议记录linkers等。在实践方面,研究编译器生成的汇编代码(例如,使用SIGPLAN和gcc -O2 -S -fverbose-asm
....); CppCon 2017演讲:Matt Godbolt GCC是一个很好的介绍。
我正在开发一个项目,该项目会在其他代码中发现运行时问题,例如:代码注入,病毒等等。
我希望你能为你雄心勃勃的项目投入数年的全职工作。它可能比您想象的要困难得多,因为优化编译器“What Has My Compiler Done for Me Lately? Unbolting the Compiler's Lid”比您认为的要好(much more complex软件使用各种复杂的技巧来隐藏自己的检查)。 malware真的很难,但有趣。