Sep 29, 2013
Andrew Brooks
Stack Trace

Picking up from where we left off on our last post, let’s keep working with the Vivisect GUI and explore some additional functionality.  If you followed along from the first part, we’ve identified our string and if we jump back to the function graph, it might be good for us to add a comment so that we have an easier time tracking our work on the binary.  To add a comment, simply highlight the line you with to comment and press the semi-colon key which will let you add a comment to that line.

Commenting Code

vv1

Once you reload the Vivisect workspace, your changes will take effect.

Similar to adding comments in your code, it’s useful to track variables throughout your programs and Vivisect gives us a nice way to rename variables.  For now, let’s close reverseme.exe.viv and generate a Vivisect workspace for the program you compiled in Part 1, “conditional.”  Open the workspace and immediately send conditional.main to FuncGraph0.  Let’s have a look at the code and see what’s going on:

.text:0x08048464  
.text:0x08048464  FUNC: int cdecl conditional.main( ) [1 XREFS]
.text:0x08048464  
.text:0x08048464  Stack Variables:
.text:0x08048464           -20: int local20
.text:0x08048464           -44: int local44
.text:0x08048464           -48: int local48
.text:0x08048464  
.text:0x08048464  55               push ebp
.text:0x08048465  89e5             mov ebp,esp
.text:0x08048467  83e4f0           and esp,0xfffffff0
.text:0x0804846a  83ec20           sub esp,32
.text:0x0804846d  b8a0850408       mov eax,loc_080485a0    ;
.text:0x08048472  890424           mov dword [esp + local48],eax
.text:0x08048475  e8e6feffff       call printf_08048360    ;printf_08048360()
.text:0x0804847a  b8b6850408       mov eax,loc_080485b6
.text:0x0804847f  8d54241c         lea edx,dword [esp + 28]
.text:0x08048483  89542404         mov dword [esp + local44],edx
.text:0x08048487  890424           mov dword [esp + local48],eax
.text:0x0804848a  e811ffffff       call __isoc99_scanf_080483a0    ;__isoc99_scanf_080483a0()
.text:0x0804848f  8b44241c         mov eax,dword [esp + local20]
.text:0x08048493  83f863           cmp eax,99
.text:0x08048496  7f0e             jg loc_080484a6

Right off the bat, Vivisect tells us that we have three stack variables, local20, local44, and local48.  In looking at the source code, or even if we run the program, it’s pretty easy to see what this program does when its executed.

user@ubuntu:~/vivisect_20130901$ ./conditional 
Please enter your age99
You are pretty young!
user@ubuntu:~/vivisect_20130901$

Fascinating.

Let’s make a few intelligent guesses…  So, 0×08048475 is a call to printf() and is responsible for asking us to input our age.  A few lines, down at 0x0804848a, we see a call to scanf() which is where we’re inputting out age.  Immediately after we enter our age, local20 is moved into EAX and them compared to the value of “99″ for our first conditional branch.  At this point, it’s pretty safe to say that local20 is our age, so we can rename this variable which will be applied throughout the code and be visible anywhere that local20 is passed in subsequent functions/code.  To name the local variable something more meaningful, place your mouse within the function, and select function > locals > select local, and rename.  Once you reload, you should now see your changes applied.

Renamed Local Variable

vv2

One thing we haven’t touched on yet is the Vivisect console.  In the console, typing “help” will show you a list of available commands.

vv3

And for additional information, “help <command>” will show extended usage.

vv4

Using the console is pretty straight forward, and if you’re stuck on something, the epydocs for the project are very helpful.

To demonstrate one of the commands, let’s say we want to find a path between two blocks of interest.  With small programs like this, it’s trivial to find a path at a glance, but Vivisect allows you to find paths automagically using the codepath command.  If we want to find a path between our conditional.main entry point and one of the conditional blocks, we can do this with the following command:

> codepath 0x08048496 0x080484c4
Tracking Paths From 0x08048496 to 0x080484c4
Function VA    Block VA    Size    Function Name
==============================
0x08048464    0x08048464      52    conditional.main
0x08048464    0x080484a6       9    conditional.main
0x08048464    0x080484bd      12    conditional.main

Where 0×0904896 is our first address, and 0x080484c4 is the second address.

Lastly, one additional command you may find to be particularly useful is the codediff command which performs a binary diff on two Vivisect workspaces.  As an exercise for the reader, change the conditional.c source code in part 1 to have it branch differently depending on the inputted ages and diff the two workspaces once you’ve compiled your changes!  Finally, even for the numerous console commands we didn’t cover, be sure to check them out on your own as the Vivisect console provides an unbelievable amount of power that would be impossible to cover in this series.

Next Sunday, we’ll wrap up this series with Part 3 where we’ll cover working with VDB, the Vivisect debugger.  That’s all for now, I’m off to watch the season finale of Breaking Bad, and you should be as well!

Read the rest of the Binary Vivisection Series

Leave a Comment