标签:table add 继承 printf fine ppi eal cmap desc
- 先写一个程序,用来查看进程的内核对象,这样我们就能比较子进程是否继承了父进程的某个句柄:
#include
#include #define NT_SUCCESS(x) ((x) >= 0)
#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
#define SystemHandleInformation 16
#define ObjectBasicInformation 0
#define ObjectNameInformation 1
#define ObjectTypeInformation 2
typedef 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 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
#include 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复制相关实验
标签:table add 继承 printf fine ppi eal cmap desc
原文地址:https://www.cnblogs.com/predator-wang/p/8537319.html