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

## Week 3
Embedded System Analysis: Understanding the RP2350 Architecture w/ Comprehensive Firmware Analysis

### Exercise 3: Examine All Vectors

#### Objective
Examine the first 16 entries of the vector table to understand the exception handler layout, identify valid code addresses, and recognize the Thumb mode addressing convention.

#### Prerequisites
- Raspberry Pi Pico 2 with debug probe connected
- OpenOCD and `arm-none-eabi-gdb` available
- `build\0x0001_hello-world.elf` loaded
- Understanding of the vector table from Week 3 Part 4
- Knowledge of Thumb mode addressing (LSB = 1 indicates Thumb code)

#### Task Description
You will examine 16 consecutive 32-bit values from the vector table, decode each entry, determine if it's a valid code address, and identify which exception handler it points to.

#### Background Information

The ARM Cortex-M vector table structure:

| Offset | Vector # | Handler Name        | Purpose |
|--------|----------|---------------------|---------|
| 0x00   | -        | Initial SP          | Stack pointer initialization |
| 0x04   | 1        | Reset               | Power-on/reset entry point |
| 0x08   | 2        | NMI                 | Non-Maskable Interrupt |
| 0x0C   | 3        | HardFault           | Serious errors |
| 0x10   | 4        | MemManage           | Memory protection fault |
| 0x14   | 5        | BusFault            | Bus error |
| 0x18   | 6        | UsageFault          | Undefined instruction, etc. |
| 0x1C-0x28 | 7-10  | Reserved            | Not used |
| 0x2C   | 11       | SVCall              | Supervisor call |
| 0x30   | 12       | Debug Monitor       | Debug events |
| 0x34   | 13       | Reserved            | Not used |
| 0x38   | 14       | PendSV              | Pendable service call |
| 0x3C   | 15       | SysTick             | System tick timer |

#### Step-by-Step Instructions

##### Step 1: Connect and Halt

```gdb
(gdb) target extended-remote :3333
(gdb) monitor reset halt
```

##### Step 2: Examine 16 Vector Table Entries

```gdb
(gdb) x/16x 0x10000000
```

**Expected output (example):**
```
0x10000000 <__vectors>:     0x20082000  0x1000015d  0x1000011b  0x1000011d
0x10000010 <__vectors+16>:  0x1000011f  0x10000121  0x10000123  0x00000000
0x10000020 <__vectors+32>:  0x00000000  0x00000000  0x00000000  0x10000125
0x10000030 <__vectors+48>:  0x00000000  0x00000000  0x10000127  0x10000129
```

##### Step 3: Analyze Each Entry

Create a table documenting each entry:

**Entry 1 (Offset 0x00):**
```
Address: 0x10000000
Value: 0x20082000
Valid Code Address? NO - This is the stack pointer (in RAM region 0x2xxxxxxx)
Handler: Initial Stack Pointer
```

**Entry 2 (Offset 0x04):**
```
Address: 0x10000004
Value: 0x1000015d
Valid Code Address? YES (starts with 0x1000...)
Thumb Mode? YES (LSB = 1, so actual address is 0x1000015c)
Handler: Reset Handler (_reset_handler)
```

**Entry 3 (Offset 0x08):**
```
Address: 0x10000008
Value: 0x1000011b
Valid Code Address? YES
Thumb Mode? YES (actual address: 0x1000011a)
Handler: NMI Handler (isr_nmi)
```

Continue this analysis for all 16 entries...

##### Step 4: Verify Handlers with Symbols

For each code address, check what function it points to:

```gdb
(gdb) info symbol 0x1000015c
```

**Expected output:**
```
_reset_handler in section .text
```

Repeat for other addresses:

```gdb
(gdb) info symbol 0x1000011a
(gdb) info symbol 0x1000011c
(gdb) info symbol 0x1000011e
```

##### Step 5: Examine Handler Code

Look at the actual code at each handler:

```gdb
(gdb) x/3i 0x1000011a
```

**Expected output for NMI handler:**
```
0x1000011a <isr_nmi>:    bkpt  0x0000
0x1000011c <isr_hardfault>: bkpt  0x0000
0x1000011e <isr_svcall>: bkpt  0x0000
```

##### Step 6: Identify Reserved Entries

Note any entries with value `0x00000000`:

```
0x00000000 = Reserved/Unused vector
```

These slots are reserved by ARM and not used on Cortex-M33.

##### Step 7: Create a Complete Map

Document all 16 entries in this format:

| Offset | Value      | Address Type | Actual Addr | Handler Name     |
|--------|------------|--------------|-------------|------------------|
| 0x00   | 0x20082000 | Stack Ptr    | N/A         | __StackTop       |
| 0x04   | 0x1000015d | Code (Thumb) | 0x1000015c  | _reset_handler   |
| 0x08   | 0x1000011b | Code (Thumb) | 0x1000011a  | isr_nmi          |
| 0x0C   | 0x1000011d | Code (Thumb) | 0x1000011c  | isr_hardfault    |
| ...    | ...        | ...          | ...         | ...              |

#### Expected Output
- First entry is the stack pointer in RAM (0x2xxxxxxx range)
- Entries 2-16 are mostly code addresses in flash (0x1000xxxx range)
- Code addresses have LSB = 1 (Thumb mode indicator)
- Reserved entries show 0x00000000
- Most handlers point to simple `bkpt` instructions (default handlers)

#### Questions for Reflection

###### Question 1: Why do all the code addresses end in odd numbers (LSB = 1)?

###### Question 2: What happens if an exception occurs for a reserved/null vector entry?

###### Question 3: Why do most exception handlers just contain `bkpt` instructions?

###### Question 4: How would you replace a default handler with your own custom handler?

#### Tips and Hints
- Use `x/32x 0x10000000` to see even more vectors (up to 48)
- Remember to subtract 1 from addresses before disassembling (remove Thumb bit)
- Use `info functions` to see all available handler symbols
- Compare GDB output with Ghidra's vector table view

#### Next Steps
- Set breakpoints at different exception handlers to see if they're ever called
- Trigger a fault intentionally to see which handler executes
- Move on to Exercise 4 to analyze your main function

#### Additional Challenge
Write a GDB script to automatically decode and display all vector table entries:

```gdb
(gdb) define vectors
> set $i = 0
> while $i < 16
>   set $addr = 0x10000000 + ($i * 4)
>   set $val = *(int*)$addr
>   printf "[%2d] 0x%08x: 0x%08x", $i, $addr, $val
>   if $i == 0
>     printf " (Stack Pointer)\n"
>   else
>     if $val != 0
>       if ($val & 0x10000000) == 0x10000000
>         printf " -> 0x%08x\n", $val & 0xFFFFFFFE
>       else
>         printf " (Invalid/Reserved)\n"
>       end
>     else
>       printf " (Reserved)\n"
>     end
>   end
>   set $i = $i + 1
> end
> end
```
