GET /api/techniques/56/
HTTP 200 OK
Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "name": "NtQueryObject",
    "category": [
        "https://search.unprotect.it/api/categories/3/"
    ],
    "description": "This function retrieves object information. By calling this function with the class ObjectTypeInformation will retrieve the specific object type (debug) to detect the debugger.",
    "resources": "https://msdn.microsoft.com/en-us/library/bb432383(v=vs.85).aspx\r\nhttps://www.codeproject.com/Articles/30815/An-Anti-Reverse-Engineering-Guide?fbclid=IwAR0fpYHnQX6C3YyBx3pnZ1m3bOYawc-kUIhZn65T5Bf7pQR26fUuVNYPs_Q#NtQueryObject",
    "tags": "",
    "snippets": [
        {
            "language": "https://search.unprotect.it/api/snippet_languages/1/",
            "author": "https://search.unprotect.it/api/snippet_authors/1/",
            "technique": "https://search.unprotect.it/api/techniques/56/",
            "description": "Support both 32/64 bit.",
            "plain_code": "program NtQueryObject;\r\n\r\n{$APPTYPE CONSOLE}\r\n\r\n{$ALIGN ON}\r\n{$MINENUMSIZE 4}\r\n\r\nuses\r\n  WinAPI.Windows, System.SysUtils;\r\n\r\ntype\r\n  TUnicodeString = record\r\n    Length: USHORT;\r\n    MaximumLength: USHORT;\r\n    Buffer: PWideChar;\r\n  end;\r\n\r\n  TObjectInformationClass = (\r\n                                    ObjectBasicInformation    = 0,\r\n                                    ObjectNameInformation     = 1,\r\n                                    ObjectTypeInformation     = 2,\r\n                                    ObjectAllTypesInformation = 3,\r\n                                    ObjectHandleInformation   = 4\r\n  );\r\n\r\n  OBJECT_TYPE_INFORMATION = record\r\n    Name: TUnicodeString;\r\n    ObjectCount: ULONG;\r\n    HandleCount: ULONG;\r\n    Reserved1: array[0..3] of ULONG;\r\n    PeakObjectCount: ULONG;\r\n    PeakHandleCount: ULONG;\r\n    Reserved2: array[0..3] of ULONG;\r\n    InvalidAttributes: ULONG;\r\n    GenericMapping: GENERIC_MAPPING;\r\n    ValidAccess: ULONG;\r\n    Unknown: UCHAR;\r\n    MaintainHandleDatabase: ByteBool;\r\n    Reserved3: array[0..1] of UCHAR;\r\n    PoolType: Byte;\r\n    PagedPoolUsage: ULONG;\r\n    NonPagedPoolUsage: ULONG;\r\n  end;\r\n  POBJECT_TYPE_INFORMATION = ^OBJECT_TYPE_INFORMATION;\r\n  TObjectTypeInformation = OBJECT_TYPE_INFORMATION;\r\n  PObjectTypeInformation = ^TObjectTypeInformation;\r\n\r\n  OBJECT_ALL_TYPE_INFORMATION = record\r\n    NumberOfObjectTypes : ULONG;\r\n    ObjectTypeInformation : array[0..0] of TObjectTypeInformation;\r\n  end;\r\n  POBJECT_ALL_TYPE_INFORMATION = ^OBJECT_ALL_TYPE_INFORMATION;\r\n  TObjectAllTypeInformation = OBJECT_ALL_TYPE_INFORMATION;\r\n  PObjectAllTypeInformation = ^TObjectAllTypeInformation;\r\n\r\n// https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntqueryobject\r\nvar\r\n  _NtQueryObject : function (\r\n                                ObjectHandle : THandle;\r\n                                ObjectInformationClass : TObjectInformationClass;\r\n                                ObjectInformation : PVOID;\r\n                                ObjectInformationLength : ULONG;\r\n                                ReturnLength : PULONG\r\n                              ): ULONG; stdcall;\r\nvar hNTDLL              : THandle;\r\n    ARet                : ULONG;\r\n    ARequiredSize       : ULONG;\r\n    pAllTypeInformation : PObjectAllTypeInformation;\r\n    pTypeInformation    : PObjectTypeInformation;\r\n    i                   : Integer;\r\n    pRow                : PObjectTypeInformation;\r\n    pDummy              : Pointer;\r\n    ADebuggerFound      : Boolean;\r\n\r\nbegin\r\n  try\r\n    ADebuggerFound := False;\r\n\r\n    @_NtQueryObject := nil;\r\n    ///\r\n\r\n    hNTDLL := LoadLibrary('NTDLL.DLL');\r\n    if (hNTDLL = 0) then\r\n      Exit();\r\n    try\r\n      @_NtQueryObject := GetProcAddress(hNTDLL, 'NtQueryObject');\r\n      if NOT Assigned(_NtQueryObject) then\r\n        Exit();\r\n      ///\r\n\r\n      ARet := _NtQueryObject(0, ObjectAllTypesInformation, @ARequiredSize, SizeOf(ULONG), @ARequiredSize);\r\n      if (ARequiredSize <= 0) then\r\n        Exit();\r\n      ///\r\n\r\n      GetMem(pAllTypeInformation, ARequiredSize);\r\n      try\r\n        ARet := _NtQueryObject(0, ObjectAllTypesInformation, pAllTypeInformation, ARequiredSize, nil);\r\n        if (ARet <> 0) then\r\n          Exit();\r\n        ///\r\n\r\n        pRow := @pAllTypeInformation^.ObjectTypeInformation;\r\n\r\n        for I := 0 to pAllTypeInformation^.NumberOfObjectTypes -1 do begin\r\n            if String.Compare(String(pRow^.Name.Buffer), 'DebugObject', True) = 0 then\r\n              ADebuggerFound := (pRow^.ObjectCount > 0);\r\n            ///\r\n\r\n            if ADebuggerFound then\r\n              break;\r\n\r\n            pRow := Pointer (\r\n              (NativeUInt(pRow^.Name.Buffer) + pRow^.Name.Length) and (NOT (SizeOf(Pointer)-1)) + SizeOf(Pointer)\r\n            );\r\n        end;\r\n      finally\r\n        FreeMem(pAllTypeInformation, ARequiredSize);\r\n      end;\r\n    finally\r\n      FreeLibrary(hNTDLL);\r\n    end;\r\n\r\n    if ADebuggerFound then\r\n      WriteLn('A Debugger Was Found!')\r\n    else\r\n      WriteLn('No Debugger Found!');\r\n  except\r\n    on E: Exception do\r\n      Writeln(E.ClassName, ': ', E.Message);\r\n  end;\r\nend."
        }
    ],
    "detection_rules": []
}