Project 2: Binary Bombs

Important Dates

Questions about the project? Send them to 354-help@cs.wisc.edu .

Due: Wed 10/17

Project to be done alone. As usual, don't cheat .

Objective

There are two main objectives of this project. The first is obvious: to become intimately familiar with x86 assembly language. This is a hugely useful skill! In real life, one is often faced with the task of trying to figure out why some code isn't working as planned, and sometimes this leads to staring at the instructions that are executing on the CPU to gain thus understanding. The second relates to the first: to gain some familiarity with powerful tools that help with this process, namely gdb (the debugger) and objdump (the disassembler). These tools will also serve you well in your future endeavors.

Overview

In this project, you will be defusing a series of binary bombs . The idea is simple: each bomb is just an executable program, which expects five inputs from you, the bomb defusing expert. If you type in the right values, you will successfully defuse the bomb. If not, the bomb explodes! (don't worry, it just prints that the bomb explodes; no real harm is done to you or your computer, probably).

The challenge, of course, is to figure out what inputs each of the five bombs you'll be given expects. To do this, you'll be using two tools, gdb and objdump. Both are incredibly useful for this type of reverse engineering work (more on them below).

To begin work, look in your project 2 directory ( ~cs354-3/handin/remzi/p2/ , if your login is remzi , which it isn't, but you get the point). Therein you will find five binary bombs, b1 through b5, roughly in increasing order of difficulty. Your task will be to create five files, b1.solution through b5.solution, each of which contains the five lines of input demanded by each bomb. For example, if the solution to bomb1 (b1) was 1, 2, 3, 4, and 5, you would create a file (using some text editor, like emacs, vi, etc.) with the following entries:

1
2
3
4
5

Important note: EACH PERSON HAS A DIFFERENT SET OF BOMBS! Thus, the answers for bomb1 for user X is different than the answers for bomb1 for user Y. Thus, sharing answers is not very useful, though it is OK to talk a bit about how to use the tools, etc., to defuse the bombs.

To test whether you've figured out a bomb's defusing code correctly, you simply run the bomb with this input file, e.g.,

prompt> ./b1 b1.solution
It should print a success message if you've figured everything out; otherwise it will tell you the bomb exploded.

You can also run each bomb interactively, and type in your guesses, one at a time. This will be useful in defusing each bomb with the debugger, as described below.

The Tools: gdb and objdump

To defuse the bombs, you'll be using two powerful tools: gdb and objdump. Both are critical in understanding what each binary bomb does.

With objdump, two important flags are -d (which disassembles a binary) and -s (which displays the full binary contents of the executable). For example, to see the assembly code of bomb b1, you might type:

prompt> objdump -d b1

This will show an assembly listing of each function in the bomb. Your first task then might be to look at main() and figure out what the code is doing (more on this below).

The -s flag is also quite useful, as it just shows the contents of each section of the executable. This may be needed when looking for the initial value of a given variable.

The debugger gdb is an even more powerful ally in your search for clues as to how to defuse each bomb. To run gdb on a particular bomb (say b1), simply type gdb b1 , which will launch the debugger and ready you for a debugging session. If you then type run the debugger will run the program, in this case prompting you for input.

However, before running the debugger, you likely need to first set some breakpoints . Breakpoints are places in the code where the debugger will stop running and let you take control of the debugging session. For example, a common thing to do will be to fire up the debugger, type break main to set a breakpoint at the main() routine of the program, and then type run to run the program. When the debugger enters the main routine, it will then freeze the program and pass control back to you, the user.

At this point, you will need to do some work. One likely command you'll use is stepi which steps through the code one instruction at a time. Another useful command is info registers which shows you the contents of all of the registers of the system. Another is x/x 0xADDRESS which is the examine command; this shows you the contents at the address ADDRESS and does so in hexadecimal (the second x determines the format, whereas the first x is the examine command). Finally, you can also have gdb disassemble the code by typing the disassemble command.

Getting good with gdb will make this project go very smoothly, so spend the time and learn! One thing to notice: hitting the up and down arrows (or control-p and control-n for previous and next, respectively) allows you to go through your gdb history and easily re-execute old commands; getting good at using your history, whether in gdb or more generally in the shell you use, is a good idea.

Good luck!

Grading

Our grading will be based entirely on whether you defuse the bombs. Each bomb is thus worth 20 percent of the grade for this project.

Handing It In

To turn in your answers, you should create five files, named b1.solution , b2.solution , b3.solution , b4.solution , and b5.solution . Each should have five lines of text that defuse the bombs b1, b2, b3, b4, and b5, respectively. These files should be found in your p2 directory where your binary bombs are.

Finally, in your p2 directory, please make a README file, which simply describes what you did (a little bit). Brevity is OK.