Developing WinDbg ExtEngCpp Extension in C++ – Introduction – Part 1

WinDbg Software Development Kit is a very powerful resource to have, especially if you know how to use it. But there is a fairly low amount of publicly available resources regarding it, and the official documentation doesn’t provide enough examples in my opinion. Furthermore, if you search online for common class from the SDK you will find few hits, and most of them will be from the official documentation.

In addition of scripting capabilities, WinDbg contains a SDK to provide the ability to development it owns extensions (DLLs). There are three categories of extensions.

- DbgEng extension DLLs. These are based on the prototypes in the dbgeng.h header file.
- WdbgExts extension DLLs. These are based on the prototypes in the wdbgexts.h header file.
- ExtEngCpp extension DLLs. These are based on the prototypes in the engextcpp.h and dbgeng.h header files. Each DLL of this type may export DbgEng extension commands. Which is the category we gonna focus on today.

In this series of short articles we gonna cover some of the poorly documented types of ExtEngCpp and see how to use them through explicit examples. ExtEngCpp is by far the most powerful engine because it offers a wide range of possibilities.

Beginners looking for a sample of a ExtEngCpp can refer to the SDK where the basics are covered in the sample provided at the following path: \Program Files (x86)\Windows Kits\8.0\Debuggers\x86\sdk\samples\extcpp

ExtRemoteData provides a function (GetString()) to return a string of characters but it doesn’t contain any functions to retrieve the content of a UNICODE_STRING. This is why I started to implement my own ExtRemoteTypedEx class and the sample below provide an example of how to use ExtRemoteData and ExtRemoteTyped together to retrieve the content of a UNICODE_STRING.

  1. LPWSTR
  2. WINAPI
  3. ExtRemoteTypedEx::GetUnicodeString(
  4.     ExtRemoteTyped TypedObject,
  5.     _Out_writes_opt_(BufferChars) PWSTR Buffer,
  6.     _In_ ULONG MaxChars
  7. )
  8. {
  9.     UNICODE_STRING SavedUnicodeString = {0};
  10.  
  11.     RtlZeroMemory(Buffer, MaxChars);
  12.  
  13.     SavedUnicodeString.Length = TypedObject.Field("Length").GetUshort();
  14.     SavedUnicodeString.MaxLength = TypedObject.Field("MaximumLength").GetUshort();
  15.     SavedUnicodeString.Buffer = TypedObject.Field("Buffer").GetPtr();
  16.  
  17.     if (SavedUnicodeString.Buffer && SavedUnicodeString.Length)
  18.     {
  19.         ExtRemoteData usData(SavedUnicodeString.Buffer,
  20.                              SavedUnicodeString.Length);
  21.         if (SavedUnicodeString.Length > MaxChars)
  22.         {
  23.             g_Ext->ThrowRemote(HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW),
  24.                                "String at %p overflows buffer, need 0x%x chars",
  25.                                TypedObject.m_Offset, SavedUnicodeString.Length);
  26.         }
  27.  
  28.         usData.GetString((LPWSTR)Buffer, SavedUnicodeString.Length);
  29.     }
  30.  
  31.     return Buffer;
  32. }

which can be used like the following:

  1.        ExtRemoteTypedEx::GetUnicodeString(ProcessObject.Object.Field("SeAuditProcessCreationInfo.ImageFileName").Field("Name"),
  2.                                            (LPWSTR)&MaxPath, sizeof(MaxPath));

In the next blogpost, we gonna see how to use COM interface and among them: IDebugDataSpaces4::ReadUnicodeStringVirtual.

I’m working a WinDbg extension to unite all my existing code in order to have an ultimate Digital Forensics & Incident Response WinDbg Extension. This will be covered in the training course I’m giving in May in Dubai, UAE.

Thanks to Frank Boldewin and aionescu for their help.

Related articles:

- Developing WinDbg ExtEngCpp Extension in C++ – Introduction – Part 1
- Developing WinDbg ExtEngCpp Extension in C++ – COM Interface – Part 2
- Developing WinDbg ExtEngCpp Extension in C++ – Memory & Debugger Markup Language (DML) – Part 3

2 thoughts on “Developing WinDbg ExtEngCpp Extension in C++ – Introduction – Part 1

Comments are closed.