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.
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$
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
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.
And for additional information, “help <command>” will show extended usage.
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!