ntdll.dll
ntdll.dll描述了windows本地NTAPI的接口。是重要的Windows NT内核级文件。当Windows启动时,ntdll.dll就
驻留在内存中特定的写保护区域,使别的程序无法占用这个内存区域。
中文名 ntdll.dll 外文名 NT Layer DLL 版 本 6.3.9600.17736 系统DLL文件 是 属 于 Windows NT
内核
目录
1 概述
2 详细介绍
3 函数调用
4 其他定义的部分函数如下
▪ Csr系列
▪ Dbg系列 调试函数
▪ Ki系列
▪ Ldr系列 Loader APIs
▪ Nls系列
▪ Nt系列及其他
5 英文解释
概述
DLL 文件名:ntdll.dll
DLL 名称: NT Layer DLL
ntdll.dll
ntdll.dll(20张)
描述:
ntdll.dll是NT操作系统重要的模块。[2]
ntdll.dll是Windows系统从ring3到ring0的入口。位于Kernel32.dll和user32.dll中的所有win32 API 最终都
是调用ntdll.dll中的函数实现的。ntdll.dll中的函数使用SYSENTRY进入ring0,函数的实现实体在ring0中。
常见错误: File Not Found, Missing File, Exception Errors
详细介绍
打开NTDLL.dll,发现CRT的许多基本函数都是在这里实现的。包括qsort,ceil这样的函数,还有strcpy堆的释放
,进程管理,似乎都是在ntdll中实现。
用户模式的代码在调用系统内核函数的时候,首先把一个叫做system call number的数放在EAX中,把参数放在
其它的寄存器中了。然后调用INT 2E中断。但是大部分应用程序并不需要直接这么做。通常都是在调用
kernel32.dll等时由他们来调用INT 2E.
内核模式的代码,做法稍微有点不同。他们通常调用由NTOSKRNL.EXE导出的NTDLL.dll中Zw开头的那一系列函数
,比如 ZwWaitForSingleObject, 反之,如果是用户级代码需要调用内核,就会利用INT 2E调用
WaitForSingleObject.对于许多函数的批量调用,你会明显发现 Zw族要比Rtl族效率高很多。
ntdll.dll中的大部分函数都是在MSDN中找不到描述的,因为这些函数介于Windows API与内核API之间,微软并
未公开全部的内核函数.
函数调用编辑
对于一部分得知其定义形式的函数,可以这样调用:
//C language
//以进程挂起函数NtSuspendProcess为例
//define function
typedef LONG (NTAPI * _____NtSuspendProcess)(IN HANDLE);
//Get Process Address (from ntdll.dll)
_____NtSuspendProcess NtSuspendProcess=(_____NtSuspendProcess)GetProcAddress(GetModuleHandle
("ntdll"),"NtSuspendProcess");
//In function "main"
//Suspend itself:
NtSuspendProcess(GetCurrentProcess());
//代码在Mingw g++ 4.8.7(Windows 8.1 64bit)编译通过
//运行时程序理应有SE_DEBUG_NAME特权
其他定义的部分函数如下
Csr系列
(configuration status register? Command and Status Register?)
CsrAllocateCaptureBuffer
CsrAllocateMessagePointer
CsrCaptureMessageBuffer
CsrCaptureMessageMultiUnicodeStringsInPlace
CsrCaptureMessageString
CsrCaptureTimeout
CsrClientCallServer
CsrClientConnectToServer
CsrFreeCaptureBuffer
CsrGetProcessId
CsrIdentifyAlertableThread
CsrNewThread
CsrProbeForRead
CsrProbeForWrite
CsrSetPriorityClass
Dbg系列 调试函数
DbgBreakPoint
DbgPrint
DbgPrintEx
DbgPrintReturnControlC
DbgPrompt
DbgQueryDebugFilterState
DbgSetDebugFilterState 6
DbgUiConnectToDbg
DbgUiContinue
DbgUiConvertStateChangeStructure
DbgUiDebugActiveProcess
DbgUiGetThreadDebugObject
DbgUiIssueRemoteBreakin
DbgUiRemoteBreakin
DbgUiSetThreadDebugObject
DbgUiStopDebugging
DbgUiWaitStateChange
DbgUserBreakPoint
Ki系列
KiRaiseUserExceptionDispatcher
KiUserApcDispatcher
KiUserCallbackDispatcher
KiUserExceptionDispatcher
Ldr系列 Loader APIs
(共34个API,NTDLL APIs)
LoadResource
LdrAccessResource
LdrAlternateResourcesEnabled
DisableThreadLibraryCalls
LdrDisableThreadCalloutsForDll
LdrEnumResources
LdrFindAppCompatVariableInfo
LdrFindEntryForAddress
EnumResourceTypesW
LdrFindResourceDirectory_U
FindResourceExA
LdrFindResource_U
LdrFlushAlternateResourceModules
LdrGetAlternateResourceModuleHandle
GetModuleHandleForUnicodeString
LdrGetDllHandle
GetProcAddress
LdrGetProcedureAddress
LdrInitializeThunk
LoadLibraryEx (LOAD_LIBRARY_AS_DATAFILE)
LdrLoadAlternateResourceModule
LoadLibrary
LdrLoadDll
LdrProcessRelocationBlock
LdrQueryApplicationCompatibilityGoo
LdrQueryImageFileExecutionOptions
LdrQueryProcessModuleInformation
LdrRelocateImage
ExitProcess
LdrShutdownProcess
ExitThread
LdrShutdownThread
LdrUnloadAlternateResourceModule
FreeLibrary
LdrUnloadDll
LdrVerifyImageMatchesChecksum
LdrVerifyMappedImageMatchesChecksum
Nls系列
代码页管理(National Language Support)
NlsAnsiCodePage
NlsMbCodePageTag
NlsMbOemCodePageTag
Nt系列及其他
(从process explorer上找到的一些函数)
NtQuerySystemInformation
NtQuerySymbolicLinkObject
NtQueryDirectoryObject
NtOpenSymbolicLinkObject
NtOpenDirectoryObject
NtQueryObject
NtQueryInformationProcess
NtSetInformationProcess
NtQuerySemaphore
NtQuerySection
NtQueryEvent
NtQueryMutant
NtResumeThread
NtSuspendThread
NtOpenThread
NtQueryInformationThread
NtQueryVirtualMemory
RtlCreateQueryDebugBuffer
RtlQueryProcessDebugInformation
RtlDestroyQueryDebugBuffer
RtlTimeToTimeFields
PropertyLengthAsVariant[5]
英文解释
NTDLL.DLL exports the WindowsNative API. The Native API is the interface used by user-mode
components of the operating system that must run without support from Win32 or other API
subsystems. Most of this API is implemented inNTDLL.DLLand at the upper edge ofntoskrnl.exe(and
its variants), and the majority of exported symbols within these libraries are prefixedNt, for
exampleNtDisplayString. Native APIs are also used to implement many of the "kernel APIs" or "base
APIs" exported by KERNEL32.DLL.The large majority of Windows applications do not call NTDLL.DLL
directly.
Applications that arelinkeddirectly against this library are known asnative applications; the
primary reason for their existence is to perform tasks that must run early in the system startup
sequence before the Win32 subsystem is available. An obvious but important example is the
creation of the Win32 subsystem process,csrss.exe. Before the csrss.exe process exists, no Win32
processes may be created, therefore the process that creates it (Smss.exe, the "session manager")
must be a native application.csrss.exeitself is a native application.
Despite having an ".exe" file extension, native applications cannot be executed by the user (or
any program in the Win32 or other subsystems). An example is theautochk.exebinary that
runschkdskduring the system initialization "Blue Screen". Other prominent examples are the
services that implement the various subsystems, such ascsrss.exe.
UnlikeWin32applications, native applications instantiate within the Kernel runtime code
(ntoskrnl.exe) and so they must have a different entry point (NtProcessStartup, rather than(w)
(Win)MainCRTStartupas is found in a Win32 application),obtain their command-line arguments via a
pointer to an in-memory structure, manage their own memory using theRtlheap API,(which the Win32
heap APIs are just wrappers around -- no real difference there) and return execution with a call
toNtTerminateProcess(as opposed toExitProcess). A common library linked with Native applications
is nt.lib, which contains startup code for Native applications, similar to how the C runtime
provides startup code for Win32 apps.
Though most of the API is undocumented, Native Applications can be built using theWindows Driver
Development Kit; manyAntiVirusand other utility software vendors incorporate Native Applications
within their products, usually to perform some boot-time task that cannot be carried out
inuserspace.
========
挂起一个进程
怎样才能挂起一个进程。线程很好办,因为系统提供了 SuspendThread() API 可以直接调用
。忘了是昨天还是前天,在用
十六进制方式查看大名鼎鼎的 Process Explorer 的时候,无意之中看到了一个原来没见过的 API 名字:
NtSuspendProcess(),望文知义,连弱智都应该能看出来这个函数的作用。与之相对应的还有
NtResumeProcess()。他们的原型为:
NTSTATUS NtSuspendProcess(HANDLE hProcess);
NTSTATUS NtResumeProcess(HANDLE hProcess);
从 NTDLL.DLL 中找到地址就可以直接用了。另外关于查询一个进程当前是不是处于被挂起状态我还不知道,估
计跑不了 NtQueryInformationProcess()。
========
深层解析最核心的dll:NTDLL.dll
打开NTDLL.dll,惊奇的发现原来CRT的许多基本函数居然都是在这里实现的!甚至包括qsort,ceil这样的函数,
还有臭名昭著的 strcpy(严格来讲,这只能怪使用者不当心)。堆的释放,进城管理,似乎都是在这。于是,
我决定,仔细察看以下它,这1410个函数是做什么的.
用户模式的代码在调用系统内核函数的时候,首先把一个叫做system call number的数放在EAX中,把参数
放在其它的寄存器中了。然后调用INT 2E中断。但是大部分应用程序并不需要直接这么做。通常都是在调用
kernel32.dll等时由他们来调用INT 2E.
内核模式的代码,做法稍微有点不同。他们通常调用由NTOSKRNL.EXE导出的NTDLL.dll中Zw开头的那一系列
函数,比如 ZwWaitForSingleObject, 反之,如果是用户级代码需要调用内核,就会利用INT 2E调用
WaitForSingleObject.对于许多函数的批量调用,你会明显发现 Zw族要比Rtl族效率高很多。
可惜ntdll.dll中的大部分函数都是undocumented.
对于一部分得知其定义形式的函数,可以这样调用:
1.先将NTDLL.DLL读入 LoadLibrary(TEXT(/"NTDLL.dll/"))
2.利用GetProcAddress 获取其函数入口地址
3.利用得到的函数指针调用
但是可以大致的分为几类吧
1 PropertyLengthAsVariant 它被排在了第一号,但是我就是不明白它是做什么的
2 Csr(configuration status register? Command and Status Register?)系列
CsrAllocateCaptureBuffer CsrAllocateMessagePointer CsrCaptureMessageBuffer
CsrCaptureMessageMultiUnicodeStringsInPlace CsrCaptureMessageString CsrCaptureTimeout
CsrClientCallServer CsrClientConnectToServer CsrFreeCaptureBuffer CsrGetProcessId
CsrIdentifyAlertableThread CsrNewThread CsrProbeForRead CsrProbeForWrite CsrSetPriorityClass
3 Dbg系列 调试函数
DbgBreakPoint DbgPrint DbgPrintEx DbgPrintReturnControlC DbgPrompt DbgQueryDebugFilterState
DbgSetDebugFilterState DbgUiConnectToDbg DbgUiContinue DbgUiConvertStateChangeStructure
DbgUiDebugActiveProcess DbgUiGetThreadDebugObject DbgUiIssueRemoteBreakin DbgUiRemoteBreakin
DbgUiSetThreadDebugObject DbgUiStopDebugging DbgUiWaitStateChange DbgUserBreakPoint
4 ki系列
KiRaiseUserExceptionDispatcher
KiUserApcDispatcher
KiUserCallbackDispatcher
KiUserExceptionDispatcher
5 Ldr系列 Loader APIs,共34个
API
NTDLL APIs
LoadResource
LdrAccessResource
Ldr*****nateResourcesEnabled
DisableThreadLibraryCalls
LdrDisableThreadCalloutsForDll
LdrEnumResources
LdrFindAppCompatVariableInfo
LdrFindEntryForAddress
EnumResourceTypesW
LdrFindResourceDirectory_U
FindResourceExA
LdrFindResource_U
LdrFlush*****nateResourceModules
LdrGet*****nateResourceModuleHandle
GetModuleHandleForUnicodeString
LdrGetDllHandle
GetProcAddress
LdrGetProcedureAddress
LdrInitializeThunk
LoadLibraryEx (LOAD_LIBRARY_AS_DATAFILE)
LdrLoad*****nateResourceModule
LoadLibrary
LdrLoadDll
LdrProcessRelocationBlock
LdrQueryApplicationCompatibilityGoo
LdrQueryImageFileExecutionOptions
LdrQueryProcessModuleInformation
LdrRelocateImage
ExitProcess
LdrShutdownProcess
ExitThread
LdrShutdownThread
LdrUnload*****nateResourceModule
FreeLibrary
LdrUnloadDll
LdrVerifyImageMatchesChecksum
LdrVerifyMappedImageMatchesChecksum
6 Nls(National Language Support)系列 代码页管理
NlsAnsiCodePage
NlsMbCodePageTag
NlsMbOemCodePageTag
7 Nt系列 共285个,大部分都是kernel32.dll,user32.dll等的核心实现
NtCreateFile, NtOpenFile, NtClose, NtWaitForSingleObject 是kernel32.dll中许多用户级代码的核心
实现。
NTSTATUS NtClose( HANDLE Handle);
竟然是CloseHandle 的原身!唯一的缺点是该函数并没有导出库,如果要调用,就必须使用
GetProcAddress 来获得其函数指针然后调用。
NtCreateFile 可以说是DDK的核心
RtlUnwind initiates an unwind of procedure call frames
结构化异常(Structured Exception Handling, SEH )的 核心。
NTSTATUS NtWaitForSingleObject( HANDLE Handle, BOOLEAN Alertable, PLARGE_INTEGER Timeout);
Waits until the specified object attains a state of signaled
我想,信号同步等,应该与之有莫大的联系吧
8 pfx 不明白
PfxFindPrefix
PfxInitialize
PfxInsertPrefix
PfxRemovePrefix
9 RestoreEm87Context SaveEm87Context
10 rtl系列 共506个。我想,rtl应该是runtime library的缩写吧。一个很庞大的函数族,里面包含像
RtlCreateUserProcess 这样的一些很基本的函数,通常供内核模式的driver等调用
下面是一部分示例
APIs Forwarded to NTDLL
API
Destination
DeleteCriticalSection
Forwarded to NTDLL.RtlDeleteCriticalSection
EnterCriticalSection
Forwarded to NTDLL.RtlEnterCriticalSection
HeapAlloc
Forwarded to NTDLL.RtlAllocateHeap
HeapFree
Forwarded to NTDLL.RtlFreeHeap
HeapReAlloc
Forwarded to NTDLL.RtlReAllocateHeap
HeapSize
Forwarded to NTDLL.RtlSizeHeap
LeaveCriticalSection
Forwarded to NTDLL.RtlLeaveCriticalSection
RtlFillMemory
Forwarded to NTDLL.RtlFillMemory
RtlMoveMemory
Forwarded to NTDLL.RtlMoveMemory
RtlUnwind
Forwarded to NTDLL.RtlUnwind
RtlZeroMemory
Forwarded to NTDLL.RtlZeroMemory
SetCriticalSectionSpinCount
Forwarded to NTDLL.RtlSetCriticalSection- SpinCount
TryEnterCriticalSection
Forwarded to NTDLL.RtlTryEnterCriticalSection
VerSetConditionMask
Forwarded to NTDLL.VerSetConditionMask
11 VerSetConditionMask 用于确认系统信息
The VerSetConditionMask function sets the bits of a 64-bit value to indicate the comparison
operator to use for a specified operating system version attribute. This function is used to
build the dwlConditionMask parameter of the VerifyVersionInfo function.
12 Zw系列 共284个。前面已经说过,为可执行性系统服务提供内核模式的入口, 为NTOSKRNL.EXE 提供实
现。由于是内核模式,所以在执行的时候并不检查用户是否有执行权限
13 内部函数 共116个。具体作用不明,很底层的东西。无法查到任何相关资料。无法得知与其相关的任何
信息。
_CIcos _CIlog _CIpow _CIsin _CIsqrt __eCommonExceptions __eEmulatorInit __eF2XM1 __eFABS
__eFADD32 __eFADD64 __eFADDPreg __eFADDreg __eFADDtop __eFCHS __eFCOM __eFCOM32 __eFCOM64
__eFCOMP __eFCOMP32 __eFCOMP64 __eFCOMPP __eFCOS __eFDECSTP __eFDIV32 __eFDIV64 __eFDIVPreg
__eFDIVR32 __eFDIVR64 __eFDIVRPreg __eFDIVRreg __eFDIVRtop __eFDIVreg __eFDIVtop __eFFREE
__eFIADD16 __eFIADD32 __eFICOM16 __eFICOM32 __eFICOMP16 __eFICOMP32 __eFIDIV16 __eFIDIV32
__eFIDIVR16 __eFIDIVR32 __eFILD16 __eFILD32 __eFILD64 __eFIMUL16 __eFIMUL32 __eFINCSTP __eFINIT
__eFIST16 __eFIST32 __eFISTP16 __eFISTP32 __eFISTP64 __eFISUB16 __eFISUB32 __eFISUBR16
__eFISUBR32 __eFLD1 __eFLD32 __eFLD64 __eFLD80 __eFLDCW __eFLDENV __eFLDL2E __eFLDLN2 __eFLDPI
__eFLDZ __eFMUL32 __eFMUL64 __eFMULPreg __eFMULreg __eFMULtop __eFPATAN __eFPREM __eFPREM1
__eFPTAN __eFRNDINT __eFRSTOR __eFSAVE __eFSCALE __eFSIN __eFSQRT __eFST __eFST32 __eFST64
__eFSTCW __eFSTENV __eFSTP __eFSTP32 __eFSTP64 __eFSTP80 __eFSTSW __eFSUB32 __eFSUB64 __eFSUBPreg
__eFSUBR32 __eFSUBR64 __eFSUBRPreg __eFSUBRreg __eFSUBRtop __eFSUBreg __eFSUBtop __eFTST __eFUCOM
__eFUCOMP __eFUCOMPP __eFXAM __eFXCH __eFXTRACT __eFYL2X __eFYL2XP1 __eGetStatusWord
14 一些CRT的基本函数 共131个 主要是字符串管理,还有些基本的数学函数
__isascii __iscsym __iscsymf __toascii _alldiv _alldvrm _allmul _alloca_probe _allrem _allshl
_allshr _atoi64 _aulldiv _aulldvrm _aullrem _aullshr _chkstk _fltused _ftol _i64toa _i64tow _itoa
_itow _lfind _ltoa _ltow _memccpy _memicmp _snprintf _snwprintf _splitpath _strcmpi _stricmp
_strlwr _strnicmp _strupr _tolower _toupper _ui64toa _ui64tow _ultoa _ultow _vsnprintf
_vsnwprintf _wcsicmp _wcslwr _wcsnicmp _wcsupr _wtoi _wtoi64 _wtol abs atan atoi atol bsearch
ceil cos fabs floor isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace
isupper iswalpha iswctype iswdigit iswlower iswspace iswxdigit isxdigit labs log mbstowcs memchr
memcmp memcpy memmove memset pow qsort sin sprintf sqrt sscanf strcat strchr strcmp strcpy
strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr strtol strtoul swprintf tan
tolower toupper towlower towupper vDbgPrintEx vDbgPrintExWithPrefix vsprintf wcscat wcschr wcscmp
wcscpy wcscspn wcslen wcsncat wcsncmp wcsncpy wcspbrk wcsrchr wcsspn wcsstr wcstol wcstombs
wcstoul
众所周知,NT中有很多为公布的api,习惯上大家喜欢把他们称为native api.上面就是一部分。
那么所谓的native api究竟是用来做什么的呢?
他是主要是用来在受控的状态下调用kernel mode的代码。说的简单点,就是一个通往kernel 的
interface.举个简单的例子,user mode 下,用户是不能直接访问硬件的。即使是像打开,关闭文件这样的简
单操作,也需要先从user mode 切换至 kernel mode.然后交给内核来执行。如果这一系列操作都交给用户来做
,这中间存在一个很大的问题。那就是user mode和kernel mode的切换,管理的问题。如果仅仅是的内核,问
题不大。可是现在的OS不仅都是多进程,而且大部分UNIX kernel 都是抢占式可重入的。这意味着当你从user
mode 切换至kernel mode 正在执行 一个很重要的操作时,会突然被另一个应用程序打断。此时进程同步就显
得极为重要。
比如,两个进程A和B,A先进入内核,需要向软盘写入一个500k的文件。读取软盘A的剩余空间,800k,够了
,但此时被挂起。B进程进入,写入一个400k的文件,然后退出。然后A继续执行。然后。。。
更常见的是,A先读取某资源V的数量,数量为1。然后B进入,占用此资源并将V-1,然后B被挂起,A继续进
行,A又将V-1,V成了-1…
最理想的方式是,将诸如此类的操作设为atomic operation.中间不允许打断。但是很多时候这样是不可能
的,而且就算可能,性能会打很大的折扣。
于是对于长时期的操作,采取lock,semaphore,Signal等来同步或控制,短操作,就设定一个critical
region.一旦进入critical region的process是不可被中断的。
Kernel mode 下的这些同步与控制非常复杂,为了系统安全,大部分程序都是运行在user mode 下,然后
由kernel 提供一个interface,交给用户来调用。Unix下这些interface都是well documented,比如很出名的
read(),write().但是windows下,如上文所提到,ntdll.dll中提供有 NtCreateFile, NtOpenFile, NtClose三
个重要的函数,MSDN中对其仅有少许的说明。
这其实是与NT的架构相关的。NT的kernel,可以算是一个modified microkernel.“Instead of supporting
one basic operating system API, NT implements several”。Windows NT 利用其特有的Environment
subsystems方式很有效的实现了这一点。整个Environment subsystems由CSRSS.EXE控制。(CSRSS.EXE这个进程
你可以在tasklist中看见。你可以用windows sdk中的debug tools在kernel debug mode下debug它,然后选
stop,它就会被强行中止掉。^_^).windows core apis被分在一个个的独立的dll中来实现
(kernel.dll,usr32.dll,gdi32.dll…)。然后这些dll交给 CSRSS.EXE来调度以给用户提供所需的接口。当用户
发出调用请求的时候,首先由CSRSS.EXE找到该dll,然后dll对于其请求的处理,会执 行以下的一个或多个步骤
。
1。立即返回。
2。向windows server发送一条消息,请求帮助 。
3。调用native api 去执行该请求。
首先,对于第一种情况,当且仅当该dll本身就可以完成该请求,比如执行GetCurrentProcess().
对于第二种情况,也很少需要。仅仅是必须要windows server参与的时候,才会如此。比如
CreateProcess()。该dll本身是无法完成的。
第三种情况也就算最常见的了。
通常是先由用户调用kernel.dll(or gdi32.dll,user.dll,etc),然后由之调用ntdll.dll,然后ntdll.dll调
用kernel mode 的KiSystemService,由之来完成具体操作。
========