The following is the solution for Exercise 01.
For this exercise, make sure you run all commands from the directory:
/path/to/cbat_tools/docs/exercises/01
Find out if it is possible to trip the assert in the function is_valid_ID
.
First, run wp
on the is_valid_ID
function in ./binary/main
using --trip-asserts
:
$ bap wp \ --func=is_valid_ID \ --trip-asserts \ binary/main
In response, wp
says SAT
, which means that wp
did find a way to trip the assert. Hence, the solution to the first task is: yes, it is possible to trip the assert in the is_valid_ID
function.
If it is possible to try the assert, use wp
's output to determine an example of an argument that will trip the assert.
When you ran the above command, wp
provides an example of an argument that will trip the assert. Your output should look something like this (it may not be identical, but it should be very close):
SAT! Model: ZF |-> 0x0 SF |-> 0x0 RSP |-> 0x000000003f800084 RSI |-> 0x0000000000000000 RDX |-> 0x0000000000000000 RDI |-> 0x00000000dde4ddef <-- An argument to trip the assert RCX |-> 0x0000000000000000 RBP |-> 0x0000000000000000 RAX |-> 0x0000000000000000 R9 |-> 0x0000000000000000 R8 |-> 0x0000000000000000 PF |-> 0x0 OF |-> 0x0 CF |-> 0x0 AF |-> 0x0 mem_orig |-> [ else |-> 0x00] mem_mod = mem_orig
The argument to the function is always placed in RDI
, so look at the value that wp
suggests for RDI
. In my case, it is 0x00000000dde4ddef
, but yours may be different. Whatever value you see there is an example of a number that will trip the assert. Try it from the command line:
$ ./binary/main 0x00000000dde4ddef
The output shows that the assertion does indeed get triggered:
main: main.c:10: is_valid_ID: Assertion `0' failed. Aborted
So, an example of an argument that will trip the assert is the value suggested by wp
for RDI
(which in my case is 0x00000000dde4ddef
).
Use bildb
to step through the program line-by-line, and replicate the behavior of tripping the assert.
You know a value to put in RDI
at the beginning of is_valid_ID
that will trip the assert. In my case, it was 0x00000000dde4ddef
.
Start up bildb
at the is_valid_ID
function:
$ bap binary/main \ --pass=run \ --run-entry-point=is_valid_ID \ --bildb-debug
You will see bildb
start up, and stop at the first instruction in the is_valid_ID
function:
BIL Debugger Starting up... Architecture Type: x86_64 Address size: 64 Registers: R10 R11 R12 R13 R14 R15 R8 R9 RAX RBP RBX RCX RDI RDX RSI RSP YMM0 YMM1 YMM10 YMM11 YMM12 YMM13 YMM14 YMM15 YMM2 YMM3 YMM4 YMM5 YMM6 YMM7 YMM8 YMM9 Entering subroutine: [%000009e9] is_valid_ID 00000a16: is_valid_ID_result :: out u32 = RAX Entering block %0000042d 00000434: #47 := RBP
Now, set RDI
to the value wp
suggested earlier, by typing set RDI=VAL
, where VAL
is the value wp
suggested. In my case:
>>> (h for help) set RDI=0x00000000dde4ddef RDI : 0xDDE4DDEF
Next, let bildb
run the function. Type n
(followed by enter
) to tell bildb
to run to the next block. It will stop at the next block:
>>> (h for help) n Entering block %0000087a 0000087f: RCX := 0x4006B8
Type n
(followed by enter
) again, to tell bildb
to run forward again. This time, it will enter the __assert_fail
function:
>>> (h for help) n Entering subroutine: [%000009d3] __assert_fail 00000a07: __assert_fail_result :: out u32 = RAX Entering block %000000bc 000000c2: call mem[0x601018, el]:u64 with noreturn
So, you have triggered the assert. You can now quite bildb
by typing q
(followed by enter
):
>>> (h for help) q Goodbye
Go back to the list of exercises.