Direct3D9 Debug Runtime On Windows 8.1

3 minute read

Came across this issue today while trying to debug something. It appears that in the latest versions of Windows, Microsoft has decided to disable the ability to use the DirectX.cpl control panel tool as well as fully disable the debugging runtimes. This is pretty annoying since not everyone wants to jump the gun to each version of Windows and supporting legacy code is a need in some cases when moving to newer versions. So thanks Microsoft on that oversight.

I Google’d around some and couldn’t find info on this problem. So I dug into the .cpl item to see how it handles enabling and disabling the features of the program.

Pretty easily, you can find that the .cpl is actually a .exe renamed. Along with that, the DirectX.cpl file uses dialogs which can be seen in full within the resources of the file. This is super helpful in finding the code handling disabling controls. We can see that the main group box of the Direct3D Debug Output Level is control ID #1164.

Looking at the .cpl within IDA, we can find where this control is used by looking for references to EnableWindow.

You’ll find a function that references that dialog window at:

  • sub_4077E2

Which at the top of this function we see:

.text:004077F9 cmp dword_412EA8, esi 
.text:004077FF mov [ebp+var_4], eax 
.text:00407802 push edi 
.text:00407803 jz short loc_407833

This checks if the value in 412EA8 is zero, if it is, jump to where the controls are disabled for this dialog. So we look at what references the 412EA8 and find:

.text:0040752D call sub_407150 
.text:00407532 mov esi, ds:RegOpenKeyA 
.text:00407538 mov dword_412EA8, eax

So navigate into that call, and we see:

.text:00407150 mov edi, edi 
.text:00407152 push ebp 
.text:00407153 mov ebp, esp 
.text:00407155 sub esp, 120h 
.text:0040715B mov eax, ___security_cookie 
.text:00407160 push esi 
.text:00407161 push edi 
.text:00407162 mov esi, offset aD3d9d_dll ; "\\d3d9d.dll" 
.text:00407167 lea edi, [ebp+String2] 
.text:0040716A movsd 
.text:0040716B movsd 
.text:0040716C mov [ebp+var_4], eax 
.text:0040716F movsw 
.text:00407171 push 105h ; uSize 
.text:00407176 lea eax, [ebp+Buffer] 
.text:0040717C push eax ; lpBuffer 
.text:0040717D movsb 
.text:0040717E call ds:GetSystemDirectoryA 
.text:00407184 lea eax, [ebp+String2] 
.text:00407187 push eax ; lpString2 
.text:00407188 lea eax, [ebp+Buffer] 
.text:0040718E push eax ; lpString1 
.text:0040718F call ds:lstrcatA 
.text:00407195 lea eax, [ebp+Buffer] 
.text:0040719B push eax ; lpFileName 
.text:0040719C call ds:GetFileAttributesA 
.text:004071A2 xor ecx, ecx 
.text:004071A4 cmp eax, 0FFFFFFFFh 
.text:004071A7 setnz cl 
.text:004071AA pop edi 
.text:004071AB pop esi 
.text:004071AC mov eax, ecx 
.text:004071AE mov ecx, [ebp+var_4] 
.text:004071B1 call sub_409EAC 
.text:004071B6 leave 
.text:004071B7 retn 
.text:004071B7 sub_407150 endp

So it appears they check the system directory for a dll called d3d39d.dll, makes sense right? My system does not have this file in either system folder (64 bit Windows 8.1). So I headed to my Direct3D9 SDK (June 2010) and found these files located in:

  • \DXSDK\Developer Runtime\x86
  • \DXSDK\Developer Runtime\x64

Keep in mind there are 3 versions of the file included in the SDK.

  • Windows XP
  • Windows Vista
  • Windows 7

Windows 8 was not around yet so there is no specific file for it. So I used the Windows 7 files. (You will have to extract each one and look at it to tell which is which. You will need to look at the files header information to find the latest one. You want to find the one that has the Major/Minor OS values set to 6 and 1 respectively.

You will need to place these files like this: (Windows does shit weird cause why not lol..)

  • \DXSDK\Developer Runtime\x64\d3d9d.dll -> C:\Windows\System32\
  • \DXSDK\Developer Runtime\x86\d3d9d.dll -> C:\Windows\SystemWOW64\

When you start the .cpl now, it should be enabled. However there is still something system wide preventing the debugging from working properly. On my system I have no debug output from the libraries so I assume something is stopping it from loading properly on Windows 8.1. Given the massive changes between 7 and 8, I assume these dlls just wont work on 8 though.