获得进程的EPROCESS |
责任编辑:admin 更新日期:2005-7-6 |
<script language="javascript" type="text/javascript">
</script> <script language="javascript" type="text/javascript"> document.write("本文网址:"); document.write("
"); </script> 本文网址:
|
本文作者:[I.T.S]SystEm32 每个Windows进程都有一个相对应的执行体进程(EPROCESS,也就是KTEB),EPROCESS不仅包括了进程的许多属性,还包扩了许多指向其他数据结构的指针,其中包含了大量有用的信息.本文仅讲述如何获得特定进程对应的EPROCESS,EPROCESS的作用及数据结构不在本文讨论范围之内. 绿盟高手flier在他的文章中提到,使用ZwQuerySystemInformation函数获取所有核心句柄表,线性搜索到进程句柄,其指向的内核对象就是EPROCESS。 ZwQuerySystemInformation函数原形如下 NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation ( IN SYSTEM_INFORMATION_CLASS SystemInformationClass, IN OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength OPTIONAL ); 参数意义如下 SystemInformationClass:被查询的系统信息的类型,SYSTEM_INFORMATION_CLASS的枚举类型之一 SystemInformation:指向一个接受系统信息的缓冲区的指针 SystemInformationLength:缓冲区长度 ReturnLength:指向一个接受实际返回字节数的变量,可以为0 为了获取EPROCESS,我们使用SYSTEM_HANDLE_INFORMATION作为第一参数来调用ZwQuerySystemInformation SYSTEM_INFORMATION_CLASS的结构如下 typedef struct _SYSTEM_HANDLE_INFORMATION { ULONG ProcessId; UCHAR ObjectTypeNumber; UCHAR Flags; USHORT Handle; PVOID Object; ACCESS_MASK GrantedAccess; } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; ProcessId:进程标识符 ObjectTypeNumber;打开的对象的类型 Flags:句柄属性标志 Handle:句柄数值,在进程打开的句柄中唯一标识某个句柄 Object:这个就是句柄对应的EPROCESS的地址 GrantedAccess:句柄对象的访问权限 下面我写了一个小程序来获得EPROCESS( GetKTEB.cpp ) 比较faint的是程序写好后发现并未如预期般获得EPROCESS,通过调试发现ZwQuerySystemInformation()返回的进程的句柄中并没有进程本身的句柄 怎么会这样?难道程序写错了?*_* 现在只好靠SoftICE给出答案了,CTRL+D唤出SoftICE,随便选了个进程--QQ,让我们来看看SoftICE的输出 :proc -o QQ Process KPEB PID Threads Pri User Time Krnl Time Status QQ 827CD520 11C 2A 8 00000B90 000008D4 Ready ---- Handle Table Information ---- Handle Table: FFAD93C8 Handle Array: E2BEB000 Entries: 590 Handle Ob Hdr * Object * Type 0000 00000000 00000018 ? 0004 E2DA5E58 E2DA5E70 Section 0008 FFAB35C8 FFAB35E0 Event 000C FFAB3B08 FFAB3B20 Event 0010 85C70188 85C701A0 Event 0014 81515778 81515790 Directory 0018 FFAB7BB2 FFAB7BCA ? 001C 814A1858 814A1870 Directory 0020 80288C88 80288CA0 Event 0024 E2CFE7F9 E2CFE811 ? 0028 842D7B08 842D7B20 Event 002C 80E9B989 80E9B9A1 ? 0030 E1372198 E13721B0 Section 0034 814602C0 814602D8 WindowStation 0038 81455CE0 81455CF8 Desktop 003C 814602C0 814602D8 WindowStation 0040 E2B3C1A8 E2B3C1C0 Key 0044 E286D6E8 E286D700 Key 0048 E2B3C0E8 E2B3C100 Key 004C E2B3C068 E2B3C080 Key 0050 E2BEE688 E2BEE6A0 Key 0054 8147C998 8147C9B0 Directory 0058 829D1128 829D1140 Event 005C 83F991E8 83F99200 Event 0060 E2BEE608 E2BEE620 Key 0064 FFB07568 FFB07580 Event 0068 801747E8 80174800 Event 006C 80174828 80174840 Event 0070 845E8808 845E8820 Event 0074 81448798 814487B0 Event 0078 E2B9A888 E2B9A8A0 Key 007C 845E8648 845E8660 Event 0080 FF9E2DB8 FF9E2DD0 Mutant 0084 FF9E2D58 FF9E2D70 Mutant 0088 83CFC378 83CFC390 Mutant 008C 801749B0 801749C8 File 0090 E2C48668 E2C48680 Section 0094 FF965168 FF965180 Event 0098 FF9E7D88 FF9E7DA0 Event 009C FFAD3DE8 FFAD3E00 Event 00A0 80AD63C8 80AD63E0 Event 00A4 E28073A8 E28073C0 Key 00A8 FF955588 FF9555A0 Thread 00AC E2770728 E2770740 Key 00B0 FF923438 FF923450 Mutant 00B4 FFAE3B38 FFAE3B50 Mutant 00B8 83B80728 83B80740 Event 00BC 83B80668 83B80680 Event 00C0 E2E3C448 E2E3C460 Section 00C4 83776A08 83776A20 Thread 00C8 81489E48 81489E60 Event 00CC 83776CC8 83776CE0 Event 00D0 83776C88 83776CA0 Event 00D4 83776768 83776780 Event 00D8 E2837D88 E2837DA0 Key 00DC 8146B3A8 8146B3C0 Event 00E0 FF908308 FF908320 Event 00E4 81494868 81494880 Event 00E8 FF9064C8 FF9064E0 Event 00EC FF908FC8 FF908FE0 Event 00F0 FF908F88 FF908FA0 Event 00F4 FF955588 FF9555A0 Thread 00F8 FF908F48 FF908F60 Event 00FC E2CB1558 E2CB1570 Port 0100 FF90A2C8 FF90A2E0 IoCompletion 0104 E2CFE708 E2CFE720 Port 0108 FF90A2C8 FF90A2E0 IoCompletion 010C 837762A8 837762C0 Thread 0110 8103BBC8 8103BBE0 Event 0114 813DBDB8 813DBDD0 Event 0118 FF814788 FF8147A0 Event 011C E1358DA8 E1358DC0 Key 0120 E2CFC428 E2CFC440 Key 0124 8103B9C8 8103B9E0 Event 0128 E2C9A968 E2C9A980 Key 012C 83B34E88 83B34EA0 Event 0130 E2CFD948 E2CFD960 Key 0134 83B34E08 83B34E20 Event .... .....................省略 看了一阵,确实没有QQ本身进程的Handle,那么怎么办呢? 想了一会儿...既然Win32子系统是由CSRSS.EXE来管理的,那么用户创建的进程的句柄应该在CSRSS.EXE里面找得到,用SoftICE验证后发现确实如此 可是这没办法得到指定进程的句柄,和我所需相去甚远,只有另选它路 后来总算想到解决办法,既然没有进程的句柄,那就创建一个吧,OpenProcess()这个函数可以打开一个进程的句柄,正合所需. 果然加上这么一句后,ZwQuerySystemInformation()获得了EPROCESS 修改好的程序代码如下,获得本身进程的EPROCESS地址,稍作修改可获取任意进程 代码: -------------------------------------------------------------------------------- #include <windows.h> #include <stdio.h> #include <aclapi.h> #include <conio.h> /* * you'll find a list of NTSTATUS status codes in the DDK header * ntstatus.h (/WINDDK00.1106/inc/ddk/wxp/) */ #define NT_SUCCESS(status) ((NTSTATUS)(status)>=0) #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) #define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L) /* ************************************************************************* * ntddk.h */ typedef LONG NTSTATUS; typedef ULONG ACCESS_MASK; /* * ntdef.h ************************************************************************* */ /* ************************************************************************* * <<Windows NT/2000 Native API Reference>> - Gary Nebbett */ typedef enum _SYSTEM_INFORMATION_CLASS { SystemHandleInformation = 16 } SYSTEM_INFORMATION_CLASS; /* *Information Class 16 */ typedef struct _SYSTEM_HANDLE_INFORMATION { ULONG ProcessId; UCHAR ObjectTypeNumber; UCHAR Flags; USHORT Handle; PVOID Object; ACCESS_MASK GrantedAccess; } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; #define InitializeObjectAttributes( p, n, a, r, s ) { (p)->Length = sizeof( OBJECT_ATTRIBUTES ); (p)->RootDirectory = r; (p)->Attributes = a; (p)->ObjectName = n; (p)->SecurityDescriptor = s; (p)->SecurityQualityOfService = NULL; } /* ************************************************************************* * <<Windows NT/2000 Native API Reference>> - Gary Nebbett ************************************************************************* */ typedef ULONG ( __stdcall *RTLNTSTATUSTODOSERROR ) ( IN NTSTATUS Status ); typedef NTSTATUS ( __stdcall *ZWQUERYSYSTEMINFORMATION ) ( IN SYSTEM_INFORMATION_CLASS SystemInformationClass, IN OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength OPTIONAL ); /************************************************************************ * * * Function Prototype * * * ************************************************************************/ static DWORD GetEprocessFromPid ( ULONG PID ); static BOOL LocateNtdllEntry ( void ); /************************************************************************ * * * Static Global Var * * * ************************************************************************/ static RTLNTSTATUSTODOSERROR RtlNtStatusToDosError = NULL; static ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation = NULL; static HMODULE hModule = NULL; /************************************************************************/ static DWORD GetEprocessFromPid ( ULONG PID ) { NTSTATUS status; PVOID buf = NULL; ULONG size = 1; ULONG NumOfHandle = 0; ULONG i; PSYSTEM_HANDLE_INFORMATION h_info = NULL; for ( size = 1; ; size *= 2 ) { if ( NULL == ( buf = calloc( size, 1 ) ) ) { fprintf( stderr, "calloc( %u, 1 ) failed/n", size ); goto GetEprocessFromPid_exit; } status = ZwQuerySystemInformation( SystemHandleInformation, buf, size, NULL ); if ( !NT_SUCCESS( status ) ) { if ( STATUS_INFO_LENGTH_MISMATCH == status ) { free( buf ); buf = NULL; } else { printf( "ZwQuerySystemInformation() failed"); goto GetEprocessFromPid_exit; } } else { break; } } /* end of for */ //返回到缓冲区的首先是一个ULONG类型的数据,表示有多少数组 NumOfHandle = (ULONG)buf; h_info = ( PSYSTEM_HANDLE_INFORMATION )((ULONG)buf+4); for(i = 0; i<NumOfHandle ;i++) { if( ( h_info.ProcessId == PID )&&( h_info.ObjectTypeNumber == 5 ))//&&( h_info.Handle==0x3d8 ) ) { printf("Handle:0x%x,OBJECT 0x%x/n/r",h_info.Handle,h_info.Object); return((DWORD)(h_info.Object)); } } GetEprocessFromPid_exit: if ( buf != NULL ) { free( buf ); buf = NULL; } return(FALSE); } /* * ntdll.dll */ static BOOL LocateNtdllEntry ( void ) { BOOL ret = FALSE; char NTDLL_DLL[] = "ntdll.dll"; HMODULE ntdll_dll = NULL; if ( ( ntdll_dll = GetModuleHandle( NTDLL_DLL ) ) == NULL ) { printf( "GetModuleHandle() failed"); return( FALSE ); } if ( !( ZwQuerySystemInformation = ( ZWQUERYSYSTEMINFORMATION )GetProcAddress( ntdll_dll, "ZwQuerySystemInformation" ) ) ) { goto LocateNtdllEntry_exit; } ret = TRUE; LocateNtdllEntry_exit: if ( FALSE == ret ) { printf( "GetProcAddress() failed"); } ntdll_dll = NULL; return( ret ); } /* end of LocateNtdllEntry */ int main(int argc,char **argv) { LocateNtdllEntry( ); //打开自身句柄,这样才能在handle列表中找到自己,PROCESS 对应 ObjectTypeNum 为5 OpenProcess( PROCESS_ALL_ACCESS,FALSE,GetCurrentProcessId() ); DWORD Addr = GetEprocessFromPid( (DWORD)GetCurrentProcessId() ); printf("result: Current EPROCESS's Address is 0x%x /n/r",Addr); return TRUE; } |
获得进程的EPROCESS--转
最新推荐文章于 2020-11-19 08:43:39 发布