从汇编角度理解Windows API的调用过程

基础介绍

我们在进行Windows编程的时候,经常会调用Windows API。在 Windows 程序中,调用 Windows 函数与调用 C 语言的库函数没有什么两样。
最主要的区别就是 C 语言库函数的机器代码会直接链接到你的程序代码中去,而 Windows 函数则是放到你的程序之外的 DLL 里。

每个 Windows 的 EXE 文件包含它所要用到的各个动态链接库以及库中的函数的引用地址。

当一个 Windows 程序被装入内存后,程序中的函数调用都被解析 DLL 函数入口的指针,同时这些被调用的函数也被装入内存。

当链接 Windows 程序以生存可执行文件时,一定得链接你的编程环境所提供的特殊的“导入库”。

用户态和内核态

我们知道Win32API的调用,都是从用户态到内核态的,也就是函数真正的实现在内核。
这里借图,不详细解释了。
在这里插入图片描述

从汇编角度看Windows API调用

以MessageBox为例:
MessageBox是一个比较常见的Windows API函数,从user32.dll中导出。

1.在程序里调用MessageBox。首先进行的操作就是压参,然后会call MessageBox,但这里我们可以看到call 的是一个地址,机器指令是FF 15,后面跟的是绝对地址(调用时后面直接跟的是函数地址,并且不需要主调函数来平衡堆栈)。
在这里插入图片描述
这个地址里的地址就是MessageBoxA的地址。
在这里插入图片描述
我们写个程序测试,也确实没毛病。
在这里插入图片描述
2.进入到函数地址,发现还是在压参和调用函数。
在这里插入图片描述
因为MessageBoxA在里面又调用了MessageBoxExA()。在这里插入图片描述
接下来的话,也是一些函数对参数的传递和处理。
MessageBoxExA()调用MessageBoxIndirectA(),也发现MessageBoxIndirectA是靠MessageBoxIndirectW实现的
在这里插入图片描述
追踪下去MessageBoxIndirectW里调用了MessageBoxTimeoutIndirectW()。
在这里插入图片描述
在MessageBoxTimeoutIndirectW里开始对参数的处理,开始真正的实现功能。

未完…
3.总归言之,经过层层调用,最终还是要到内核中去,一个简单的API调用,背后的实现却不简单。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章