- Write a program that looks at the kernel object of the process so that we can compare whether the child process inherits a handle from the parent process:
#include <windows.h>#include<stdio.h>#defineNt_success (x) ((x) >= 0)#defineStatus_info_length_mismatch 0xc0000004#defineSystemhandleinformation 16#defineObjectbasicinformation 0#defineObjectnameinformation 1#defineObjecttypeinformation 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); typedefstruct_unicode_string{USHORT Length; USHORT MaximumLength; Pwstr Buffer;} Unicode_string,*Punicode_string;typedefstruct_system_handle{ULONG ProcessId; BYTE Objecttypenumber; BYTE Flags; USHORT Handle; PVOID Object; Access_mask grantedaccess;} System_handle,*Psystem_handle;typedefstruct_system_handle_information{ULONG Handlecount; System_handle handles[1];} System_handle_information,*Psystem_handle_information;typedefenum_pool_type{NonPagedPool, PagedPool, Nonpagedpoolmustsucceed, Dontusethistype, Nonpagedpoolcachealigne D, pagedpoolcachealigned, nonpagedpoolcachealignedmusts} pool_type,*Ppool_type;typedefstruct_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) {returnGetProcAddress (Getmodulehandlea (LibraryName), procname);}intMainintARGC, WCHAR *argv[]) {NTSTATUS status; ULONG pid; HANDLE ProcessHandle; ULONG handleinfosize=0x10000; Psystem_handle_information Handleinfo; HANDLE Duphandle=NULL; ULONG returnlength; intNcount =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"); returnFALSE; } _ntduplicateobject Ntduplicateobject=(_ntduplicateobject) getlibraryprocaddress ("Ntdll.dll","Ntduplicateobject"); if(NULL = =ntduplicateobject) {printf ("Get Address of Ntduplicateobject failed!\n"); returnFALSE; } _ntqueryobject Ntqueryobject=(_ntqueryobject) getlibraryprocaddress ("Ntdll.dll","Ntqueryobject"); if(NULL = =ntqueryobject) {printf ("Get Address of Ntqueryobject failed!\n"); returnFALSE; } if(! (ProcessHandle =openprocess (Process_dup_handle, FALSE, PID))) {printf ("Open Process failed!\n"); returnFALSE; } 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)) { returnFALSE; } for(inti =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 and so display.*/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, Objectnameinf O, Returnlength, NULL ))) {/*We have the type name and so just display.*/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 ();}
- The parent process then writes a random one, primarily to create three named Kernel objects, and then let the child process inherit two of them:
#include <iostream>#include<windows.h>voidMain () {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);}
Three mutex handles created by the parent process:
Then look at the child process:
Sure enough, it inherits the 1 and 3 handles.
"Windows core Programming" chapter 3rd--handle Replication related experiments