Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在windows中从程序集调用标准函数_Windows_Assembly - Fatal编程技术网

在windows中从程序集调用标准函数

在windows中从程序集调用标准函数,windows,assembly,Windows,Assembly,我在玩弄汇编和它在翻译后产生的实际字节(反正是在x86上),我发现自己在问: 在Linux中,当您想要调用say printf时,您将把参数和调用代码放在堆栈上,然后调用int 0x80。这是非常优雅的,并且将始终转换为相同的字节 但是在Windows上,我试着编译一个小程序,就像这样 #include <stdio.h> int main() { printf("abcdefgh"); return 0; } #包括 int main(){ printf(“abc

我在玩弄汇编和它在翻译后产生的实际字节(反正是在x86上),我发现自己在问:

在Linux中,当您想要调用say printf时,您将把参数和调用代码放在堆栈上,然后调用int 0x80。这是非常优雅的,并且将始终转换为相同的字节

但是在Windows上,我试着编译一个小程序,就像这样

#include <stdio.h>
int main() {
    printf("abcdefgh");
    return 0;
}
#包括
int main(){
printf(“abcdefgh”);
返回0;
}
然后把它拆开。这会产生类似于“call _printf”的东西,其中_printf代表类似于“jmp*0x406124”的东西和两个nop(即使使用静态链接!)

我假设跳转中的地址是printf库函数的动态加载地址,所以每次加载时可能会有所不同?还是我完全错了?那么,动态加载器如何仅仅从指令代码中知道程序想要调用什么函数(对于如此短的程序,这可能是一个近似的调用)?动态链接器是否自行更改指令代码


对于简单的系统调用来说,这似乎是一个非常麻烦的问题,但我知道Windows也可以使用int 0x80代码,只是函数代码经常更改(或者我听说是这样)。那么,在Windows上的指令中直接调用printf(或任何其他系统调用)最简单的方法是什么呢?

不,如果您想在linux上使用
printf
,您不需要执行
int 0x80
,因为这是一个系统调用,
printf
是一个库函数。此外,系统调用不在堆栈上使用参数。事实上,在linux上也是如此,你会得到一个
调用printf
,它将通过动态链接器填充的指针间接跳转。是的,在linux上,过程链接表中的指针(我认为这是正确的名称)开始指向一个例程,该例程在库中查找实际的符号地址。第一个调用首先通过符号查找函数,该函数更新跳转表,然后跳转到库中的实际函数。所以动态链接是惰性地完成的。尝试在asm中单步执行第一次呼叫和第二次呼叫。您描述的在Windows上看到的与Linux.Google中的“导入地址表”(IAT)相同。这是我的第一个结果: