《Undocumented Windows 2000 Secrets》翻译 --- 第二章(2)
第二章 The Windows 2000 Native API
翻译:Kendiv
更新:
Windows 2000运行时库
Nt*()和Zw*()函数构成了Native API的基本部分,但并不是主要部分,还有一部分代码位于ntdll.dll中。该DLL至少导出了1179个符号。其中的249和248个分别属于Nt*()和Zw*()函数集,剩余的682个函数并不通过INT 2eh中断进行调用。显然,这一大组函数并不依赖Windows 2000内核。那提供它们的目的何在呢?让我们继续往下看。
C运行时库
如果你研究过位于ntdll.dll导出节(export section)的符号,你会发现很多在C程序员看来很熟悉的小写的函数名称。这些都是众所周知的名子,如memcpy()、sprintf()和qsort(),这些C运行时库中的函数都合并到了ntdll.dll中。对于ntoskrnl.exe也是如此,它同样提供了一组与C运行时函数十分相像的函数,虽然这两组函数并不相同。附录B的表B-3列出了这两组函数,并指出了每个函数分别属于哪个模块。
你可以简单的将ntdll.lib(来自Windows 2000 DDK)添加到导入库列表(链接器在解析符号期间将扫描该列表)中,就可以链接到这些函数。如果你更喜欢对话框,你可以选择Visual C/C++的工程菜单中的Settings子菜单,然后单击Linke页,选择Category General,然后将ntdll.dll添加到Object/Library模块列表中。还有一种方法:在源文件中,添加如下的内容:
#pragma comment(linker,”/defaultlib:ntdll.lib”)
这同样有效,好处是,其他开发人员可以使用Visual C/C++的默认设置来rebuild你的工程。
反编译这些与C运行时函数类似的函数(来自ntdll.dll和ntoskrnl.exe),会发现ntdll.dll并不依赖于ntoskrnl.exe,这和ndll.dll中的Native API不一样。事实上,这两个模块分别实现了这些函数。本节出现的其他函数也是如此。注意,表B-3中的一些函数并不使用其导出的名称。例如,如果在内核模式的驱动程序中针对一个64位的LARGE_INTEGER使用移位操作符<<和>>,编译器和链接器会自动导入ntoskrnl.exe的_allshr()和_allshl()。
扩展的运行时函数
随同标准的C运行时函数,Windows 2000还提供了一组扩展的运行时函数。在次强调,ntdll.dll和ntoskrnl.exe分别实现了它们。并且其中有些函数是重叠的。这些扩展函数的名字都有一个共同的前缀Rtl(for Runtime Library)。附录B的表B-4列出了所有这些扩展函数。Windows 2000提供的这些运行时函数还包含用于普通任务的助手函数(helper function),这些任务都超过了C运行时函数的能力范围。例如,其中的某些用于管理安全性,另一些用于操作Windows 2000特有的数据结构,还有一些对内存管理提供支持。很难理解为什么微软仅在Windows 2000 DDK中提供了其中115个函数的文档,而扔掉了其余406个非常有用的函数。
浮点模拟器(The Floating-Point Emulator)
让我用ntdll.dll提供的另一组函数集合来结束这次API函数汇展。表2-1列出了这些函数的名称,这些名称可能对于汇编程序员有些眼熟。去了名称前的__e前缀,你就会得到i386系列CPU中的FPU(Floating-Point Unit)汇编助记符。事实上,从表2-1中列出的函数来看,ntdll.dll包含了一个完整的浮点模拟器。这再次证明了这个DLL是一个庞大的代码仓库,这吸引了众多的System Spelunker去反编译它。
表2-1. ntdll.dll的浮点模拟器接口
|
函数名称 | |||
|
_eCommonExceptions |
_eFIST32 |
_eFLD64 |
_eFSTP32 |
|
_eEnulatorInit |
_eFISTP16 |
_eFLD80 |
_eFSTp64 |
|
_eF2XM1 |
_eFISTP32 |
_eFLDCW |
_eFSTP80 |
|
_eFABS |
_eFISTP64 |
_eFLDENV |
_eFSTSW |
|
_eFADD32 |
_eFISUB16 |
_eFLDL2E |
_eFSUB32 |
|
_eFADD64 |
_eFISUB32 |
_eFLDLN2 |
_eFSUB64 |
|
_eFADDPreg |
_eFISUBR16 |
_eFLDPI |
_eFSUBPreg |
|
_eFADDreg |
_eFISUBR32 |
_eFLDZ |
_eFSUBR32 |
|
_eFADDtop |
_eFLDI |
_eFMUL32 |
_eFSUBR64 |
|
_eFCHS |
_eFIDIVR16 |
_eFMUL64 |
_eFSUBreg |
|
_eFCOM |
_eFIDIVR32 |
_eFMULPreg |
_eFSUBRPreg |
|
_eFCOM32 |
_eFILD16 |
_eFMULreg |
_eFSUBRreg |
|
_eCOM64 |
_eFILD32 |
_eFMULtop |
_eFSUBRtop |
|
_eFCOMP |
_eFILD64 |
_eFPATAN |
_eFSUBtop |
|
_eFCOMP32 |
_eFIMUL16 |
_eFPREm |
_eFTST |
|
_eFCOMP64 |
_eFIMUL32 |
_eFPREM1 |
_eFUCOM |
|
_eFCOMPP |
_eFINCSTP |
_eFPTAN |
_eFUCOMP |
|
_eFCOS |
_eFINIT |
_eFRNDINT |
_eFUCOMPP |
|
_eFDECSTP |
_eFIST16 |
_eFRSTOR |
_eFXAM |
|
_eFIDIVR16 |
_eFIST32 |
_eFSAVE |
_eFXCH |
|
_eFIDIVR32 |
_eFISTP16 |
_eFSCALE |
_eFXTRACT |
|
_eFILD16 |
_eFISTP32 |
_eFSIN |
_eFYL2X |
|
_eFILD32 |
_eFISTP64 |
_eFSQRT |
_eFYL2XP1 |
|
_eFILD64 |
_eFISUB16 |
_eFST |
_eGetStatusWord |
|
_eFIMUL16 |
_eFISUB32 |
_eFST32 |
NPXEMULATORTABLE |
|
_eFIMUL32 |
_eFISUBR16 |
_eFST64 |
RestoreEm87Context |
|
_eFINCSTP |
_eFISUBR32 |
_eFSTCW |
SaveEm87Context |
|
_eFINIT |
_eFLD16 |
_eFSTENV |
|
|
_eFIST16 |
_eFLD32 |
_eFSTP |
|
有关浮点指令集的更多信息,请参考Intel 80386 CPU的原始文档。可以从Intel官方网站:http://developer.intel.com/design/pentium/manuals/来下载PDF格式的Pentium手册。讲解这些机器码指令集的手册是:Intel Architecture SoftWare Developer’s Manual. Volume 2:Instruction Set Reference(Intel 1999b)。
其它的API函数
除附录B和表2-1列出的函数外,ntdll.dll和ntoskrnl.exe还为多个内核组件导出了为数众多的函数。为了避免更长的表格,我这里仅列出可用函数的名称前缀及其所属类别(表2-2)。
表2-2 函数名前缀及其所属分类
|
前缀 |
ntdll.dll |
ntoskrnl.exe |
分类 |
|
_e |
|
N/A |
浮点模拟器 |
|
Cc |
|
N/A |
Cache管理器 |
|
Csr |
|
|
Client-Server运行时库 |
|
Dbg |
N/A |
|
调试支持 |
|
Ex |
N/A |
|
执行支持(Executive Support) |
|
FsRtl |
N/A |
|
文件系统运行时库 |
|
Hal |
N/A |
|
硬件抽象层调度器 |
|
Inbv |
N/A |
|
系统初始化/VGA启动驱动(bootvid.dll) |
|
Init |
N/A |
|
系统初始化 |
|
Interlocked |
N/A |
|
处理线程安全的变量 |
|
Io |
N/A |
|
I/O管理器 |
|
Kd |
N/A |
|
内核调试支持 |
|
Ke |
N/A |
|
内核例程 |
|
Ki |
|
|
内核中断例程 |
|
Ldr |
|
|
映像加载器 |
|
Lpc |
N/A |
|
本地过程调用(LPC)设备 |
|
Lsa |
N/A |
|
本地安全授权 |
|
Mm |
N/A |
|
