# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)

## Week 1
Introduction and Overview of Embedded Reverse Engineering: Ethics, Scoping, and Basic Concepts

### Exercise 4: Connect GDB & Basic Exploration

#### Objective
Set up GDB (GNU Debugger) to dynamically analyze the "hello, world" program running on your Pico 2, verifying that your debugging setup works correctly.

#### Prerequisites
- Raspberry Pi Pico 2 with "hello-world" binary already flashed
- OpenOCD installed and working
- GDB (arm-none-eabi-gdb) installed
- Your Pico 2 connected to your computer via USB CMSIS-DAP interface
- CMake build artifacts available (`.elf` file from compilation)

#### Task Description

In this exercise, you'll:
1. Start OpenOCD to provide a debug server
2. Connect GDB to the Pico 2 via OpenOCD
3. Set a breakpoint at the main function
4. Examine registers and memory while the program is running
5. Verify that your dynamic debugging setup works

#### Important Setup Notes

Before you start, make sure:
- Your Pico 2 is **powered on** and connected to your computer
- You have **OpenOCD** installed for ARM debugging
- You have **GDB** (specifically `arm-none-eabi-gdb`) installed
- Your binary file (`0x0001_hello-world.elf`) is available in the `build/` directory

#### Step-by-Step Instructions

##### Step 1: Start OpenOCD in Terminal 1

Open a **new terminal window** (PowerShell, Command Prompt, or WSL):

**On Windows (PowerShell/Command Prompt):**
```
openocd ^
  -s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
  -f interface/cmsis-dap.cfg ^
  -f target/rp2350.cfg ^
  -c "adapter speed 5000"
```

**Expected Output:**
```
Open On-Chip Debugger 0.12.0+dev
...
Info : CMSIS-DAP: SWD detected
Info : RP2350 (dual core) detected
Info : Using JTAG interface
...
Info : accepting 'gdb' connection on tcp/3333
```

##### Step 2: Start GDB in Terminal 2

Open a **second terminal window** and navigate to your project directory:

```
arm-none-eabi-gdb build\0x0001_hello-world.elf
```

**Expected Output:**
```
Reading symbols from build\0x0001_hello-world.elf...
(gdb)
```

##### Step 3: Connect GDB to OpenOCD

At the GDB prompt `(gdb)`, type:

```gdb
target extended-remote localhost:3333
```

**Expected Output:**
```
Remote debugging using localhost:3333
(gdb)
```

(The warning is normal - you already loaded the .elf file, so it doesn't matter)

##### Step 4: Reset and Halt the Target

To reset the Pico 2 and prepare for debugging, type:

```gdb
monitor reset halt
```

**Expected Output:**
```
(gdb)
```

(This resets the processor and halts it, preventing execution until you tell it to run)

##### Step 5: Set a Breakpoint at main

To stop execution at the beginning of the `main` function:

```gdb
b main
```

**Expected Output:**
```
Breakpoint 1 at 0x10000234: file ../0x0001_hello-world.c, line 4.
(gdb)
```

**What this means:**
- Breakpoint 1 is set at address `0x10000234`
- That's in the file `../0x0001_hello-world.c` at line 4
- The breakpoint is at the `main` function

##### Step 6: Continue Execution to the Breakpoint

Now let the program run until it hits your breakpoint:

```gdb
c
```

**Expected Output:**
```
Continuing.

Breakpoint 1, main () at ../0x0001_hello-world.c:4
4       stdio_init_all();
(gdb)
```

**Great!** Your program is now halted at the beginning of `main()`.

##### Step 7: Examine the Assembly with `disas`

To see the assembly language of the current function:

```gdb
disas
```

**Expected Output:**
```
Dump of assembler code for function main:
=> 0x10000234 <+0>:     push    {r3, lr}
   0x10000236 <+2>:     bl      0x1000156c <stdio_init_all>
   0x1000023a <+6>:     ldr     r0, [pc, #8]    @ (0x10000244 <main+16>)
   0x1000023c <+8>:     bl      0x100015fc <__wrap_puts>
   0x10000240 <+12>:    b.n     0x1000023a <main+6>
   0x10000242 <+14>:    nop
   0x10000244 <+16>:    adds    r4, r1, r7
   0x10000246 <+18>:    asrs    r0, r0, #32
End of assembler dump.
(gdb)
```

**Interpretation:**
- The `=>` arrow shows where we're currently stopped (at `0x10000234`)
- We can see the `push`, `bl` (branch and link), `ldr`, and `b.n` (branch) instructions
- This is the exact code you analyzed in the Ghidra exercises!

##### Step 8: View All Registers with `i r`

To see the current state of all CPU registers:

```gdb
i r
```

**Expected Output:**
```
r0             0x0                 0
r1             0x10000235          268436021
r2             0x80808080          -2139062144
r3             0xe000ed08          -536810232
r4             0x100001d0          268435920
r5             0x88526891          -2007865199
r6             0x4f54710           83183376
r7             0x400e0014          1074659348
r8             0x43280035          1126694965
r9             0x0                 0
r10            0x10000000          268435456
r11            0x62707361          1651536737
r12            0xed07f600          -318245376
sp             0x20082000          0x20082000
lr             0x1000018f          268435855
pc             0x10000234          0x10000234 <main>
xpsr           0x69000000          1761607680
```

**Key Registers to Understand:**
| Register | Value        | Meaning                                           |
| -------- | ------------ | ------------------------------------------------- |
| `pc`     | `0x10000234` | Program Counter - we're at the start of `main`    |
| `sp`     | `0x20082000` | Stack Pointer - top of our stack in RAM           |
| `lr`     | `0x1000018f` | Link Register - where we return from `main`       |
| `r0-r3`  | Various      | Will hold function arguments and return values    |

##### Step 9: Step Into the First Instruction

To execute one assembly instruction:

```gdb
si
```

**Expected Output:**
```
0x10000236 in main () at ../0x0001_hello-world.c:5
5       stdio_init_all();
(gdb)
```

The `pc` should now be at `0x10000236`, which is the next instruction.

##### Step 10: Answer These Questions

Based on what you've observed:

###### Question 1: GDB Connection
- Was GDB able to connect to OpenOCD? (Yes/No)
- Did the program stop at your breakpoint? (Yes/No)
- __________

###### Question 2: Breakpoint Address
- What is the memory address of the `main` function's first instruction?
- __________
- Is this in Flash memory (0x100...) or RAM (0x200...)?
- __________

###### Question 3: Stack Pointer
- What is the value of the Stack Pointer (sp) when you're at `main`?
- __________
- Is this in Flash or RAM?
- __________

###### Question 4: First Instruction
- What is the first instruction in `main`?
- __________
- What does it do? (Hint: `push` = save to stack)
- __________

###### Question 5: Disassembly Comparison
- Look at the disassembly from GDB (Step 7)
- Compare it to the disassembly from Ghidra (Exercise 1)
- Are they the same?
- __________

#### Deeper Exploration (Optional Challenge)

##### Challenge 1: Step Through stdio_init_all
1. Continue stepping: `si` (step into) or `ni` (next instruction)
2. Eventually, you'll reach `bl 0x1000156c <stdio_init_all>`
3. Use `si` to step **into** that function
4. What instructions do you see?
5. What registers are being modified?

##### Challenge 2: View Specific Registers
Instead of viewing all registers, you can view just a few:
```gdb
i r pc sp lr r0 r1 r2
```
This shows only the registers you care about.

##### Challenge 3: Examine Memory
To examine memory at a specific address (e.g., where the string is):
```gdb
x/16b 0x100019cc
```
This displays 16 bytes (`b` = byte) starting at address `0x100019cc`. Can you see the "hello, world" string?

##### Challenge 4: Set a Conditional Breakpoint
Set a breakpoint that only triggers after a certain condition:
```gdb
b *0x1000023a if $r0 != 0
```
This is useful when you want to break on a condition rather than every time.

#### Questions for Reflection

1. **Why does GDB show both the C source line AND the assembly?**
   - This is because the .elf file contains debug symbols
   - What would happen if we used a stripped binary?

2. **How does GDB know the assembly for each instruction?**
   - It disassembles the binary on-the-fly based on the architecture

3. **Why is the Stack Pointer so high (0x20082000)?**
   - It's at the top of RAM and grows downward
   - Can you calculate how much RAM this Pico 2 has?

4. **What's the difference between `si` (step into) and `ni` (next instruction)?**
   - `si` steps into function calls
   - `ni` executes entire functions without stopping inside them

#### Important GDB Commands Reference

| Command                | Short Form | What It Does                         |
| ---------------------- | ---------- | ------------------------------------ |
| `target extended-remote localhost:3333` |            | Connect to OpenOCD               |
| `monitor reset halt`   |            | Reset and halt the processor    |
| `break main`           | `b main`   | Set a breakpoint at main function   |
| `continue`             | `c`        | Continue until breakpoint           |
| `step instruction`     | `si`       | Step one instruction (into calls)   |
| `next instruction`     | `ni`       | Step one instruction (over calls)   |
| `disassemble`          | `disas`    | Show assembly for current function  |
| `info registers`       | `i r`      | Show all register values            |
| `x/Nxy ADDRESS`        | `x`        | Examine memory (N=count, x=format, y=size) |
| `quit`                 | `q`        | Exit GDB                            |

**Examples for `x` command:**
- `x/10i $pc` - examine 10 instructions at program counter
- `x/16b 0x20000000` - examine 16 bytes starting at RAM address
- `x/4w 0x10000000` - examine 4 words (4-byte values) starting at Flash address

#### Troubleshooting

##### Problem: "OpenOCD not found"
**Solution:** Make sure OpenOCD is in your PATH or use the full path to the executable

##### Problem: "Target not responding"
**Solution:** 
- Check that your Pico 2 is properly connected
- Make sure OpenOCD is running and shows "accepting 'gdb' connection"
- Restart both OpenOCD and GDB

##### Problem: "Cannot find breakpoint at main"
**Solution:** 
- Make sure you compiled with debug symbols
- The .elf file must include symbol information
- Try breaking at an address instead: `b *0x10000234`

##### Problem: GDB shows "No source available"
**Solution:**
- This happens with stripped binaries
- You can still see assembly with `disas`
- You can still examine memory and registers

#### Summary

By completing this exercise, you've:
1. ✅ Set up OpenOCD as a debug server
2. ✅ Connected GDB to a Pico 2 board
3. ✅ Set a breakpoint and halted execution
4. ✅ Examined assembly language in a live debugger
5. ✅ Viewed CPU registers and their values
6. ✅ Verified your dynamic debugging setup works

You're now ready for Week 2, where you'll:
- Step through code line by line
- Watch variables and memory change
- Understand program flow in detail
- Use this knowledge to modify running code

#### Next Steps

1. **Close GDB**: Type `quit` or `q` to exit
2. **Close OpenOCD**: Type `Ctrl+C` in the OpenOCD terminal
3. **Review**: Go back to the Ghidra exercises and compare static vs. dynamic analysis
4. **Prepare**: Read through Week 2 materials to understand what's coming next
