Results 1 to 3 of 3

Thread: RtlQueryProcessDebugInformation as Anti-Dbg Trick

  1. #1
    Registered User
    Join Date
    Aug 2005
    Location
    Italy
    Posts
    133
    Blog Entries
    31

    RtlQueryProcessDebugInformation as Anti-Dbg Trick

    The following paper will uncover some interesting undocumented functions relative to Windows Heap Enumeration.

    RtlCreateQueryDebugBuffer
    RtlQueryProcessDebugInformation
    RtlDestroyQueryDebugBuffer


    Here the prototypes for each function:

    Code:
    PDEBUG_BUFFER
    NTAPI
    RtlCreateQueryDebugBuffer(
    IN ULONG  Size,
    IN BOOLEAN  EventPair);
    Code:
    NTSTATUS
    NTAPI
    RtlQueryProcessDebugInformation(
    IN ULONG  ProcessId,
    IN ULONG  DebugInfoClassMask,
    IN OUT PDEBUG_BUFFER  DebugBuffer);
    Code:
    NTSTATUS
    NTAPI
    RtlDestroyQueryDebugBuffer(
    IN PDEBUG_BUFFER  DebugBuffer);
    Code:
    RtlCreateQueryDebugBuffer
    allocates buffer for storing heap data in case of success, it returns pointer to allocated debug buffer. Here the declaration of debug buffer:

    Code:
    typedef struct _DEBUG_BUFFER {
    HANDLE  SectionHandle;
    PVOID  SectionBase;
    PVOID  RemoteSectionBase;
    ULONG  SectionBaseDelta;
    HANDLE  EventPairHandle;
    ULONG  Unknown[2];
    HANDLE  RemoteThreadHandle;
    ULONG  InfoClassMask;
    ULONG  SizeOfInfo;
    ULONG  AllocatedSize;
    ULONG  SectionSize;
    PVOID  ModuleInformation;
    PVOID  BackTraceInformation;
    PVOID  HeapInformation;
    PVOID  LockInformation;
    PVOID  Reserved[8];
    } DEBUG_BUFFER, *PDEBUG_BUFFER;
    After the buffer allocation we can call the Heap Process Debug Information, we can call RtlQueryProcessDebugInformation to load all heap blocks of the process. This function loads entire heap nodes and corresponding heap blocks of the process. Debug Buffer contains the pointer to heap information structure at offset 0×38. First parameter of this heap structure is node count and after that it contains array of DEBUG_HEAP_INFORMATION structure which represent each heap node.

    Code:
    typedef struct _DEBUG_HEAP_INFORMATION
    {
    ULONG Base; // 0×00
    ULONG Flags; // 0×04
    USHORT Granularity; // 0×08
    USHORT Unknown; // 0×0A
    ULONG Allocated; // 0×0C
    ULONG Committed; // 0×10
    ULONG TagCount; // 0×14
    ULONG BlockCount; // 0×18
    ULONG Reserved[7]; // 0×1C
    PVOID Tags; // 0×38
    PVOID Blocks; // 0×3C Heap block pointer for this node.
    } DEBUG_HEAP_INFORMATION, *PDEBUG_HEAP_INFORMATION;
    As you should know a debugged process presents different flags respect a not debugged one, here the sample anti-dbg code:

    Code:
    #define WIN32_LEAN_AND_MEAN
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include 
    
    #include “defs.h”
    
    #pragma comment(lib,”ntdll.lib”)
    #pragma comment(lib,”psapi.lib”)
    
    void QueryDbgBufferMethod(void)
    {
    PDEBUG_BUFFER buffer;
    NTSTATUS ntStatus;
    
    buffer = RtlCreateQueryDebugBuffer(0,FALSE);
    
    ntStatus = RtlQueryProcessDebugInformation(GetCurrentProcessId(),
    PDI_HEAPS|PDI_HEAP_BLOCKS,
    buffer);
    
    PDEBUG_HEAP_INFORMATION heapInfo = PDEBUG_HEAP_INFORMATION(PULONG(buffer->HeapInformation) + 1);
    
    if (heapInfo->Flags == 0×50000062)
    MessageBoxA(NULL,”Debugged”,”Warning”,MB_OK);
    else
    MessageBoxA(NULL,”Not Debugged”,”Warning”,MB_OK);
    
    RtlDestroyQueryDebugBuffer(buffer);
    }
    and here ‘defs.h

    Code:
    typedef LONG NTSTATUS;
    #define STATUS_SUCCESS ((NTSTATUS)0×00000000L)
    
    typedef struct _DEBUG_BUFFER {
    HANDLE SectionHandle;
    PVOID  SectionBase;
    PVOID  RemoteSectionBase;
    ULONG  SectionBaseDelta;
    HANDLE  EventPairHandle;
    ULONG  Unknown[2];
    HANDLE  RemoteThreadHandle;
    ULONG  InfoClassMask;
    ULONG  SizeOfInfo;
    ULONG  AllocatedSize;
    ULONG  SectionSize;
    PVOID  ModuleInformation;
    PVOID  BackTraceInformation;
    PVOID  HeapInformation;
    PVOID  LockInformation;
    PVOID  Reserved[8];
    } DEBUG_BUFFER, *PDEBUG_BUFFER;
    
    typedef struct _DEBUG_HEAP_INFORMATION
    {
    ULONG Base; // 0×00
    ULONG Flags; // 0×04
    USHORT Granularity; // 0×08
    USHORT Unknown; // 0×0A
    ULONG Allocated; // 0×0C
    ULONG Committed; // 0×10
    ULONG TagCount; // 0×14
    ULONG BlockCount; // 0×18
    ULONG Reserved[7]; // 0×1C
    PVOID Tags; // 0×38
    PVOID Blocks; // 0×3C
    } DEBUG_HEAP_INFORMATION, *PDEBUG_HEAP_INFORMATION;
    
    // RtlQueryProcessDebugInformation.DebugInfoClassMask constants
    #define PDI_MODULES                       0×01
    #define PDI_BACKTRACE                     0×02
    #define PDI_HEAPS                         0×04
    #define PDI_HEAP_TAGS                     0×08
    #define PDI_HEAP_BLOCKS                   0×10
    #define PDI_LOCKS                         0×20
    
    extern “C”
    __declspec(dllimport)
    NTSTATUS
    __stdcall
    RtlQueryProcessDebugInformation(
    IN ULONG  ProcessId,
    IN ULONG  DebugInfoClassMask,
    IN OUT PDEBUG_BUFFER  DebugBuffer);
    
    extern “C”
    __declspec(dllimport)
    PDEBUG_BUFFER
    __stdcall
    RtlCreateQueryDebugBuffer(
    IN ULONG  Size,
    IN BOOLEAN  EventPair);
    extern “C”
    __declspec(dllimport)
    NTSTATUS
    __stdcall
    RtlDestroyQueryDebugBuffer(
    IN PDEBUG_BUFFER  DebugBuffer);
    Regards,
    Giuseppe 'Evilcry' Bonfa'

  2. #2
    Registered User
    Join Date
    Dec 2005
    Posts
    216
    Blog Entries
    5
    Useful, thanks

  3. #3
    Registered User
    Join Date
    Aug 2005
    Location
    Italy
    Posts
    133
    Blog Entries
    31
    tnx rendari

    Just a precisation, as you can see in the code I used psapi.lib, this is obviously not necessary for the code that I reported here, but can be used to enumerate all processes and by passing their PID to RtlQueryProcessDebugInformation we can inspect if there are debugged running processes

    It's important to implement a check for the return value of RtlQueryProcessDebugInformation cause, for some PIDs it fails and we have a non sense DEBUG_BUFFER and a consequent non sense DEBUG_HEAP_INFORMATION.

    Implement a check for 0xC0000008 and 0xC0000017

    Regards,
    Giuseppe 'Evilcry' Bonfa'

    http://evilcry.netsons.org (Repository)
    http://evilcodecave.blogspot.com
    http://evilcodecave.wordpress.com

Similar Threads

  1. NtSetDebugFilterState as Anti-Dbg Trick
    By evilcry in forum Blogs Forum
    Replies: 11
    Last Post: December 18th, 2012, 11:27
  2. PAGE_EXECUTE_WRITECOPY As Anti-Debug Trick
    By walied in forum Advanced Reversing and Programming
    Replies: 9
    Last Post: October 1st, 2012, 08:31
  3. Yet Another Anti-Debug Trick
    By walied in forum Malware Analysis and Unpacking Forum
    Replies: 0
    Last Post: January 22nd, 2012, 11:31
  4. RtlQueryProcessHeapInformation as Anti-Dbg Trick
    By evilcry in forum Blogs Forum
    Replies: 0
    Last Post: April 14th, 2009, 12:18
  5. Is This A New Anti Debug Trick
    By DaBoo in forum The Newbie Forum
    Replies: 6
    Last Post: June 15th, 2007, 10:15

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •