The blog continues at suszter.com/ReversingOnWindows

July 24, 2012

Detecting Read Access to Uninitialized Stack Memory

As I mentioned in the previous post I developed a program that is able to trace when the stack memory is being accessed. This time, I improved this program so if there is a read access to the portion of the stack memory that was not written before it issues a read-before-write notification. This happens when for example an uninitialized variable is being read.

Here is one of the erroneous C program I tested my test tool with. The C program reads uninitialized variable both in process and process2 functions from the CONTEXT structure. Highlighted the lines accessing uninitialized memory.
// TestRBW.cpp : Example file to test read-before-write bugs.
// Compile with optimization disabled.

#include "stdafx.h"
#include <string.h>

#define MAX 16

typedef struct _CONTEXT
{
    int arr[MAX];
    int a;
    int b;
    int c;
} CONTEXT;

void init(CONTEXT* ctx)
{
    memset(ctx->arr, 0, sizeof(ctx->arr[0]) * (MAX-1));
    ctx->a = 1;
}

void process(CONTEXT* ctx)

{
    int trash;

    for (int i = 0; i < MAX; i++)

    {
        trash = ctx->arr[i];
    }
}

void process2(CONTEXT* ctx)

{
    ctx->b = ctx->c;
}

void process3(int num)

{
    int trash;

    if (num)

        trash = num;
}

int _tmain(int argc, _TCHAR* argv[])

{
    CONTEXT ctx;

    // Erroneously initializes context. The last element of arr member remains unitialized.

    // b and c members remain uninitialized, too.
    init(&ctx);

    // Accesses to each element of the array. Read-before-write error should be reported in this function.

    process(&ctx);

    // Copies c to b but c is uninitialized. Read-before-write error should be reported in this function.

    process2(&ctx);

    // This contains no read-before-write bug.

    process3(ctx.a);
}
And here is the result of the test. In the log you can see both of the bugs were detected.
0:000> !region 18 18f000 1000
[Data Access] Data at 0018ff28 is read before it is written
[Data Access] EIP=00401044 Data=0018ff28 R
[Data Access] 00401044 8b048a          mov     eax,dword ptr [edx+ecx*4]
[Data Access] Data at 0018ff34 is read before it is written
[Data Access] EIP=00401059 Data=0018ff34 R
[Data Access] 00401059 8b5148          mov     edx,dword ptr [ecx+48h]
Break reason: 00000010
Looking the functions of the two EIPs. Highlighted the lines accessing uninitialized memory.
TestRBW!process:
00401020 55              push    ebp
00401021 8bec            mov     ebp,esp
00401023 83ec08          sub     esp,8
00401026 c745f800000000  mov     dword ptr [ebp-8],0
0040102d eb09            jmp     TestRBW!process+0x18 (00401038)
0040102f 8b45f8          mov     eax,dword ptr [ebp-8]
00401032 83c001          add     eax,1
00401035 8945f8          mov     dword ptr [ebp-8],eax
00401038 837df810        cmp     dword ptr [ebp-8],10h
0040103c 7d0e            jge     TestRBW!process+0x2c (0040104c)
0040103e 8b4df8          mov     ecx,dword ptr [ebp-8]
00401041 8b5508          mov     edx,dword ptr [ebp+8]
00401044 8b048a          mov     eax,dword ptr [edx+ecx*4]
00401047 8945fc          mov     dword ptr [ebp-4],eax
0040104a ebe3            jmp     TestRBW!process+0xf (0040102f)
0040104c 8be5            mov     esp,ebp
0040104e 5d              pop     ebp
0040104f c3              ret
TestRBW!process2:
00401050 55              push    ebp
00401051 8bec            mov     ebp,esp
00401053 8b4508          mov     eax,dword ptr [ebp+8]
00401056 8b4d08          mov     ecx,dword ptr [ebp+8]
00401059 8b5148          mov     edx,dword ptr [ecx+48h]
0040105c 895044          mov     dword ptr [eax+44h],edx
0040105f 5d              pop     ebp
00401060 c3              ret
I built this new functionality on the top of one mentioned in the previous post. The additions are the followings:
  • We trace both read and write memory accesses to the stack memory.
  • We maintain a structure to flag what memory addresses on the stack have been written.
  • Before the program starts to trace the memory it considers that memory addresses greater or equal than ESP have been written and maintain the structure according to this.
  • If a write memory access occurs we maintain the structure to flag the memory region has been written.
  • If an element is popped from the stack (read access to stack memory) we maintain the structure to remove addresses belongs to the unused portion of the stack memory.
  • If a read access memory occurs we read the structure and check if the memory at the address has been written. Giving notification according to results.

July 8, 2012

Tracing access to stack memory

In the previous post I wrote about a concept to intercept when arbitrary region of the memory is being accessed.

Below is an example output of the Windbg extension. I set it to monitor when the stack memory of the current thread (Address: 18d000 Size: 3000) is being accessed, and to break in when there is a call to other module (Break reason: 2).

In the log you can see the address where the memory access occurred and the instruction caused the memory access. Also, you can see the address of the data being accessed, and the type of the data access (R for read, W for write).

July 1, 2012

Data Access Breakpoint Using Memory Protection

When debugging data formats I sometimes think about how cool would be to have a debugger command that would allow me to place data access breakpoint on arbitrary region of the memory. Certainly, I can put hardware breakpoint on memory region with the restrictions that the size of the region is either 1, 2 or 4 bytes on IA32 architecture.

But what if I want to place a breakpoint on a data dump that has a size of greater than 4 bytes. For example, I want to do this to see what location within the region would be first accessed. Normally, there is no way to do this because of the lack of the support IA32 architecture provides. Software solution is possible but not implemented in debuggers such as in Ollydbg and in Windbg.

What you could do in these circumstances is to guess where the code parsing the data starts, and place a breakpoint on the execution flow, so when you break in the debugger you can trace the code from that point and watch the data flow. This is likely to be tedious process because you spend time stepping through code you are not interested. The other ideas tend to be even more tedious, and require prepration work (hooking etc.) We shouldn't forget that the reason we want to place breakpoint on memory region is usually to narrow down the scope of total debugging.

Some time ago I've seen how Armadillo protection uses debugge/debugger process to mark encrypted pages and when there is an access to the page it gets decrypted and executed on-the-fly. Also, EMET (Enhanced Mitigation Experience Toolkit) in the heap spray mitigation function uses to mark certain pages as unaccessible so the system cannot allocate memory to that address. This has inspired me how to write a plugin that allows me to place data breakpoint on arbitrary memory region. Yay!

Using VirtualProtect it's possible to disable all access to the memory page in the process address space. I however don't use VirtualProtect in the plugin but use VirtualProtectEx instead because the extended version allows me to disable all access to the memory in specified process rather than the current process.

The prototype has been developed as an extension command for Windbg. It requires two parameters describing the breakpoint: the address and the size of the region. When data is accessed within this region the we break in the debugger.

When the extension command runs it locates the base address of the memory page the specified region belongs to. Next, PAGE_NOACCESS protection flag is set for the memory page. This allows us to filter any access to the memory page via exception handling.

When the target runs in the debugger, and if there is an attempt to read from the protected page it results in an access violation. Due to this, the exception event callback implemented in the Windbg extension is executed. This callback verifies if the address of inaccessible data is within the region of the data breakpoint. If it is we restore the original protection flags for the page and break in the debugger - breakpoint hit. Otherwise, we restore the original protection flag to execute the single instruction previously generated the exception. Then we restore the protection flags do disable all access and continue to run the application until there is an attempt to read from the protected page resulting in an access violation.

The exception information is stored in EXCEPTION_RECORD structure which is available in the exception even callback function. Exception->ExceptionAddress is the address where the exception occurred. Exception->ExceptionInformation[1] is the address of the inaccessible data. More information on exception is available here.

Before I run the plugin command I also run sxn av so if access violation occurs we don't break in the debugger but get notification of the exception. Thus we let the event callback handle the exception.

When the memory page is too big - irrespectively of the breakpoint size - it might be possible it's being accessed too many times. In this case, the debugging tends to be extremely slow because of the frequent context switches between the target process and the debugger.

An enhancement of this plugin would be to let the execution continue when a data is accessed but to record each address being accessed so we can trace the memory access for certain memory regions.

June 18, 2012

Calling C# Code from Windbg Extension

It could be useful to write functions in C#, and to call some of those from Windbg plugin. Here is an approach how to achieve this.

Create a new project from Class Library template in Microsoft Visual C# 2010 Express.

Go to project properties an tick Register for COM interop off.

Enable ComVisible by editing AssemblyInfo.cs like below.
[assembly: ComVisible(true)]
Here is a simplified implementation to add.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace ExtensionUtils
{
    public interface IManagedInterface
    {
        int Func();
    } 
    public class Utils : IManagedInterface
    {
        public int Func()
        {
            return 1;
        }
    }
}
When compiling the code both ExtensionUtils.tlb and ExtensionUtils.dll have been created.

Open the Windbg plugin in Microsoft Visual C++ 2010 Express.

Add the following code that calls the C# function. But make sure to to copy ExtensionUtils.tlb and ExtensionUtils.dll files to directory that has been added to the (additional) include directories in the project settings.

#import "ExtensionUtils.tlb" named_guids 
[...] 
    HRESULT hRes; 
    CoInitialize(NULL); 
    ExtensionUtils::IManagedInterface *pManagedInterface = NULL; 
    hRes = CoCreateInstance(ExtensionUtils::CLSID_Utils, NULL, CLSCTX_INPROC_SERVER, 
     ExtensionUtils::IID_IManagedInterface, reinterpret_cast<void**> (&pManagedInterface));
    if (hRes == S_OK)
    {
        int ret = pManagedInterface->Func();
    } 
    CoUninitialize();
That's how I did.

June 5, 2012

Banned APIs Used by Browsers

I wrote a simple script for Windbg that finds deprecated functions in the modules of the process address space. It parses the name of the imported functions in the Import Address Table (IAT) of the PE image. Each API name is matched to a list of deprecated API names. If there is a match the script prints the API name out.

Here are some browser test have been done with the script. The result, in short, is all browsers use banned APIs that are flagged unsafe by Microsoft.

Chrome
I randomly chose modules in the Chrome's process address space, and found the following banned API.
0:012> $$>a< c:/work/BannedApi.wds chrome.dll c:/work/BannedApiList.txt
IAT Address: 01643000, Size: 000009b4
kernel32!IsBadWritePtr
1909 APIs scanned in IAT, 1 APIs have the name of deprecated APIs.
MSDN says "Important  This [IsBadWritePtr] function is obsolete and should not be used".

By the way, Chrome guys do pretty good job because this was the only one banned API I found in the address space albeit I didn't check all of the modules.

Firefox
Here are the banned APIs found in Firefox.
0:011> $$>a< c:/work/BannedApi.wds plugin_container c:/work/BannedApiList.txt
IAT Address: 00002000, Size: 000000d4
MSVCR80!wcslen
221 APIs scanned in IAT, 1 APIs have the name of deprecated APIs.
0:011> $$>a< c:/work/BannedApi.wds mozjs c:/work/BannedApiList.txt
IAT Address: 00169000, Size: 0000020c
MSVCR80!memcpy
MSVCR80!sprintf
546 APIs scanned in IAT, 2 APIs have the name of deprecated APIs.
0:011> $$>a< c:/work/BannedApi.wds xul c:/work/BannedApiList.txt
IAT Address: 00a27000, Size: 00002230
kernel32!lstrcatW
MSVCR80!_snprintf
MSVCR80!wcstok
MSVCR80!wcsncat
MSVCR80!strcat
MSVCR80!sscanf
MSVCR80!_ui64toa
MSVCR80!wcsncpy
MSVCR80!_i64toa
MSVCR80!sprintf
MSVCR80!memcpy
MSVCR80!strcpy
MSVCR80!_snwprintf
MSVCR80!strncpy
MSVCR80!wcslen
MSVCR80!strlen
MSVCR80!wcscpy
USER32!wsprintfW
7672 APIs scanned in IAT, 18 APIs have the name of deprecated APIs.
0:034> $$>a< c:/work/BannedApi.wds firefox.exe c:/work/BannedApiList.txt
IAT Address: 00003000, Size: 0000013c
MSVCR80!sprintf
MSVCR80!strlen
MSVCR80!_snprintf
MSVCR80!_vsnwprintf
MSVCR80!wcscpy
MSVCR80!strcpy
MSVCR80!wcslen
MSVCR80!_snwprintf
359 APIs scanned in IAT, 8 APIs have the name of deprecated APIs.
This is not a comprehensive list, I randomly chose modules in the process address space.

MSDN says "These functions [memcpy] are deprecated because more secure versions are available". Also "Security Note    These functions [strcpy] incur a potential threat brought about by a buffer overrun problem".

Internet Explorer
Some banned APIs in IE.
0:020> $$>a< c:/work/BannedApi.wds iexplore.exe c:/work/BannedApiList.txt
IAT Address: 00001000, Size: 0000020c
msvcrt!_vsnwprintf
392 APIs scanned in IAT, 1 APIs have the name of deprecated APIs.
0:020> $$>a< c:/work/BannedApi.wds jscript9.dll c:/work/BannedApiList.txt
IAT Address: 00001000, Size: 000003c4
msvcrt!_vsnwprintf
msvcrt!memcpy
743 APIs scanned in IAT, 2 APIs have the name of deprecated APIs.
0:020> $$>a< c:/work/BannedApi.wds MSHTML.dll c:/work/BannedApiList.txt
IAT Address: 00001000, Size: 00000fd4
msvcrt!memcpy
msvcrt!_vsnwprintf
msvcrt!_vsnprintf
SHLWAPI!StrCpyNW
3209 APIs scanned in IAT, 4 APIs have the name of deprecated APIs.
0:020> $$>a< c:/work/BannedApi.wds XmlLite.dll c:/work/BannedApiList.txt
IAT Address: 00001000, Size: 00000090
msvcrt!memcpy
msvcrt!_vsnwprintf
106 APIs scanned in IAT, 2 APIs have the name of deprecated APIs.
0:020> $$>a< c:/work/BannedApi.wds IEFRAME.dll c:/work/BannedApiList.txt
IAT Address: 00001000, Size: 00001640
msvcrt!_vsnprintf
msvcrt!_vsnwprintf
msvcrt!memcpy
USER32!wsprintfW
4478 APIs scanned in IAT, 4 APIs have the name of deprecated APIs.
Note
It's important to note that the presence of banned APIs doesn't mean the application is vulnerable, it means those shouldn't be there according to the Security Development Lifecycle Guideline because it's easy to go wrong with them.

If you want to try the script out I put it here. The script requires a text file containing the banned APIs, and you can get it from here.

June 2, 2012

Thoughts on Advanced .NET Debugging book

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.
  This blog is written and maintained by Attila Suszter. Read in Feed Reader.