標籤:table add 繼承 printf fine ppi eal cmap desc
- 先寫一個程式,用來查看進程的核心對象,這樣我們就能比較子進程是否繼承了父進程的某個控制代碼:
#include <windows.h>#include <stdio.h>#define NT_SUCCESS(x) ((x) >= 0)#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004#define SystemHandleInformation 16#define ObjectBasicInformation 0#define ObjectNameInformation 1#define ObjectTypeInformation 2typedef NTSTATUS(NTAPI *_NtQuerySystemInformation)( ULONG SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength );typedef NTSTATUS(NTAPI *_NtDuplicateObject)( HANDLE SourceProcessHandle, HANDLE SourceHandle, HANDLE TargetProcessHandle, PHANDLE TargetHandle, ACCESS_MASK DesiredAccess, ULONG Attributes, ULONG Options );typedef NTSTATUS(NTAPI *_NtQueryObject)( HANDLE ObjectHandle, ULONG ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength );typedef struct _UNICODE_STRING{ USHORT Length; USHORT MaximumLength; PWSTR Buffer;} UNICODE_STRING, *PUNICODE_STRING;typedef struct _SYSTEM_HANDLE{ ULONG ProcessId; BYTE ObjectTypeNumber; BYTE Flags; USHORT Handle; PVOID Object; ACCESS_MASK GrantedAccess;} SYSTEM_HANDLE, *PSYSTEM_HANDLE;typedef struct _SYSTEM_HANDLE_INFORMATION{ ULONG HandleCount; SYSTEM_HANDLE Handles[1];} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;typedef enum _POOL_TYPE{ NonPagedPool, PagedPool, NonPagedPoolMustSucceed, DontUseThisType, NonPagedPoolCacheAligned, PagedPoolCacheAligned, NonPagedPoolCacheAlignedMustS} POOL_TYPE, *PPOOL_TYPE;typedef struct _OBJECT_TYPE_INFORMATION{ UNICODE_STRING Name; ULONG TotalNumberOfObjects; ULONG TotalNumberOfHandles; ULONG TotalPagedPoolUsage; ULONG TotalNonPagedPoolUsage; ULONG TotalNamePoolUsage; ULONG TotalHandleTableUsage; ULONG HighWaterNumberOfObjects; ULONG HighWaterNumberOfHandles; ULONG HighWaterPagedPoolUsage; ULONG HighWaterNonPagedPoolUsage; ULONG HighWaterNamePoolUsage; ULONG HighWaterHandleTableUsage; ULONG InvalidAttributes; GENERIC_MAPPING GenericMapping; ULONG ValidAccess; BOOLEAN SecurityRequired; BOOLEAN MaintainHandleCount; USHORT MaintainTypeList; POOL_TYPE PoolType; ULONG PagedPoolUsage; ULONG NonPagedPoolUsage;} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;PVOID GetLibraryProcAddress(PSTR LibraryName, PSTR ProcName){ return GetProcAddress(GetModuleHandleA(LibraryName), ProcName);}int main(int argc, WCHAR *argv[]){ NTSTATUS status; ULONG pid; HANDLE processHandle; ULONG handleInfoSize = 0x10000; PSYSTEM_HANDLE_INFORMATION handleInfo; HANDLE dupHandle = NULL; ULONG returnLength; int nCount = 0; pid = 13104;//Input which process do you want to query. _NtQuerySystemInformation NtQuerySystemInformation = (_NtQuerySystemInformation)GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation"); if (NULL == NtQuerySystemInformation){ printf("Get address of NtQuerySystemInformation failed!\n"); return FALSE; } _NtDuplicateObject NtDuplicateObject = (_NtDuplicateObject)GetLibraryProcAddress("ntdll.dll", "NtDuplicateObject"); if (NULL == NtDuplicateObject){ printf("Get address of NtDuplicateObject failed!\n"); return FALSE; } _NtQueryObject NtQueryObject = (_NtQueryObject)GetLibraryProcAddress("ntdll.dll", "NtQueryObject"); if (NULL == NtQueryObject){ printf("Get address of NtQueryObject failed!\n"); return FALSE; } if (!(processHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid))){ printf("Open process failed!\n"); return FALSE; } handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize); while ((status = NtQuerySystemInformation(//Query system handle information, if return STATUS_INFO_LENGTH_MISMATCH, you should realloc space. SystemHandleInformation, handleInfo, handleInfoSize, NULL )) == STATUS_INFO_LENGTH_MISMATCH){ handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);//assign new value to handleInfoSize } if (!NT_SUCCESS(status)) { return FALSE; } for (int i = 0; i < handleInfo->HandleCount; i++)//reverse all handles { SYSTEM_HANDLE handle = handleInfo->Handles[i]; POBJECT_TYPE_INFORMATION objectTypeInfo; PVOID objectNameInfo; UNICODE_STRING objectName; if (handle.ProcessId != pid) continue; if (!NT_SUCCESS(status = NtDuplicateObject(//duplicate handle information into self. processHandle, (HANDLE)handle.Handle, GetCurrentProcess(), &dupHandle, 0, 0, 0 ))) { continue; } //////////////////////////////////////////////////////////////////////////////////// //you can query objectNameInfo directly. objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000); if (!NT_SUCCESS(status = NtQueryObject(//Get the object according handle. dupHandle, ObjectTypeInformation, objectTypeInfo, 0x1000, NULL ))) { printf("Query [%#x] Error:%x!\n", handle.Handle, status); CloseHandle(dupHandle); continue; } if (handle.GrantedAccess == 0x0012019f) { /* We have the type, so display that. */ printf( "[%#x] %.*S: (did not get name)\n", handle.Handle, objectTypeInfo->Name.Length / 2, objectTypeInfo->Name.Buffer ); free(objectTypeInfo); CloseHandle(dupHandle); continue; } objectNameInfo = malloc(0x1000); if (!NT_SUCCESS(NtQueryObject( dupHandle, ObjectNameInformation, objectNameInfo, 0x1000, &returnLength ))){ objectNameInfo = realloc(objectNameInfo, returnLength); if (!NT_SUCCESS(NtQueryObject( dupHandle, ObjectNameInformation, objectNameInfo, returnLength, NULL ))) { /* We have the type name, so just display that. */ printf( "[%#x] %.*S: (could not get name)\n", handle.Handle, objectTypeInfo->Name.Length / 2, objectTypeInfo->Name.Buffer ); free(objectTypeInfo); free(objectNameInfo); CloseHandle(dupHandle); continue; } } objectName = *(PUNICODE_STRING)objectNameInfo; if (objectName.Length) { /* The object has a name. */ printf( "[%#x] %.*S: %.*S\n", handle.Handle, objectTypeInfo->Name.Length / 2, objectTypeInfo->Name.Buffer, objectName.Length / 2, objectName.Buffer ); } else { /* Print something else. */ printf( "[%#x] %.*S: (unnamed)\n", handle.Handle, objectTypeInfo->Name.Length / 2, objectTypeInfo->Name.Buffer ); } nCount++; free(objectTypeInfo); free(objectNameInfo); CloseHandle(dupHandle); } printf("Handle Count:%d\n", nCount); free(handleInfo); CloseHandle(processHandle); getchar();}
- 然後父進程就隨便寫一個,主要是為了建立三個命名核心對象,然後讓子進程繼承其中的兩個:
#include <iostream>#include <windows.h>void main(){ SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE;//if the handle can be inherited. HANDLE hMuxtex1 = CreateMutex(&sa, FALSE, "TestHandle1"); HANDLE hMuxtex2 = CreateMutex(NULL, FALSE, "TestHandle2"); HANDLE hMuxtex3 = CreateMutex(&sa, FALSE, "TestHandle3"); STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); CreateProcess(NULL, "E:\\Coding\\Cpp\\test\\Windows_Core\\P96_3\\Debug\\P96_3.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi); while (TRUE);}
父進程建立的三個互斥量控制代碼:
然後再去查看子進程:
果然之繼承了其中的1和3控制代碼。
《Windows核心編程》第3章——handle複製相關實驗