Windows 提供的基础系统文件(从上到下为依赖关系)
msvcrt.dll
ucrtbase.dll
提供基础 CRT (C语言运行时)库,例如fopen
,_sleep
等。前者msvcrt
绑定MSVC
版本号,不同的版本不完全兼容(这也是安装很多软件时会让你装微软运行时的缘故),后者是微软新出的通用版本,所谓Universal CRT
kernel32.dll
kernelbase.dll
提供 Win32 兼容 API 函数,例如基本的CreateFileW
(注意 CreateFile 是宏而非函数)和SleepEx
等,这些函数都是面向用户端的ntdll.dll
提供用户端的 WinNT 内核函数入口,例如NtCreateFile
和NtDelayExecution
。这些以Nt
打头的函数是用户端能接触到的 Windows 系统最底层的函数。参数要求严苛(例如全部要求 wchar_t 编码,路径名要求奇葩的 NTFS 格式),实现都是些syscall
ntoskrnl.exe
WinNT 系统内核镜像(NT Operating System KeRNeL)。这里存放真正的内核代码,用户端接触不到,入口即为上面的ntdll
维基百科:https://en.wikipedia.org/wiki...
微软公开的 Windows API 都是继承自 Windows 95 上古年代的 Win32 API,即 kernel*
提供的那些。MDSN 上有完整的文档,Windows SDK 有完整的头文件。微软(名义上)保证 API 和 ABI 的双兼容,这就是 WinXP 甚至某些 Win98 上运行的程序都可以直接在 Win11 上运行的原因。
但是 Windows NT 内核,WinNT API 才是精华。比如 Win32 API 中 Sleep(0)
的特殊行为,在 WinNT API 中可是明确的区分为 NtDelayExecution
和 NtYieldExecution
。ntdll
提供了大量贴近内核功能强大的函数,微软一不提供文档说明和头文件定义,二不保证不同版本间 AxI 兼容(比如这次 IoRing ABI 不兼容,让我调试了好久),想用有时还得手动 LoadLibrary
(当然绝大多数情况链接 ntdll.lib
就够了)
想用 WinNT API,首先要知道 WinNT 提供了哪些函数可以用。这里最简单的办法,使用 PE Viewer(笔者这里使用 XPEViewer) 打开 ntdll.dll
,查看导出函数表
这些函数都是很规范的 Pascal 命名,看名字就能把用途猜个大概,然后在网上搜索即可。如果往下翻一翻还可以看到 ntdll
还定义了很多 CRT 中的函数。
通过 PE Viewer 只能看到函数名,如果要调用需要他们的精确声明。一部分声明可以在 ntoskrnl.exe
的符号文件(PDB)中找到
PDB 是公开的,可以在微软的符号服务器下载。在 MSVC 中调试系统 dll 时自动下载部分符号文件(kernel32.pdb
、ntdll.pdb
等),但绝不可能下载到 ntoskrnl.pdb
。这里可以用 PDBDownloader 手工下载。
下载之后的 pdb 文件可以使用 PDBRipper 读取
PDBRipper 现在有个 bug,不支持结构体中的匿名共用体。
也可以用 pdbex 直接导出头文件,而且没有匿名共用体的 bug
PDB 文件中能获取到绝大多数函数中用到的数据结构(结构体和共用体),仍然没有精确的函数声明。函数声明可以在网上找到一部分,剩下的我也不知道从哪搞 ;)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。