2012-12-16 22 views
7

Próbuję pisać, używając metody wtrysku DLL, aplikacji, która wyświetla mapy bitowe używane przez inny program i chcę uzyskać dla tej specyficznej listy procesów uchwytów GDI, których używa (lista w narzędziu GDIView.exe). Znalazłem artykuł o funkcji NtQuerySystemInformation, ale ten opis działa tylko z uchwytami do Kernel Objects. Czy ktoś może pomóc?Jak uzyskać listę uchwytów GDI

+1

Jeśli chcesz otrzymać dostęp do obiektów GDI innej aplikacji, trzeba skoordynować z tej aplikacji. W przeciwnym razie nie wiesz, czy druga aplikacja zniszczy obiekt, gdy go używasz. Nie ma po prostu niezawodnego sposobu, aby to zrobić bez współpracy z drugą aplikacją. –

Odpowiedz

12

Oto kod aplikacji konsoli, który zrzuca wszystkie uchwyty GDI dla danego identyfikatora procesu. Powinien się skompilować i działać poprawnie w przypadku aplikacji 32- lub 64-bitowych, a także 32-bitowej aplikacji działającej w 64-bitowych systemach operacyjnych. Korzysta z wielu nieudokumentowanych funkcji, więc nie należy polegać na tym :-) Kredyty na strukturach dla wspólnej tabeli GDI idą do oryginalnej pracy z Feng Yuan. (Musiałem to zaadaptować na WOW64).

Oto przykładowe dane wyjściowe po ran na schowek (64 bity) procesu:

[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

Prawdopodobnie powinieneś udokumentować, jakie wersje systemu Windows działają. –

+0

Do tej pory wiadomo, że działa w systemie Windows 7, jedynym, który mam pod ręką :-). Ale został zaprojektowany do pracy na XP i wyżej. –

3

Najpierw musisz zdefiniować, co masz na myśli dokładnie według "uchwytów GDI" i dlaczego musisz o nich wiedzieć, ponieważ istnieją różne rodzaje uchwytów.

Technicznie są tam 3 główne rodzaje uchwytów:

  • Kernel uchwytami. Przykłady: uchwyty plików, obiekty synchronizacji (zdarzenia, muteksy itp.), Odwzorowania plików itp.
  • Uchwyty użytkownika. Przykłady: HWND, HDC, HICON, uchwyty pulpitu itp.
  • Uchwyty GDI. Przykłady: HBITMAP, HGDIOBJ (podtypy to HRGN, HPEN itd.).

W szczególności niektórzy ludzie mylą użytkownika z uchwytami GDI. Nie każdy wie, że HDC, który jest używany do rysowania, jest w rzeczywistości , a nie uchwytem GDI.

Z punktu widzenia wdrożenia istnieje duża różnica między uchwytami użytkownika i GDI. Uchwyty użytkowników są systemowe i zarządzane w jądrze. W związku z tym istnieje możliwość zebrania wszystkich informacji o nich w trybie jądra. Uchwyty OTOH GDI są specyficzne dla procesu. Niektóre obiekty GDI są zarządzane wyłącznie w trybie użytkownika (np. Regiony i DIB).

+0

Jestem szczególnie zainteresowany HBITMAP. GDIView wskazuje adres jądra dla tego typu uchwytu, więc myślę, że jest on zarządzany w trybie jądra. – 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; 
    } 

i kod GDIInquiry.h jest podany poniżej

#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; 

Finish

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 
Powiązane problemy