Mona 2 is a very useful extension developed by the Corelan Team. Originally written for Immunity Debugger, it now works in WinDbg as well.
Installation in WinDbg
You’ll need to install everything for both WinDbg x86 and WinDbg x64:
- Install Python 2.7 (download it from here)
Install the x86 and x64 versions in different directories, e.g. c:\python27(32) and c:\python27.
- Download the right zip package from here, and extract and run vcredist_x86.exe and vcredist_x64.exe.
- Download the two exes (x86 and x64) from here and execute them.
- Download windbglib.py and mona.py from here and put them in the same directories as windbg.exe (32-bit and 64-bit versions).
- Configure the symbol search path as follows:
- click on File→Symbol File Path
- save the workspace (File→Save Workspace).
Running mona.py under WinDbg
Running mona.py in WinDbg is simple:
- Load the pykd extension with the command
- To run mona use
To update mona enter
!py mona update
Many functions of mona dump data to files created in the mona’s working directory. We can specify a working directory which depends on the process name and id by using the format specifiers %p (process name) and %i (process id). For instance, type
!py mona config -set workingfolder "C:\mona_files\%p_%i"
You can exclude specific modules from search operations:
!mona config -set excluded_modules "module1.dll,module2.dll" !mona config -add excluded_modules "module3.dll,module4.dll"
You can also set the author:
!mona config -set author Kiuhnm
This information will be used when producing metasploit compatible output.
If there’s something wrong with WinDbg and mona, try running WinDbg as an administrator.
You can find more information about Mona here.
This example is taken from Mona’s Manual.
Let’s say that we control the value of ECX in the following code:
MOV EAX, [ECX]
We want to use that piece of code to jmp to our shellcode (i.e. the code we injected into the process) whose address is at ESP+4, so we need the call above to call something like “ADD ESP, 4 | RET“.
There is a lot of indirection in the piece of code above:
- (ECX = p1) → p2
- p2+58h → p3 → “ADD ESP,4 | RET”
First we need to find p3:
!py mona config -set workingfolder c:\logs !py mona stackpivot -distance 4,4
The function stackpivot finds pointers to code equivalent to “ADD ESP, X | RET” where X is between min and max, which are specified through the option “-distance min,max“.
The pointers/addresses found are written to c:\logs\stackpivot.txt.
Now that we have our p3 (many p3s!) we need to find p1:
!py mona find -type file -s "c:\logs\stackpivot.txt" -x * -offset 58 -level 2 -offsetlevel 2
Let’s see what all those options mean:
- “-x *” means “accept addresses in pages with any access level” (as another example, with “-x X” we want only addresses in executable pages).
- “-level 2” specifies the level of indirection, that is, it tells mona to find “a pointer (p1) to a pointer (p2) to a pointer (p3)”.
- The first two options (-type and -s) specifies that p3 must be a pointer listed in the file “c:\logs\stackpivot.txt“.
- “-offsetlevel 2” and “-offset 58” tell mona that the second pointer (p2) must point to the third pointer (p3) once incremented by 58h.
Don’t worry too much if this example isn’t perfectly clear to you. This is just an example to show you what Mona can do. I admit that the syntax of this command is not very intuitive, though.
The command findwild allows you to find chains of instructions with a particular form.
Consider this example:
!mona findwild -s "push r32 # * # pop eax # inc eax # * # retn"
The option “-s” specifies the shape of the chain:
- instructions are separated with ‘#‘
- r32 is any 32-bit register
- * is any sequence of instructions
The optional arguments supported are:
- -depth <nr>: maximum length of the chain
- -b <address>: base address for the search
- -t <address>: top address for the search
- -all: returns also chains which contain “bad” instructions, i.e. instructions that might break the chain (jumps, calls, etc…)
Mona can find ROP gadgets and build ROP chains, but I won’t talk about this here because you’re not supposed to know what a ROP chain is or what ROP is. As I said, don’t worry if this article doesn’t make perfect sense to you. Go on to the next article and take it easy!