NtQueryInformationProcess

Created the Monday 18 March 2019. Updated 3 years, 6 months ago.

This function retrieves information about a running process. Malware are able to detect if the process is currently being attached to a debugger using the ProcessDebugPort (0x7) information class.

A nonzero value returned by the call indicates that the process is being debugged.


Technique Identifier

U0120


Code Snippets

program NtQueryProcessInformation;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Winapi.Windows,
  System.SysUtils;

function NtQueryInformationProcess(
  ProcessHandle : THandle;
  ProcessInformationClass : DWORD;
  ProcessInformation : Pointer;
  ProcessInformationLength : ULONG;
  ReturnLength : PULONG
): LongInt; stdcall; external 'ntdll.dll';

// https://docs.microsoft.com/en-gb/windows/win32/api/winternl/nf-winternl-ntqueryinformationprocess
function isDebuggerPresent(): Boolean;
var hProcess : THandle;
    APortNumber : DWORD;
    ARetLen : Cardinal;

const ProcessDebugPort = 7;
begin
  hProcess := GetCurrentProcess();
  if hProcess = 0 then
    Exit();
  ///

  if NtQueryInformationProcess(hProcess, ProcessDebugPort, @APortNumber, sizeOf(DWORD), @ARetLen) <> ERROR_SUCCESS then
    Exit();

  result := APortNumber <> 0;
end;

begin
  try
    if isDebuggerPresent() then
      raise Exception.Create('Debugger Detected !');

    WriteLn('No Debugger Detected :)');
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

  WriteLn('Press a return key to close application.');
  ReadLn;
end.
using System;
using System.Runtime.InteropServices;

[DllImport("ntdll.dll", SetLastError = true)]
static extern int NtQueryInformationProcess(
    IntPtr processHandle,
    int processInformationClass,
    ref IntPtr processInformation,
    uint processInformationLength,
    ref IntPtr returnLength
);

[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetCurrentProcess();

bool isBeingDebugged()
{
    var ERROR_SUCCESS = 0x0;
    var ProcessDebugPort = 0x7;

    IntPtr currProcessHandle = GetCurrentProcess();
    if (currProcessHandle == IntPtr.Zero)
    {
        throw new Exception("Could not retrieve current process handle.");
    }

    IntPtr returnLength = IntPtr.Zero;
    IntPtr portNumber = IntPtr.Zero;

    int ntStatus = NtQueryInformationProcess(currProcessHandle, ProcessDebugPort, ref portNumber, (uint)IntPtr.Size, ref returnLength);        
    if (ntStatus != ERROR_SUCCESS)
    {
        throw new Exception("Could not query information process.");
    }

    return (portNumber != IntPtr.Zero);
}

if (isBeingDebugged())
{
    throw new Exception("Debugger Detected !");
}

Console.WriteLine("No Debugger Detected :)");

Detection Rules

rule Detect_NtQueryInformationProcess: AntiDebug {
    meta: 
        description = "Detect NtQueryInformationProcess as anti-debug"
        author = "Unprotect"
        comment = "Experimental rule"
    strings:
        $1 = "NtQueryInformationProcess" fullword ascii
    condition:   
       uint16(0) == 0x5A4D and filesize < 1000KB and $1
}
rule:
  meta:
    name: check process job object
    namespace: anti-analysis/anti-debugging/debugger-detection
    authors:
      - michael.hunhoff@mandiant.com
    scope: function
    mbc:
      - Anti-Behavioral Analysis::Debugger Detection [B0001]
    references:
      - https://github.com/LordNoteworthy/al-khaser/blob/master/al-khaser/AntiDebug/ProcessJob.cpp
    examples:
      - al-khaser_x86.exe_:0x426730
  features:
    - and:
      - match: contain loop
      - basic block:
        - and:
          - api: kernel32.QueryInformationJobObject
          - number: 0x3 = JobObjectBasicProcessIdList
      - basic block:
        - and:
          - api: kernel32.OpenProcess
          - number: 0x400 = PROCESS_QUERY_INFORMATION

Additional Resources

External Links

Subscribe to our Newsletter


The information entered into this form is mandatory. It will be subjected to computer processing. It is processed by computer in order to support our users and readers. The recipients of the data will be : contact@unprotect.it.

According to the Data Protection Act of January 6th, 1978, you have at any time, a right of access to and rectification of all of your personal data. If you wish to exercise this right and gain access to your personal data, please write to Thomas Roccia at contact@unprotect.it.

You may also oppose, for legitimate reasons, the processing of your personal data.