Reading and Debugging X86 Programs



Introduction 

Lab Steps

Part 1 – Find The Number

  1. Log into your Unix account on felix or helix (not on tanner, since we will need a Linux machine for this lab). In your csc8400 directory create another directory called x86, then switch your current directory to csc8400/x86.
  2. Copy the executable guess_one_number from the /mnt/a/mdamian/courses/x86 directory into your csc8400/x86 directory. Invoke gdb with guess_one_number as an argument:
             gdb ./guess_one_number
  1. Set the disassembly language to Intel:
             set disassembly-flavor intel
 
4.          Disassemble the main function: 
 
             disas main
 
5.          The piece of code of interest to you is the following: 
 
0x08048492 <main+48>:       mov    eax,DWORD PTR [ebp-0x8]
0x08048495 <main+51>:       cmp    eax,0x309
0x0804849a <main+56>:       jg     0x80484a1 <main+63>
0x0804849c <main+58>:       call   0x8048444 <print_error>
0x080484a1 <main+63>:       mov    DWORD PTR [esp],0x80485c0
0x080484a8 <main+70>:       call   0x8048370 <puts@plt>
 
6.          Set a breakpoint to the first cmp machine instruction:
 
             break *(main+51)
 
7.          Tell the debugger to display the next machine instruction to be executed:
 
             display /i $eip
 
8.          Invoke the run command to start running the program. Execution will stop at the first breakpoint. 
 
             run
 
9.          The program will ask you to guess the secret number. Enter your guess. Step carefully through instructions, inspecting registers and stack contents:
 
             x /d $ebp-8
             p /d 0x309
             ni
 
10.       Rerun the program (type in run),  hoping to “guess” the secret number this time. 
 
11.       Once you have your number, quit the debugger with quit. 
 
12.       Write down your number: _________________ 

Part 2 – Find The Two Numbers

  1. Copy the executable guess_two_numbers from the /mnt/a/mdamian/courses/x86 directory into your csc8400/x86 directory. Invoke gdb with guess_two_numbers as an argument:
             gdb ./guess_two_numbers
 
2.          Set the disassembly language to Intel:
 
              set disassembly-flavor intel
 
3.          Disassemble the main function: 
 
             disas main
 
4.          The piece of code of interest to you is the following: 
 
0x08048499 <main+55>:       mov    eax,DWORD PTR [ebp-0x8]
0x0804849c <main+58>:       cmp    eax,0xb
0x0804849f <main+61>:       jle    0x80484a6 <main+68>
0x080484a1 <main+63>:       call   0x8048444 <print_error>
0x080484a6 <main+68>:       mov    eax,DWORD PTR [ebp-0x8]
0x080484a9 <main+71>:       lea    edx,[eax+0x2]
0x080484ac <main+74>:       mov    eax,DWORD PTR [ebp-0xc]
0x080484af <main+77>:       cmp    edx,eax
0x080484b1 <main+79>:       je     0x80484b8 <main+86>
0x080484b3 <main+81>:       call   0x8048444 <print_error>
0x080484b8 <main+86>:       mov    DWORD PTR [esp],0x80485e8
0x080484bf <main+93>:       call   0x8048370 <puts@plt>
 
5.          Set a breakpoint to the first cmp machine instruction:
 
             break *(main+58)
 
6.          Tell the debugger to display the next machine instruction to be executed:
 
             display /i $eip
 
7.          Invoke the run command to start running the program. Execution will stop at the first breakpoint. 
 
             run
 
8.          Inspect the stack contents at address $ebp-8 
 
9.          Step carefully through instructions, inspecting registers (using the p command, which stands for print) and memory contents (using the x command, which stands for examine). 
 
10.       Rerun the program as many times as necessary to find the two numbers.

 

11.       Write down the two numbers: _____________________
 

Part 3 – Find The Three Numbers

Now that you’ve warmed up to the debugger, let’s try a slightly more challenging hunt. 
  1. Copy the executable guess_three_numbers from the /mnt/a/mdamian/courses/x86 directory into your csc8400/x86 directory. Invoke gdb with guess_three_numbers as an argument.
  2. Set the disassembly language to Intel.
  3. Disassemble the main function. The piece of code of interest to you is the following:
0x080484f5 <main+83>:       mov    eax,DWORD PTR [ebp-0x8]
0x080484f8 <main+86>:       cmp    edx,eax
0x080484fa <main+88>:       je     0x8048501 <main+95>
0x080484fc <main+90>:       call   0x8048484 <print_error>
0x08048501 <main+95>:       mov    eax,DWORD PTR [ebp-0x8]
0x08048504 <main+98>:       lea    edx,[eax+0xa]
0x08048507 <main+101>:      mov    eax,DWORD PTR [ebp-0x10]
0x0804850a <main+104>:      cmp    edx,eax
0x0804850c <main+106>:      je     0x8048513 <main+113>
0x0804850e <main+108>:      call   0x8048484 <print_error>
0x08048513 <main+113>:      mov    edx,DWORD PTR [ebp-0x8]
0x08048516 <main+116>:      mov    eax,DWORD PTR [ebp-0x10]
0x08048519 <main+119>:      lea    eax,[edx+eax*1]
0x0804851c <main+122>:      lea    edx,[eax+0xa]
0x0804851f <main+125>:      mov    eax,DWORD PTR [ebp-0xc]
0x08048522 <main+128>:      cmp    edx,eax
0x08048524 <main+130>:      je     0x804852b <main+137>
0x08048526 <main+132>:      call   0x8048484 <print_error>
0x0804852b <main+137>:      mov    DWORD PTR [esp],0x804865c
0x08048532 <main+144>:      call   0x80483a4 <puts@plt>
 
  1. Set a breakpoint to the first cmp machine instruction.
  2. Tell the debugger to display the next machine instruction to be executed.
  3. Start running the program. Execution will stop at the first breakpoint.
  4. The program will ask you for your username and three numbers. Enter the data. Here’s an example:

mdamian 11 22 33

  1. Go step by step through the assembly code. Inspect register (using the p command) and memory contents (using the x command) to learn the three numbers your program expects. Rerun your code as many times as necessary to figure out the answer.
  2. Write down the three numbers:   ______________________________________