Added PDFs

This commit is contained in:
Kevin Thomas
2026-08-15 07:11:17 -04:00
parent 556116e6cc
commit 054787416f
20 changed files with 219 additions and 38 deletions
+19 -5
View File
@@ -1,22 +1,25 @@
# Week 1: Introduction and Overview of Embedded Reverse Engineering: Ethics, Scoping, and Basic Concepts # Week 1: Introduction and Overview of Embedded Reverse Engineering: Ethics, Scoping, and Basic Concepts
--- ***
**LEGAL DISCLAIMER:** **LEGAL DISCLAIMER:**
The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only. The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with. You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that: By using this repository and course, you acknowledge and agree that:
1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility. 1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein. 2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud. 3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
**IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.** **IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.**
---
***
## What You'll Learn This Week ## What You'll Learn This Week
By the end of this week, you will be able to: By the end of this week, you will be able to:
- Understand what a microcontroller is and how it works - Understand what a microcontroller is and how it works
- Know the basic registers of the ARM Cortex-M33 processor - Know the basic registers of the ARM Cortex-M33 processor
- Understand memory layout (Flash vs RAM) and why it matters - Understand memory layout (Flash vs RAM) and why it matters
@@ -40,6 +43,7 @@ The RP2350 has two "brains" inside it - we call these **cores**. One brain uses
### What is Reverse Engineering? ### What is Reverse Engineering?
Reverse engineering is like being a detective for code. Instead of writing code and compiling it, we take compiled code (the 1s and 0s that the computer actually runs) and figure out what it does. This is useful for: Reverse engineering is like being a detective for code. Instead of writing code and compiling it, we take compiled code (the 1s and 0s that the computer actually runs) and figure out what it does. This is useful for:
- Understanding how things work - Understanding how things work
- Finding bugs or security issues - Finding bugs or security issues
- Learning how software interacts with hardware - Learning how software interacts with hardware
@@ -68,6 +72,7 @@ The ARM Cortex-M33 has several important registers:
These 13 registers are your "scratch paper." When the processor needs to add two numbers, subtract, or do any calculation, it uses these registers to hold the values. These 13 registers are your "scratch paper." When the processor needs to add two numbers, subtract, or do any calculation, it uses these registers to hold the values.
**Example:** If you want to add 5 + 3: **Example:** If you want to add 5 + 3:
1. Put 5 in `r0` 1. Put 5 in `r0`
2. Put 3 in `r1` 2. Put 3 in `r1`
3. Add them and store the result (8) in `r2` 3. Add them and store the result (8) in `r2`
@@ -75,6 +80,7 @@ These 13 registers are your "scratch paper." When the processor needs to add two
##### The Stack Pointer (`r13` / SP) ##### The Stack Pointer (`r13` / SP)
The **stack** is a special area of memory that works like a stack of plates: The **stack** is a special area of memory that works like a stack of plates:
- When you add something, you put it on top (called a **PUSH**) - When you add something, you put it on top (called a **PUSH**)
- When you remove something, you take it from the top (called a **POP**) - When you remove something, you take it from the top (called a **POP**)
@@ -85,11 +91,11 @@ The two Arm ABI documents we verified give the formal proof for these rules. In
``` ```
Higher Memory Address (0x20082000) Higher Memory Address (0x20082000)
+------------------+ +------------------+
| | ← Stack starts here (empty) | | Stack starts here (empty)
+------------------+ +------------------+
| Pushed Item 1 | ← SP points here after 1 push | Pushed Item 1 | SP points here after 1 push
+------------------+ +------------------+
| Pushed Item 2 | ← SP points here after 2 pushes | Pushed Item 2 | SP points here after 2 pushes
+------------------+ +------------------+
Lower Memory Address (0x20081FF8) Lower Memory Address (0x20081FF8)
``` ```
@@ -196,6 +202,7 @@ stdio_init_all();
``` ```
This function initializes all the standard I/O (input/output) for the Pico. It sets up: This function initializes all the standard I/O (input/output) for the Pico. It sets up:
- **USB CDC** (so you can see output when connected to a computer via USB) - **USB CDC** (so you can see output when connected to a computer via USB)
- **UART** (serial communication pins) - **UART** (serial communication pins)
@@ -225,6 +232,7 @@ while (true)
### Why This Code is Perfect for Learning ### Why This Code is Perfect for Learning
This simple program is ideal for reverse engineering practice because: This simple program is ideal for reverse engineering practice because:
- It has a clear, recognizable function call (`printf`) - It has a clear, recognizable function call (`printf`)
- It has an infinite loop we can observe - It has an infinite loop we can observe
- It's small enough to understand completely - It's small enough to understand completely
@@ -258,6 +266,7 @@ When done correctly, your Pico 2 will appear as a USB mass storage device (like
##### Step 3: Flash and Run ##### Step 3: Flash and Run
Back in VS Code, click the **Run** button in the status bar. The extension will: Back in VS Code, click the **Run** button in the status bar. The extension will:
1. Copy the compiled `.uf2` file to the Pico 2 1. Copy the compiled `.uf2` file to the Pico 2
2. The Pico 2 will automatically reboot and start running your code 2. The Pico 2 will automatically reboot and start running your code
@@ -270,6 +279,7 @@ Once flashed, your Pico 2 will immediately start executing the hello-world progr
### Prerequisites ### Prerequisites
Before we start, make sure you have: Before we start, make sure you have:
1. A Raspberry Pi Pico 2 board 1. A Raspberry Pi Pico 2 board
2. GDB (GNU Debugger) installed 2. GDB (GNU Debugger) installed
3. OpenOCD or another debug probe connection 3. OpenOCD or another debug probe connection
@@ -312,6 +322,7 @@ Breakpoint 1 at 0x10000234: file ../0x0001_hello-world.c, line 5.
``` ```
**What this tells us:** **What this tells us:**
- GDB found our `main` function - GDB found our `main` function
- It's located at address `0x10000234` in flash memory - It's located at address `0x10000234` in flash memory
- The source file and line number are shown (because we have debug symbols) - The source file and line number are shown (because we have debug symbols)
@@ -347,6 +358,7 @@ End of assembler dump.
``` ```
**Understanding the output:** **Understanding the output:**
- The `=>` arrow shows where we're currently stopped - The `=>` arrow shows where we're currently stopped
- Each line shows: `address <offset>: instruction operands` - Each line shows: `address <offset>: instruction operands`
- We can see the calls to `stdio_init_all` and `__wrap_puts` (printf was optimized to puts) - We can see the calls to `stdio_init_all` and `__wrap_puts` (printf was optimized to puts)
@@ -492,6 +504,7 @@ xpsr 0x69000000 1761607680
``` ```
**Key registers to watch:** **Key registers to watch:**
| Register | Value | Meaning | | Register | Value | Meaning |
| -------- | ------------ | ----------------------------------------------- | | -------- | ------------ | ----------------------------------------------- |
| `pc` | `0x10000234` | Program Counter - we're at the start of `main` | | `pc` | `0x10000234` | Program Counter - we're at the start of `main` |
@@ -637,6 +650,7 @@ int main(void)
##### Why We Start with .elf Files ##### Why We Start with .elf Files
We're using the `.elf` file because it contains symbols that help us learn: We're using the `.elf` file because it contains symbols that help us learn:
- Function names are visible (`main`, `stdio_init_all`, `puts`) - Function names are visible (`main`, `stdio_init_all`, `puts`)
- Variable names may be preserved - Variable names may be preserved
- The structure of the code is easier to understand - The structure of the code is easier to understand
BIN
View File
Binary file not shown.
+39 -4
View File
@@ -1,22 +1,25 @@
# Week 2: Hello, World - Debugging and Hacking Basics: Debugging and Hacking a Basic Program for the Pico 2 # Week 2: Hello, World - Debugging and Hacking Basics: Debugging and Hacking a Basic Program for the Pico 2
--- ***
**LEGAL DISCLAIMER:** **LEGAL DISCLAIMER:**
The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only. The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with. You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that: By using this repository and course, you acknowledge and agree that:
1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility. 1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein. 2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud. 3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
**IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.** **IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.**
---
***
## What You'll Learn This Week ## What You'll Learn This Week
By the end of this tutorial, you will be able to: By the end of this tutorial, you will be able to:
- Connect to a live embedded system using OpenOCD and GDB - Connect to a live embedded system using OpenOCD and GDB
- Step through code instruction by instruction and watch the stack change - Step through code instruction by instruction and watch the stack change
- Examine memory, registers, and decode little-endian values - Examine memory, registers, and decode little-endian values
@@ -28,6 +31,7 @@ By the end of this tutorial, you will be able to:
## Review from Week 1 ## Review from Week 1
This week builds directly on Week 1 concepts. You should already be comfortable with: This week builds directly on Week 1 concepts. You should already be comfortable with:
- **Registers** (`r0`-`r12`, SP, LR, PC) - We'll watch them change and manipulate `r0` to change program behavior - **Registers** (`r0`-`r12`, SP, LR, PC) - We'll watch them change and manipulate `r0` to change program behavior
- **Memory Layout** (Flash at `0x10000000`, RAM at `0x20000000`) - Critical for understanding where we can write - **Memory Layout** (Flash at `0x10000000`, RAM at `0x20000000`) - Critical for understanding where we can write
- **The Stack** and how `push`/`pop` work - We'll watch this in action - **The Stack** and how `push`/`pop` work - We'll watch this in action
@@ -48,6 +52,7 @@ Think of it like this: imagine a train is heading to New York City. Live hacking
#### Why is This Important? #### Why is This Important?
Live hacking techniques are used for: Live hacking techniques are used for:
- **Security Research**: Finding vulnerabilities in embedded systems - **Security Research**: Finding vulnerabilities in embedded systems
- **Penetration Testing**: Testing if systems can be compromised - **Penetration Testing**: Testing if systems can be compromised
- **Malware Analysis**: Understanding how malicious code works - **Malware Analysis**: Understanding how malicious code works
@@ -58,6 +63,7 @@ Live hacking techniques are used for:
> **"With great power comes great responsibility!"** > **"With great power comes great responsibility!"**
Imagine you're a security researcher testing an industrial control system at a power plant. You need to verify that an attacker couldn't: Imagine you're a security researcher testing an industrial control system at a power plant. You need to verify that an attacker couldn't:
1. Change the values being displayed to engineers 1. Change the values being displayed to engineers
2. Make dangerous equipment appear safe 2. Make dangerous equipment appear safe
3. Hide malicious activity from monitoring systems 3. Hide malicious activity from monitoring systems
@@ -89,6 +95,7 @@ int main(void) {
``` ```
This simple program: This simple program:
1. Initializes I/O with `stdio_init_all()` 1. Initializes I/O with `stdio_init_all()`
2. Enters an infinite `while(true)` loop 2. Enters an infinite `while(true)` loop
3. Prints `"hello, world\r\n"` forever 3. Prints `"hello, world\r\n"` forever
@@ -151,6 +158,7 @@ Here's our step-by-step attack strategy:
#### Prerequisites #### Prerequisites
Before we start, make sure you have: Before we start, make sure you have:
1. A Raspberry Pi Pico 2 board with debug probe connected 1. A Raspberry Pi Pico 2 board with debug probe connected
2. OpenOCD installed and configured 2. OpenOCD installed and configured
3. GDB (arm-none-eabi-gdb) installed 3. GDB (arm-none-eabi-gdb) installed
@@ -160,6 +168,7 @@ Before we start, make sure you have:
#### What You'll Need Open #### What You'll Need Open
You will need **THREE** terminal windows: You will need **THREE** terminal windows:
1. **Terminal 1**: Running OpenOCD (the debug server) 1. **Terminal 1**: Running OpenOCD (the debug server)
2. **Terminal 2**: Running GDB (where we do the hacking) 2. **Terminal 2**: Running GDB (where we do the hacking)
3. **PuTTY**: Running your serial monitor (to see output) 3. **PuTTY**: Running your serial monitor (to see output)
@@ -183,6 +192,7 @@ openocd -s "$env:USERPROFILE\.pico-sdk\openocd\0.12.0+dev\scripts" -f interface/
``` ```
**What this command means:** **What this command means:**
- `openocd` = the OpenOCD program - `openocd` = the OpenOCD program
- `-s ...` = path to OpenOCD scripts folder - `-s ...` = path to OpenOCD scripts folder
- `-f interface/cmsis-dap.cfg` = use the CMSIS-DAP debug probe configuration - `-f interface/cmsis-dap.cfg` = use the CMSIS-DAP debug probe configuration
@@ -239,6 +249,7 @@ arm-none-eabi-gdb build\0x0001_hello-world.elf
``` ```
**What this command means:** **What this command means:**
- `arm-none-eabi-gdb` = the ARM version of GDB - `arm-none-eabi-gdb` = the ARM version of GDB
- `build\0x0001_hello-world.elf` = our compiled program with debug symbols - `build\0x0001_hello-world.elf` = our compiled program with debug symbols
@@ -284,6 +295,7 @@ The program is still running (you can see "hello, world" still printing in PuTTY
``` ```
**What this command means:** **What this command means:**
- `monitor` = send a command to OpenOCD (not GDB) - `monitor` = send a command to OpenOCD (not GDB)
- `reset` = reset the processor - `reset` = reset the processor
- `halt` = stop execution immediately - `halt` = stop execution immediately
@@ -316,6 +328,7 @@ Our program code starts at address `0x10000000`. Let's look at the first 1000 in
``` ```
**What this command means:** **What this command means:**
- `x` = examine memory - `x` = examine memory
- `/1000i` = show 1000 instructions - `/1000i` = show 1000 instructions
- `0x10000000` = starting address - `0x10000000` = starting address
@@ -379,6 +392,7 @@ Note: automatically using hardware breakpoints for read-only addresses.
``` ```
**What this means:** **What this means:**
- `b` = set breakpoint - `b` = set breakpoint
- `*0x10000234` = at this exact memory address - `*0x10000234` = at this exact memory address
- GDB confirms the breakpoint is set and even tells us which line of C code this corresponds to! - GDB confirms the breakpoint is set and even tells us which line of C code this corresponds to!
@@ -404,6 +418,7 @@ Thread 1 "rp2350.cm0" hit Breakpoint 1, main ()
``` ```
**What happened:** **What happened:**
- The processor ran until it reached address `0x10000234` - The processor ran until it reached address `0x10000234`
- It stopped right before executing the instruction at that address - It stopped right before executing the instruction at that address
- GDB shows us we're at line 5 of our C source code - GDB shows us we're at line 5 of our C source code
@@ -446,6 +461,7 @@ Before we execute the `push` instruction, let's see what's on the stack:
``` ```
**What this command means:** **What this command means:**
- `x` = examine memory - `x` = examine memory
- `/10x` = show 10 values in hexadecimal - `/10x` = show 10 values in hexadecimal
- `$sp` = starting at the stack pointer address - `$sp` = starting at the stack pointer address
@@ -459,6 +475,7 @@ Before we execute the `push` instruction, let's see what's on the stack:
``` ```
**What this shows:** **What this shows:**
- The stack pointer is at address `0x20082000` - The stack pointer is at address `0x20082000`
- The stack is empty (all zeros) - The stack is empty (all zeros)
- This is the "top" of our stack in RAM - This is the "top" of our stack in RAM
@@ -475,6 +492,7 @@ Now let's trace back where this initial `0x20082000` value came from. It comes f
``` ```
**What this shows:** **What this shows:**
- The first command `x/x $sp` reads one word at the stack pointer (currently `0x00000000`) - The first command `x/x $sp` reads one word at the stack pointer (currently `0x00000000`)
- The second command `x/x 0x10000000` reads the **first entry in the vector table** at address `0x10000000` - The second command `x/x 0x10000000` reads the **first entry in the vector table** at address `0x10000000`
- That vector table entry contains `0x20082000` - this is the **initial stack pointer value**! - That vector table entry contains `0x20082000` - this is the **initial stack pointer value**!
@@ -492,6 +510,7 @@ Now let's execute just ONE assembly instruction:
``` ```
**What this command means:** **What this command means:**
- `si` = step instruction (execute one assembly instruction) - `si` = step instruction (execute one assembly instruction)
**You should see:** **You should see:**
@@ -540,6 +559,7 @@ Now let's see what the push instruction did to our stack:
``` ```
**What changed:** **What changed:**
- The stack pointer moved from `0x20082000` to `0x20081ff8` - The stack pointer moved from `0x20082000` to `0x20081ff8`
- That's 8 bytes lower (2 * 4-byte values) - That's 8 bytes lower (2 * 4-byte values)
- Two new values appeared: `0xe000ed08` and `0x1000018f` - Two new values appeared: `0xe000ed08` and `0x1000018f`
@@ -621,6 +641,7 @@ Address Value Address Value
``` ```
**Key Points:** **Key Points:**
1. The stack grows DOWNWARD (addresses get smaller) 1. The stack grows DOWNWARD (addresses get smaller)
2. The SP always points to the last item pushed 2. The SP always points to the last item pushed
3. `r3` was pushed first, then `lr` was pushed on top of it 3. `r3` was pushed first, then `lr` was pushed on top of it
@@ -657,6 +678,7 @@ We don't need to examine every instruction inside `stdio_init_all` - it's just s
``` ```
**What this command means:** **What this command means:**
- `n` = next (step over function calls, don't go inside them) - `n` = next (step over function calls, don't go inside them)
**You should see:** **You should see:**
@@ -731,6 +753,7 @@ This is loading a **pointer** - the address of our "hello, world" string!
The value `0x6c6c6568` looks strange, but it's actually ASCII characters! Let's decode it: The value `0x6c6c6568` looks strange, but it's actually ASCII characters! Let's decode it:
**ASCII Table Reference:** **ASCII Table Reference:**
| Hex | Character | | Hex | Character |
| ------ | --------- | | ------ | --------- |
| `0x68` | h | | `0x68` | h |
@@ -753,6 +776,7 @@ Let's tell GDB to show this as a string instead of a hex number:
``` ```
**What this command means:** **What this command means:**
- `x` = examine memory - `x` = examine memory
- `/s` = show as a string - `/s` = show as a string
- `$r0` = at the address stored in `r0` - `$r0` = at the address stored in `r0`
@@ -807,6 +831,7 @@ Let's look at the main function to understand what we're dealing with:
``` ```
**What this command means:** **What this command means:**
- `x` = examine memory (Week 1 review!) - `x` = examine memory (Week 1 review!)
- `/5i` = show 5 instructions - `/5i` = show 5 instructions
- `0x10000234` = the address of main (we found this in Week 1!) - `0x10000234` = the address of main (we found this in Week 1!)
@@ -823,6 +848,7 @@ Let's look at the main function to understand what we're dealing with:
``` ```
> **REVIEW:** This is the same disassembly we analyzed in Week 1! Remember: > **REVIEW:** This is the same disassembly we analyzed in Week 1! Remember:
>
> - `push {r3, lr}` saves registers to the stack > - `push {r3, lr}` saves registers to the stack
> - `bl` is "branch with link" - it calls a function and saves the return address in LR > - `bl` is "branch with link" - it calls a function and saves the return address in LR
> - `b.n` is the infinite loop that jumps back to the `ldr` instruction > - `b.n` is the infinite loop that jumps back to the `ldr` instruction
@@ -847,6 +873,7 @@ while (true)
``` ```
The compiler: The compiler:
1. Loads the string address into `r0` (first argument) 1. Loads the string address into `r0` (first argument)
2. Calls `puts()` (optimized from `printf()` since we're just printing a string) 2. Calls `puts()` (optimized from `printf()` since we're just printing a string)
3. Loops back forever with `b.n` 3. Loops back forever with `b.n`
@@ -872,6 +899,7 @@ We want to stop the program RIGHT BEFORE it calls `puts()`. That's at address `0
``` ```
**What this command means:** **What this command means:**
- `b` = set a breakpoint (same as Week 1!) - `b` = set a breakpoint (same as Week 1!)
- `*0x1000023c` = at this exact memory address (the asterisk means "address") - `*0x1000023c` = at this exact memory address (the asterisk means "address")
@@ -896,6 +924,7 @@ Now let's run the program until it hits our breakpoint:
``` ```
**What this command means:** **What this command means:**
- `c` = continue (run until something stops us) - `c` = continue (run until something stops us)
**You should see:** **You should see:**
@@ -921,6 +950,7 @@ Let's double-check where we are using the `disas` command:
``` ```
**What this command means:** **What this command means:**
- `disas` = disassemble the current function - `disas` = disassemble the current function
**You should see:** **You should see:**
@@ -957,6 +987,7 @@ Let's see what string `r0` is currently pointing to:
``` ```
**What this command means:** **What this command means:**
- `x` = examine memory (Week 1 review!) - `x` = examine memory (Week 1 review!)
- `/s` = display as a string - `/s` = display as a string
- `$r0` = the address stored in register `r0` - `$r0` = the address stored in register `r0`
@@ -1054,7 +1085,7 @@ We need to write 13 bytes (12 characters + null terminator) to SRAM:
| r | - | | r | - |
| l | - | | l | - |
| d | - | | d | - |
| \r | - | | `\r` | - |
| \0 | - | | \0 | - |
**Type this command:** **Type this command:**
@@ -1064,6 +1095,7 @@ We need to write 13 bytes (12 characters + null terminator) to SRAM:
``` ```
**What this command means:** **What this command means:**
- `set` = modify memory - `set` = modify memory
- `{char[13]}` = treat the target as an array of 13 characters - `{char[13]}` = treat the target as an array of 13 characters
- `0x20040000` = the address where we're writing (safe SRAM offset) - `0x20040000` = the address where we're writing (safe SRAM offset)
@@ -1108,6 +1140,7 @@ Now for the magic moment! We'll change `r0` from pointing to the original string
``` ```
**What this command means:** **What this command means:**
- `set` = modify a value - `set` = modify a value
- `$r0` = the `r0` register - `$r0` = the `r0` register
- `= 0x20040000` = change it to this address (where our string is) - `= 0x20040000` = change it to this address (where our string is)
@@ -1277,6 +1310,7 @@ In our GDB hack, we set a breakpoint at `0x1000023c` - right before `bl __wrap_p
**Click on address `0x1000023c` in the Listing view.** **Click on address `0x1000023c` in the Listing view.**
Notice: Notice:
- The instruction is `bl __wrap_puts` - a function call - The instruction is `bl __wrap_puts` - a function call
- The previous instruction at `0x1000023a` loaded `r0` with the string address - The previous instruction at `0x1000023a` loaded `r0` with the string address
- Ghidra shows `= "hello, world\r"` right in the listing! - Ghidra shows `= "hello, world\r"` right in the listing!
@@ -1363,6 +1397,7 @@ int main(void)
``` ```
From this view, you can immediately see: From this view, you can immediately see:
- The program loops forever (`do { } while (true)`) - The program loops forever (`do { } while (true)`)
- It calls `__wrap_puts()` with a string argument - It calls `__wrap_puts()` with a string argument
- To change the output, you need to change what's passed to `puts()` - To change the output, you need to change what's passed to `puts()`
@@ -1387,7 +1422,7 @@ When you navigate to the string address `0x100019cc`, you'll see the string stor
20 77 6f 20 77 6f
``` ```
This shows the raw bytes of our string: `68 65 6c 6c 6f 2c 20 77 6f...` which spell out "hello, world\r" in ASCII. This shows the raw bytes of our string: `68 65 6c 6c 6f 2c 20 77 6f...` which spell out `"hello, world\r"` in ASCII.
##### Step 8: Patching Data in Ghidra (Preview) ##### Step 8: Patching Data in Ghidra (Preview)
BIN
View File
Binary file not shown.
+27 -2
View File
@@ -1,22 +1,25 @@
# Week 3: Embedded System Analysis: Understanding the RP2350 Architecture w/ Comprehensive Firmware Analysis # Week 3: Embedded System Analysis: Understanding the RP2350 Architecture w/ Comprehensive Firmware Analysis
--- ***
**LEGAL DISCLAIMER:** **LEGAL DISCLAIMER:**
The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only. The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with. You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that: By using this repository and course, you acknowledge and agree that:
1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility. 1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein. 2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud. 3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
**IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.** **IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.**
---
***
## What You'll Learn This Week ## What You'll Learn This Week
By the end of this tutorial, you will be able to: By the end of this tutorial, you will be able to:
- Understand how the RP2350 boots from the on-chip bootrom - Understand how the RP2350 boots from the on-chip bootrom
- Know what the vector table is and why it's important - Know what the vector table is and why it's important
- Trace the complete boot sequence from power-on to `main()` - Trace the complete boot sequence from power-on to `main()`
@@ -28,6 +31,7 @@ By the end of this tutorial, you will be able to:
## Review from Weeks 1-2 ## Review from Weeks 1-2
This week builds on your GDB and Ghidra skills from previous weeks: This week builds on your GDB and Ghidra skills from previous weeks:
- **GDB Commands** (`x`, `b`, `c`, `si`, `disas`, `i r`) - We'll use all of these to trace the boot process - **GDB Commands** (`x`, `b`, `c`, `si`, `disas`, `i r`) - We'll use all of these to trace the boot process
- **Memory Layout** (Flash at `0x10000000`, RAM at `0x20000000`) - Understanding where code and data live - **Memory Layout** (Flash at `0x10000000`, RAM at `0x20000000`) - Understanding where code and data live
- **Registers** (`r0`-`r12`, SP, LR, PC) - We'll watch how they're initialized during boot - **Registers** (`r0`-`r12`, SP, LR, PC) - We'll watch how they're initialized during boot
@@ -161,6 +165,7 @@ Here's what it looks like in the Pico SDK:
``` ```
**The magic numbers:** **The magic numbers:**
- `0xffffded3` = Start marker ("I'm a valid Pico binary!") - `0xffffded3` = Start marker ("I'm a valid Pico binary!")
- `0xab123579` = End marker ("End of the header block") - `0xab123579` = End marker ("End of the header block")
@@ -192,6 +197,7 @@ Contents of section .text:
``` ```
Command 1 explained (`--start-address=0x1000013c --stop-address=0x10000150`): Command 1 explained (`--start-address=0x1000013c --stop-address=0x10000150`):
- Starts at `0x1000013c`, so it does **not** include the start marker at `0x10000138` (`d3deffff`). - Starts at `0x1000013c`, so it does **not** include the start marker at `0x10000138` (`d3deffff`).
- Shows IMAGE_DEF body fields and the end marker: - Shows IMAGE_DEF body fields and the end marker:
- `42012110` = `42 01 21 10` (item type/size + secure mode field) - `42012110` = `42 01 21 10` (item type/size + secure mode field)
@@ -201,6 +207,7 @@ Command 1 explained (`--start-address=0x1000013c --stop-address=0x10000150`):
- `4ff00000` at `0x1000014c` is already the next instruction word after IMAGE_DEF. - `4ff00000` at `0x1000014c` is already the next instruction word after IMAGE_DEF.
Command 2 explained (`--start-address=0x10000130 --stop-address=0x10000154`): Command 2 explained (`--start-address=0x10000130 --stop-address=0x10000154`):
- Starts earlier, so it captures context **and** both IMAGE_DEF markers. - Starts earlier, so it captures context **and** both IMAGE_DEF markers.
- `a0010010 90a31ae7` = binary-info context before IMAGE_DEF. - `a0010010 90a31ae7` = binary-info context before IMAGE_DEF.
- `d3deffff` at `0x10000138` = `PICOBIN_BLOCK_MARKER_START`. - `d3deffff` at `0x10000138` = `PICOBIN_BLOCK_MARKER_START`.
@@ -223,6 +230,7 @@ assuming a fixed address.
**XIP (Execute In Place)** means the processor can run code directly from flash memory without copying it to RAM first. **XIP (Execute In Place)** means the processor can run code directly from flash memory without copying it to RAM first.
Think of it like reading a book: Think of it like reading a book:
- **Without XIP**: You photocopy every page into a notebook, then read from the notebook - **Without XIP**: You photocopy every page into a notebook, then read from the notebook
- **With XIP**: You just read directly from the book! - **With XIP**: You just read directly from the book!
@@ -266,6 +274,7 @@ The XIP flash region starts at address `0x10000000`. This is where your compiled
### What is the Vector Table? ### What is the Vector Table?
The **vector table** is a list of addresses at the very beginning of your program. It tells the CPU: The **vector table** is a list of addresses at the very beginning of your program. It tells the CPU:
1. Where to set the stack pointer 1. Where to set the stack pointer
2. Where to start executing code (reset handler) 2. Where to start executing code (reset handler)
3. Where to go when errors or interrupts happen 3. Where to go when errors or interrupts happen
@@ -297,10 +306,12 @@ On ARM Cortex-M processors, all code runs in **Thumb mode**. The processor uses
| `0` (even) | ARM | "This is ARM code" (not used on Cortex-M) | | `0` (even) | ARM | "This is ARM code" (not used on Cortex-M) |
So `0x1000015d` means: So `0x1000015d` means:
- The actual code is at `0x1000015c` (even address) - The actual code is at `0x1000015c` (even address)
- The `+1` tells the processor "use Thumb mode" - The `+1` tells the processor "use Thumb mode"
**GDB vs Ghidra:** **GDB vs Ghidra:**
- GDB shows `0x1000015d` (with Thumb bit) - GDB shows `0x1000015d` (with Thumb bit)
- Ghidra shows `0x1000015c` (actual instruction address) - Ghidra shows `0x1000015c` (actual instruction address)
- Both are correct! They're just displaying it differently. - Both are correct! They're just displaying it differently.
@@ -350,6 +361,7 @@ __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y);
``` ```
Let's do the math: Let's do the math:
- `ORIGIN(SCRATCH_Y)` = `0x20081000` - `ORIGIN(SCRATCH_Y)` = `0x20081000`
- `LENGTH(SCRATCH_Y)` = `0x1000` (4 KB) - `LENGTH(SCRATCH_Y)` = `0x1000` (4 KB)
- `__StackTop` = `0x20081000` + `0x1000` = **`0x20082000`** - `__StackTop` = `0x20081000` + `0x1000` = **`0x20082000`**
@@ -365,6 +377,7 @@ This value (`0x20082000`) is what we see at offset `0x00` in the vector table!
### Prerequisites ### Prerequisites
Before we start, make sure you have: Before we start, make sure you have:
1. A Raspberry Pi Pico 2 board with debug probe connected 1. A Raspberry Pi Pico 2 board with debug probe connected
2. OpenOCD installed and configured 2. OpenOCD installed and configured
3. GDB (`arm-none-eabi-gdb`) installed 3. GDB (`arm-none-eabi-gdb`) installed
@@ -409,6 +422,7 @@ Let's look at the first 4 entries of the vector table at `0x10000000`:
``` ```
**What this command means:** **What this command means:**
- `x` = examine memory (Week 1 review!) - `x` = examine memory (Week 1 review!)
- `/4x` = show 4 values in hexadecimal - `/4x` = show 4 values in hexadecimal
- `0x10000000` = the address of the vector table - `0x10000000` = the address of the vector table
@@ -451,6 +465,7 @@ Let's confirm our math by examining what's at `0x10000000`:
``` ```
This matches: This matches:
- `SCRATCH_Y` starts at `0x20081000` - `SCRATCH_Y` starts at `0x20081000`
- `SCRATCH_Y` is 4 KB (`0x1000` bytes) - `SCRATCH_Y` is 4 KB (`0x1000` bytes)
- `0x20081000` + `0x1000` = `0x20082000` - `0x20081000` + `0x1000` = `0x20082000`
@@ -510,6 +525,7 @@ This is "Compare and Branch if Zero". If `r0` is `0` (meaning we're on Core 0),
The RP2350 has **two cores**, but only **Core 0** should run the startup code! If both cores tried to initialize the same memory and peripherals, chaos would ensue. The RP2350 has **two cores**, but only **Core 0** should run the startup code! If both cores tried to initialize the same memory and peripherals, chaos would ensue.
So the reset handler checks: So the reset handler checks:
- **Core 0?** -> Continue with startup - **Core 0?** -> Continue with startup
- **Core 1?** -> Go back to the bootrom and wait - **Core 1?** -> Go back to the bootrom and wait
@@ -629,11 +645,13 @@ The data copy table contains entries that describe what to copy where. Let's exa
``` ```
The data_cpy_table contains multiple entries. Each entry has three values: The data_cpy_table contains multiple entries. Each entry has three values:
1. **Source address** (in flash) 1. **Source address** (in flash)
2. **Destination address** (in RAM) 2. **Destination address** (in RAM)
3. **End address** (where to stop copying) 3. **End address** (where to stop copying)
In the output above, we see: In the output above, we see:
- **First entry**: `0x10001b4c` (source), `0x20000110` (dest), `0x200002ac` (end) - **First entry**: `0x10001b4c` (source), `0x20000110` (dest), `0x200002ac` (end)
- **Second entry starts**: `0x10001ce8` (source of next entry), ... - **Second entry starts**: `0x10001ce8` (source of next entry), ...
@@ -904,6 +922,7 @@ That's not real code - it's the magic number `0xffffded3` being misinterpreted!
### Why Use Ghidra for Boot Analysis? ### Why Use Ghidra for Boot Analysis?
While GDB is excellent for dynamic analysis (watching code execute), Ghidra excels at: While GDB is excellent for dynamic analysis (watching code execute), Ghidra excels at:
- **Seeing the big picture** - Understanding code flow without running it - **Seeing the big picture** - Understanding code flow without running it
- **Cross-references** - Finding all places that call a function - **Cross-references** - Finding all places that call a function
- **Decompilation** - Seeing C-like code even for assembly routines - **Decompilation** - Seeing C-like code even for assembly routines
@@ -1222,14 +1241,17 @@ Understanding the boot process is critical for both attackers and defenders. Kno
#### Real-World Applications #### Real-World Applications
**Industrial Control Systems:** **Industrial Control Systems:**
- An attacker with physical access could replace firmware to hide malicious behavior - An attacker with physical access could replace firmware to hide malicious behavior
- Understanding the boot sequence helps identify the earliest point where security checks can be added - Understanding the boot sequence helps identify the earliest point where security checks can be added
**IoT Devices:** **IoT Devices:**
- Compromised boot code could establish backdoors before the main application runs - Compromised boot code could establish backdoors before the main application runs
- Secure boot implementations verify the vector table and reset handler integrity - Secure boot implementations verify the vector table and reset handler integrity
**Medical Devices:** **Medical Devices:**
- Boot-time attacks could modify critical safety parameters before device operation - Boot-time attacks could modify critical safety parameters before device operation
- Understanding initialization helps implement tamper detection - Understanding initialization helps implement tamper detection
@@ -1269,6 +1291,7 @@ Understanding the boot process is critical for both attackers and defenders. Kno
#### 4. Memory Protection Unit (MPU) #### 4. Memory Protection Unit (MPU)
Configure the Cortex-M33's MPU to: Configure the Cortex-M33's MPU to:
- Mark code regions as execute-only (no reading code as data) - Mark code regions as execute-only (no reading code as data)
- Separate privileged and unprivileged memory regions - Separate privileged and unprivileged memory regions
- Prevent execution from RAM regions (defend against code injection) - Prevent execution from RAM regions (defend against code injection)
@@ -1364,6 +1387,7 @@ https://datasheets.raspberrypi.com/rp2350/rp2350-datasheet.pdf
### Pico SDK Source Code ### Pico SDK Source Code
The startup code lives in: The startup code lives in:
- `crt0.S` - Main startup assembly (vector table at `.section .vectors`, reset handler, data copy, BSS clear, platform_entry) - `crt0.S` - Main startup assembly (vector table at `.section .vectors`, reset handler, data copy, BSS clear, platform_entry)
- `memmap_default.ld` - Default linker script (section ordering: `.vectors` -> `.binary_info_header` -> `.embedded_block` -> `.reset`) - `memmap_default.ld` - Default linker script (section ordering: `.vectors` -> `.binary_info_header` -> `.embedded_block` -> `.reset`)
- `embedded_start_block.inc.S` - IMAGE_DEF block (replaces RP2040's `boot2_generic_03h.S`) - `embedded_start_block.inc.S` - IMAGE_DEF block (replaces RP2040's `boot2_generic_03h.S`)
@@ -1545,6 +1569,7 @@ well within the 4 KB scan window the bootrom uses (Datasheet 5.9.5, p. 429).
``` ```
> **Datasheet References:** > **Datasheet References:**
>
> - 5.1.5.1 (p. 357): Block markers `0xffffded3` (start) and `0xab123579` (end) > - 5.1.5.1 (p. 357): Block markers `0xffffded3` (start) and `0xab123579` (end)
> - 5.9.5 (p. 429): IMAGE_DEF must appear within first 4 kB of flash image > - 5.9.5 (p. 429): IMAGE_DEF must appear within first 4 kB of flash image
> - 5.9.5.1 (p. 429): Bootrom enters via reset handler at vector table offset +4 > - 5.9.5.1 (p. 429): Bootrom enters via reset handler at vector table offset +4
BIN
View File
Binary file not shown.
+23 -9
View File
@@ -1,22 +1,25 @@
# Week 4: Variables in Embedded Systems: Debugging and Hacking Variables w/ GPIO Output Basics # Week 4: Variables in Embedded Systems: Debugging and Hacking Variables w/ GPIO Output Basics
--- ***
**LEGAL DISCLAIMER:** **LEGAL DISCLAIMER:**
The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only. The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with. You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that: By using this repository and course, you acknowledge and agree that:
1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility. 1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein. 2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud. 3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
**IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.** **IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.**
---
***
## What You'll Learn This Week ## What You'll Learn This Week
By the end of this tutorial, you will be able to: By the end of this tutorial, you will be able to:
- Understand what variables are and how they're stored in memory - Understand what variables are and how they're stored in memory
- Know the difference between initialized, uninitialized, and constant variables - Know the difference between initialized, uninitialized, and constant variables
- Use Ghidra to analyze binaries without debug symbols - Use Ghidra to analyze binaries without debug symbols
@@ -142,11 +145,11 @@ uint8_t age; // This will be 0, not garbage!
+-----------------------------------------------------------------+ +-----------------------------------------------------------------+
| Raspberry Pi Pico 2 | | Raspberry Pi Pico 2 |
| | | |
| GPIO 16 -------â–º Red LED | | GPIO 16 ------- Red LED |
| GPIO 17 -------â–º Green LED | | GPIO 17 ------- Green LED |
| GPIO 18 -------â–º Blue LED | | GPIO 18 ------- Blue LED |
| ... | | ... |
| GPIO 25 -------â–º Onboard LED | | GPIO 25 ------- Onboard LED |
+-----------------------------------------------------------------+ +-----------------------------------------------------------------+
``` ```
@@ -167,11 +170,11 @@ Each high-level function calls lower-level code. Let's trace `gpio_init()`:
``` ```
gpio_init(LED_PIN) gpio_init(LED_PIN)
↓
gpio_set_dir(LED_PIN, GPIO_IN) // Initially set as input gpio_set_dir(LED_PIN, GPIO_IN) // Initially set as input
↓
gpio_put(LED_PIN, 0) // Set output value to 0 gpio_put(LED_PIN, 0) // Set output value to 0
↓
gpio_set_function(LED_PIN, GPIO_FUNC_SIO) // Connect to SIO block gpio_set_function(LED_PIN, GPIO_FUNC_SIO) // Connect to SIO block
``` ```
@@ -184,6 +187,7 @@ The SIO (Single-cycle I/O) block is a special hardware unit in the RP2350 that p
### Prerequisites ### Prerequisites
Before we start, make sure you have: Before we start, make sure you have:
1. A Raspberry Pi Pico 2 board 1. A Raspberry Pi Pico 2 board
2. Ghidra installed (for static analysis) 2. Ghidra installed (for static analysis)
3. Python installed (for UF2 conversion) 3. Python installed (for UF2 conversion)
@@ -236,6 +240,7 @@ int main(void) {
``` ```
**What this code does:** **What this code does:**
1. Declares a variable `age` and initializes it to `42` 1. Declares a variable `age` and initializes it to `42`
2. Changes `age` to `43` 2. Changes `age` to `43`
3. Initializes the serial output 3. Initializes the serial output
@@ -298,11 +303,13 @@ Ghidra will open. Now we need to create a new project.
A dialog appears. The file is identified as a "BIN" (raw binary without debug symbols). A dialog appears. The file is identified as a "BIN" (raw binary without debug symbols).
**Click the three dots (...) next to "Language" and:** **Click the three dots (...) next to "Language" and:**
1. Search for "Cortex" 1. Search for "Cortex"
2. Select **ARM Cortex 32 little endian default** 2. Select **ARM Cortex 32 little endian default**
3. Click **OK** 3. Click **OK**
**Click the "Options..." button and:** **Click the "Options..." button and:**
1. Change **Block Name** to `.text` 1. Change **Block Name** to `.text`
2. Change **Base Address** to `10000000` (the XIP address!) 2. Change **Base Address** to `10000000` (the XIP address!)
3. Click **OK** 3. Click **OK**
@@ -324,6 +331,7 @@ Wait for analysis to complete (watch the progress bar in the bottom right).
Look at the **Symbol Tree** panel on the left. Expand **Functions**. Look at the **Symbol Tree** panel on the left. Expand **Functions**.
You'll see function names like: You'll see function names like:
- `FUN_1000019a` - `FUN_1000019a`
- `FUN_10000210` - `FUN_10000210`
- `FUN_10000234` - `FUN_10000234`
@@ -409,6 +417,7 @@ The compiler **optimized it out**! Here's what happened:
3. Compiler removes the unused `42` and just uses `43` directly 3. Compiler removes the unused `42` and just uses `43` directly
**What is `0x2b`?** Let's check: **What is `0x2b`?** Let's check:
- `0x2b` in hexadecimal = `43` in decimal - `0x2b` in hexadecimal = `43` in decimal
The compiler replaced our variable with the constant value! The compiler replaced our variable with the constant value!
@@ -470,6 +479,7 @@ python ..\uf2conv.py build\0x0005_intro-to-variables-h.bin --base 0x10000000 --f
``` ```
**What this command means:** **What this command means:**
- `uf2conv.py` = the conversion script - `uf2conv.py` = the conversion script
- `--base 0x10000000` = the XIP base address - `--base 0x10000000` = the XIP base address
- `--family 0xe48bff59` = the RP2350 family ID - `--family 0xe48bff59` = the RP2350 family ID
@@ -529,6 +539,7 @@ int main(void) {
``` ```
**What this code does:** **What this code does:**
1. Declares `age` without initializing it (will be 0 due to BSS zeroing) 1. Declares `age` without initializing it (will be 0 due to BSS zeroing)
2. Initializes GPIO 16 as an output 2. Initializes GPIO 16 as an output
3. In a loop: prints age, blinks the LED 3. In a loop: prints age, blinks the LED
@@ -644,6 +655,7 @@ This is used in `gpio_set_dir`. Patch this to `0x11` as well.
This is inside the loop for `gpio_put`. Patch this to `0x11` as well. This is inside the loop for `gpio_put`. Patch this to `0x11` as well.
Patch each one with **Patch Instruction**, then verify: Patch each one with **Patch Instruction**, then verify:
- `10000244`: `10 23` -> `11 23` - `10000244`: `10 23` -> `11 23`
- `10000252`: `10 24` -> `11 24` - `10000252`: `10 24` -> `11 24`
@@ -694,6 +706,7 @@ age: 66
And now the **GREEN LED on GPIO 17** should be blinking instead of the red one! And now the **GREEN LED on GPIO 17** should be blinking instead of the red one!
**We successfully:** **We successfully:**
1. Changed the printed value from 0 to 66 1. Changed the printed value from 0 to 66
2. Changed which LED blinks from red (GPIO 16) to green (GPIO 17) 2. Changed which LED blinks from red (GPIO 16) to green (GPIO 17)
@@ -713,6 +726,7 @@ mcrr p0, #4, r4, r5, c4 ; GPIO direction control
``` ```
**What this means:** **What this means:**
- `mcrr` = Move to Coprocessor from two ARM Registers - `mcrr` = Move to Coprocessor from two ARM Registers
- `p0` = Coprocessor 0 (the GPIO coprocessor) - `p0` = Coprocessor 0 (the GPIO coprocessor)
- `r4` = Contains the GPIO pin number - `r4` = Contains the GPIO pin number
BIN
View File
Binary file not shown.
+17 -3
View File
@@ -1,22 +1,25 @@
# Week 5: Integers and Floats in Embedded Systems: Debugging and Hacking Integers and Floats w/ Intermediate GPIO Output Assembler Analysis # Week 5: Integers and Floats in Embedded Systems: Debugging and Hacking Integers and Floats w/ Intermediate GPIO Output Assembler Analysis
--- ***
**LEGAL DISCLAIMER:** **LEGAL DISCLAIMER:**
The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only. The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with. You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that: By using this repository and course, you acknowledge and agree that:
1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility. 1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein. 2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud. 3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
**IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.** **IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.**
---
***
## What You'll Learn This Week ## What You'll Learn This Week
By the end of this tutorial, you will be able to: By the end of this tutorial, you will be able to:
- Understand how integers and floating-point numbers are stored in memory - Understand how integers and floating-point numbers are stored in memory
- Know the difference between signed and unsigned integers (`uint8_t` vs `int8_t`) - Know the difference between signed and unsigned integers (`uint8_t` vs `int8_t`)
- Understand how floats and doubles are represented using IEEE 754 encoding - Understand how floats and doubles are represented using IEEE 754 encoding
@@ -141,6 +144,7 @@ Use this exact process any time you need to encode a decimal float manually.
Quick decode check (reverse direction, fully expanded): Quick decode check (reverse direction, fully expanded):
Given the 32-bit pattern: Given the 32-bit pattern:
- `0 | 10000100 | 01010100000000000000000` - `0 | 10000100 | 01010100000000000000000`
Decode it field by field: Decode it field by field:
@@ -207,6 +211,7 @@ int main(void) {
> An ARM **literal pool** is a small table of constants that the assembler places near code in memory. Instead of encoding a large immediate value directly in an instruction, the CPU executes a load instruction (such as `ldr`) that reads the constant from that nearby table. That is why Ghidra can show constant loads rather than a classic stack local. > An ARM **literal pool** is a small table of constants that the assembler places near code in memory. Instead of encoding a large immediate value directly in an instruction, the CPU executes a load instruction (such as `ldr`) that reads the constant from that nearby table. That is why Ghidra can show constant loads rather than a classic stack local.
**What this code does:** **What this code does:**
1. Declares a `float` variable `fav_num` and initializes it to `42.5` 1. Declares a `float` variable `fav_num` and initializes it to `42.5`
2. Initializes the serial output 2. Initializes the serial output
3. Prints `fav_num` forever in a loop using the `%f` format specifier 3. Prints `fav_num` forever in a loop using the `%f` format specifier
@@ -272,11 +277,13 @@ Ghidra will open. Now we need to create a new project.
A dialog appears. The file is identified as a "BIN" (raw binary without debug symbols). A dialog appears. The file is identified as a "BIN" (raw binary without debug symbols).
**Click the three dots (...) next to "Language" and:** **Click the three dots (...) next to "Language" and:**
1. Search for "Cortex" 1. Search for "Cortex"
2. Select **ARM Cortex 32 little endian default** 2. Select **ARM Cortex 32 little endian default**
3. Click **OK** 3. Click **OK**
**Click the "Options..." button and:** **Click the "Options..." button and:**
1. Change **Block Name** to `.text` 1. Change **Block Name** to `.text`
2. Change **Base Address** to `10000000` (the XIP address!) 2. Change **Base Address** to `10000000` (the XIP address!)
3. Click **OK** 3. Click **OK**
@@ -298,6 +305,7 @@ Wait for analysis to complete (watch the progress bar in the bottom right).
Look at the **Symbol Tree** panel on the left. Expand **Functions**. Look at the **Symbol Tree** panel on the left. Expand **Functions**.
You'll see function names like: You'll see function names like:
- `FUN_1000019a` - `FUN_1000019a`
- `FUN_10000210` - `FUN_10000210`
- `FUN_10000234` - `FUN_10000234`
@@ -752,6 +760,7 @@ int main(void) {
``` ```
**What this code does:** **What this code does:**
1. Declares a `double` variable `fav_num` and initializes it to `42.52525` 1. Declares a `double` variable `fav_num` and initializes it to `42.52525`
2. Initializes the serial output 2. Initializes the serial output
3. Prints `fav_num` forever in a loop using the `%lf` format specifier 3. Prints `fav_num` forever in a loop using the `%lf` format specifier
@@ -817,11 +826,13 @@ Ghidra will open. Now we need to create a new project.
A dialog appears. The file is identified as a "BIN" (raw binary without debug symbols). A dialog appears. The file is identified as a "BIN" (raw binary without debug symbols).
**Click the three dots (...) next to "Language" and:** **Click the three dots (...) next to "Language" and:**
1. Search for "Cortex" 1. Search for "Cortex"
2. Select **ARM Cortex 32 little endian default** 2. Select **ARM Cortex 32 little endian default**
3. Click **OK** 3. Click **OK**
**Click the "Options..." button and:** **Click the "Options..." button and:**
1. Change **Block Name** to `.text` 1. Change **Block Name** to `.text`
2. Change **Base Address** to `10000000` (the XIP address!) 2. Change **Base Address** to `10000000` (the XIP address!)
3. Click **OK** 3. Click **OK**
@@ -843,6 +854,7 @@ Wait for analysis to complete (watch the progress bar in the bottom right).
Look at the **Symbol Tree** panel on the left. Expand **Functions**. Look at the **Symbol Tree** panel on the left. Expand **Functions**.
You'll see function names like: You'll see function names like:
- `FUN_1000019a` - `FUN_1000019a`
- `FUN_10000210` - `FUN_10000210`
- `FUN_10000238` - `FUN_10000238`
@@ -983,7 +995,7 @@ The sign bit is bit 63 of the 64-bit double, which is bit 31 of r3 (the high reg
``` ```
r3 = 0x4045433B = 0100 0000 0100 0101 0100 0011 0011 1011 r3 = 0x4045433B = 0100 0000 0100 0101 0100 0011 0011 1011
^ ^
r3 bit 31 = 0 -> sign = 0 -> Positive number ✓ r3 bit 31 = 0 -> sign = 0 -> Positive number
``` ```
**2. Exponent - bits 62-52 = bits 30-20 of r3** **2. Exponent - bits 62-52 = bits 30-20 of r3**
@@ -1164,12 +1176,14 @@ Look in the Listing view for the two data constants:
### Step 20: Patch Both Constants ### Step 20: Patch Both Constants
**Patch the low word:** **Patch the low word:**
1. Click on the data at address `10000254` containing `645A1CAC` 1. Click on the data at address `10000254` containing `645A1CAC`
2. Open the Bytes window and enable byte editing (Pencil icon) 2. Open the Bytes window and enable byte editing (Pencil icon)
3. Overwrite bytes `ac 1c 5a 64` with `8f c2 f5 28` (little-endian for `0x645A1CAC -> 0x28F5C28F`) 3. Overwrite bytes `ac 1c 5a 64` with `8f c2 f5 28` (little-endian for `0x645A1CAC -> 0x28F5C28F`)
4. Press Enter 4. Press Enter
**Patch the high word:** **Patch the high word:**
1. Click on the data at address `10000258` containing `4045433B` 1. Click on the data at address `10000258` containing `4045433B`
2. Keep byte editing enabled in the Bytes window 2. Keep byte editing enabled in the Bytes window
3. Overwrite bytes `3b 43 45 40` with `5c ff 58 40` (little-endian for `0x4045433B -> 0x4058FF5C`) 3. Overwrite bytes `3b 43 45 40` with `5c ff 58 40` (little-endian for `0x4045433B -> 0x4058FF5C`)
BIN
View File
Binary file not shown.
+19 -2
View File
@@ -1,22 +1,25 @@
# Week 6: Static Variables in Embedded Systems: Debugging and Hacking Static Variables w/ GPIO Input Basics # Week 6: Static Variables in Embedded Systems: Debugging and Hacking Static Variables w/ GPIO Input Basics
--- ***
**LEGAL DISCLAIMER:** **LEGAL DISCLAIMER:**
The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only. The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with. You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that: By using this repository and course, you acknowledge and agree that:
1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility. 1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein. 2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud. 3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
**IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.** **IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.**
---
***
## What You'll Learn This Week ## What You'll Learn This Week
By the end of this tutorial, you will be able to: By the end of this tutorial, you will be able to:
- Understand the difference between regular (automatic) variables and static variables - Understand the difference between regular (automatic) variables and static variables
- Know where different types of variables are stored (stack vs static storage) - Know where different types of variables are stored (stack vs static storage)
- Configure GPIO pins as inputs and use internal pull-up resistors - Configure GPIO pins as inputs and use internal pull-up resistors
@@ -35,6 +38,7 @@ By the end of this tutorial, you will be able to:
A **static variable** is a special kind of variable that "remembers" its value between function calls or loop iterations. Unlike regular variables that get created and destroyed each time, static variables **persist** for the entire lifetime of your program. A **static variable** is a special kind of variable that "remembers" its value between function calls or loop iterations. Unlike regular variables that get created and destroyed each time, static variables **persist** for the entire lifetime of your program.
Think of it like this: Think of it like this:
- **Regular variable:** Like writing on a whiteboard that gets erased after each class - **Regular variable:** Like writing on a whiteboard that gets erased after each class
- **Static variable:** Like writing in a notebook that you keep forever - **Static variable:** Like writing in a notebook that you keep forever
@@ -218,10 +222,12 @@ gpio_put(LED_GPIO, pressed ? 0 : 1);
``` ```
This is a compact if-else statement: This is a compact if-else statement:
- If `pressed` is **true (1)**: output `0` (LED OFF... wait, that seems backwards!) - If `pressed` is **true (1)**: output `0` (LED OFF... wait, that seems backwards!)
- If `pressed` is **false (0)**: output `1` (LED ON) - If `pressed` is **false (0)**: output `1` (LED ON)
**Why is it inverted?** Because of the pull-up resistor! **Why is it inverted?** Because of the pull-up resistor!
- Button **released** -> GPIO reads `1` -> `pressed = 1` -> output `0` -> LED OFF - Button **released** -> GPIO reads `1` -> `pressed = 1` -> output `0` -> LED OFF
- Button **pressed** -> GPIO reads `0` -> `pressed = 0` -> output `1` -> LED ON - Button **pressed** -> GPIO reads `0` -> `pressed = 0` -> output `1` -> LED ON
@@ -273,6 +279,7 @@ This is why when you look for `gpio_pull_up` in the binary, you might find `gpio
### Prerequisites ### Prerequisites
Before we start, make sure you have: Before we start, make sure you have:
1. A Raspberry Pi Pico 2 board 1. A Raspberry Pi Pico 2 board
2. A Raspberry Pi Pico Debug Probe 2. A Raspberry Pi Pico Debug Probe
3. OpenOCD installed and configured 3. OpenOCD installed and configured
@@ -287,6 +294,7 @@ Before we start, make sure you have:
### Hardware Setup ### Hardware Setup
Connect your button like this: Connect your button like this:
- One side of button -> GPIO 15 - One side of button -> GPIO 15
- Other side of button -> GND - Other side of button -> GND
@@ -408,12 +416,14 @@ static_fav_num: 45
``` ```
**Notice the difference:** **Notice the difference:**
- `regular_fav_num` stays at 42 every time (it's recreated each loop) - `regular_fav_num` stays at 42 every time (it's recreated each loop)
- `static_fav_num` increases each time (it persists and remembers its value) - `static_fav_num` increases each time (it persists and remembers its value)
### Step 4: Test the Button ### Step 4: Test the Button
Now test the button behavior: Now test the button behavior:
- **Button NOT pressed:** LED should be OFF - **Button NOT pressed:** LED should be OFF
- **Button PRESSED:** LED should turn ON - **Button PRESSED:** LED should turn ON
@@ -687,6 +697,8 @@ You can see this directly. Run `x/10i 0x1000028e` in GDB and you will get exactl
```gdb ```gdb
(gdb) x/s 0x10003578 (gdb) x/s 0x10003578
0x10003578: "static_fav_num: %d\r\n" 0x10003578: "static_fav_num: %d\r\n"
```
- `0x10003578` flash address of the `"static_fav_num: %d\r\n"` string literal, also in **`.rodata`** in flash for the same reason. - `0x10003578` flash address of the `"static_fav_num: %d\r\n"` string literal, also in **`.rodata`** in flash for the same reason.
So the pool contains addresses into three different regions: RAM `.data` (the static variable), and flash `.rodata` (both format strings). Only the RAM address needed to be in the pool, the flash addresses could in principle be reached other ways, but they are also too large to encode as 16-bit immediates, so they go in the pool too. So the pool contains addresses into three different regions: RAM `.data` (the static variable), and flash `.rodata` (both format strings). Only the RAM address needed to be in the pool, the flash addresses could in principle be reached other ways, but they are also too large to encode as 16-bit immediates, so they go in the pool too.
@@ -985,6 +997,7 @@ file_offset = address - 0x10000000
``` ```
For example: For example:
- Address `0x10000264` -> file offset `0x264` (612 in decimal) - Address `0x10000264` -> file offset `0x264` (612 in decimal)
- Address `0x10000286` -> file offset `0x286` (646 in decimal) - Address `0x10000286` -> file offset `0x286` (646 in decimal)
@@ -1046,6 +1059,7 @@ To change `eor.w r3, r3, #1` to `eor.w r3, r3, #0`:
> ?? **Why offset `0x288` and not `0x286`?** The immediate value `#1` is in the **third byte** of the 4-byte instruction. The instruction starts at file offset `0x286`, so the immediate byte is at `0x286 + 2 = 0x288`. > ?? **Why offset `0x288` and not `0x286`?** The immediate value `#1` is in the **third byte** of the 4-byte instruction. The instruction starts at file offset `0x286`, so the immediate byte is at `0x286 + 2 = 0x288`.
Now the logic is permanently changed: Now the logic is permanently changed:
- Button released (input = 1): `1 XOR 0 = 1` -> LED **ON** - Button released (input = 1): `1 XOR 0 = 1` -> LED **ON**
- Button pressed (input = 0): `0 XOR 0 = 0` -> LED **OFF** - Button pressed (input = 0): `0 XOR 0 = 0` -> LED **OFF**
@@ -1076,6 +1090,7 @@ python ..\uf2conv.py build\0x0014_static-variables-h.bin --base 0x10000000 --fam
``` ```
**What this command means:** **What this command means:**
- `uf2conv.py` = the conversion script (in the parent `Embedded-Hacking` directory) - `uf2conv.py` = the conversion script (in the parent `Embedded-Hacking` directory)
- `--base 0x10000000` = the XIP base address where code runs from - `--base 0x10000000` = the XIP base address where code runs from
- `--family 0xe48bff59` = the RP2350 family ID - `--family 0xe48bff59` = the RP2350 family ID
@@ -1099,10 +1114,12 @@ static_fav_num: 43
``` ```
**Check the LED behavior:** **Check the LED behavior:**
- LED should now be **ON by default** (when button is NOT pressed) - LED should now be **ON by default** (when button is NOT pressed)
- LED should turn **OFF** when you press the button - LED should turn **OFF** when you press the button
**BOOM! We successfully:** **BOOM! We successfully:**
1. Changed the printed value from 42 to 43 1. Changed the printed value from 42 to 43
2. Inverted the LED/button logic 2. Inverted the LED/button logic
BIN
View File
Binary file not shown.
+13 -4
View File
@@ -1,22 +1,25 @@
# Week 7: Constants in Embedded Systems: Debugging and Hacking Constants w/ 1602 LCD I2C Basics # Week 7: Constants in Embedded Systems: Debugging and Hacking Constants w/ 1602 LCD I2C Basics
--- ***
**LEGAL DISCLAIMER:** **LEGAL DISCLAIMER:**
The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only. The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with. You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that: By using this repository and course, you acknowledge and agree that:
1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility. 1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein. 2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud. 3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
**IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.** **IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.**
---
***
## What You'll Learn This Week ## What You'll Learn This Week
By the end of this tutorial, you will be able to: By the end of this tutorial, you will be able to:
- Understand the difference between `#define` macros and `const` variables - Understand the difference between `#define` macros and `const` variables
- Know how constants are stored differently in memory (compile-time vs runtime) - Know how constants are stored differently in memory (compile-time vs runtime)
- Understand the I2C (Inter-Integrated Circuit) communication protocol - Understand the I2C (Inter-Integrated Circuit) communication protocol
@@ -341,6 +344,7 @@ bl i2c_init ; Call the function
### Prerequisites ### Prerequisites
Before we start, make sure you have: Before we start, make sure you have:
1. A Raspberry Pi Pico 2 board 1. A Raspberry Pi Pico 2 board
2. A Raspberry Pi Pico Debug Probe 2. A Raspberry Pi Pico Debug Probe
3. OpenOCD installed and configured 3. OpenOCD installed and configured
@@ -463,6 +467,7 @@ int main(void) {
### Step 3: Verify It's Working ### Step 3: Verify It's Working
**Check the LCD:** **Check the LCD:**
- Line 1 should show: `Reverse` - Line 1 should show: `Reverse`
- Line 2 should show: `Engineering` - Line 2 should show: `Engineering`
@@ -613,6 +618,7 @@ Look for this instruction:
**Surprise!** The `const` variable is ALSO embedded as an immediate value - not loaded from memory! The compiler saw that `OTHER_FAV_NUM` is never address-taken (`&OTHER_FAV_NUM` is never used), so it optimized the `const` the same way as `#define` - as a constant embedded directly in the instruction. **Surprise!** The `const` variable is ALSO embedded as an immediate value - not loaded from memory! The compiler saw that `OTHER_FAV_NUM` is never address-taken (`&OTHER_FAV_NUM` is never used), so it optimized the `const` the same way as `#define` - as a constant embedded directly in the instruction.
The difference is the instruction encoding: The difference is the instruction encoding:
- `FAV_NUM` (42): `movs r1, #0x2a` - 16-bit Thumb instruction (values 0-255) - `FAV_NUM` (42): `movs r1, #0x2a` - 16-bit Thumb instruction (values 0-255)
- `OTHER_FAV_NUM` (1337): `movw r1, #0x539` - 32-bit Thumb-2 instruction (values 0-65535) - `OTHER_FAV_NUM` (1337): `movw r1, #0x539` - 32-bit Thumb-2 instruction (values 0-65535)
@@ -636,8 +642,8 @@ These are the values that `ldr rN, [pc, #offset]` instructions load:
| `0x100002a8` | `0x2000062C` | &i2c1_inst (I2C struct in RAM) | | `0x100002a8` | `0x2000062C` | &i2c1_inst (I2C struct in RAM) |
| `0x100002ac` | `0x10003EE8` | "Reverse" string address | | `0x100002ac` | `0x10003EE8` | "Reverse" string address |
| `0x100002b0` | `0x10003EF0` | "Engineering" string address | | `0x100002b0` | `0x10003EF0` | "Engineering" string address |
| `0x100002b4` | `0x10003EFC` | "FAV_NUM: %d\r\n" format str | | `0x100002b4` | `0x10003EFC` | `"FAV_NUM: %d\r\n"` format str |
| `0x100002b8` | `0x10003F0C` | "OTHER_FAV_NUM: %d\r\n" fmt | | `0x100002b8` | `0x10003F0C` | `"OTHER_FAV_NUM: %d\r\n"` fmt |
> Tip: **Why does the disassembly at `0x100002a4` show `strh r0, [r4, #52]` instead of data?** Same reason as Week 6 - GDB's `x/i` tries to decode raw data as instructions. Use `x/wx` to see the actual word values or we can also use `x/x`. > Tip: **Why does the disassembly at `0x100002a4` show `strh r0, [r4, #52]` instead of data?** Same reason as Week 6 - GDB's `x/i` tries to decode raw data as instructions. Use `x/wx` to see the actual word values or we can also use `x/x`.
@@ -728,6 +734,7 @@ The value 42 is embedded directly in a 16-bit Thumb instruction. This is expecte
The value 1337 is ALSO embedded directly in an instruction - but this time a 32-bit Thumb-2 `movw` because the value doesn't fit in 8 bits. The value 1337 is ALSO embedded directly in an instruction - but this time a 32-bit Thumb-2 `movw` because the value doesn't fit in 8 bits.
**Why wasn't `const` stored in memory?** In theory, `const int OTHER_FAV_NUM = 1337` creates a variable in the `.rodata` section. But the compiler optimized it away because: **Why wasn't `const` stored in memory?** In theory, `const int OTHER_FAV_NUM = 1337` creates a variable in the `.rodata` section. But the compiler optimized it away because:
1. We never take the address of `OTHER_FAV_NUM` (no `&OTHER_FAV_NUM`) 1. We never take the address of `OTHER_FAV_NUM` (no `&OTHER_FAV_NUM`)
2. The value fits in a 16-bit `movw` immediate 2. The value fits in a 16-bit `movw` immediate
3. Loading from an immediate is faster than loading from memory 3. Loading from an immediate is faster than loading from memory
@@ -798,6 +805,7 @@ file_offset = address - 0x10000000
``` ```
For example: For example:
- Address `0x1000028e` -> file offset `0x28E` (654 in decimal) - Address `0x1000028e` -> file offset `0x28E` (654 in decimal)
- Address `0x10003ee8` -> file offset `0x3EE8` (16104 in decimal) - Address `0x10003ee8` -> file offset `0x3EE8` (16104 in decimal)
@@ -905,6 +913,7 @@ python ..\uf2conv.py build\0x0017_constants-h.bin --base 0x10000000 --family 0xe
### Step 23: Verify the Hack ### Step 23: Verify the Hack
**Check the LCD:** **Check the LCD:**
- Line 1 should now show: `Exploit` (instead of "Reverse") - Line 1 should now show: `Exploit` (instead of "Reverse")
- Line 2 should still show: `Engineering` - Line 2 should still show: `Engineering`
BIN
View File
Binary file not shown.
+13 -2
View File
@@ -1,22 +1,25 @@
# Week 9: Operators in Embedded Systems: Debugging and Hacking Operators w/ DHT11 Temperature & Humidity Sensor Single-Wire Protocol Basics. # Week 9: Operators in Embedded Systems: Debugging and Hacking Operators w/ DHT11 Temperature & Humidity Sensor Single-Wire Protocol Basics.
--- ***
**LEGAL DISCLAIMER:** **LEGAL DISCLAIMER:**
The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only. The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with. You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that: By using this repository and course, you acknowledge and agree that:
1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility. 1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein. 2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud. 3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
**IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.** **IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.**
---
***
## What You'll Learn This Week ## What You'll Learn This Week
By the end of this tutorial, you will be able to: By the end of this tutorial, you will be able to:
- Understand all six types of C operators (arithmetic, increment, relational, logical, bitwise, assignment) - Understand all six types of C operators (arithmetic, increment, relational, logical, bitwise, assignment)
- Know how the DHT11 temperature and humidity sensor communicates with the Pico 2 - Know how the DHT11 temperature and humidity sensor communicates with the Pico 2
- Understand how post-increment operators affect variable values - Understand how post-increment operators affect variable values
@@ -339,6 +342,7 @@ if (dht11_read(&hum, &temp)) {
### Prerequisites ### Prerequisites
Before we start, make sure you have: Before we start, make sure you have:
1. A Raspberry Pi Pico 2 board 1. A Raspberry Pi Pico 2 board
2. A Raspberry Pi Pico Debug Probe 2. A Raspberry Pi Pico Debug Probe
3. Ghidra installed (for static analysis) 3. Ghidra installed (for static analysis)
@@ -572,6 +576,7 @@ x/32i 0x10000240
``` ```
You may see values like: You may see values like:
- `#0x32` (50) for arithmetic_operator - `#0x32` (50) for arithmetic_operator
- `#0x5` (5) for increment_operator - `#0x5` (5) for increment_operator
- `#0x0` (0) for relational and logical operators - `#0x0` (0) for relational and logical operators
@@ -589,6 +594,7 @@ i r r0 r1
``` ```
You should see: You should see:
- `r0` = address of format string - `r0` = address of format string
- `r1` = value to print - `r1` = value to print
@@ -674,11 +680,13 @@ ghidraRun
### Step 20: Configure the Binary Format ### Step 20: Configure the Binary Format
**Click the three dots (...) next to "Language" and:** **Click the three dots (...) next to "Language" and:**
1. Search for "Cortex" 1. Search for "Cortex"
2. Select **ARM Cortex 32 little endian default** 2. Select **ARM Cortex 32 little endian default**
3. Click **OK** 3. Click **OK**
**Click the "Options..." button and:** **Click the "Options..." button and:**
1. Change **Block Name** to `.text` 1. Change **Block Name** to `.text`
2. Change **Base Address** to `10000000` 2. Change **Base Address** to `10000000`
3. Click **OK** 3. Click **OK**
@@ -802,6 +810,7 @@ bl FUN_xxxxx ; dht11_init
``` ```
**How do we know it's dht11_init?** **How do we know it's dht11_init?**
- The argument `4` is the GPIO pin number - The argument `4` is the GPIO pin number
- We physically connected the DHT11 to GPIO 4! - We physically connected the DHT11 to GPIO 4!
@@ -843,6 +852,7 @@ bl FUN_xxxxx ; dht11_read
``` ```
**Understanding the stack offsets:** **Understanding the stack offsets:**
- `sp + 0x8` = address of `hum` variable - `sp + 0x8` = address of `hum` variable
- `sp + 0xc` = address of `temp` variable - `sp + 0xc` = address of `temp` variable
- These are `float` pointers passed to the function - These are `float` pointers passed to the function
@@ -1201,6 +1211,7 @@ Imagine a scenario where temperature sensors control critical systems:
- **HVAC systems** - Climate control in sensitive environments - **HVAC systems** - Climate control in sensitive environments
By manipulating sensor readings, an attacker could: By manipulating sensor readings, an attacker could:
- Cause equipment to overheat while displaying normal temperatures - Cause equipment to overheat while displaying normal temperatures
- Trigger false alarms - Trigger false alarms
- Bypass safety interlocks - Bypass safety interlocks
BIN
View File
Binary file not shown.
+27 -5
View File
@@ -1,22 +1,25 @@
# Week 10: Conditionals in Embedded Systems: Debugging and Hacking Static & Dynamic Conditionals w/ SG90 Servo Motor PWM Basics # Week 10: Conditionals in Embedded Systems: Debugging and Hacking Static & Dynamic Conditionals w/ SG90 Servo Motor PWM Basics
--- ***
**LEGAL DISCLAIMER:** **LEGAL DISCLAIMER:**
The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only. The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with. You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that: By using this repository and course, you acknowledge and agree that:
1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility. 1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein. 2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud. 3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
**IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.** **IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.**
---
***
## What You'll Learn This Week ## What You'll Learn This Week
By the end of this tutorial, you will be able to: By the end of this tutorial, you will be able to:
- Understand the difference between static and dynamic conditionals in C - Understand the difference between static and dynamic conditionals in C
- Know how if/else statements and switch/case blocks work at the assembly level - Know how if/else statements and switch/case blocks work at the assembly level
- Understand Pulse Width Modulation (PWM) and how it controls servo motors - Understand Pulse Width Modulation (PWM) and how it controls servo motors
@@ -377,6 +380,7 @@ The **SG90** is a small, inexpensive hobby servo motor commonly used in robotics
**NEVER power the servo directly from the Pico's 3.3V pin!** **NEVER power the servo directly from the Pico's 3.3V pin!**
Servos can draw over 1000mA during movement spikes. The Pico's 3.3V regulator cannot handle this and you will: Servos can draw over 1000mA during movement spikes. The Pico's 3.3V regulator cannot handle this and you will:
- Cause brownouts (Pico resets) - Cause brownouts (Pico resets)
- Damage the Pico's voltage regulator - Damage the Pico's voltage regulator
- Potentially damage your USB port - Potentially damage your USB port
@@ -410,6 +414,7 @@ Servos can draw over 1000mA during movement spikes. The Pico's 3.3V regulator ca
### Why the Capacitor? ### Why the Capacitor?
The **1000 uF capacitor** acts as a tiny battery: The **1000 uF capacitor** acts as a tiny battery:
- Absorbs sudden current demands when servo moves - Absorbs sudden current demands when servo moves
- Prevents voltage drops that could reset the Pico - Prevents voltage drops that could reset the Pico
- Smooths out electrical noise - Smooths out electrical noise
@@ -421,6 +426,7 @@ The **1000 uF capacitor** acts as a tiny battery:
### Prerequisites ### Prerequisites
Before we start, make sure you have: Before we start, make sure you have:
1. A Raspberry Pi Pico 2 board 1. A Raspberry Pi Pico 2 board
2. A Raspberry Pi Pico Debug Probe 2. A Raspberry Pi Pico Debug Probe
3. Ghidra installed (for static analysis) 3. Ghidra installed (for static analysis)
@@ -599,6 +605,7 @@ one
``` ```
**Watch the servo:** **Watch the servo:**
- It should sweep from 0° to 180° every second - It should sweep from 0° to 180° every second
- The movement is continuous and repetitive - The movement is continuous and repetitive
@@ -789,11 +796,13 @@ ghidraRun
### Step 20: Configure the Binary Format ### Step 20: Configure the Binary Format
**Click the three dots (...) next to "Language" and:** **Click the three dots (...) next to "Language" and:**
1. Search for "Cortex" 1. Search for "Cortex"
2. Select **ARM Cortex 32 little endian default** 2. Select **ARM Cortex 32 little endian default**
3. Click **OK** 3. Click **OK**
**Click the "Options..." button and:** **Click the "Options..." button and:**
1. Change **Block Name** to `.text` 1. Change **Block Name** to `.text`
2. Change **Base Address** to `10000000` 2. Change **Base Address** to `10000000`
3. Click **OK** 3. Click **OK**
@@ -849,9 +858,10 @@ bl FUN_10001884 undefined FUN_10001884()
``` ```
**How do we know it's puts?** **How do we know it's puts?**
- It takes a single string argument - It takes a single string argument
- The hex `0x31` is ASCII "1" - The hex `0x31` is ASCII "1"
- The hex `0x0d` is carriage return "\r" - The hex `0x0d` is carriage return `"\r"`
- We saw "1" echoed in PuTTY - We saw "1" echoed in PuTTY
1. Right-click -> **Edit Function Signature** 1. Right-click -> **Edit Function Signature**
@@ -879,6 +889,7 @@ mov.cc.w r3,#0x3e8
``` ```
These values are: These values are:
- `0x7D0` (2000 decimal) - maximum pulse width - `0x7D0` (2000 decimal) - maximum pulse width
- `0x3E8` (1000 decimal) - minimum pulse width - `0x3E8` (1000 decimal) - minimum pulse width
@@ -931,6 +942,7 @@ Next, let's change the word "one" to "fun":
4. Click on the `6f` byte and type `66 75 6e` on your keyboard to overwrite those three bytes with "f-u-n". 4. Click on the `6f` byte and type `66 75 6e` on your keyboard to overwrite those three bytes with "f-u-n".
**ASCII Reference:** **ASCII Reference:**
| Character | Hex | | Character | Hex |
| --------- | ---- | | --------- | ---- |
| o | 0x6f | | o | 0x6f |
@@ -1226,6 +1238,7 @@ Follow the same process:
### Step 52: Identify getchar ### Step 52: Identify getchar
Look for a function that: Look for a function that:
- Returns a value in `r0` - Returns a value in `r0`
- That value is then compared against `0x31` ("1") - That value is then compared against `0x31` ("1")
@@ -1249,6 +1262,7 @@ ldr r0, =0x40070000 ; UART0 base address
``` ```
Check the RP2350 datasheet Section 2.2 (Address Map): Check the RP2350 datasheet Section 2.2 (Address Map):
- `0x40070000` = UART0 - `0x40070000` = UART0
This confirms it's a UART initialization function! This confirms it's a UART initialization function!
@@ -1311,6 +1325,7 @@ skip_printf:
### The Goal ### The Goal
We want to create **secret commands** that: We want to create **secret commands** that:
1. Respond to 'x' and 'y' instead of '1' and '2' 1. Respond to 'x' and 'y' instead of '1' and '2'
2. Move the servo WITHOUT printing anything 2. Move the servo WITHOUT printing anything
3. Leave NO trace in the terminal 3. Leave NO trace in the terminal
@@ -1318,10 +1333,12 @@ We want to create **secret commands** that:
### Step 54: Plan the Patches ### Step 54: Plan the Patches
**Original behavior:** **Original behavior:**
- '1' (0x31) -> prints "1" and "one", moves servo - '1' (0x31) -> prints "1" and "one", moves servo
- '2' (0x32) -> prints "2" and "two", moves servo - '2' (0x32) -> prints "2" and "two", moves servo
**Hacked behavior:** **Hacked behavior:**
- 'x' (0x78) -> moves servo SILENTLY (replacing '1') - 'x' (0x78) -> moves servo SILENTLY (replacing '1')
- 'y' (0x79) -> moves servo SILENTLY (replacing '2') - 'y' (0x79) -> moves servo SILENTLY (replacing '2')
@@ -1395,6 +1412,7 @@ The compiler stored the 180.0 float value (`0x43340000`) in a literal pool at ad
**New:** `0x41f00000` (30.0f) **New:** `0x41f00000` (30.0f)
Here is how to apply the patch: Here is how to apply the patch:
1. Press `G` and jump to address `100002c4`. 1. Press `G` and jump to address `100002c4`.
2. In your **Bytes** window (make sure the Pencil icon is still clicked!), you will see the raw little-endian bytes: `00 00 34 43`. 2. In your **Bytes** window (make sure the Pencil icon is still clicked!), you will see the raw little-endian bytes: `00 00 34 43`.
3. Click on the first `00` and type `00 00 f0 41`. 3. Click on the first `00` and type `00 00 f0 41`.
@@ -1545,8 +1563,8 @@ python ..\uf2conv.py build\0x0020_dynamic-conditionals-h.bin --base 0x10000000 -
| '2' | 0x32 | 50 | | '2' | 0x32 | 50 |
| 'x' | 0x78 | 120 | | 'x' | 0x78 | 120 |
| 'y' | 0x79 | 121 | | 'y' | 0x79 | 121 |
| '\r' | 0x0d | 13 | | `'\r'` | 0x0d | 13 |
| '\n' | 0x0a | 10 | | `'\n'` | 0x0a | 10 |
### IEEE-754 Common Angles ### IEEE-754 Common Angles
@@ -1583,11 +1601,13 @@ python ..\uf2conv.py build\0x0020_dynamic-conditionals-h.bin --base 0x10000000 -
The ability to create hidden commands has serious implications: The ability to create hidden commands has serious implications:
**Legitimate Uses:** **Legitimate Uses:**
- Factory test modes - Factory test modes
- Debugging interfaces - Debugging interfaces
- Emergency recovery features - Emergency recovery features
**Malicious Uses:** **Malicious Uses:**
- Backdoors in firmware - Backdoors in firmware
- Hidden surveillance features - Hidden surveillance features
- Unauthorized control of systems - Unauthorized control of systems
@@ -1595,6 +1615,7 @@ The ability to create hidden commands has serious implications:
### Real-World Example ### Real-World Example
Imagine a drone with hacked firmware: Imagine a drone with hacked firmware:
- Normal keys ('1', '2') control it visibly with logging - Normal keys ('1', '2') control it visibly with logging
- Hidden keys ('x', 'y') control it with NO log entries - Hidden keys ('x', 'y') control it with NO log entries
- An attacker could operate the drone while security monitors show nothing - An attacker could operate the drone while security monitors show nothing
@@ -1602,6 +1623,7 @@ Imagine a drone with hacked firmware:
### The Nuclear Fuel Rod Analogy ### The Nuclear Fuel Rod Analogy
A fast-moving servo is like a nuclear fuel rod: A fast-moving servo is like a nuclear fuel rod:
- Both are small components with immense power - Both are small components with immense power
- Both require precise control to prevent damage - Both require precise control to prevent damage
- Both can "go critical" if pushed beyond limits - Both can "go critical" if pushed beyond limits
BIN
View File
Binary file not shown.
+22 -2
View File
@@ -1,22 +1,25 @@
# Week 11: Structures and Functions in Embedded Systems: Debugging and Hacking w/ IR Remote Control and NEC Protocol Basics # Week 11: Structures and Functions in Embedded Systems: Debugging and Hacking w/ IR Remote Control and NEC Protocol Basics
--- ***
**LEGAL DISCLAIMER:** **LEGAL DISCLAIMER:**
The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only. The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with. You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that: By using this repository and course, you acknowledge and agree that:
1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility. 1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein. 2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud. 3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
**IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.** **IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.**
---
***
## What You'll Learn This Week ## What You'll Learn This Week
By the end of this tutorial, you will be able to: By the end of this tutorial, you will be able to:
- Understand C structures (structs) and how they organize related data - Understand C structures (structs) and how they organize related data
- Know how structs are represented in memory and assembly code - Know how structs are represented in memory and assembly code
- Understand the NEC infrared (IR) protocol for remote control communication - Understand the NEC infrared (IR) protocol for remote control communication
@@ -81,6 +84,7 @@ typedef struct {
| `bool led3_state = false;` | ... (all in one container!) | | `bool led3_state = false;` | ... (all in one container!) |
**Benefits of Structs:** **Benefits of Structs:**
1. **Organization** - Related data stays together 1. **Organization** - Related data stays together
2. **Readability** - Code is easier to understand 2. **Readability** - Code is easier to understand
3. **Maintainability** - Changes are easier to make 3. **Maintainability** - Changes are easier to make
@@ -175,6 +179,7 @@ simple_led_ctrl_t leds = {
``` ```
**Benefits:** **Benefits:**
- Clear which value goes to which member - Clear which value goes to which member
- Order doesn't matter (can rearrange lines) - Order doesn't matter (can rearrange lines)
- Self-documenting code - Self-documenting code
@@ -412,6 +417,7 @@ bl gpio_init ; call gpio_init(18)
### Prerequisites ### Prerequisites
Before we start, make sure you have: Before we start, make sure you have:
1. A Raspberry Pi Pico 2 board 1. A Raspberry Pi Pico 2 board
2. A Raspberry Pi Pico Debug Probe 2. A Raspberry Pi Pico Debug Probe
3. Ghidra installed (for static analysis) 3. Ghidra installed (for static analysis)
@@ -596,6 +602,7 @@ int main(void) {
### Step 4: Verify It's Working ### Step 4: Verify It's Working
**Open PuTTY (115200 baud) and test:** **Open PuTTY (115200 baud) and test:**
- Press "1" on remote -> Red LED lights, terminal shows `NEC command: 0x0C` - Press "1" on remote -> Red LED lights, terminal shows `NEC command: 0x0C`
- Press "2" on remote -> Green LED lights, terminal shows `NEC command: 0x18` - Press "2" on remote -> Green LED lights, terminal shows `NEC command: 0x18`
- Press "3" on remote -> Yellow LED lights, terminal shows `NEC command: 0x5E` - Press "3" on remote -> Yellow LED lights, terminal shows `NEC command: 0x5E`
@@ -740,6 +747,7 @@ info registers r1 r2 r3 r4
``` ```
Depending on which button you pressed, one of the state registers will be `1` (ON) and the others will be `0` (OFF): Depending on which button you pressed, one of the state registers will be `1` (ON) and the others will be `0` (OFF):
- `r1` = State for the **Red** LED (GPIO 16) - `r1` = State for the **Red** LED (GPIO 16)
- `r3` = State for the **Green** LED (GPIO 17) - `r3` = State for the **Green** LED (GPIO 17)
- `r4` = State for the **Yellow** LED (GPIO 18) - `r4` = State for the **Yellow** LED (GPIO 18)
@@ -785,11 +793,13 @@ ghidraRun
### Step 20: Configure the Binary Format ### Step 20: Configure the Binary Format
**Click the three dots (...) next to "Language" and:** **Click the three dots (...) next to "Language" and:**
1. Search for "Cortex" 1. Search for "Cortex"
2. Select **ARM Cortex 32 little endian default** 2. Select **ARM Cortex 32 little endian default**
3. Click **OK** 3. Click **OK**
**Click the "Options..." button and:** **Click the "Options..." button and:**
1. Change **Block Name** to `.text` 1. Change **Block Name** to `.text`
2. Change **Base Address** to `10000000` 2. Change **Base Address** to `10000000`
3. Click **OK** 3. Click **OK**
@@ -838,6 +848,7 @@ Look for three consecutive calls with values 16, 17, 18:
``` ```
This pattern reveals the struct members! Update the function signature: This pattern reveals the struct members! Update the function signature:
1. Right-click on `FUN_10000558` -> **Edit Function Signature** 1. Right-click on `FUN_10000558` -> **Edit Function Signature**
2. Change to: `void gpio_init(uint gpio)` 2. Change to: `void gpio_init(uint gpio)`
3. Click **OK** 3. Click **OK**
@@ -985,6 +996,7 @@ python ..\uf2conv.py build\0x0023_structures-h.bin --base 0x10000000 --family 0x
### Step 34: Verify the Hack ### Step 34: Verify the Hack
**Open PuTTY and test:** **Open PuTTY and test:**
- Press "1" on remote -> **GREEN** LED lights (was red!) - Press "1" on remote -> **GREEN** LED lights (was red!)
- Terminal still shows `NEC command: 0x0C` - Terminal still shows `NEC command: 0x0C`
- Press "2" on remote -> **RED** LED lights (was green!) - Press "2" on remote -> **RED** LED lights (was green!)
@@ -1020,12 +1032,14 @@ python ..\uf2conv.py build\0x0023_structures-h.bin --base 0x10000000 --family 0x
### Real-World Example: Stuxnet ### Real-World Example: Stuxnet
**Stuxnet** was a cyberweapon that: **Stuxnet** was a cyberweapon that:
- Attacked Iranian nuclear centrifuges - Attacked Iranian nuclear centrifuges
- Made centrifuges spin at dangerous speeds - Made centrifuges spin at dangerous speeds
- Fed FALSE "everything normal" data to operators - Fed FALSE "everything normal" data to operators
- Operators saw stable readings while equipment was destroyed - Operators saw stable readings while equipment was destroyed
Our LED example demonstrates the same principle: Our LED example demonstrates the same principle:
- Logs show expected behavior - Logs show expected behavior
- Hardware performs different actions - Hardware performs different actions
- Attackers can hide malicious activity - Attackers can hide malicious activity
@@ -1319,6 +1333,7 @@ quit
### Step 52: Explore the Symbol Tree ### Step 52: Explore the Symbol Tree
With .ELF files, you get more information: With .ELF files, you get more information:
1. Look at the **Symbol Tree** panel 1. Look at the **Symbol Tree** panel
2. Expand **Functions** - you may see named functions! 2. Expand **Functions** - you may see named functions!
3. Expand **Labels** - data labels may appear 3. Expand **Labels** - data labels may appear
@@ -1342,6 +1357,7 @@ movs r0, #0x12 ; led3_pin = 18
We'll swap the red (GPIO 16) and yellow (GPIO 18) LEDs: We'll swap the red (GPIO 16) and yellow (GPIO 18) LEDs:
**Find and patch in the .bin file:** **Find and patch in the .bin file:**
1. Change `0x10` (16) to `0x12` (18) 1. Change `0x10` (16) to `0x12` (18)
2. Change `0x12` (18) to `0x10` (16) 2. Change `0x12` (18) to `0x10` (16)
@@ -1375,6 +1391,7 @@ python ..\uf2conv.py build\0x0026_functions-h.bin --base 0x10000000 --family 0xe
### Step 57: Verify the Hack ### Step 57: Verify the Hack
**Open PuTTY and test:** **Open PuTTY and test:**
- Press "1" -> **YELLOW** LED blinks (was red!) - Press "1" -> **YELLOW** LED blinks (was red!)
- Terminal shows: `LED 1 activated on GPIO 16` (WRONG - it's actually GPIO 18!) - Terminal shows: `LED 1 activated on GPIO 16` (WRONG - it's actually GPIO 18!)
- Press "3" -> **RED** LED blinks (was yellow!) - Press "3" -> **RED** LED blinks (was yellow!)
@@ -1554,12 +1571,14 @@ Over these weeks, you've built skills that few people possess:
The techniques you've learned can be used for: The techniques you've learned can be used for:
**Good:** **Good:**
- Security research - Security research
- Debugging proprietary systems - Debugging proprietary systems
- Understanding how things work - Understanding how things work
- Career in cybersecurity - Career in cybersecurity
**Danger:** **Danger:**
- Unauthorized system access - Unauthorized system access
- Sabotage of critical infrastructure - Sabotage of critical infrastructure
- Fraud and deception - Fraud and deception
@@ -1569,6 +1588,7 @@ The techniques you've learned can be used for:
### Keep Learning ### Keep Learning
This is just the beginning: This is just the beginning:
- Explore more complex protocols (SPI, CAN bus) - Explore more complex protocols (SPI, CAN bus)
- Learn dynamic analysis with debuggers - Learn dynamic analysis with debuggers
- Study cryptographic implementations - Study cryptographic implementations
BIN
View File
Binary file not shown.