Using the SOS debugging extension (http://msdn.microsoft.com/en-us/library/bb190764(v=vs.110).aspx) we can easily save modules in a .NET memory dump.
I wanted to do some runtime analysis of an EXE, but I only had dmp file.
0:000> .load C:\windows\microsoft.net\Framework64\v2.0.50727\sos.dll
0:000> lmv m qfbox2
start end module name
00000000`00e20000 00000000`00e40000 QFBox2 (deferred)
Image path: C:\QIK-QUBE2\QFB\QFBox2.exe
Image name: QFBox2.exe
Has CLR image header, track-debug-data flag not set
Timestamp: Thu May 15 16:54:56 2014 (537464C0)
CheckSum: 00000000
ImageSize: 00020000
File version: 2.0.1.3
Product version: 2.0.1.3
File flags: 0 (Mask 3F)
File OS: 4 Unknown Win32
File type: 1.0 App
File date: 00000000.00000000
Translations: 0000.04b0
CompanyName: Company
ProductName: QIK Function Box
InternalName: QFBox2.exe
OriginalFilename: QFBox2.exe
ProductVersion: 2.0.1.3
FileVersion: 2.0.1.3
FileDescription: QIK Function Box
LegalCopyright: Company
0:000> !SaveModule 00000000`00e20000 C:\support\qfbox2.exe
4 sections in file
section 0 – VA=2000, VASize=16254, FileAddr=400, FileSize=16400
section 1 – VA=1a000, VASize=5d, FileAddr=16800, FileSize=200
section 2 – VA=1c000, VASize=1350, FileAddr=16a00, FileSize=1400
section 3 – VA=1e000, VASize=c, FileAddr=17e00, FileSize=200
OK great, we can now explore EXE easily with tool like .NET reflector or ILDasm as-is.
But trying to launch EXE we get error:
Via WinDbg
To resolve this issue:
1. Decompile with ILDasm Windows SDK. In ILDasm click File –> Open select EXE, then File –> Dump, leave defauts, and click OK.
2. Recompile with ILasm, under Microsoft.NET directories, specify .res file output by ILDasm. Because this is .NET 2.0 app I used ILAsm from .NET 2.0 folder.
c:\windows\microsoft.net\framework\v2.0.50727\ilasm.exe qfbox2.il /resource=qfbox2.res /x64
In this case app failed to launch:
In WinDbg:
ModLoad: 00007ffd`8d860000 00007ffd`8d86a000 C:\Windows\Microsoft.NET\Framework64\v2.0.50727\culture.dll
(20b0.17a0): CLR exception – code e0434f4d (first chance)
(20b0.17a0): CLR exception – code e0434f4d (!!! second chance !!!)
KERNELBASE!RaiseException+0x68:
00007ffd`8fc568d8 488b8c24c0000000 mov rcx,qword ptr [rsp+0C0h] ss:00000000`0050f560=000048ce57469afc
0:000> kv
Child-SP RetAddr : Args to Child : Call Site
00000000`0050f4a0 00007ffd`87fd5acf : 00000000`00739a40 00000000`0240f680 00000000`0050f5d0 00000000`00739a40 : KERNELBASE!RaiseException+0x68
00000000`0050f580 00007ffd`88138daf : 00000000`0240f680 00007ffd`00000000 00000000`00000000 00000000`00000001 : mscorwks!RaiseTheExceptionInternalOnly+0x2ff
00000000`0050f670 00007ffd`88392eec : ffffffff`fffffffe 00000000`0050db80 00007c0c`00000000 00000000`00000000 : mscorwks!UnwindAndContinueRethrowHelperAfterCatch+0x63
00000000`0050f6d0 00007ffd`88847cfd : ffffffff`ffffffff 00000000`00739a40 00000000`00000000 00000000`0050f6d8 : mscorwks! ?? ::FNODOBFM::`string’+0xa006c
00000000`0050f730 00007ffd`888fea5b : 00000000`00000000 00007ffd`880c44c4 00000000`00000000 00000000`00000000 : mscoreei!CorExeMain+0xe0
00000000`0050f780 00007ffd`9024168d : 00007ffd`88840000 00000000`00000000 00000000`00000000 00000000`00000000 : MSCOREE!CorExeMain_Exported+0xcb
00000000`0050f7b0 00007ffd`92554629 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KERNEL32!BaseThreadInitThunk+0xd
00000000`0050f7e0 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x1d
0:000> .load C:\windows\microsoft.net\Framework64\v2.0.50727\SOS.dll
0:000> !Printexception
Exception object: 000000000240f680
Exception type: System.BadImageFormatException
Message: Could not load file or assembly ‘qfbox2.exe’ or one of its dependencies. An attempt was made to load a program with an incorrect format.
InnerException: <none>
StackTrace (generated):
<none>
StackTraceString: <none>
HResult: 8007000b
So I recompile with the following options:
c:\windows\microsoft.net\framework\v2.0.50727\ilasm.exe qfbox2.il /resource=qfbox2.res
Note: If we wanted debug version with PDBs we could also add
ilasm.exe qfbox2.il /resource=qfbox2.res /debug /pdb
OK application now launches:
However, it is running 32-bit :
To fix that we run corflags.exe from Windows SDK.
Note: Windows 7 SDK v7.0A (.NET 3.5) and earlier use /PE32- instead of /32BITREQ-
C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools>corflags C:\qik-qube2\qfb\qfbox2.exe
Microsoft (R) .NET Framework CorFlags Conversion Tool. Version 4.0.30319.33440
Copyright (c) Microsoft Corporation. All rights reserved.
Version : v2.0.50727
CLR Header: 2.5
PE : PE32
CorFlags : 0x3
ILONLY : 1
32BITREQ : 1
32BITPREF : 0
Signed : 0
C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools>corflags C:\qik-qube2\qfb\qfbox2.exe /32BITREQ-
Microsoft (R) .NET Framework CorFlags Conversion Tool. Version 4.0.30319.33440
Copyright (c) Microsoft Corporation. All rights reserved.
C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools>corflags C:\qik-qube2\qfb\qfbox2.exe
Microsoft (R) .NET Framework CorFlags Conversion Tool. Version 4.0.30319.33440
Copyright (c) Microsoft Corporation. All rights reserved.
Version : v2.0.50727
CLR Header: 2.5
PE : PE32
CorFlags : 0x1
ILONLY : 1
32BITREQ : 0
32BITPREF : 0
Signed : 0
We can see it is now running as 64-bit.
Note:
After rebooting my system for Windows Updates using /x64 ILASM option worked fine. In addition without /x64 option the EXE directly compiled to x64 without needing corflags to change it. I couldn’t reproduce this issue again.
Using DumpBin.exe /headers from Windows SDK we compared what was different between the two process:
EXE Dumped from DMP | Recompiled EXE |
machine (x86) (It was an x64 EXE) |
machine (x64) |
4 number of sections | 3 number of sections |
102 characteristics | 22 characteristics |
16400 size of code | 16200 size of code |
0 entry point | 1819E entry point |
1 Debug Directory | None |
Summary
2000 .reloc |
Summary 2000 .reloc |