Binary Ninja Blog

Why Does Binary Ninja Install Its Own Copy of WinDbg?

Binary Ninja’s Time Travel Debugging integration is amazing. A common question I get asked is why you have to install WinDbg from within Binary Ninja instead of using an existing version from the Microsoft Store.

The short answer is that the WinDbg DLLs in C:\Program Files\WindowsApps cannot be loaded by binaryninja.exe.

But why not?

Binary Ninja’s TTD integration uses Microsoft’s debugging engine. When we replay a trace, our debugger loads DLLs shipped with WinDbg, including dbgeng.dll, dbghelp.dll, dbgcore.dll, and dbgmodel.dll. This gives us WinDbg’s TTD backend inside Binary Ninja’s debugger UI.

Modern WinDbg is distributed as an MSIX package through the Microsoft Store. On one of my test systems, its package was installed here:

C:\Program Files\WindowsApps\
    Microsoft.WinDbg_1.2606.22001.0_arm64__8wekyb3d8bbwe

The package even contained the x64 debugging engine we needed:

C:\Program Files\WindowsApps\
    Microsoft.WinDbg_1.2606.22001.0_arm64__8wekyb3d8bbwe\
    amd64\dbgeng.dll

When I was originally developing the TTD integration, I tried to have binaryninja.exe load those DLLs directly. However, a plain LoadLibrary using the complete path failed with ERROR_ACCESS_DENIED.

Initially I thought it was just a dependency issue, but then I copied the entire WinDbg folder to Desktop\windbg and tried the same LoadLibrary call again. Surprisingly, it worked. This puzzled me for a while, but since it didn’t block my development, I didn’t dig into it at the time.

Fast forward to this past August, when I prompted an LLM to investigate. Initially, it also suspected a dependency issue and tried loading the DLL with LoadLibraryEx. But after I pointed out the bizarre “copy, then successfully load” behavior, it checked the security descriptor and uncovered the real reason.

The two relevant access-control entries of the WinDbg package looked like this in SDDL:

(XA;OICI;0x1200a9;;;BU;
    (WIN://SYSAPPID Contains "Microsoft.WinDbg_8wekyb3d8bbwe"))
(A;OICI;FR;;;BU)

The second ACE is ordinary: it grants BUILTIN\Users (BU) generic read access (FR). The first is a conditional access-control entry: it grants rights including execute only when the calling process has a WIN://SYSAPPID security attribute containing Microsoft.WinDbg_8wekyb3d8bbwe. Windows places this protected attribute in the access token of a process launched as part of the signed WinDbg package; an application cannot simply claim the identity for itself.

This explains the apparently contradictory result. binaryninja.exe is a normal unpackaged desktop process, so it can read dbgeng.dll but lacks the WinDbg identity required to map it as executable code.

ACLs are filesystem metadata, not bytes embedded in the DLL, so a normal copy to the desktop creates new files with the destination directory’s ordinary ACLs. The copied dbgeng.dll contains the same code, but binaryninja.exe is now allowed to map it as an image.

That is why Binary Ninja cannot simply discover the Store installation and load dbgeng.dll in place. Our Install WinDbg/TTD command downloads Microsoft’s WinDbg MSIX bundle, verifies that it is signed by Microsoft, and extracts it into Binary Ninja’s user data directory, normally:

%APPDATA%\Binary Ninja\windbg

To set it up, follow the WinDbg/TTD installation instructions: in the usual case, it is just Debugger → Install WinDbg/TTD, followed by restarting Binary Ninja.