Winapi 如何命名w32-g++;编译器知道在WIN32机器可执行文件中插入系统调用的位置吗?

Winapi 如何命名w32-g++;编译器知道在WIN32机器可执行文件中插入系统调用的位置吗?,winapi,assembly,mingw,portable-executable,ida,Winapi,Assembly,Mingw,Portable Executable,Ida,今天,仅出于测试目的,我想到了以下想法:在代码块中创建和编译一个简单的源代码,使用Release target删除不必要的调试代码,这是一个包含三个nop操作的主函数,只为了更快地找到主函数的入口点 代码块示例原始程序: 使用IDA反汇编程序,我看到了一些奇怪的事情,操作系统实际上可以在主函数中添加传统的机器代码调用(隐式添加),这是对系统函数的调用,该函数位于kernel32.dll中,用于操作系统线程处理 IDA计划视图: 在仅出于测试原因的机器代码中,三个“nop”(90)被替换为“和

今天,仅出于测试目的,我想到了以下想法:在代码块中创建和编译一个简单的源代码,使用Release target删除不必要的调试代码,这是一个包含三个nop操作的主函数,只为了更快地找到主函数的入口点

代码块示例原始程序:

使用IDA反汇编程序,我看到了一些奇怪的事情,操作系统实际上可以在主函数中添加传统的机器代码调用(隐式添加),这是对系统函数的调用,该函数位于kernel32.dll中,用于操作系统线程处理

IDA计划视图:

在仅出于测试原因的机器代码中,三个“nop”(90)被替换为“和esp,0FFFFF0H”,程序被重新打包,这就是为什么“无操作”操作码在视图中不可显示的原因

观察到的行为:

为每个打开的进程创建一个新线程是合乎逻辑的,因为我们可以在TaskManager中对其进行探索,TaskManager是一个在自己的线程中运行的进程,这就是编译器添加此代码(隐式默认线程)的原因

我的问题:

编译器如何知道自动“注入”此调用代码的位置

为什么以前不在将路由到主函数入口点的上层函数(sub_401B8C)中进行此调用

如果没有init节可用,则在GCC编译任何调用的函数时 main(或更准确地说,指定为程序条目的任何函数 点由语言前端调用expand_main_函数),它 插入对_umain的过程调用,作为之后的第一个可执行代码 函数序言。libgcc2.c和 运行全局构造函数


大概它只添加到
main
。调用函数是C运行时的一部分,在编译过程中不会生成。而且它不是操作系统添加的,它可能是在机器代码生成阶段之前添加的。事实上,您可以在
gcc-S
输出中看到它已经作为
call\uuuuu main
(一个不吉利的命名选择)PS:请不要将代码作为图像发布。因为您所有的代码示例都作为图像发布,所以被否决。请不要那样做!你的陈述不连贯。在您的问题中,您声称操作系统能够以某种方式注入代码,但在您解释的示例中,调用是由编译器或链接器插入的。事实上,你甚至没有提供那么多细节。该结构无助于澄清任何问题。您已经确定“[i]在磁盘上的文件中不存在”。这几乎排除了操作系统以任何方式参与进来。如果代码出现在磁盘上的PE映像中,则是编译器或链接器生成了该代码。我不明白,您对什么感到困惑,或者“两种变体”是什么。代码是在编译时添加的,当生成的代码用于托管环境(而不是独立环境)时,它是名为
main
的函数的专用代码。
和esp,0fffff0h
是在GCC生成的代码所需的16字节边界上对齐堆栈,正如Jester在其回答中指出的,调用是调用全局构造函数的GCC运行时代码(库)。除了
main
“它将插入对_umain的过程调用作为第一个可执行代码”之外,您将找不到编译器为函数生成的额外代码,非常感谢!线程的工作发生在start()过程中。