2012-12-16 16 views
7

Sto provando a scrivere, utilizzando il metodo di iniezione DLL, l'applicazione che mostra le bitmap utilizzate da un altro programma e voglio ottenere questo elenco di GDI Handles specifico che sta usando (lista come nell'utilità GDIView.exe). Ho trovato un articolo sulla funzione NtQuerySystemInformation, ma questa descrizione funziona solo con gli handle per gli oggetti del kernel. Qualcuno può aiutare?Come ottenere l'elenco delle maniglie GDI

+1

Se vuoi l'accesso a oggetti GDI di un'altra applicazione, è necessario coordinare con tale applicazione. Altrimenti non sai se l'altra app distruggerà l'oggetto mentre lo stai usando. Semplicemente non esiste un modo affidabile per farlo senza la cooperazione con l'altra app. –

risposta

12

Ecco un codice dell'applicazione della console che esegue il dump di tutti gli handle GDI per un determinato identificativo di processo. Dovrebbe essere compilato e funzionante per applicazioni a 32 o 64 bit, nonché per applicazioni a 32 bit in esecuzione su sistemi operativi a 64 bit. Utilizza molte funzioni non documentate quindi non fare affidamento su di esso :-) I crediti sulle strutture per la tabella GDI condivisa vanno al lavoro originale Feng Yuan. (Ho dovuto adattarlo per WOW64).

Ecco un esempio di output quando eseguito su un blocchetto (64 bit) processo:

[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 

EnumGdi.cpp:

#include "stdafx.h" 
#include "enumgdi.h" 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    if (argc < 2) 
    { 
     printf("Format is EnumGdi <process id>\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); 
} 

EnumGdi.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; 
+2

Probabilmente dovresti documentare su quali versioni di Windows è noto che funzionino. –

+0

Finora è noto lavorare su Windows 7, l'unico che ho a portata di mano :-). Ma è stato progettato per funzionare su XP e versioni successive. –

3

Per prima cosa devi definire cosa intendi esattamente con "Gestisci GDI" e perché devi conoscerli, perché esistono diversi tipi di handle.

Tecnicamente Ci sono 3 principali tipi di maniglie:

  • kernel gestisce. Esempi: handle di file, oggetti di sincronizzazione (eventi, mutex, ecc.), Mappature di file e così via.
  • Gestione utenti. Esempi: HWND, HDC, HICON, maniglie del desktop e così via.
  • Handle GDI. Esempi: HBITMAP, HGDIOBJ (i sottotipi sono HRGN, HPEN e così via).

In particolare alcune persone confondono tra gli handle utente e GDI. Non tutti sanno che HDC utilizzato per il disegno è in realtà non un handle GDI.

Dal punto di vista dell'implementazione c'è una grande differenza tra gli handle utente e GDI. Gli handle utente sono a livello di sistema, sono gestiti nel kernel. Quindi c'è la possibilità di raccogliere tutte le informazioni su di loro nella modalità kernel. Gli handle OTOH GDI sono specifici del processo. Alcuni oggetti GDI sono gestiti esclusivamente in modalità utente (come regioni e DIB).

+0

Sono interessato in particolare agli HBITMAP. GDIView indica l'indirizzo del kernel per questo tipo di handle, quindi penso che sia gestito in modalità kernel. – cadaver

0
Compilable and Buildable 
//Lets name it GDIInquiry.cpp 
    #pragma once 
    #include "stdafx.h" 
    #include "StdAfx.h" 
    #include <tchar.h> 
    #include <stdio.h> 
    #include <malloc.h> 
    #include <dbghelp.h> 
    #include <shlwapi.h> 
    #include <ShlObj.h> 
    #include "GDIInquiry.h" 

    int _tmain(int argc, _TCHAR* argv[]) 
    { 
     if (argc < 2) 
     { 
      printf("Format is EnumGdi <process id>\n"); 
      system("pause"); 
      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(); 
      system("pause"); 
      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); 

     int nDCHandle, nRegionHandle, nBitmapHandle, nPaletteHandle, nFontHandle, nPenHandle, nBrushHandle, nOtherHandle; 
     nDCHandle = nRegionHandle = nBitmapHandle = nPaletteHandle = nFontHandle = nPenHandle = nBrushHandle = nOtherHandle = 0; 

     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); 
       system("pause"); 
       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); 
       system("pause"); 
       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); 
       system("pause"); 
       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); 
       system("pause"); 
       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); 
        nDCHandle++; 
        break; 

       case 4: 
        //printf("Region handle:0x%08X\n", gdiHandle); 
        nRegionHandle++; 
        break; 

       case 5: 
        //printf("Bitmap handle:0x%08X\n", gdiHandle); 
        nBitmapHandle++; 
        break; 

       case 8: 
        //printf("Palette handle:0x%08X\n", gdiHandle); 
        nPaletteHandle++; 
        break; 

       case 10: 
        //printf("Font handle:0x%08X\n", gdiHandle); 
        nFontHandle++; 
        break; 

       case 16: 
        //printf("Brush handle:0x%08X\n", gdiHandle); 
        nPenHandle++; 
        break; 

       case 48: 
        //printf("Pen handle:0x%08X\n", gdiHandle); 
        nBrushHandle++; 
        break; 

       default: 
        //printf("Unknown type handle:0x%08X\n", gdiHandle); 
        nOtherHandle++; 
        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); 
       system("pause"); 
       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); 
       system("pause"); 
       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); 
       system("pause"); 
       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); 
       system("pause"); 
       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); 
        nDCHandle++; 
        break; 

       case 4: 
        //printf("Region handle:0x%08X\n", gdiHandle); 
        nRegionHandle++; 
        break; 

       case 5: 
        //printf("Bitmap handle:0x%08X\n", gdiHandle); 
        nBitmapHandle++; 
        break; 

       case 8: 
        //printf("Palette handle:0x%08X\n", gdiHandle); 
        nPaletteHandle++; 
        break; 

       case 10: 
        //printf("Font handle:0x%08X\n", gdiHandle); 
        nFontHandle++; 
        break; 

       case 16: 
        //printf("Brush handle:0x%08X\n", gdiHandle); 
        nPenHandle++; 
        break; 

       case 48: 
        //printf("Pen handle:0x%08X\n", gdiHandle); 
        nBrushHandle++; 
        break; 

       default: 
        //printf("Unknown type handle:0x%08X\n", gdiHandle); 
        nOtherHandle++; 
        break; 
       } 
      } 
      free(table); 
     } 
     CloseHandle(hProcess); 
     int nTotalGDI = nDCHandle + nRegionHandle + nBitmapHandle + nPaletteHandle + nFontHandle + nPenHandle + nBrushHandle + nOtherHandle; 
     printf("Bitmap:%d\n", nBitmapHandle); 
     printf("Brush:%d\n", nPenHandle); 
     printf("DeviceContext:%d\n", nDCHandle); 
     printf("Font:%d\n", nFontHandle); 
     printf("Palette:%d\n", nPaletteHandle); 
     printf("Pen:%d\n", nBrushHandle); 
     printf("Region:\%d\n", nRegionHandle); 
     printf("Unknown:%d\n", nOtherHandle); 
     printf("GDITotal:%d\n", nTotalGDI); 
     return 1; 
    } 

e GDIInquiry.h codice è indicato sotto

#pragma once 
#include "stdafx.h" 
#include "Winternl.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 
{ 
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; 

Fine

Run commands: 
..\..\GDIInquiry\Debug GDIInquiry.exe PID 

Sample Output: 
cmd 
Microsoft Windows [Version 6.1.7601] 
Copyright (c) 2009 Microsoft Corporation. All rights reserved. 

..\..\GDIInquiry\Debug>GDIInquiry.exe 6772 
Bitmap:302 
Brush:139 
DeviceContext:133 
Font:75 
Palette:1 
Pen:0 
Region:11 
Unknown:0 
GDITotal:661 
Problemi correlati