Wednesday, June 12, 2013

Windbg Tricks - Javascript Windbg Instrumentation

This post is going to cover three levels of usefulness of windbg instrumentation via javascript : subpar, normal, and abnormal.

SUBPAR

The most basic way of instrumenting windbg via javascript is to set a breakpoint on a simple function, such as Math.atan, call Math.atan at the appropriate time in javascript to force windbg to break, and then do whatever you need to do in windbg. Useful, yes, but it's lame and gets extremely tiring after the first time of doing it.

NORMAL

A better way to instrument windbg via javascript is to create a way for javascript to print a message in windbg (and trigger a break):
bu jscript!Js::Math::Atan ".printf \"DEBUG: %mu\\n\", poi(poi(esp+10)+c) ; g"
(If you want to break, remove the ; g)

That's cool, but what if you want to do something a little more complicated, like track all allocations of a specific size after certain javascript statements have been executed. With the previous method, the javascript would have to look something like this:
function log(msg) {
    Math.atan(msg);
}

function track_all_allocations_and_frees_size_x20() {
    Math.asin();
}

log("Executing main javascript");
execute_main_javascript();

log("Track all allocations and frees now");
track_all_allocations_and_frees_size_x20();
do_something_cool();
... and the windbg breakpoints would be something like this:
bu jscript!Js::Math::Atan ".printf \"DEBUG: %mu\\n\", poi(poi(esp+10)+c) ; g"
bu jscript!Js::Math::Asin "bp ntdll!RtlAllocateHeap .if(poi(esp+c) == 0x20) { .echo ALLOCATED ONE ; knL } ; g"
This is more useful, but is still very inflexible. For every new javascript<-->windbg binding you might want, you'd need to also modify your breakpoints in windbg.

ABNORMAL

Below is an abnormally useful way to instrument windbg with javascript:
bu jscript!Js::Math::Atan ".block { .shell -ci \".printf \\\"%mu\\\\n\\\", poi(poi(esp+10)+c)\" find /v \"13333333337\" > cmd_to_exec.txt & exit } ; $$><cmd_to_exec.txt"
This lets you execute windbg commands directly from javascript. The breakpoint basically does an eval("WINDBG_CMD") with a string from memory. Broken down, the breakpoint goes like this:
.block {
    .shell -ci ".printf \"%mu\\n\", poi(poi(esp+10)+c)" find /v \"13333333337\" > cmd_to_exec.txt
}
$$<>cmd_to_exec.txt
Using .block helps to end the .shell command, since semicolons don't work as statement endings for the .shell command (see this article on msdn for more details).

find /v "13333333337" > cmd_to_exec.txt simply saves what was printf'd to the file cmd_to_exec.txt. Specifically, the find command filters out all lines from stdin that contain 13333333337. Any string here will work as long as you never expect to see it in a windbg command that you'd execute via javascript.

$$<>cmd_to_exec.txt runs the string we saved to cmd_to_exec.txt as a windbg script.

This method makes things much simpler. Going back to the first example, we can now do things like this:
function exec(cmd) {
    Math.atan(cmd);
}
function log(msg) {
    exec(".echo " + msg);
}
function track_allocations(size) {
    exec('bp ntdll!RtlAllocateHeap ".if(poi(esp+c) == 0n' + size + '){ .echo ALLOCATED ONE ; knL } ; g" ; g');
}

log("Executing main javascript");
execute_main_javascript();

var alloc_size = 0x20;
log("Tracking allocations of size " + alloc_size.toString(0x10));
track_allocations(0x20);
do_something_cool();
Almost makes you wish you could write a javascript interface to windbg, doesn't it?

Abnormally useful. Laters.

Saturday, April 13, 2013

Windbg Tricks - Module Relocation

When ASLR is not supported, pseudo ASLR is often used to introduce a degree of entropy in where the module is loaded into memory.

The basic idea behind pseudo ASLR is to pre-allocate memory at the location of a module's preferred base address. This forces the module to be loaded at a non-predetermined address. See this for more details.

I stumbled across the windbg command !imgreloc the other day. It can be used to show all modules that have been relocated, and what their original preferred base address is.

Below is the output when run while attached to firefox.exe (see this ticket about dll blocking and this firefox ticket for a specific history of pseudo ASLR in firefox):

0:017> !imgreloc
00280000 sqlite3 - RELOCATED from 10000000
00300000 js3250 - RELOCATED from 10000000
00400000 firefox - at preferred address
004e0000 nspr4 - RELOCATED from 10000000
00510000 smime3 - RELOCATED from 10000000
00530000 nss3 - RELOCATED from 10000000
005d0000 nssutil3 - RELOCATED from 10000000
005f0000 plc4 - RELOCATED from 10000000
00600000 plds4 - RELOCATED from 10000000
00610000 ssl3 - RELOCATED from 10000000
00640000 xpcom - RELOCATED from 10000000
01220000 browserdirprovider - RELOCATED from 10000000
01540000 brwsrcmp - RELOCATED from 10000000
01de0000 nssdbm3 - RELOCATED from 10000000
02000000 xpsp2res - RELOCATED from 00010000
036a0000 softokn3 - RELOCATED from 10000000
03980000 freebl3 - RELOCATED from 10000000
039d0000 nssckbi - RELOCATED from 10000000
10000000 xul - at preferred address
59a60000 dbghelp - at preferred address
5ad70000 uxtheme - at preferred address
0:017> .shell -ci "!imgreloc" findstr RELOCATED
00280000 sqlite3 - RELOCATED from 10000000
00300000 js3250 - RELOCATED from 10000000
004e0000 nspr4 - RELOCATED from 10000000
00510000 smime3 - RELOCATED from 10000000
00530000 nss3 - RELOCATED from 10000000
005d0000 nssutil3 - RELOCATED from 10000000
005f0000 plc4 - RELOCATED from 10000000
00600000 plds4 - RELOCATED from 10000000
00610000 ssl3 - RELOCATED from 10000000
00640000 xpcom - RELOCATED from 10000000
01220000 browserdirprovider - RELOCATED from 10000000
01540000 brwsrcmp - RELOCATED from 10000000
01de0000 nssdbm3 - RELOCATED from 10000000
02000000 xpsp2res - RELOCATED from 00010000
036a0000 softokn3 - RELOCATED from 10000000
03980000 freebl3 - RELOCATED from 10000000
039d0000 nssckbi - RELOCATED from 10000000

Searching for preferred instead of RELOCATED will yield a list of modules that should remain at their preferred address (and thus be usable for ROP or other such techniques).

Windbg Tricks

I have a long list of common windbg tricks that I use. I plan on putting many of them on this blog with the label windbg trick.

This is mainly for my own use so I don't forget about them. Maybe they will be useful for others as well.