# Debugging

## Remote debugging - gdbserver <a href="#docs-internal-guid-11e4f0cb-7fff-a8a1-4a5e-c053dffca575" id="docs-internal-guid-11e4f0cb-7fff-a8a1-4a5e-c053dffca575"></a>

If you want to connect to a gdb session from a remote machine, then you can run a gdbserver.

```
gdbserver 0.0.0.0:22222 program-file-name
```

The 22222 is the port in this case.

Or, if you want to attach to an existing process:

```
gdbserver --attach :22222 process_id_here
```

Connecting with radare2, for example:&#x20;

```
r2 -d gdb://host-name-here:22222
```

## Pwntools

You can load the executable in GDB like this:

```
io = pwn.gdb.debug([executable_filepath, argument1])
```

It also starts up a gdbserver, but trying to connect to it with radare2 fails (waits forever)

## GDB <a href="#docs-internal-guid-0e4a3569-7fff-9456-7ad6-c08071e2e205" id="docs-internal-guid-0e4a3569-7fff-9456-7ad6-c08071e2e205"></a>

Although I really prefer Radare2's user interface in just about every way, GDB is the only debugger that actually works consistently.&#x20;

### **Watching**

You can watch addresses for changes and stop when a change was made to that address. Can be useful if you're not sure where exactly a value is changed.

* `rwatch` stops when the specified address is accessed for reading
* `watch` stops when it's accessed for writing
* `awatch` stops on both reads and writes.

## Radare2&#x20;

### **Usage tips**

Run it in debug mode:

```
r2 -d filename
r2 -d process_id
```

Don’t forget to analyze using `aaa`. Alternatively, you can pass the `-A` flag when running radare2.

#### **Random Basics**

You can pipe with `|` and redirect with `>`

You can run commands at certain addresses with `@` ( `pd @ main`)

If you want to modify binaries on disk, then you have to use `-w` flag.

Help: `?`\
Help about debugging: `d?`

Running r2 command: `:`. For example `:aaa`&#x20;

You can use `ctrl+r` to do a reverse search for previous commands

#### **Analysis and Disassembly**

You have to analyze before you can disassemble. Analyze everything: `aaa`

List functions: `afl`

Rename location: `afn new_name_here loc.140011790`

Move to location: `s?`

Move to main: `s main`

Print stuff: `p?`&#x20;

Disassemble the current function: `pdf`

Disassemble the next N opcodes (`pdf` might not work when running shellcode on the stack): `pd number_of_opcodes`

Print stack: `pxr optional_byte_amount @ esp` (`rsp` for 64 bit programs). Stack grows downwards, so the latest pushes are at the top.

#### **Debugging**

Debugging: `d?`

Place a breakpoint at either an address or function name: `db address_or_function`

Remove breakpoint: `db - address_or_function`

Print registers: `dr`

Continue: `dc`

Continue until address: `dcu address`

Stepping: `ds?`

Reload process: `do` (alias for `oo`)

Reload process in debugger mode with arguments (alias for `ood`): `doo`

Set register: `dr eax = 0x00000000X`

#### **Visuals**

Basic visual mode: `V`  , use `p` to cycle. Not too useful.

Graph view: `VV`. Zoom: `+-`

Visual panels: `V!`

Exit back to command line mode: `q`

**Configuration**

Change configuration variables with `e`.

![](https://lh4.googleusercontent.com/Mv2KVXxSHTdaG4OxU32p5JRoA3rCzfYzL9vOHkcWyz2Pd0zb3ewSnBUxvkL08H_UvBT-IhtC0_z8uw1rGmo5foVVURCr_mMrGHy_GnRigUz7ESQWmD964v01Ec3aGnjVcmKqhyxwBEBrTp1popg0bw)

The utf8 ones create a nicer graph view and nicer arrows.

Show opcode description appends a comment after each instruction to explain what it’s doing.

iocache allows you to modify files that haven’t been opened with the write flag. But it still won’t be written to disk, just in memory.

#### **Forking**

Note: I haven’t been able to get forking following working correctly in r2. I’ve used GDB for that. But I’ve probably just been using r2 wrong

Environment variables:

* `e dbg.forks=true`
* `e dbg.follow.child = true`

Commands:

* `dcf`: continue until fork
* `dp`: list processes

### **Finding ROP Gadgets**

You can use the `/R` syntax to find ROP gadgets:&#x20;

{% embed url="<https://radareorg.github.io/blog/posts/ropnroll/>" %}

Though, **msfelfscan** might give much better results. Radare2 didn’t find a `jmp esp` while msfelfscan did.

### **Remote usage**

On the remote server:

```
gdbserver 0.0.0.0:22222 program-file-name
```

On the local server:

```
r2 -d gdb://host-name-here:22222
```

### **Searching**

You can search for hex values in the binary like this:

```
/ \xde\xad\xbe\xef
```

### **Rabin2**

Rabin2 can be super useful for finding things in a binary.

For example, I used it to find static variable addresses by listing exported symbols:

```
rabin2 -s executable_name
```

### **Feed input from a file**

Create a file `~/input.rr2`:

```
Feed input from a file
Create a file ~/input.rr2:
```

Then put some shellcode in the input file for example:

```
echo $'\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999' > /home/user/level01/exploit/payload
```

Then run the program using that configuration:

```
r2 -r /path/to/input.rr2 -d /path/to/executable
```

You can reload it (and restart the process) with `doo`
