关于未公开函数ZwQuerySystemInformation的使用
来源:互联网 发布:mysql数据库主键类型 编辑:程序博客网 时间:2024/04/28 22:21
最近看一些关于内核方面的资料,碰到未公开函数,未能在微软官方找到答案,从网上了解到一些信息,摘录下来备用。
我看到驱动程序在ring0调用的一段代码的使用:
ULONG GetModuleBase(PCHAR szModuleName){ ULONG uSize = 0x10000; PVOID pModuleInfo = ExAllocatePoolWithTag(NonPagedPool, uSize, 'GetB'); if (pModuleInfo == NULL) { KdPrint(("ExAllocatePoolWithTag failed\n")); return 0; } RtlZeroMemory(pModuleInfo, uSize); NTSTATUS status = ZwQuerySystemInformation(SystemModuleInformation, pModuleInfo, uSize, NULL); if(!NT_SUCCESS(status)) { KdPrint(("FindModuleByAddress query failed\n")); KdPrint(("FindModuleByAddress status: 0x%x\n", status)); if (pModuleInfo != NULL) { ExFreePool(pModuleInfo); pModuleInfo = NULL; } return 0; } ULONG uNumberOfModules = *(PULONG)pModuleInfo; if (uNumberOfModules == 0) { return 0; } PRTL_PROCESS_MODULE_INFORMATION pStart = (PRTL_PROCESS_MODULE_INFORMATION)((ULONG)pModuleInfo + sizeof(ULONG)); for (ULONG uCount = 0; uCount < uNumberOfModules; uCount++) { PUCHAR pszFullPathName = (PUCHAR)pStart->FullPathName; ULONG uOffsetName = pStart->OffsetToFileName; PUCHAR pszName = (PUCHAR)(pszFullPathName + uOffsetName); if (_stricmp((const char *)pszName, szModuleName) == 0) { ULONG uImageBase = (ULONG)pStart->ImageBase; if (pModuleInfo != NULL) { ExFreePool(pModuleInfo); pModuleInfo = NULL; } return uImageBase; } pStart++; } if (pModuleInfo != NULL) { ExFreePool(pModuleInfo); pModuleInfo = NULL; } return 0;}上面代码GetModuleBase功能是获取指定名字的模块的内存中的基址。
其中ZwQuerySystemInformation函数微软官方链接:ZwQuerySystemInformation并未能提供足够的信息,SystemModuleInformation并没有在官方链接中找到描述的使用方法。我想官方不可能会漏掉这个使用,故意不公开一定是有原因的,传统上的原因是这块内容很可能在后面的版本改变不公开给用户使用。我不管是什么原因,能弄清楚这块内容,就是我的目标。
函数原型:
NTSTATUS WINAPI ZwQuerySystemInformation( _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, _Inout_ PVOID SystemInformation, _In_ ULONG SystemInformationLength, _Out_opt_ PULONG ReturnLength);
在网上找到一段利用在ring3中利用ZwQuerySystemInformation来获取进程模块信息的代码,稍加修改,就可以正常编译运行,功能类似于ddk提供的drivers.exe的功能,上代码:
// DeepInNativeApi.cpp : Defines the entry point for the console application.///** For x86/EWindows XP SP1 & VC 7 Win7 32bit&VC9* cl listmodule.c /Os /G6 /W3** Usage: listmodule*//************************************************************************* ** Head File ** *************************************************************************/#include <stdio.h>#include <stdlib.h>#include <malloc.h>#include <windows.h>/************************************************************************* ** Macro ** *************************************************************************/#pragma comment( linker, “/subsystem:console” )typedef LONG NTSTATUS;#define NT_SUCCESS(status) ((NTSTATUS)(status)>=0)/*************************************************************************** <<Windows NT/2000 Native API Reference>> by Gary Nebbett*//** 虽然本程序用不到这么多枚举值,还是列出一份最完整的。这个程序本身不求完* 美,尽可能多地保留一些未文档化的参考资料。*/typedef enum _SYSTEM_INFORMATION_CLASS // Q S{ SystemBasicInformation, // 00 Y N SystemProcessorInformation, // 01 Y N SystemPerformanceInformation, // 02 Y N SystemTimeOfDayInformation, // 03 Y N SystemNotImplemented1, // 04 Y N SystemProcessesAndThreadsInformation, // 05 Y N SystemCallCounts, // 06 Y N SystemConfigurationInformation, // 07 Y N SystemProcessorTimes, // 08 Y N SystemGlobalFlag, // 09 Y Y SystemNotImplemented2, // 10 Y N SystemModuleInformation, // 11 Y N SystemLockInformation, // 12 Y N SystemNotImplemented3, // 13 Y N SystemNotImplemented4, // 14 Y N SystemNotImplemented5, // 15 Y N SystemHandleInformation, // 16 Y N SystemObjectInformation, // 17 Y N SystemPagefileInformation, // 18 Y N SystemInstructionEmulationCounts, // 19 Y N SystemInvalidInfoClass1, // 20 SystemCacheInformation, // 21 Y Y SystemPoolTagInformation, // 22 Y N SystemProcessorStatistics, // 23 Y N SystemDpcInformation, // 24 Y Y SystemNotImplemented6, // 25 Y N SystemLoadImage, // 26 N Y SystemUnloadImage, // 27 N Y SystemTimeAdjustment, // 28 Y Y SystemNotImplemented7, // 29 Y N SystemNotImplemented8, // 30 Y N SystemNotImplemented9, // 31 Y N SystemCrashDumpInformation, // 32 Y N SystemExceptionInformation, // 33 Y N SystemCrashDumpStateInformation, // 34 Y Y/N SystemKernelDebuggerInformation, // 35 Y N SystemContextSwitchInformation, // 36 Y N SystemRegistryQuotaInformation, // 37 Y Y SystemLoadAndCallImage, // 38 N Y SystemPrioritySeparation, // 39 N Y SystemNotImplemented10, // 40 Y N SystemNotImplemented11, // 41 Y N SystemInvalidInfoClass2, // 42 SystemInvalidInfoClass3, // 43 SystemTimeZoneInformation, // 44 Y N SystemLookasideInformation, // 45 Y N SystemSetTimeSlipEvent, // 46 N Y SystemCreateSession, // 47 N Y SystemDeleteSession, // 48 N Y SystemInvalidInfoClass4, // 49 SystemRangeStartInformation, // 50 Y N SystemVerifierInformation, // 51 Y Y SystemAddVerifier, // 52 N Y SystemSessionProcessesInformation // 53 Y N} SYSTEM_INFORMATION_CLASS;typedef struct _SYSTEM_MODULE_INFORMATION // Information Class 11{ ULONG Reserved[2]; PVOID Base; ULONG Size; ULONG Flags; USHORT Index; USHORT Unknown; USHORT LoadCount; USHORT ModuleNameOffset; CHAR ImageName[256];} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;/** <<Windows NT/2000 Native API Reference>> by Gary Nebbett**************************************************************************//** 参看DDK文档以及<<Windows NT/2000 Native API Reference>> by Gary Nebbett* 这些Native API由ntdll.dll输出*/typedef NTSTATUS ( __stdcall *ZWQUERYSYSTEMINFORMATION ) ( IN SYSTEM_INFORMATION_CLASS SystemInformationClass, IN OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength OPTIONAL );typedef ULONG ( __stdcall *RTLNTSTATUSTODOSERROR ) ( IN NTSTATUS Status );/************************************************************************* ** Function Prototype ** *************************************************************************/static void ListModule ( void );static BOOLEAN LocateNtdllEntry ( void );static void PrintWin32Error ( char *message, DWORD dwMessageId );static void PrintZwError ( char *message, NTSTATUS status );static PVOID PrivateFindModule ( const char *ModuleName );/************************************************************************* ** Static Global Var ** *************************************************************************//** 由ntdll.dll输出的Native API函数指针*/static ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation = NULL;static RTLNTSTATUSTODOSERROR RtlNtStatusToDosError = NULL;/************************************************************************/static void ListModule ( void ){ NTSTATUS status; PSYSTEM_MODULE_INFORMATION module = NULL; ULONG n = 0; ULONG i = 0; void *buf = NULL; ZwQuerySystemInformation( SystemModuleInformation, &n, 0, &n ); if ( NULL == ( buf = calloc( ( size_t )n, 1 ) ) ) { fprintf( stderr, "calloc() failed\n" ); goto ListModule_return; } /* * <<Windows NT/2000 Native API Reference>> by Gary Nebbett所给的例子 * 1.3以及A.2对第二、三形参理解有误,下面才是正确的用法。 */ status = ZwQuerySystemInformation( SystemModuleInformation, buf, n, NULL ); if ( !NT_SUCCESS( status ) ) { PrintZwError( "ZwQuerySystemInformation() failed", status ); goto ListModule_return; } module = ( PSYSTEM_MODULE_INFORMATION )( ( PULONG )buf + 1 ); n = *( ( PULONG )buf ); for ( i = 0; i < n; i++ ) { printf( "0x%08X %s\n", module[i].Base, module[i].ImageName + module[i].ModuleNameOffset ); }ListModule_return: if ( buf != NULL ) { free( buf ); buf = NULL; } return;} /* end of ListModule *//** ntdll.dll输出了所有的Native API*/static BOOLEAN LocateNtdllEntry ( void ){ BOOLEAN boolean_ret = FALSE; char NTDLL_DLL[] = "ntdll.dll"; HMODULE ntdll_dll = NULL; /* * returns a handle to a mapped module without incrementing its * reference count */ if ( ( ntdll_dll = GetModuleHandle( NTDLL_DLL ) ) == NULL ) { PrintWin32Error( "GetModuleHandle() failed", GetLastError() ); return( FALSE ); } if ( !( ZwQuerySystemInformation = ( ZWQUERYSYSTEMINFORMATION )GetProcAddress( ntdll_dll, "ZwQuerySystemInformation" ) ) ) { goto LocateNtdllEntry_return; } if ( !( RtlNtStatusToDosError = ( RTLNTSTATUSTODOSERROR )GetProcAddress( ntdll_dll, "RtlNtStatusToDosError" ) ) ) { goto LocateNtdllEntry_return; } boolean_ret = TRUE;LocateNtdllEntry_return: if ( FALSE == boolean_ret ) { PrintWin32Error( "GetProcAddress() failed", GetLastError() ); } ntdll_dll = NULL; return( boolean_ret );} /* end of LocateNtdllEntry */static void PrintWin32Error ( char *message, DWORD dwMessageId ){ char *errMsg; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwMessageId, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), ( LPTSTR )&errMsg, 0, NULL ); fprintf( stderr, "%s: %s", message, errMsg ); LocalFree( errMsg ); return;} /* end of PrintWin32Error */static void PrintZwError ( char *message, NTSTATUS status ){ char *errMsg; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, RtlNtStatusToDosError( status ), MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), ( LPTSTR )&errMsg, 0, NULL ); fprintf( stderr, "%s: %s", message, errMsg ); LocalFree( errMsg ); return;} /* end of PrintZwError */int main ( int argc, char * argv[] ){ if ( FALSE == LocateNtdllEntry() ) { fprintf( stderr, "LocateNtdllEntry() failed\n" ); return( EXIT_FAILURE ); } ListModule();system("pause"); return( EXIT_SUCCESS );} /* end of main *//************************************************************************/上面的代码列出了并未文档化的一个枚举结构SYSTEM_INFORMATION_CLASS,这个结构很重要,在微软文档中讲述ZwQuerySystemInformation的第一个参数就指定需要这个结构的一个枚举值(但这个枚举的内容没有全部列出,只列出一小部分,其中没包括第11项SystemModuleInformation,当然也没有包含SYSTEM_MODULE_INFORMATION结构了)。
我们可以再分析一下SYSTEM_MODULE_INFORMATION结构:
typedef struct _SYSTEM_MODULE_INFORMATION // Information Class 11
{
ULONG Reserved[2]; //未了解用途
PVOID Base; //进程基址
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset; //进程名字偏移
CHAR ImageName[256]; //进程映像全路径
}
上面的代码使用了以上结构的三个成员,我贴上代码在我本机运行的结果:
再贴一张drivers.exe执行的结果图,其中很多信息也是通过ZwQuerySystemInformation函数实现的,只是第一个参数不同而已。
- 关于未公开函数ZwQuerySystemInformation的使用
- ZwQuerySystemInformation函数的用法
- ZwQuerySystemInformation函数的用法
- 未公开的函数 NtQuerySystemInformation
- 未公开的加密函数
- ZwQuerySystemInformation的使用
- //关于函数ZwQuerySystemInformation的第一个参数 SystemInformationClass
- PB绝对有用的未公开函数
- 如何调用未公开的API函数
- 如何调用未公开的API函数
- PB绝对有用的未公开函数
- MFC未公开的有用函数收集
- VCL未公开的单元、函数
- PB绝对有用的未公开函数
- 未公开文档函数的调用
- PB绝对有用的未公开函数
- 关于ZwQuerySystemInformation
- 未公开函数
- ibatis mybatis sql语句配置 符号不兼容 大于号 小于号
- Oracle 逗号字符串转成行
- 为新增加用户添加vsftp新目录
- THIS_MODULE
- 堆和栈的区别
- 关于未公开函数ZwQuerySystemInformation的使用
- 空间标题栏流光文字
- JS 回调(CallBack)
- 利用十大最佳游戏开发工具开发游戏
- TimeUnlocker时间解锁器帮助
- Linux常用文件系统的制作命令
- 日志模块(一头文件就实现了日志记录)
- SqlServer-ROLLUP/CUBE
- Oracle Autonomous Transactions(自治事务)