Here are some thoughts on Advanced .NET Debugging book.
The book is written from software development point of view. Examples reference to source code. Information is used in debugging examples taken from source code and from debugging symbol files. Therefore some examples are not applicable on binaries without source code information.
Most of the debugging examples rely on SOS and SOSEX Windbg plugins. Online help for those plugins are already available, and this book doesn't seem to add new information to them, albeit it demonstrates examples with snippet copied from Windbg command window.
ILDasm is a great tool but there is so little about it in this book. Particularly, I'd like to see, for example, that the information extracted from binaries by ILDasm can be used during debugging; a kind of guide to use statically acquired information during dynamic analysis.
The author describes some low-level structures in an accessible manner, but some topics aren't discussed while others are overwhelmed with theory. There is very little information about IL instructions, however I'd expect more on that because that's a key area to understand to effectively debug .NET programs.
The author doesn't go beyond a certain point when discussing certain topics, for example, it's not discussed how the code generation works that would be useful to match IL code blocks to their native counterparts. (MSDN describes how can be done this via profiler or debugging interfaces of .NET Framework.)
The figures about internal structures or flow charts, etc. seem to be simple and easy to follow them, I liked these parts.
I particularly liked the Managed Heap and Garbage Collection chapter.
If you're an engineer who wants to troubleshoot software failures this book is a good one to start with. However, if you're a reverse engineer who wants to debug binaries without having debug or source information available you might need an other book with different approach.
June 2, 2012
May 19, 2012
Test for termination on heap corruption flag in Windbg
This note describes two ways to verify the heap manager settings if the termination on corruption flag is enabled. Both of them require Windbg.
- Execute the below command to print the value of the disable break on failure cookie. If the value is zero the termination on heap corruption flag is set, otherwise it's unset. For more details about this see the previous post.
0:031> db ntdll!RtlpDisableBreakOnFailureCookie L4
77230098 aa cb 7f 69 ...i
- Another way is to execute the following command to print if the termination on heap corruption is enabled.
0:031> !heap -s
LFH Key : 0x726d2f4c
Termination on corruption : DISABLED
Internet Explorer: ENABLEDI asked Mozilla what's the reason to not enable this mitigation but haven't heard back from them so far.
Chrome: ENABLED
Mozilla Firefox: DISABLED
May 13, 2012
About termination on heap corruption feature
The following line enables the feature to terminate the process if heap corruption is detected by the Windows heap manager.
At line
As the next step, a simple application that intentionally corrupts the heap was created. I placed a breakpoint to see what happens when
When the breakpoint hit, I got the code snippet below. The caller function was
I observed the following situations are possible.
BOOL bResult = HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
I created a simple application calling the above function, and loaded it in Windbg to trace how the feature is enabled.At line
77396d11 there is a check if HeapEnableTerminationOnCorruption, that is 1, is specified.
77396d11 837d0c01 cmp dword ptr [ebp+0Ch],1
77396d15 7507 jne ntdll!RtlSetHeapInformation+0x59 (77396d1e)
77396d17 83259800447700 and dword ptr [ntdll!RtlpDisableBreakOnFailureCookie (77440098)],0
77396d1e 33c0 xor eax,eax
As it can be seen, if HeapEnableTerminationOnCorruption is specified, [RtlpDisableBreakOnFailureCookie] is set to zero.As the next step, a simple application that intentionally corrupts the heap was created. I placed a breakpoint to see what happens when
[RtlpDisableBreakOnFailureCookie] is accessed.When the breakpoint hit, I got the code snippet below. The caller function was
RtlpReportHeapFailure implying heap failure, so I have reason to think the code snippet is not reached unless heap corruption is encountered.RtlpGetModifiedProcessCookie returns with a cookie value, and I observed that value was the same to the initial value of [RtlpDisableBreakOnFailureCookie].
7740f5ad e8e67cf7ff call ntdll!RtlpGetModifiedProcessCookie (77387298)
7740f5b2 390598004477 cmp dword ptr [ntdll!RtlpDisableBreakOnFailureCookie (77440098)],eax
7740f5b8 7411 je ntdll!RtlpReportHeapFailure+0x23 (7740f5cb)
7740f5ba 6868424477 push offset ntdll!RtlpHeapFailureInfo (77444268)
7740f5bf 68740300c0 push 0C0000374h
7740f5c4 e8a3f0ffff call ntdll!RtlReportCriticalFailure (7740e66c)
7740f5c9 eb1a jmp ntdll!RtlpReportHeapFailure+0x3d (7740f5e5)
7740f5cb 8b4508 mov eax,dword ptr [ebp+8]
7740f5ce 3b0540674477 cmp eax,dword ptr [ntdll!RtlpHeapErrorHandlerThreshold (77446740)]
7740f5d4 7f0f jg ntdll!RtlpReportHeapFailure+0x3d (7740f5e5)
7740f5d6 e864f1ffff call ntdll!RtlpPrintErrorInformation (7740e73f)
7740f5db e840f0ffff call ntdll!RtlIsAnyDebuggerPresent (7740e620)
7740f5e0 84c0 test al,al
7740f5e2 7401 je ntdll!RtlpReportHeapFailure+0x3d (7740f5e5)
7740f5e4 cc int 3
7740f5e5 5d pop ebp
7740f5e6 c20400 ret 4
At line 7740f5b2 the cookie value [RtlpDisableBreakOnFailureCookie] is being compared against the return cookie value of RtlpGetModifiedProcessCookie.I observed the following situations are possible.
HeapEnableTerminationOnCorruptionis unset, and the heap is corrupted. In that case at line7740f5b8the jump is taken and the process might not be immediately terminated.HeapEnableTerminationOnCorruptionis set, and the heap is corrupted. In that case at line7740f5b8the jump is not taken and the process is to be immediately terminated.
May 12, 2012
Minimum set up to use Windbg from Visual Studio
Below is an example to set up Windbg in Visual C++ 2010 Express.
Select Tools, then select External Tools... in Visual C++. Click on Add and provide the followings.
Select Tools, then select External Tools... in Visual C++. Click on Add and provide the followings.
Title &WindbgSave the configuration and test if it works. Open a project that builds an executable file. Select Tools, then select Windbg to start the debugger. In the command window type
Command C:\Program Files (x86)\Debugging Tools for Windows (x86)\windbg.exe
Arguments -srcpath $(ProjectDir) $(TargetPath)
Initial directory $(TargetDir)
.open example.cpp to load the source code. The source window should pop up with the source file in it. Move the cursor in the source window and press F9 to place a breakpoint.
May 6, 2012
Guide to create Windbg extension in Visual Studio 2010
I'm describing a way to create an extension for Windbg in Visual Studio 2010 Express. The description is applied for the 32-bit version of Windows debugger but the same steps could be easily adopted for the 64-bit debugger. If you're not interested in setting up a Visual Studio configuration, but want a sample extension, you can download one from CodePlex. That one was created using the steps below.
Create an Empty Visual C++ Project and save the solution as sampext. Add
Copy the
Set the configuration type of the project to
Add
Add
Add
Set up the module definition file to
The extension is now ready to be built.
Create an Empty Visual C++ Project and save the solution as sampext. Add
sampext.cpp to the project with the following content.
#include "sampext.h"
EXT_DECLARE_GLOBALS();
EXT_CLASS::EXT_CLASS()
{
}
Add sampext.h to the project with the following content.
#pragma once
#include "engextcpp.hpp"
class EXT_CLASS : public ExtExtension
{
protected:
public:
EXT_CLASS();
EXT_COMMAND_METHOD(ver);
};
Add ver.cpp to the project file with the following content. This file contains the implementation of the sample command.
#include "ver.h"
EXT_COMMAND(ver,
"Shows version number of the extension.\n",
""
)
{
g_Ext->Out("Sample Windbg Extension in Visual Studio v0.1\n");
}
Add
ver.h, too.
#pragma once
#include "sampext.h"
Add sampext.def that is the definition file.
EXPORTS
;--------------------------------------------------------------------
; Core exports provided by the ExtCpp framework.
;--------------------------------------------------------------------
DebugExtensionInitialize
DebugExtensionUninitialize
DebugExtensionNotify
help
;--------------------------------------------------------------------
; Extension commands.
;--------------------------------------------------------------------
ver
Create a folder called sdk in the solution folder.Copy the
inc and lib folders from the sdk folder of Windbg to the sdk folder of the solution.Set the configuration type of the project to
Dynamic Library DLL.Add
$(SolutionDir)sdk\inc to the additional include directories.Add
$(SolutionDir)sdk\lib\i386 to the additional library dependencies.Add
engextcpp.lib to the additional dependencies in the linker input.Set up the module definition file to
samplext.def in the linker input.The extension is now ready to be built.
May 2, 2012
An example when /sdl flag doesn't work in Visual Studio 11 Beta
Microsoft introduced a new compiler defense in Visual Studio 11 Beta that is to mitigate simple dangling pointer bugs. When the memory has been freed using the
Here is an example when
delete operator the pointer is set to 0x8123.Here is an example when
0x8123 set.
delete [] ptr;
push edi
call dword ptr ds:[12E2094h]
mov eax,8123h
test edi,edi
cmovne edi,eax
However, consider the following code snippet.
void* arr[1];
arr[0] = new BYTE[MAX];
delete [] arr[0];
delete [] arr[0];
I compiled the code and realized there is no sanitization.
push esi
void* arr[1];
arr[0] = new BYTE[MAX];
push 7Bh
call dword ptr ds:[12A2090h]
mov esi,eax
delete [] arr[0];
push esi
call dword ptr ds:[12A2094h]
delete [] arr[0];
push esi
call dword ptr ds:[12A2094h]
add esp,0Ch
return 0;
xor eax,eax
pop esi
I asked Microsoft about this issue, and they confirmed that the /sdl flag doesn't work in this scenario. The reason is that in line delete [] arr[0], the expression arr[0] passed into the delete call is dereference. VS11 provides initial support for pointer sanitization when "the expression passed into the delete call does not involve a dereference." For more info see their blog post.