I guess this happens to everyone: you need to write a test project to see if some features work and you’re stuck in poor documentation and google has no examples for you …
Recently I was trying to call WerRegisterRuntimeExceptionModule(…) to register my custom exception filtering module and I was stuck in registering module as specified in documentation. Documentation says:
However, it actually leaves more questions such as:
1. What is the preferred key to store the value, HKLM or HKCU?
2. What is exact format of the value, is it [Name of Dll + Path of Dll], or a subkey should be created?
3. If subkey RuntimeExceptionHelperModules should be created, what should be the names of the values? Name of dll? Or full path?
Unfortunately, documentation leaves out these details thus making people to lose their time trying to find out replies to these questions using “try & see” approach. Well, the situation does not look hopeless. In order to find answers to these questions you will need some disassembler, for example, IDA Pro.
If I fire up my file manager (Far) and make a search on all files in System32 folder by searching string “RuntimeExceptionHelperModules” I got the following:
So, I got three binaries from my search. Now you have to analyse all of them to see if they have something useful. I started from WerFault.exe and I guess I have found something interesting:
.text:0102F251 lea eax, [ebp+LibFileName] .text:0102F257 push eax .text:0102F258 mov ecx, ebx .text:0102F25A call ?IsHelperModuleInstalled@CRuntimePlugin@@AAEHPBG@Z ; CRuntimePlugin::IsHelperModuleInstalled(ushort const *)
As you can see above, the function CRuntimePlugin::IsHelperModuleInstalled checks if module is properly registered. Let’s step in, and see where it looks for it:
.text:0102EC5F loc_102EC5F: ; CODE XREF: CRuntimePlugin::IsHelperModuleInstalled(ushort const *)+Aj .text:0102EC5F push eax .text:0102EC60 push eax .text:0102EC61 push eax .text:0102EC62 push 10h .text:0102EC64 push [ebp+arg_0] .text:0102EC67 push offset aSoftwareMicr_8 ; "Software\\Microsoft\\Windows\\Windows Erro"... .text:0102EC6C push 80000002h .text:0102EC71 call ds:__imp__RegGetValueW@28 ; RegGetValueW(x,x,x,x,x,x,x) .text:0102EC77 neg eax .text:0102EC79 sbb eax, eax .text:0102EC7B inc eax
So, it get’s value at subkey “aSoftwareMicr_8”, let’s try to get more data about the subkey:
.text:010064F8 aSoftwareMicr_8: ; DATA XREF: CRuntimePlugin::IsHelperModuleInstalled(ushort const *)+3Co .text:010064F8 unicode 0,
.text:010064F8 unicode 0, ,0 .text:0100659A align 4
OK, we can see now that the key is Software\Microsoft\Windows\Windows Error Reporting\RuntimeExceptionHelperModules and 80000002h is HKEY_LOCAL_MACHINE. Now, when situation is more clear, you can try to register your exception module in the following key:
And make sure that WerExceptionModule.dll (this is my custom exception filter dll) is in system folder, so it will be properly found by WerFault.exe. OTOH, you can also specify path to dll instead, i.e.:
You have to keep in mind, however, that if you specify full path in registry, you should also specify it when calling WerRegisterRuntimeExceptionModule(…):
typedef HRESULT (WINAPI *p2WerRegisterRuntimeExceptionModule)(PCWSTR pwszOutOfProcessCallbackDll, PVOID pContext); // get address of WerRegisterRuntimeExceptionModule in kernel32.dll p2WerRegisterRuntimeExceptionModule fproc = (p2WerRegisterRuntimeExceptionModule)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "WerRegisterRuntimeExceptionModule"); // register exception filter dll HRESULT hr = fproc(TEXT("C:\\MyFolder\\WerExceptionModule.dll"), NULL); // simulate crash: char *sz = NULL; *sz = 4;