Performance Analysis Tool (PAL) PerfMon Templates Don’t Load in Win10

Using Performance Analysis Tool ( on Windows 10 build 10130 I had exported a PerfMon template for Calculated Disk IOPS:



However when attempting to import into PerfMon on Windows 10 the Next and Finish buttons are disabled.



If we hit “Back” arrow, then forward again, the Finish button is enabled, but clicking it results in error:

When attempting to create the Data Collector Set the following system error occurred:
Not enough storage is available to complete this operation.


Using Rohitab API Monitor with Windows Application UI Development monitoring on, I attached ApiMonitor to mmc.exe process hosting PerfMon.msc just before I imported the template.


We find this function call:

#    Time of Day    Thread    Module    API    Return Value    Error    Duration
636128    2:00:46.910 PM    3    PLA.dll    LoadStringW ( 0x00007ffeb0bf0000, 10027, 0x000000000904b200, 1024 )    0    0 = The operation completed successfully.     0.0000226



Looking at MSDN documentation for LoadString we can see it returns 0 if the resource does not exist.

Using a simple test script  based on the one here

We can on Server 2008 R2 the values are there:


However on Windows 10 :


Dumping all resource strings in the DLL, we find in Windows 10, these strings are no longer present at all.

Sample script here:!28213&authkey=!AGecn7l_8oE95uU&ithint=file%2czip

So we changed the XML file to have a blank description.





Now it imports fine…

Posted in AppCompat, PerfMon, Windows 10 | Tagged | 3 Comments

Retrieving COM Class Factory For Component Failed 800700c1

A customer had migrated from 32-bit Windows XP to 64-bit Windows 8 and many of their .NET apps failed to launch, with an error like below:


The registry key for HKCR\CLSID\<GUID> was present, and the relevant OCX/DLL had been registered and was present on the system.

When you see error 800700c1 typically the issue is you have a 64-bit EXE trying to load a 32-bit DLL, which is not possible in Windows.

This issue is typically unique to .NET applications that also load native DLLs, because they can be compiled to “ANY CPU”

We should check the .NET exe with with CorFlags ( )

This tool is available from the Windows SDK in the .NET Development Tools subcomponent (Developer Tools -> Windows Development Tools -> .NET Development Tools)


We can see with 32bitreq = 0, this is set to “ANY CPU” This means it will run as 64-bit EXE on Windows x64 and 32-bit EXE on 32-bit Windows. As a consequence

  • Any native DLLs it loads must be 64-bit
  • Any installer that installs reg keys must be marked as 64-bit so reg keys go to correct location

If the application needs/benefits from addressing more than 2GB of RAM then it may be best to leave it as “Any CPU” However then 64-bit versions of all DLLs it loads need to be installed/registered.

The easiest way to fix such an application is to change app to x86.

This can be done with compiler options in Visual Studio


Or the EXE can be modified using corflags.exe

For example:

corflags /32bit+ C:\source\wds\wds.exe

Now the EXE will run in 32-bit mode, even on x64 OS.


Posted in .NET | Tagged | Leave a comment

Removing Forced Reboot From An EXE

Had this process I wanted to execute during a number of tasks, this process had a command line argument “—reboot” which forced an immediate reboot. If you tried to run the command without the “–reboot” option you were given an error “You must specify –reboot  option”

But we wanted to control when the reboot occurred.

Using IDA Pro it is relatively easy to remove the reboot. Some programs may launch shutdown.exe to initiate shutdown/restart but in this case the program called Windows API ExitWindowsEx

Opening the EXE in IDA Pro we find ExitWindowsEx in the import table, then double click it.


With ExitWindowsEx selected we hit ‘X’ or right click and select Jump to xref to operand



From here we can see there are two different locations that call this API:



Clicking the locations we find code like this:


The two push commands are setting up the parameters for ExitWindowsEx, and the test eax, eax command is checking the return code. Looking up ExitWindowsEx function in MSDN ( we can see it returns TRUE if the call was successful.

In this program, if the restart fails, it rolls back its changes, so we need to lie that the reboot succeeded, so we will set eax to 1.

We select push eax then select option to Assemble


We enter our code


We then continue inserting nop instructions until they go to the test eax, eax instruction


We then Apply Patches to input file


And our program no longer forces reboot, we can control when the reboot occurs.

Before doing this type of patch you should understand the implications and what you might break by eliminating this forced reboot…

Posted in IDA, Patching | Tagged | Leave a comment

Temporary Post Used For Theme Detection (cd245a28-700a-4b77-a8df-ee723246d31a – 3bfe001a-32de-4114-a6b4-4005b770f6d7)

This is a temporary post that was not deleted. Please delete this manually. (c167073f-39ab-45a8-9cc1-d0631f20788a – 3bfe001a-32de-4114-a6b4-4005b770f6d7)

Posted in Uncategorized | Leave a comment

Force Skype for Business UI

If you receive a message like this:

You have the newer version of Lync called Skype for Business. However, your admin would like you to use Lync or it’s the only version your server supports. Please restart now to use Lync.


If you select “Restart later” you can use the Skype UI and everything seems to work, but on restarting Lync you are back to the old Lync UI.

The proper way to change this is on the Lync backend.

But if you don’t have access to it a temporary workaround is to set EnableSkypeUI to 00 00 00 01 under HKEY_CURRENT_USER\Software\Microsoft\Office\Lync


However this will get reset back to 0 each time you launch Skype for Business.

To fix this, set it to 1, then deny your user account “Set Value” permission. Do this by right clicking Lync folder in registry and select Permissions –> Advanced –> Add, then select Advanced permissions and Deny Set Value.


You will still get the prompt to restart Skype into Lync mode, just that it will always remain in Skype UI.

Posted in Lync, Registry | Tagged | 3 Comments

Experimental Use of 64-bit Dump of 32-bit .NET Process in WinDbg

A .NET dmp file is typically best captured as 32-bit for 32-bit process. On x64 system this could be using the 32-bit task manager (C:\windows\syswow64\taskmgr.exe), WinDbg (x86), or a tool like ProcDump ( )

However what if a 32-bit .NET process has already been captured in 64-bit dmp file, and the issue is really hard to reproduce?

If you try to open with WinDbg x64 and try to load SOS you will get a failure:

00000000`76f21eb2 c3              ret
0:000> .loadby sos clr
The call to LoadLibrary(C:\Windows\Microsoft.NET\Framework\v4.0.30319\sos) failed, Win32 error 0n193
    “%1 is not a valid Win32 application.”
Please check your debugger configuration and/or network access.

So we try to force load of x64 SOS:

0:000> .cordll -u -ve -I clr -lp c:\windows\\framework64\v4.0.30319
Automatically loaded SOS Extension
CLRDLL: Loaded DLL c:\windows\\framework64\v4.0.30319\mscordacwks.dll
CLR DLL status: Loaded DLL c:\windows\\framework64\v4.0.30319\mscordacwks.dll

However we can’t run any SOS commands successfully:

0:000> !threads
Failed to load data access DLL, 0x80004005
Verify that 1) you have a recent build of the debugger (6.2.14 or newer)
            2) the file mscordacwks.dll that matches your version of clr.dll is
                in the version directory or on the symbol path
            3) or, if you are debugging a dump file, verify that the file
                mscordacwks_<arch>_<arch>_<version>.dll is on your symbol path.
            4) you are debugging on supported cross platform architecture as
                the dump file. For example, an ARM dump file must be debugged
                on an X86 or an ARM machine; an AMD64 dump file must be
                debugged on an AMD64 machine.

You can also run the debugger command .cordll to control the debugger’s
load of mscordacwks.dll.  .cordll -ve -u -l will do a verbose reload.
If that succeeds, the SOS command should work on retry.

If you are debugging a minidump, you need to make sure that your executable
path is pointing to clr.dll as well.
0:000> .cordll -ve -u -l
CLRDLL: LoadLibrary(C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscordacwks.dll) failed, Win32 error 193
CLRDLL: Unable to find mscordacwks_AMD64_x86_4.6.42.00.dll by mscorwks search
CLRDLL: Unable to find ‘mscordacwks_AMD64_x86_4.6.42.00.dll’ on the path
CLRDLL: Unable to get version info for ‘c:\symbols\clr.dll\54EFEAF769a000\mscordacwks_AMD64_x86_4.6.42.00.dll’, Win32 error 0n87
Cannot Automatically load SOS
CLRDLL: ERROR: Unable to load DLL mscordacwks_AMD64_x86_4.6.42.00.dll, Win32 error 0n87
CLR DLL status: ERROR: Unable to load DLL mscordacwks_AMD64_x86_4.6.42.00.dll, Win32 error 0n87

Trying to use SosEX extension also fails:

0:000:x86> .load C:\debugging\sosex64.dll
This dump has no SOSEX heap index.
The heap index makes searching for references and roots much faster.
To create a heap index, run !bhi
0:000:x86> !bhi
The target is 32-bit. 32-bit managed targets must be debugged using a 32-bit debugger.
0:000:x86> !wow64exts.sw
Switched to Host mode
0:000> !bhi
CLRDLL: CLR DLL load disabled
Unable to initialize .NET data interface. Version of mscordacwks.dll is required.
Locate and load the correct version of mscordacwks.dll. See documentation for the .cordll command.

So we try to open dmp file in WinDbg (x86) :

0:000> .loadby sos clr
0:000> !threads
SOS does not support the current target architecture.

0:000> .load wow64exts
0:000> !wow64exts.sw
Switched to Guest (WoW) mode
0:000:x86> !threads
SOS does not support the current target architecture.

0:000:x86> .load c:\support\sosex32.dll
This dump has no SOSEX heap index.
The heap index makes searching for references and roots much faster.
To create a heap index, run !bhi
0:000:x86> !bhi
Enumerating heap objects…Failed to load module 00000000012d3fbc. Error = 0x80131c49
Failed to load module 00000000012d3fbc. Error = 0x80131c49
Request for array class data for 0000000071635a78 failed. Error=0x80004001.
BuildHeapIndex failed. Error = 0x80004001.

0:000:x86> !wow64exts.sw
Switched to Host mode
0:000> !bhi
The target is 64-bit. 64-bit managed targets must be debugged using a 64-bit debugger.

What if we try removing the SOS architecture check, will it explode?

To do this I opened another instance of WinDbg (x86) and selected File –> Attach to a Process and selected our WinDbg (x86) process that had SOS extension loaded.

(225c.1f34): Break instruction exception – code 80000003 (first chance)
eax=feaab000 ebx=00000000 ecx=77771080 edx=10010044 esi=77771080 edi=77771080
eip=7773b270 esp=07c6f8b4 ebp=07c6f8e0 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
7773b270 cc              int     3
0:002> lmvm sos
Browse full module list
start    end        module name
54890000 54950000   sos        (deferred)            
    Image path: C:\Windows\Microsoft.NET\Framework\v4.0.30319\sos.dll
    Image name: sos.dll
    Browse all global symbols  functions  data
    Timestamp:        Fri Feb 27 14:50:08 2015 (54EFE970)
    CheckSum:         000B91DB
    ImageSize:        000C0000
    File version:
    Product version:  4.0.30319.0
    File flags:       8 (Mask 3F) Private
    File OS:          4 Unknown Win32
    File type:        2.0 Dll
    File date:        00000000.00000000
    Translations:     0409.04b0
    CompanyName:      Microsoft Corporation
    ProductName:      Microsoft® .NET Framework
    InternalName:     SOS.dll
    OriginalFilename: SOS.dll
    FileVersion: built by: NETFXREL1
    PrivateBuild:     DDBLD629A
    FileDescription:  Microsoft NTSD extension for .NET Runtime
    LegalCopyright:   © Microsoft Corporation.  All rights reserved.
    Comments:         Flavor=Retail
0:002> s -a 0x54890000 0x54950000 “SOS does not support the current target architecture”
54893224  53 4f 53 20 64 6f 65 73-20 6e 6f 74 20 73 75 70  SOS does not sup

Let’s try and find a reference to this address. We’ll convert it into Little Endian (reverse it) and search for those bytes 24 32 89 54

0:001> s -b 0x54890000 0x54950000 24 32 89 54
548af180  24 32 89 54 89 35 ac c0-91 54 e8 11 79 03 00 83  $2.T.5…T..y…

Now let’s disassemble that function:

0:001> uf 548af180

548af140 55              push    ebp
548af141 8bec            mov     ebp,esp
548af143 51              push    ecx
548af144 a1fcc09154      mov     eax,dword ptr [sos!g_ExtControl (5491c0fc)]
548af149 8d55fc          lea     edx,[ebp-4]
548af14c 56              push    esi
548af14d 52              push    edx
548af14e 50              push    eax
548af14f 8b08            mov     ecx,dword ptr [eax]
548af151 33f6            xor     esi,esi
548af153 ff9190000000    call    dword ptr [ecx+90h]
548af159 8b45fc          mov     eax,dword ptr [ebp-4]
548af15c 3d4c010000      cmp     eax,14Ch
548af161 750a            jne     sos!ArchQuery+0x2d (548af16d)  Branch

548af163 e888feffff      call    sos!X86Machine::GetInstance (548aeff0)
548af168 8bf0            mov     esi,eax
548af16a 8b45fc          mov     eax,dword ptr [ebp-4]

548af16d 3dc4010000      cmp     eax,1C4h
548af172 7507            jne     sos!ArchQuery+0x3b (548af17b)  Branch

548af174 e8f7fdffff      call    sos!ARMMachine::GetInstance (548aef70)
548af179 8bf0            mov     esi,eax

548af17b 85f6            test    esi,esi
548af17d 751d            jne     sos!ArchQuery+0x5c (548af19cBranch <- Jumps if valid platform

548af17f 6824328954      push    offset sos!`string’ (54893224) <- ERROR MESSAGE
548af184 8935acc09154    mov     dword ptr [sos!g_targetMachine (5491c0ac)],esi
548af18a e811790300      call    sos!ExtErr (548e6aa0)
548af18f 83c404          add     esp,4
548af192 b805400080      mov     eax,80004005h
548af197 5e              pop     esi
548af198 8be5            mov     esp,ebp
548af19a 5d              pop     ebp
548af19b c3              ret

548af19c 8935acc09154    mov     dword ptr [sos!g_targetMachine (5491c0ac)],esi
548af1a2 33c0            xor     eax,eax
548af1a4 5e              pop     esi
548af1a5 8be5            mov     esp,ebp
548af1a7 5d              pop     ebp
548af1a8 c3              ret
0:001> u 54893224
54893224 53              push    ebx
54893225 4f              dec     edi
54893226 53              push    ebx
54893227 20646f65        and     byte ptr [edi+ebp*2+65h],ah
5489322b 7320            jae     sos!`string’+0x29 (5489324d)
5489322d 6e              outs    dx,byte ptr [esi]
5489322e 6f              outs    dx,dword ptr [esi]
5489322f 7420            je      sos!`string’+0x2d (54893251)

We take the address of the conditional jmp we want to remove, and replace it with an unconditional jmp:

0:001> a 548af17d
jmp sos!ArchQuery+0x5c
jmp sos!ArchQuery+0x5c
548af17f <Ctrl+C>

We can now see in decompilation the jmp is gone:

548af17b 85f6            test    esi,esi
548af17d eb1d            jmp     sos!ArchQuery+0x5c (548af19c)  Branch

We continue with ‘g’ and go back to our WinDbg that has the bad dmp file open…

Now we’re getting somewhere:

Pre Patch

0:000:x86> !threads
SOS does not support the current target architecture.

Post Patch

At least now we can run some SOS commands. Many commands work, or at least partially work. They may not behave 100% correctly, but at least some of the information seems to be correct in my initial investigation.

0:000:x86> !threads
ThreadCount:      2
UnstartedThread:  0
BackgroundThread: 1
PendingThread:    0
DeadThread:       0
Hosted Runtime:   no
       ID OSID ThreadOBJ    State GC Mode     GC Alloc Context  Domain   Count Apt Exception
   0    1 1ad4 0112ac20     a6028 Preemptive  0324F8A8:00000000 01124b98 1     STA System.Runtime.InteropServices.SEHException 0324f644
   2    2 1e04 01138b70     2b228 Preemptive  00000000:00000000 01124b98 0     MTA (Finalizer)

0:000:x86> !pe
Exception object: 0324f644
Exception type:   System.Runtime.InteropServices.SEHException
Message:          External component has thrown an exception.
InnerException:   <none>
StackTrace (generated):
c0000005 Exception in C:\Windows\Microsoft.NET\Framework\v4.0.30319\ debugger extension.
      PC: 548c5f3d  VA: 00000000  R/W: 0  Parameter: 00000000

Stack based commands (!dumpstack \ !clrstack \!eestack ) however will thrown an exception like this in the debugger.

(225c.21e0): Access violation – code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=0635d844 ecx=00000000 edx=00000000 esi=778d919c edi=00fbb644
eip=548a87b3 esp=0635d26c ebp=0635d7f4 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010206
548a87b3 8b01            mov     eax,dword ptr [ecx]  ds:002b:00000000=????????

And result in error displayed in WinDbg

0:000:x86> !DumpStack
OS Thread Id: 0x1ad4 (0)
TEB information is not available so a stack size of 0xFFFF is assumed
Current frame: ntdll_77870000!NtWaitForSingleObject+0xc
c0000005 Exception in C:\Windows\Microsoft.NET\Framework\v4.0.30319\SOS.dll.DumpStack debugger extension.
      PC: 548a87b3  VA: 00000000  R/W: 0  Parameter: 00000000

Posted in .NET, 64-bit, WinDbg, Patching | Tagged | Leave a comment

Patching a Null Pointer Access Violation

An application was crashing about 5x a time a day so crash dumps were enabled via registry

Looking at the dmp files the program always crashed at same point in the program.

This dump file has an exception of interest stored in it.
The stored exception information can be accessed via .ecxr.
(51c.1160): Access violation – code c0000005 (first/second chance not available)
00007ff9`b879ed4a c3              ret
0:007> .ecxr
rax=0000000000000000 rbx=000000412a47e678 rcx=0000000000000010
rdx=000000412605e6c0 rsi=000000412a47d798 rdi=0000004123d9a040
rip=00007ff994a0a260 rsp=000000412605ea70 rbp=000000412a46e350
r8=00000041238b3820  r9=00000041280b7b10 r10=000000412380f430
r11=000000412605e230 r12=0000000000000004 r13=00007ff994a370f0
r14=00007ff9b21b1c80 r15=0000000000000000
iopl=0         nv up ei ng nz na pe cy
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010283
00007ff9`94a0a260 443920         
cmp     dword ptr [rax],r12d ds:00000000`00000000=????????

While I waited for patch from vendor, I wanted to experiment patching the crash on my own. For patching I’ve used IDA Pro.

To easily find the code in IDA pro I first dumped the crash location in bytes:

0:007> db Updater!GetSettingsCollection+0x760
00007ff9`94a0a260  44 39 20 74 0c 83 38 06-75 0c 83 f9 40 74 07 eb  D9 t..8.u…@t..
00007ff9`94a0a270  aa 41 3b cc eb f7 48 8b-5c 24 40 48 8b 03 4c 8b  .A;…H.\$@H..L.
00007ff9`94a0a280  70 40 49 8b ce ff 15 9d-63 02 00 48 8d 54 24 58  p@I…..c..H.T$X
00007ff9`94a0a290  48 8b cb 41 ff d6 89 44-24 30 85 c0 0f 89 85 00  H..A…D$0……
00007ff9`94a0a2a0  00 00 e8 6d e6 00 00 83-38 02 0f 86 6b ff ff ff  …m….8…k…
00007ff9`94a0a2b0  c7 44 24 50 4c 0a 00 00-4c 89 ac 24 00 01 00 00  .D$PL…L..$….
00007ff9`94a0a2c0  48 c7 84 24 08 01 00 00-44 00 00 00 48 8d 4c 24  H..$….D…H.L$
00007ff9`94a0a2d0  50 48 89 8c 24 10 01 00-00 48 c7 84 24 18 01 00  PH..$….H..$…

I then loaded the faulting module, updater.dll, into IDA and searched for the first 8 bytes by clicking Search –> Find Sequence of Bytes. I also enabled Find all occurrences just in case this byte sequence re-occurred


With only one result, we found what we are looking for:


To find a place to insert my patch code, I went to end of the .text segment where we found alignment bytes

align 100h

To insert patch code we selected the align statement and changed it to code (‘C’ keyboard shortcut, or Edit –> Code )

So now we had something like this

db 0
db 0
db 0

The patching code I wanted to insert would check if rax = 0 , if so jump to the location where [rax] was no longer used.

Something like

cmp rax,0
jz <Skip use of [rax]>
jmp <return to code using [rax]>

IDA’s Hex-Rays doesn’t support assembling x64 code, so I couldn’t use “assemble” to generate the byte code for the cmp instruction.

If I don’t know the byte code, I just did a quick search for similar instruction, and used the bytes from it – by searching for cmp rax, I found the bytes I needed

For the jump instructions I found jz near ptr loc_address works fine. However IDA will only assemble this if there is already a jump to that location, otherwise it will fail “Invalid Operand”

To manually calculate the jump, we take the subtract source & destination addresses:

18002FF31 (Source Address) – 18000A265 (Destination Address) = 25CCC + 5 (length of our jmp instruction) = 25CD1. Because we are jumping “backwards” make negative = FF FD A3 2F

I just used the Windows calculator in “hex mode” To get the negative hex number calculated 0 minus 25CD1.

Convert to Little Endian (Reverse Bytes) = 2F A3 FD FF


E9 is the op code for the relative jmp we need, so based on this calculation our jmp instruction is

E9 2F A3 FD FF

We insert these using IDA’s Edit –> Patch Program –> Change Bytes

Original Code

.text:000000018000A251 loc_18000A251:      
.text:000000018000A251                 mov     rax, [rsp+388h+var_2F8]
.text:000000018000A259                 mov     rax, [rax+108h]
.text:000000018000A260                 cmp     [rax], r12d <—Crash
.text:000000018000A263                 jz      short loc_18000A271
.text:000000018000A265                 cmp     dword ptr [rax], 6
.text:000000018000A268                 jnz     short loc_18000A276
.text:000000018000A26A                 cmp     ecx, 40h
.text:000000018000A26D loc_18000A26D:  
.text:000000018000A26D                 jz      short loc_18000A276
.text:000000018000A26F                 jmp     short loc_18000A21B

Jump to Patched Code

000000018000A251 loc_18000A251:     
.text:000000018000A251                 mov     rax, [rsp+388h+var_2F8]
.text:000000018000A259                 mov     rax, [rax+108h]
.text:000000018000A260                 jmp     patched_code
.text:000000018000A265                 nop     ; because we couldn’t fit some
.text:000000018000A266                 nop     ; instruction here
.text:000000018000A267                 nop
.text:000000018000A268 loc_18000A268: ;
.text:000000018000A268                 jnz     short loc_18000A276
.text:000000018000A26A loc_18000A26A:
.text:000000018000A26A                 cmp     ecx, 40h
.text:000000018000A26D loc_18000A26D: 
.text:000000018000A26D                 jz      short loc_18000A276
.text:000000018000A26F                 jmp     short loc_18000A21B

.text:000000018000A271 loc_18000A271:         
.text:000000018000A271                 cmp     ecx, r12d
.text:000000018000A274                 jmp     short loc_18000A26D

The Patch:

.text:000000018002FF1F patched_code:                           ; CODE XREF: sub_180009B00+760j
.text:000000018002FF1F                 cmp     rax, 0
.text:000000018002FF23                 jz      loc_18000A21B ; If RAX=0 skip [RAX] code
.text:000000018002FF29                 cmp     [rax], r12d ; RAX!=0 continue on
.text:000000018002FF2C                 jz      loc_18000A271
.text:000000018002FF32                 cmp     dword ptr [rax], 6
.text:000000018002FF35                 jmp     loc_18000A268 ; continues normal execution of program

Once we were ready to test the changes we applied them by selecting Edit –> Patch Program –> Apply Patches to Input File

I always ensure I have a backup of original file, as it is quite easy to break something.


This patch did happen to resolve this crash. However doing this type of patch will frequently lead to other types of crash or bugs, and so can be a very time consuming process.

However it is important to remember, lost source code or bad vendor support, does not mean bugs can’t be fixed…

Posted in WinDbg, Patching, IDA | Tagged | Leave a comment