c++ - 如何获取 GDI 句柄列表

c++ - 如何获取 GDI 句柄列表

这是一个控制台应用程序代码,它转储给定进程标识符的所有 GDI 句柄。它应该为 32 位或 64 位应用程序以及在 64 位操作系统上运行的 32 位应用程序编译和工作正常。它使用了很多未记录的函数,所以不要依赖它 :-) 共享 GDI 表的结构归功于冯源的原创作品。(我不得不为 WOW64 改编它)。

以下是在记事本(64 位)进程上运行时的示例输出:

[C:\Temp\EnumGdi\Debug]EnumGdi.exe 5916

DC handle:0xF20105DB

Bitmap handle:0xDF05118B

Font handle:0xDC0A19E0

Font handle:0xAB0A1A62

DC handle:0xA3011A63

Region handle:0xAF041B7B

Brush handle:0x11101C5B

Font handle:0x280A1CA1

Font handle:0xBB0A1D13

Bitmap handle:0xA3051DD8

Font handle:0xB40A1DDC

Region handle:0x3A041EE4

Brush handle:0x0B101F04

Region handle:0xC6041F3D

Font handle:0x2C0A2384

Brush handle:0xBA1024DA

枚举Gdi.cpp:

#include "stdafx.h"

#include "enumgdi.h"

int _tmain(int argc, _TCHAR* argv[])

{

if (argc < 2)

{

printf("Format is EnumGdi \n");

return 0;

}

// get process identifier

DWORD dwId = _wtoi(argv[1]);

// open the process

HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwId);

DWORD err = 0;

if (hProcess == NULL)

{

printf("OpenProcess %u failed\n", dwId);

err = GetLastError();

return -1;

}

// determine if 64 or 32-bit processor

SYSTEM_INFO si;

GetNativeSystemInfo(&si);

// NOTE: as this is undocumented, it *may vary* depending on bitness (32/64) and on Windows version.

// use WinDbg "dt ntdll!_PEB" command and search for GdiSharedHandleTable offset to find the truth out

DWORD GdiSharedHandleTableOffset = si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ? 0xF8 : 0x94;

DWORD tableCount = 16384; // count of GDI table cells

// determine if this process is running on WOW64

BOOL wow;

IsWow64Process(GetCurrentProcess(), &wow);

// read basic info to get PEB address, we only need the beginning of PEB

DWORD pebSize = GdiSharedHandleTableOffset + 8;

LPBYTE peb = (LPBYTE)malloc(pebSize);

ZeroMemory(peb, pebSize);

if (wow)

{

// we're running as a 32-bit process in a 64-bit process

PROCESS_BASIC_INFORMATION_WOW64 pbi;

ZeroMemory(&pbi, sizeof(pbi));

// get process information from 64-bit world

_NtQueryInformationProcess query = (_NtQueryInformationProcess)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtWow64QueryInformationProcess64");

err = query(hProcess, 0, &pbi, sizeof(pbi), NULL);

if (err != 0)

{

printf("NtWow64QueryInformationProcess64 failed\n");

CloseHandle(hProcess);

return -1;

}

// read PEB from 64-bit address space

_NtWow64ReadVirtualMemory64 read = (_NtWow64ReadVirtualMemory64)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtWow64ReadVirtualMemory64");

err = read(hProcess, pbi.PebBaseAddress, peb, pebSize, NULL);

if (err != 0)

{

printf("NtWow64ReadVirtualMemory64 PEB failed\n");

CloseHandle(hProcess);

return -1;

}

// get GDI table ptr from PEB

GDICELL_WOW64* gdiTable = (GDICELL_WOW64*)*(LPVOID*)(peb + GdiSharedHandleTableOffset); // address in remote process adress space

if (gdiTable == NULL)

{

printf("GDI32.DLL is not loaded in the process\n");

CloseHandle(hProcess);

return -1;

}

free(peb);

DWORD tableSize = sizeof(GDICELL_WOW64) * tableCount; // size of GDI table

GDICELL_WOW64* table = (GDICELL_WOW64*)malloc(tableSize); // local table copied over to our address space

// copy GDI table

err = read(hProcess, gdiTable, table, tableSize, NULL);

if (err != 0)

{

printf("NtWow64ReadVirtualMemory64 GdiTable failed\n");

free(table);

CloseHandle(hProcess);

return -1;

}

for(DWORD i = 0; i < tableCount; i++)

{

GDICELL_WOW64 cell = table[i];

if (cell.wProcessId != dwId)

continue;

HGDIOBJ gdiHandle = (HGDIOBJ)((cell.wUpper << 16) + i);

WORD type = cell.wType & 0x7F;

switch(type)

{

case 1:

printf("DC handle:0x%08X\n", gdiHandle );

break;

case 4:

printf("Region handle:0x%08X\n", gdiHandle);

break;

case 5:

printf("Bitmap handle:0x%08X\n", gdiHandle);

break;

case 8:

printf("Palette handle:0x%08X\n", gdiHandle);

break;

case 10:

printf("Font handle:0x%08X\n", gdiHandle);

break;

case 16:

printf("Brush handle:0x%08X\n", gdiHandle);

break;

case 48:

printf("Pen handle:0x%08X\n", gdiHandle);

break;

default:

printf("Unknown type handle:0x%08X\n", gdiHandle);

break;

}

}

free(table);

}

else

{

// we're running as a 32-bit process in a 32-bit OS, or as a 64-bit process in a 64-bit OS

PROCESS_BASIC_INFORMATION pbi;

ZeroMemory(&pbi, sizeof(pbi));

// get process information

_NtQueryInformationProcess query = (_NtQueryInformationProcess)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryInformationProcess");

err = query(hProcess, 0, &pbi, sizeof(pbi), NULL);

if (err != 0)

{

printf("NtQueryInformationProcess failed\n");

CloseHandle(hProcess);

return -1;

}

// read PEB

_NtReadVirtualMemory read = (_NtReadVirtualMemory)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtReadVirtualMemory");

err = read(hProcess, pbi.PebBaseAddress, peb, pebSize, NULL);

if (err != 0)

{

printf("NtReadVirtualMemory PEB failed\n");

CloseHandle(hProcess);

return -1;

}

// get GDI table ptr

GDICELL* gdiTable = (GDICELL*)*(LPVOID*)(peb + GdiSharedHandleTableOffset); // address in remote process adress space

if (gdiTable == NULL)

{

printf("GDI32.DLL is not loaded in the process\n");

CloseHandle(hProcess);

return -1;

}

free(peb);

DWORD tableSize = sizeof(GDICELL) * tableCount; // size of GDI table

GDICELL* table = (GDICELL*)malloc(tableSize); // local table copied over to our address space

// read GDI table

err = read(hProcess, gdiTable, table, tableSize, NULL);

if (err != 0)

{

printf("NtReadVirtualMemory GdiTable failed\n");

free(table);

CloseHandle(hProcess);

return -1;

}

for(DWORD i = 0; i < tableCount; i++)

{

GDICELL cell = table[i];

if (cell.wProcessId != dwId)

continue;

HGDIOBJ gdiHandle = (HGDIOBJ)((cell.wUpper << 16) + i);

WORD type = cell.wType & 0x7F;

switch(type)

{

case 1:

printf("DC handle:0x%08X\n", gdiHandle );

break;

case 4:

printf("Region handle:0x%08X\n", gdiHandle);

break;

case 5:

printf("Bitmap handle:0x%08X\n", gdiHandle);

break;

case 8:

printf("Palette handle:0x%08X\n", gdiHandle);

break;

case 10:

printf("Font handle:0x%08X\n", gdiHandle);

break;

case 16:

printf("Brush handle:0x%08X\n", gdiHandle);

break;

case 48:

printf("Pen handle:0x%08X\n", gdiHandle);

break;

default:

printf("Unknown type handle:0x%08X\n", gdiHandle);

break;

}

}

free(table);

}

CloseHandle(hProcess);

}

枚举Gdi.h:

#pragma once

#include "stdafx.h"

// defines a GDI CELL

typedef struct

{

LPVOID pKernelAddress;

USHORT wProcessId;

USHORT wCount;

USHORT wUpper;

USHORT wType;

LPVOID pUserAddress;

} GDICELL;

// defines a GDI CELL for WOW64

typedef struct

{

PVOID64 pKernelAddress;

USHORT wProcessId;

USHORT wCount;

USHORT wUpper;

USHORT wType;

PVOID64 pUserAddress;

} GDICELL_WOW64;

// NtQueryInformationProcess for pure 32 and 64-bit processes

typedef NTSTATUS (NTAPI *_NtQueryInformationProcess)(

IN HANDLE ProcessHandle,

ULONG ProcessInformationClass,

OUT PVOID ProcessInformation,

IN ULONG ProcessInformationLength,

OUT PULONG ReturnLength OPTIONAL

);

typedef NTSTATUS (NTAPI *_NtReadVirtualMemory)(

IN HANDLE ProcessHandle,

IN PVOID BaseAddress,

OUT PVOID Buffer,

IN SIZE_T Size,

OUT PSIZE_T NumberOfBytesRead);

// NtQueryInformationProcess for 32-bit process on WOW64

typedef NTSTATUS (NTAPI *_NtWow64ReadVirtualMemory64)(

IN HANDLE ProcessHandle,

IN PVOID64 BaseAddress,

OUT PVOID Buffer,

IN ULONG64 Size,

OUT PULONG64 NumberOfBytesRead);

// PROCESS_BASIC_INFORMATION for pure 32 and 64-bit processes

typedef struct _PROCESS_BASIC_INFORMATION {

PVOID Reserved1;

PVOID PebBaseAddress;

PVOID Reserved2[2];

ULONG_PTR UniqueProcessId;

PVOID Reserved3;

} PROCESS_BASIC_INFORMATION;

// PROCESS_BASIC_INFORMATION for 32-bit process on WOW64

// The definition is quite funky, as we just lazily doubled sizes to match offsets...

typedef struct _PROCESS_BASIC_INFORMATION_WOW64 {

PVOID Reserved1[2];

PVOID64 PebBaseAddress;

PVOID Reserved2[4];

ULONG_PTR UniqueProcessId[2];

PVOID Reserved3[2];

} PROCESS_BASIC_INFORMATION_WOW64;

相关文章

蓝鲸游戏哪里玩 推荐蓝鲸游戏的玩法和平台
狗狗都有哪些品种?探索各类犬种的魅力与特点
国内365bet登录网址

狗狗都有哪些品种?探索各类犬种的魅力与特点

🕒 08-21 👁️ 9656
南雪APP下载
beat365体育ios版下载

南雪APP下载

🕒 06-28 👁️ 6709
游戏玩家必选 罗技G105背光键盘首测
bas365

游戏玩家必选 罗技G105背光键盘首测

🕒 08-21 👁️ 1119
长期喝红糖水:好处、风险与科学饮用指南
beat365体育ios版下载

长期喝红糖水:好处、风险与科学饮用指南

🕒 01-03 👁️ 7031
青岛12种美食特产,作为“伴手礼”最棒!青岛旅游必备
beat365体育ios版下载

青岛12种美食特产,作为“伴手礼”最棒!青岛旅游必备

🕒 09-23 👁️ 4149
巴厘岛婚纱照要多少钱
国内365bet登录网址

巴厘岛婚纱照要多少钱

🕒 10-17 👁️ 1715
[官方旗舰店]小米米家电动滑板车3青春版锂电池电动折叠代驾两轮代步车电动车 白色
天涯明月刀青龙换世雅集答题指引 雅集刷新时间地点整理
beat365体育ios版下载

天涯明月刀青龙换世雅集答题指引 雅集刷新时间地点整理

🕒 07-09 👁️ 6590