Overhall w/ slides

This commit is contained in:
Kevin Thomas
2026-03-15 10:40:20 -04:00
parent ece5664050
commit 612c0b5f3a
61 changed files with 6305 additions and 240 deletions
+3
View File
@@ -0,0 +1,3 @@
{
"cmake.sourceDirectory": "C:/Users/assem.KEVINTHOMAS/OneDrive/Documents/Embedded-Hacking/0x0001_hello-world"
}
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 325 KiB

After

Width:  |  Height:  |  Size: 340 KiB

+53 -7
View File
@@ -43,7 +43,7 @@ VIDEO PROMO [HERE](https://www.youtube.com/watch?v=aD7X9sXirF8)
## Week 1
Introduction and Overview of Embedded Reverse Engineering: Ethics, Scoping, and Basic Concepts
### Week 1 Slides [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK01/WEEK01.pdf)
### Week 1 Slides [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK01/WEEK01-SLIDES.pdf)
### Week 1 Notebook [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK01/WEEK01.md)
@@ -68,7 +68,7 @@ This chapter covers the debugging of our firmware for the Pico 2 MCU hello, worl
## Week 2
Hello, World - Debugging and Hacking Basics: Debugging and Hacking a Basic Program for the Pico 2
### Week 2 Slides [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK02/WEEK02.pdf)
### Week 2 Slides [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK02/WEEK02-SLIDES.pdf)
### Week 2 Notebook [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK02/WEEK02.md)
@@ -88,6 +88,8 @@ This chapter covers the hacking of our firmware for the Pico 2 MCU hello, world
## Week 3
Embedded System Analysis: Understanding the RP2350 Architecture w/ Comprehensive Firmware Analysis
### Week 3 Slides [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK03/WEEK03-SLIDES.pdf)
### Week 3 Notebook [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK03/WEEK03.md)
#### Exercise 1: Trace a Reset [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK03/WEEK03-01.md)
@@ -96,7 +98,7 @@ Embedded System Analysis: Understanding the RP2350 Architecture w/ Comprehensive
#### Exercise 3: Examine All Vectors [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK03/WEEK03-03.md)
#### Exercise 4: Find Your Main Function [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK03/WEEK03-04.md)
#### Exercise 4: Find Your Main Function and Trace Back [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK03/WEEK03-04.md)
### Chapter 4: Embedded System Analysis
This chapter covers a comprehensive embedded system analysis reviewing parts of the RP2350 datasheet and helpful firmware analysis tools.
@@ -106,6 +108,8 @@ This chapter covers a comprehensive embedded system analysis reviewing parts of
## Week 4
Variables in Embedded Systems: Debugging and Hacking Variables w/ GPIO Output Basics
### Week 4 Slides [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK04/WEEK04-SLIDES.pdf)
### Week 4 Notebook [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK04/WEEK04.md)
#### Exercise 1: Analyze Variable Storage in Ghidra [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK04/WEEK04-01.md)
@@ -149,6 +153,8 @@ This chapter covers hacking uninitialized variables as well as an intro to GPIO
## Week 5
Integers and Floats in Embedded Systems: Debugging and Hacking Integers and Floats w/ Intermediate GPIO Output Assembler Analysis
### Week 5 Slides [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK05/WEEK05-SLIDES.pdf)
### Week 5 Notebook [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK05/WEEK05.md)
#### Exercise 1: Analyze the Float Binary in Ghidra [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK05/WEEK05-01.md)
@@ -207,6 +213,8 @@ This chapter covers hacking the double floating-point data type as it relates to
## Week 6
Static Variables in Embedded Systems: Debugging and Hacking Static Variables w/ GPIO Input Basics
### Week 6 Slides [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK06/WEEK06-SLIDES.pdf)
### Week 6 Notebook [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK06/WEEK06.md)
#### Exercise 1: Change the Static Variable Initial Value from 42 to 100 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK06/WEEK06-01.md)
@@ -235,6 +243,8 @@ This chapter covers hacking static variables as well as an intro to GPIO inputs
## Week 7
Constants in Embedded Systems: Debugging and Hacking Constants w/ 1602 LCD I2C Basics
### Week 7 Slides [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK07/WEEK07-SLIDES.pdf)
### Week 7 Notebook [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK07/WEEK07.md)
#### Exercise 1: Change Both LCD Lines [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK07/WEEK07-01.md)
@@ -258,13 +268,25 @@ This chapter covers debugging constants as well as an intro to I2C as we work a
### Chapter 25: Hacking Constants
This chapter covers hacking constants as well as an intro to I2C as we work a 1602 LCD as it relates to embedded development on the Pico 2.
-> Click [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/Embedded-Hacking.pdf) to read the FREE pdf book.
## Week 8
### Midterm Exam
## Week 9
Operators in Embedded Systems: Debugging and Hacking Operators w/ DHT11 Temperature & Humidity Sensor Single-Wire Protocol Basics.
Operators in Embedded Systems: Debugging and Hacking Operators w/ DHT11 Temperature & Humidity Sensor Single-Wire Protocol Basics
-> Click [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/Embedded-Hacking.pdf) to read the FREE pdf book.
### Week 9 Slides [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK09/WEEK09-SLIDES.pdf)
### Week 9 Notebook [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK09/WEEK09.md)
#### Exercise 1: Change the Sleep Duration [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK09/WEEK09-01.md)
#### Exercise 2: Invert the Temperature Reading [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK09/WEEK09-02.md)
#### Exercise 3: Add a Fixed Temperature Offset [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK09/WEEK09-03.md)
#### Exercise 4: Find All printf Format Strings [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK09/WEEK09-04.md)
### Chapter 26: Operators
This chapter covers operators as well as an intro to single-wire protocol as we work a DHT11 temperature and humidity sensor as it relates to embedded development on the Pico 2.
@@ -282,7 +304,19 @@ This chapter covers hacking operators as well as an intro to single-wire protoco
-> Click [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/Embedded-Hacking.pdf) to read the FREE pdf book.
## Week 10
Conditionals in Embedded Systems: Debugging and Hacking Conditionals w/ SG90 Servo Motor PWM Basics
Conditionals in Embedded Systems: Debugging and Hacking Static & Dynamic Conditionals w/ SG90 Servo Motor PWM Basics
### Week 10 Slides [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK10/WEEK10-SLIDES.pdf)
### Week 10 Notebook [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK10/WEEK10.md)
#### Exercise 1: Change Servo Angle Range [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK10/WEEK10-01.md)
#### Exercise 2: Add a Third Command [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK10/WEEK10-02.md)
#### Exercise 3: Reverse the Servo Direction [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK10/WEEK10-03.md)
#### Exercise 4: Speed Profile [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK10/WEEK10-04.md)
### Chapter 29: Static Conditionals
This chapter covers static conditionals as well as an intro to PWM as we work a SG90 servo motor as it relates to embedded development on the Pico 2.
@@ -315,7 +349,19 @@ This chapter covers hacking dynamic conditionals as well as additional PWM examp
-> Click [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/Embedded-Hacking.pdf) to read the FREE pdf book.
## Week 11
Functions in Embedded Systems: Debugging and Hacking Structs & Functions w/ Infrared Receiver & Transmitter Basics and the Final Project Intro.
Structures and Functions in Embedded Systems: Debugging and Hacking w/ IR Remote Control and NEC Protocol Basics
### Week 11 Slides [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK11/WEEK11-SLIDES.pdf)
### Week 11 Notebook [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK11/WEEK11.md)
#### Exercise 1: Add a Fourth LED [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK11/WEEK11-01.md)
#### Exercise 2: Change Blink Count [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK11/WEEK11-02.md)
#### Exercise 3: Swap All Three LEDs [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK11/WEEK11-03.md)
#### Exercise 4: Change Blink Speed [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK11/WEEK11-04.md)
### Chapter 35: Structures
This chapter covers structures as well as an intro to infrared basics as we work a infrared receiver and infrared remote controller as it relates to embedded development on the Pico 2.
+10 -10
View File
@@ -1,4 +1,4 @@
# Embedded Systems Reverse Engineering
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 1
@@ -99,7 +99,7 @@ Based on what you found:
- Is each character one byte or more? __________
- What does `\r` and `\n` represent? (Hint: `\r` = carriage return, `\n` = newline)
## Expected Output
#### Expected Output
You should be able to fill in a summary like:
@@ -112,40 +112,40 @@ Referenced by: [Function names]
Used in: [How the program uses it]
```
## Deeper Exploration (Optional Challenge)
#### Deeper Exploration (Optional Challenge)
### Challenge 1: Follow the String Usage
##### Challenge 1: Follow the String Usage
1. From the cross-references you found, click on the instruction that uses the string
2. You should navigate to the `ldr` (load) instruction that loads the string's address into register `r0`
3. This is how the `printf` function gets the pointer to the string!
### Challenge 2: Find Other Strings
##### Challenge 2: Find Other Strings
1. Go back to the Defined Strings window
2. Look for other strings in the binary
3. Are there any other text strings besides "hello, world"?
4. If yes, where are they and what are they used for?
### Challenge 3: Understand Little-Endian
##### Challenge 3: Understand Little-Endian
1. When Ghidra shows the string address in the `ldr` instruction, it's showing a number
2. Look at the raw bytes of that address value
3. Notice how the bytes are stored in "backwards" order? That's little-endian!
4. Can you convert the hex bytes to the actual address?
## Questions for Reflection
#### Questions for Reflection
1. **Why is the string stored in Flash memory?** Why not in RAM?
2. **How does `printf()` know where to find the string?** (Hint: The address is loaded into `r0`)
3. **What would happen if we didn't have the `\r\n` at the end?** How would the output look?
4. **Could we modify this string at runtime?** Why or why not?
## Tips and Hints
#### Tips and Hints
- Strings in compiled binaries are often stored in read-only memory (Flash) to save RAM
- The `\r` and `\n` characters are special: they're single bytes (0x0D and 0x0A in hex)
- When you see a string in Ghidra's listing, the ASCII representation is shown on the right side
- You can scroll left/right in the Listing view to see different representations (hex, ASCII, disassembly)
## Real-World Application
#### Real-World Application
Understanding where strings are stored is crucial for:
- **Firmware modification**: Finding text messages to modify
@@ -153,7 +153,7 @@ Understanding where strings are stored is crucial for:
- **Vulnerability analysis**: Finding format string bugs or hardcoded credentials
- **Localization**: Finding where text needs to be translated
## Summary
#### Summary
By completing this exercise, you've learned:
1. How to find strings in a binary using Ghidra's Defined Strings window
+13 -13
View File
@@ -1,4 +1,4 @@
# Embedded Systems Reverse Engineering
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 1
@@ -31,7 +31,7 @@ A **cross-reference** is a link between different parts of the code:
In this exercise, we're tracking **code → data** references to understand where and how the program uses the "hello, world" string.
## Step-by-Step Instructions
#### Step-by-Step Instructions
##### Step 1: Navigate to the main Function
@@ -94,13 +94,13 @@ This means:
- What is the address of the data reference you found? (e.g., `DAT_10000244`)
- __________
#### Question 2: Referenced By
###### Question 2: Referenced By
- How many places reference this data?
- __________
- Which function(s) use it?
- __________
#### Question 3: Reference Type
###### Question 3: Reference Type
- Is it a read or write operation?
- __________
- Why? (What's the program doing with this data?)
@@ -119,9 +119,9 @@ This means:
- Then a function (probably `printf` or `puts`) is called with `r0` as the argument
- Can you trace this complete flow?
## Deeper Analysis (Optional Challenge)
#### Deeper Analysis (Optional Challenge)
### Challenge 1: Find the Actual String Address
##### Challenge 1: Find the Actual String Address
1. Navigate to the `DAT_10000244` location
2. Look at the value stored there
3. Can you decode the hex bytes and find the actual address of "hello, world"?
@@ -131,7 +131,7 @@ This means:
If you see bytes: `CC 19 00 10`
Read backwards: `10 00 19 CC` = `0x100019CC`
### Challenge 2: Understand the Indirection
##### Challenge 2: Understand the Indirection
1. In C, if we want to load an address, we do: `char *ptr = &some_string;`
2. Then to use it: `printf(ptr);`
3. In assembly, this becomes:
@@ -139,12 +139,12 @@ Read backwards: `10 00 19 CC` = `0x100019CC`
- Call the function: `bl printf`
4. Can you see this pattern in the assembly?
### Challenge 3: Follow Multiple References
##### Challenge 3: Follow Multiple References
1. Try this with different data items in the binary
2. Find a data reference that has **multiple** cross-references
3. What data is used in more than one place?
## Questions for Reflection
#### Questions for Reflection
1. **Why does the code need to load an address from memory?**
- Why can't it just use the address directly?
@@ -164,14 +164,14 @@ Read backwards: `10 00 19 CC` = `0x100019CC`
- Data section (constants/strings)
- Is everything at different addresses for a reason?
## Tips and Hints
#### Tips and Hints
- If you right-click and don't see "References", try right-clicking directly on the instruction address instead
- You can also use **Search → For Cross References** from the menu for a more advanced search
- In the Decompile view (right side), cross-references may be shown in a different format or with different colors
- Multi-level references: You can right-click on a data item and then follow the chain to another data item
## Real-World Applications
#### Real-World Applications
Understanding cross-references is crucial for:
- **Vulnerability hunting**: Finding where user input flows through the code
@@ -179,7 +179,7 @@ Understanding cross-references is crucial for:
- **Malware analysis**: Tracking command-and-control server addresses or encryption keys
- **Reverse engineering**: Understanding program logic by following data dependencies
## Summary
#### Summary
By completing this exercise, you've learned:
1. How to find and interpret cross-references in Ghidra
@@ -188,7 +188,7 @@ By completing this exercise, you've learned:
4. The relationship between high-level C code and assembly-level data flow
5. How addresses are indirectly referenced in position-independent code
## Expected Final Understanding
#### Expected Final Understanding
You should now understand this flow:
```
+18 -18
View File
@@ -1,4 +1,4 @@
# Embedded Systems Reverse Engineering
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 1
@@ -33,7 +33,7 @@ Before you start, make sure:
- You have **GDB** (specifically `arm-none-eabi-gdb`) installed
- Your binary file (`0x0001_hello-world.elf`) is available in the `build/` directory
## Step-by-Step Instructions
#### Step-by-Step Instructions
##### Step 1: Start OpenOCD in Terminal 1
@@ -64,12 +64,12 @@ Info : accepting 'gdb' connection on tcp/3333
Open a **second terminal window** and navigate to your project directory:
```
arm-none-eabi-gdb -q build/0x0001_hello-world.elf
arm-none-eabi-gdb build\0x0001_hello-world.elf
```
**Expected Output:**
```
Reading symbols from build/0x0001_hello-world.elf...
Reading symbols from build\0x0001_hello-world.elf...
(gdb)
```
@@ -257,37 +257,37 @@ Based on what you've observed:
- Are they the same?
- __________
## Deeper Exploration (Optional Challenge)
#### Deeper Exploration (Optional Challenge)
### Challenge 1: Step Through stdio_init_all
##### Challenge 1: Step Through stdio_init_all
1. Continue stepping: `si` (step into) or `ni` (next instruction)
2. Eventually, you'll reach `bl 0x1000156c <stdio_init_all>`
3. Use `si` to step **into** that function
4. What instructions do you see?
5. What registers are being modified?
### Challenge 2: View Specific Registers
##### Challenge 2: View Specific Registers
Instead of viewing all registers, you can view just a few:
```gdb
i r pc sp lr r0 r1 r2
```
This shows only the registers you care about.
### Challenge 3: Examine Memory
##### Challenge 3: Examine Memory
To examine memory at a specific address (e.g., where the string is):
```gdb
x/16b 0x100019cc
```
This displays 16 bytes (`b` = byte) starting at address `0x100019cc`. Can you see the "hello, world" string?
### Challenge 4: Set a Conditional Breakpoint
##### Challenge 4: Set a Conditional Breakpoint
Set a breakpoint that only triggers after a certain condition:
```gdb
b *0x1000023a if $r0 != 0
```
This is useful when you want to break on a condition rather than every time.
## Questions for Reflection
#### Questions for Reflection
1. **Why does GDB show both the C source line AND the assembly?**
- This is because the .elf file contains debug symbols
@@ -304,7 +304,7 @@ This is useful when you want to break on a condition rather than every time.
- `si` steps into function calls
- `ni` executes entire functions without stopping inside them
## Important GDB Commands Reference
#### Important GDB Commands Reference
| Command | Short Form | What It Does |
| ---------------------- | ---------- | ------------------------------------ |
@@ -324,30 +324,30 @@ This is useful when you want to break on a condition rather than every time.
- `x/16b 0x20000000` - examine 16 bytes starting at RAM address
- `x/4w 0x10000000` - examine 4 words (4-byte values) starting at Flash address
## Troubleshooting
#### Troubleshooting
### Problem: "OpenOCD not found"
##### Problem: "OpenOCD not found"
**Solution:** Make sure OpenOCD is in your PATH or use the full path to the executable
### Problem: "Target not responding"
##### Problem: "Target not responding"
**Solution:**
- Check that your Pico 2 is properly connected
- Make sure OpenOCD is running and shows "accepting 'gdb' connection"
- Restart both OpenOCD and GDB
### Problem: "Cannot find breakpoint at main"
##### Problem: "Cannot find breakpoint at main"
**Solution:**
- Make sure you compiled with debug symbols
- The .elf file must include symbol information
- Try breaking at an address instead: `b *0x10000234`
### Problem: GDB shows "No source available"
##### Problem: GDB shows "No source available"
**Solution:**
- This happens with stripped binaries
- You can still see assembly with `disas`
- You can still examine memory and registers
## Summary
#### Summary
By completing this exercise, you've:
1. ✅ Set up OpenOCD as a debug server
@@ -363,7 +363,7 @@ You're now ready for Week 2, where you'll:
- Understand program flow in detail
- Use this knowledge to modify running code
## Next Steps
#### Next Steps
1. **Close GDB**: Type `quit` or `q` to exit
2. **Close OpenOCD**: Type `Ctrl+C` in the OpenOCD terminal
Binary file not shown.
+41 -44
View File
@@ -1,9 +1,6 @@
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
# Week 1: Introduction and Overview of Embedded Reverse Engineering: Ethics, Scoping, and Basic Concepts
## Week 1: Introduction and Overview of Embedded Reverse Engineering: Ethics, Scoping, and Basic Concepts
### 🎯 What You'll Learn This Week
## 🎯 What You'll Learn This Week
By the end of this week, you will be able to:
- Understand what a microcontroller is and how it works
@@ -16,17 +13,17 @@ By the end of this week, you will be able to:
---
### 📚 Part 1: Understanding the Basics
## 📚 Part 1: Understanding the Basics
#### What is a Microcontroller?
### What is a Microcontroller?
Think of a microcontroller as a tiny computer on a single chip. Just like your laptop has a processor, memory, and storage, a microcontroller has all of these packed into one small chip. The **RP2350** is the microcontroller chip that powers the **Raspberry Pi Pico 2**.
#### What is the ARM Cortex-M33?
### What is the ARM Cortex-M33?
The RP2350 has two "brains" inside it - we call these **cores**. One brain uses ARM Cortex-M33 instructions, and the other can use RISC-V instructions. In this course, we'll focus on the **ARM Cortex-M33** core because it's more commonly used in the industry.
#### 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:
- Understanding how things work
@@ -35,13 +32,13 @@ Reverse engineering is like being a detective for code. Instead of writing code
---
### 📚 Part 2: Understanding Processor Registers
## 📚 Part 2: Understanding Processor Registers
#### What is a Register?
### What is a Register?
A **register** is like a tiny, super-fast storage box inside the processor. The processor uses registers to hold numbers while it's doing calculations. Think of them like the short-term memory your brain uses when doing math in your head.
#### The ARM Cortex-M33 Registers
### The ARM Cortex-M33 Registers
The ARM Cortex-M33 has several important registers:
@@ -104,9 +101,9 @@ The Program Counter always points to the **next instruction** the processor will
---
### 📚 Part 3: Understanding Memory Layout
## 📚 Part 3: Understanding Memory Layout
#### XIP - Execute In Place
### XIP - Execute In Place
The RP2350 uses something called **XIP (Execute In Place)**. This means the processor can run code directly from the flash memory (where your program is stored) without copying it to RAM first.
@@ -114,7 +111,7 @@ The RP2350 uses something called **XIP (Execute In Place)**. This means the proc
This is where your program code starts in flash memory. Remember this address - we'll use it a lot!
#### Memory Map Overview
### Memory Map Overview
```
┌─────────────────────────────────────┐
@@ -128,7 +125,7 @@ This is where your program code starts in flash memory. Remember this address -
└─────────────────────────────────────┘
```
#### Stack vs Heap
### Stack vs Heap
| Stack | Heap |
| ---------------------------------------- | ---------------------------------- |
@@ -140,7 +137,7 @@ This is where your program code starts in flash memory. Remember this address -
---
### 📚 Part 3.5: Reviewing Our Hello World Code
## 📚 Part 3.5: Reviewing Our Hello World Code
Before we start debugging, let's understand the code we'll be working with. Here's our `0x0001_hello-world.c` program:
@@ -156,7 +153,7 @@ int main(void) {
}
```
#### Breaking Down the Code
### Breaking Down the Code
##### The Includes
@@ -202,14 +199,14 @@ while (true)
>
> In embedded systems, we often use both carriage return (`\r`) and newline (`\n`) together. The `\r` moves the cursor back to the beginning of the line, and `\n` moves to the next line. This ensures proper display across different terminal programs.
#### What Happens When This Runs?
### What Happens When This Runs?
1. **Power on** - The Pico boots up and starts executing code from flash memory
2. **`stdio_init_all()`** - Sets up USB and/or UART for communication
3. **Infinite loop begins** - The program enters the `while(true)` loop
4. **Print forever** - "hello, world" is sent over and over as fast as possible
#### Why This Code is Perfect for Learning
### Why This Code is Perfect for Learning
This simple program is ideal for reverse engineering practice because:
- It has a clear, recognizable function call (`printf`)
@@ -219,7 +216,7 @@ This simple program is ideal for reverse engineering practice because:
When we debug this code, we'll be able to see how the C code translates to ARM assembly instructions!
#### Compiling and Flashing to the Pico 2
### Compiling and Flashing to the Pico 2
Now that we understand the code, let's get it running on our hardware:
@@ -252,9 +249,9 @@ Once flashed, your Pico 2 will immediately start executing the hello-world progr
---
### 📚 Part 4: Dynamic Analysis with GDB
## 📚 Part 4: Dynamic Analysis with GDB
#### Prerequisites
### Prerequisites
Before we start, make sure you have:
1. A Raspberry Pi Pico 2 board
@@ -262,11 +259,11 @@ Before we start, make sure you have:
3. OpenOCD or another debug probe connection
4. The sample "hello-world" binary loaded on your Pico 2
#### Connecting to Your Pico 2 with OpenOCD
### Connecting to Your Pico 2 with OpenOCD
Open a terminal and start OpenOCD:
```bash
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
@@ -274,22 +271,22 @@ openocd ^
-c "adapter speed 5000"
```
#### Connecting to Your Pico 2 with GDB
### Connecting to Your Pico 2 with GDB
Open another terminal and start GDB with your binary:
```bash
arm-none-eabi-gdb -q build/0x0001_hello-world.elf
```powershell
arm-none-eabi-gdb build\0x0001_hello-world.elf
```
Connect to your target:
```bash
```powershell
(gdb) target extended-remote localhost:3333
(gdb) monitor reset halt
```
#### Basic GDB Commands: Your First Steps
### Basic GDB Commands: Your First Steps
Now that we're connected, let's learn three essential GDB commands that you'll use constantly in embedded reverse engineering.
@@ -378,7 +375,7 @@ xpsr 0x69000000 1761607680
> 💡 **Tip:** You can also use `i r pc sp lr` to show only specific registers you care about.
#### Quick Reference: Essential GDB Commands
### Quick Reference: Essential GDB Commands
| Command | Short Form | What It Does |
| --------------------- | ---------- | ------------------------------------ |
@@ -397,9 +394,9 @@ xpsr 0x69000000 1761607680
---
### 🔬 Part 5: Static Analysis with Ghidra
## 🔬 Part 5: Static Analysis with Ghidra
#### Setting Up Your First Ghidra Project
### Setting Up Your First Ghidra Project
Before we dive into GDB debugging, let's set up Ghidra to analyze our hello-world binary. Ghidra is a powerful reverse engineering tool that will help us visualize the disassembly and decompiled code.
@@ -435,7 +432,7 @@ When prompted, click **Yes** to auto-analyze the binary. Accept the default anal
Ghidra will now process the binary, identifying functions, strings, and cross-references. This may take a moment.
#### Reviewing the Main Function in Ghidra
### Reviewing the Main Function in Ghidra
Once analysis is complete, let's find our `main` function:
@@ -502,9 +499,9 @@ In future weeks, we'll work with `.bin` files that have been stripped of symbols
---
### 📊 Part 6: Summary and Review
## 📊 Part 6: Summary and Review
#### What We Learned
### What We Learned
1. **Registers**: The ARM Cortex-M33 has 13 general-purpose registers (`r0`-`r12`), plus special registers for the stack pointer (`r13`/SP), link register (`r14`/LR), and program counter (`r15`/PC).
@@ -537,7 +534,7 @@ In future weeks, we'll work with `.bin` files that have been stripped of symbols
6. **Little-Endian**: The RP2350 stores multi-byte values with the least significant byte at the lowest address, making them appear "backwards" when viewed as a single value.
#### The Program Flow
### The Program Flow
```
┌─────────────────────────────────────────────────────┐
@@ -560,27 +557,27 @@ In future weeks, we'll work with `.bin` files that have been stripped of symbols
---
### ✅ Practice Exercises
## ✅ Practice Exercises
Try these on your own to reinforce what you learned:
#### Exercise 1: Explore in Ghidra
### Exercise 1: Explore in Ghidra
1. Open your `0x0001_hello-world` project in Ghidra
2. Find the `stdio_init_all` function in the Symbol Tree
3. Look at its decompiled code - can you understand what it's setting up?
#### Exercise 2: Find Strings in Ghidra
### Exercise 2: Find Strings in Ghidra
1. In Ghidra, go to **Window → Defined Strings**
2. Look for `"hello, world"` - what address is it at?
3. Double-click to navigate to it in the listing
#### Exercise 3: Cross-References
### Exercise 3: Cross-References
1. In Ghidra, navigate to the `main` function
2. Find the `ldr r0, [DAT_...]` instruction that loads the string
3. Right-click on `DAT_10000244` and select **References → Show References to**
4. This shows you where this data is used!
#### Exercise 4: Connect GDB (Preparation for Week 2)
### Exercise 4: Connect GDB (Preparation for Week 2)
1. Start OpenOCD and connect GDB as shown in Part 4
2. Set a breakpoint at main: `b main`
3. Continue: `c`
@@ -591,7 +588,7 @@ Try these on your own to reinforce what you learned:
---
### 🎓 Key Takeaways
## 🎓 Key Takeaways
1. **Reverse engineering combines static and dynamic analysis** - we look at the code (static with Ghidra) and run it to see what happens (dynamic with GDB).
@@ -605,7 +602,7 @@ Try these on your own to reinforce what you learned:
---
### 📖 Glossary
## 📖 Glossary
| Term | Definition |
| ------------------- | --------------------------------------------------------- |
BIN
View File
Binary file not shown.
+5 -5
View File
@@ -1,4 +1,4 @@
# Embedded Systems Reverse Engineering
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 2
@@ -13,7 +13,7 @@ Write your own message into SRAM and redirect `r0` so the running program prints
- Raspberry Pi Pico 2 with debug probe connected
- OpenOCD and `arm-none-eabi-gdb` available in your PATH
- Serial monitor (PuTTY/minicom/screen) set to 115200 baud
- `build/0x0001_hello-world.elf` present and flashed to the board
- `build\0x0001_hello-world.elf` present and flashed to the board
- Week 2 setup steps (0a0e) completed: OpenOCD, serial monitor, and GDB ready
#### Task Description
@@ -23,7 +23,7 @@ You will create a custom string in SRAM at `0x20000000`, point `r0` at it just b
##### Step 1: Start OpenOCD
```bash
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
@@ -36,8 +36,8 @@ openocd ^
##### Step 3: Launch GDB
```bash
arm-none-eabi-gdb build/0x0001_hello-world.elf
```powershell
arm-none-eabi-gdb build\0x0001_hello-world.elf
```
##### Step 4: Connect and Halt
+3 -3
View File
@@ -1,4 +1,4 @@
# Embedded Systems Reverse Engineering
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 2
@@ -12,7 +12,7 @@ Practice writing to an alternate SRAM location and redirecting `r0` so your mess
#### Prerequisites
- Raspberry Pi Pico 2 with debug probe connected
- OpenOCD, `arm-none-eabi-gdb`, and a serial monitor ready (Week 2 steps 0a0e complete)
- `build/0x0001_hello-world.elf` flashed and running
- `build\0x0001_hello-world.elf` flashed and running
- Comfortable setting breakpoints at `0x1000023c`
#### Task Description
@@ -22,7 +22,7 @@ You will inject a short string into `0x20001000`, point `r0` there, and verify t
##### Step 1: Start OpenOCD
```bash
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
+2 -2
View File
@@ -1,4 +1,4 @@
# Embedded Systems Reverse Engineering
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 2
@@ -11,7 +11,7 @@ Inspect the byte-level layout of your injected string in SRAM and correlate byte
#### Prerequisites
- Pico 2 connected with OpenOCD, GDB, and a serial monitor ready
- `build/0x0001_hello-world.elf` flashed and running
- `build\0x0001_hello-world.elf` flashed and running
- Ability to break before `__wrap_puts` at `0x1000023c`
- A payload already written to SRAM (e.g., at `0x20000000` from Exercise 1)
+2 -2
View File
@@ -1,4 +1,4 @@
# Embedded Systems Reverse Engineering
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 2
@@ -11,7 +11,7 @@ Create a reusable GDB command that injects a string into SRAM, repoints `r0`, an
#### Prerequisites
- Pico 2 connected with OpenOCD, GDB, and serial monitor ready
- `build/0x0001_hello-world.elf` available
- `build\0x0001_hello-world.elf` available
- Familiarity with breaking at `0x1000023c` and injecting strings from prior exercises
#### Task Description
Binary file not shown.
+32 -36
View File
@@ -1,10 +1,6 @@
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
# 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
### 🎯 What You'll Learn This Week
## 🎯 What You'll Learn This Week
By the end of this tutorial, you will be able to:
- Connect to a live embedded system using OpenOCD and GDB
@@ -16,7 +12,7 @@ By the end of this tutorial, you will be able to:
- Hijack register values to redirect program behavior
- Modify a running program's output in real-time
### 🔄 Review from Week 1
## 🔄 Review from Week 1
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
- **Memory Layout** (Flash at `0x10000000`, RAM at `0x20000000`) - Critical for understanding where we can write
@@ -27,7 +23,7 @@ This week builds directly on Week 1 concepts. You should already be comfortable
---
### 📚 Part 1: Understanding Live Hacking
## 📚 Part 1: Understanding Live Hacking
#### What is Live Hacking?
@@ -56,7 +52,7 @@ The techniques you'll learn today are *exactly* how this would be done. Understa
---
### 📚 Part 2: Review - Memory Layout (from Week 1)
## 📚 Part 2: Review - Memory Layout (from Week 1)
> 🔄 **REVIEW:** In Week 1, we learned about the RP2350's memory layout. This knowledge is essential for our hack!
@@ -111,7 +107,7 @@ But SRAM (starting at `0x20000000`) is **read-write**! This is where we'll creat
---
### 📚 Part 3: The Attack Plan
## 📚 Part 3: The Attack Plan
Here's our step-by-step attack strategy:
@@ -136,7 +132,7 @@ Here's our step-by-step attack strategy:
---
### 📚 Part 4: Setting Up Your Environment
## 📚 Part 4: Setting Up Your Environment
#### Prerequisites
@@ -156,7 +152,7 @@ You will need **THREE** terminal windows:
---
### 🔬 Part 5: GDB Deep Dive - Exploring the Binary
## 🔬 Part 5: GDB Deep Dive - Exploring the Binary
Before we start hacking, let's use GDB to thoroughly understand our program. This hands-on tutorial will teach you to examine memory, step through code, and watch the stack in action.
@@ -168,7 +164,7 @@ OpenOCD is the bridge between your computer and the Pico 2's debug interface. It
**Open Terminal 1 and type:**
```bash
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
@@ -228,19 +224,19 @@ The program is running and printing `"hello, world"` in an infinite loop!
**Open Terminal 3** and start GDB with your binary:
```bash
arm-none-eabi-gdb build/0x0001_hello-world.elf
```powershell
arm-none-eabi-gdb build\0x0001_hello-world.elf
```
**What this command means:**
- `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
**You should see:**
```
GNU gdb (Arm GNU Toolchain 13.2) 13.2
Reading symbols from build/0x0001_hello-world.elf...
Reading symbols from build\0x0001_hello-world.elf...
(gdb)
```
@@ -744,7 +740,7 @@ There's our string! The `\r` is a carriage return character (part of `\r\n`).
---
### 🔬 Part 6: Starting the Debug Session for the Hack
## 🔬 Part 6: Starting the Debug Session for the Hack
##### Step 1: Start OpenOCD (Debug Server)
@@ -752,7 +748,7 @@ OpenOCD is the bridge between your computer and the Pico 2's debug interface. It
**Open Terminal 1 and type:**
```bash
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
@@ -812,19 +808,19 @@ The program is running and printing `"hello, world"` in an infinite loop!
**Open Terminal 3** and start GDB with your binary:
```bash
arm-none-eabi-gdb build/0x0001_hello-world.elf
```powershell
arm-none-eabi-gdb build\0x0001_hello-world.elf
```
**What this command means:**
- `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
**You should see:**
```
GNU gdb (Arm GNU Toolchain 13.2) 13.2
Reading symbols from build/0x0001_hello-world.elf...
Reading symbols from build\0x0001_hello-world.elf...
(gdb)
```
@@ -884,7 +880,7 @@ xPSR: 0xf9000000 pc: 0x00000088 msp: 0xf0000000
---
### 🔬 Part 7: Analyzing the Target
## 🔬 Part 7: Analyzing the Target
> 🔄 **REVIEW:** We're using the same GDB commands we learned earlier. The `x` command examines memory, and `/5i` shows 5 instructions.
@@ -949,7 +945,7 @@ If we can change what `r0` points to, we can make it print **anything we want**!
---
### 🔬 Part 8: Setting the Trap
## 🔬 Part 8: Setting the Trap
> 🔄 **REVIEW:** In Week 1, we used `b main` and `b *0x10000234` to set breakpoints. Now we'll use the same technique at a more strategic location!
@@ -1035,7 +1031,7 @@ Dump of assembler code for function main:
---
### 🔬 Part 9: Examining the Current State
## 🔬 Part 9: Examining the Current State
> 🔄 **REVIEW:** In Week 1, we used `x/s $r0` to view the "hello, world" string. We also learned about **little-endian** byte ordering - remember how `0x6c6c6568` spelled "lleh" backwards?
@@ -1066,7 +1062,7 @@ There it is! The register `r0` contains `0x100019cc`, which is the address of ou
---
### 🔬 Part 10: The Failed Hack Attempt (Learning Why)
## 🔬 Part 10: The Failed Hack Attempt (Learning Why)
##### Step 11: Try to Directly Change the String (This Will Fail!)
@@ -1114,7 +1110,7 @@ The original string is still there. Our hack attempt failed... but we're not giv
---
### 🔬 Part 11: The Real Hack - Writing to SRAM
## 🔬 Part 11: The Real Hack - Writing to SRAM
##### Step 12: Understanding the Solution
@@ -1184,7 +1180,7 @@ GDB shows it's at the `ram_vector_table` location - that's just a label from the
---
### 🔬 Part 12: Hijacking the Register
## 🔬 Part 12: Hijacking the Register
> 🔄 **REVIEW:** In Week 1, we learned that `r0` holds the first argument to a function. When `puts()` is called, it expects `r0` to contain a pointer to the string it should print. By changing `r0`, we change what gets printed!
@@ -1239,7 +1235,7 @@ The value `0x68` is the ASCII code for 'h' - the first character of "hacky"!
---
### 🔬 Part 13: Executing the Hack
## 🔬 Part 13: Executing the Hack
##### Step 17: Continue Execution
@@ -1282,7 +1278,7 @@ You just modified a running program on real hardware! The processor executed cod
---
### 🔬 Part 14: Static Analysis with Ghidra - Understanding the Hack
## 🔬 Part 14: Static Analysis with Ghidra - Understanding the Hack
Now that we've performed the hack dynamically with GDB, let's use Ghidra to understand the same concepts through static analysis. This shows how you could plan such an attack without even connecting to the hardware!
@@ -1542,7 +1538,7 @@ This step helps you understand the mechanics of modifying binary data. Once you'
---
### 📊 Part 15: Summary and Review
## 📊 Part 15: Summary and Review
#### What We Accomplished
@@ -1613,7 +1609,7 @@ AFTER OUR HACK:
---
### ✅ Practice Exercises
## ✅ Practice Exercises
#### Exercise 1: Change the Message
Try creating a different message! Write your name to SRAM and make the program print it:
@@ -1658,7 +1654,7 @@ Now you can just type `hack` each time!
---
### 🎓 Key Takeaways
## 🎓 Key Takeaways
#### Building on Week 1
@@ -1682,7 +1678,7 @@ Now you can just type `hack` each time!
---
### 🔐 Security Implications
## 🔐 Security Implications
#### How Would This Work in the Real World?
@@ -1705,7 +1701,7 @@ Imagine an attacker with physical access to an industrial control system:
---
### 📖 Glossary
## 📖 Glossary
#### New Terms This Week
BIN
View File
Binary file not shown.
+5 -5
View File
@@ -1,4 +1,4 @@
# Embedded Systems Reverse Engineering
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 3
@@ -12,7 +12,7 @@ Single-step through the first 10 instructions of the reset handler to understand
#### Prerequisites
- Raspberry Pi Pico 2 with debug probe connected
- OpenOCD and `arm-none-eabi-gdb` available in your PATH
- `build/0x0001_hello-world.elf` present and flashed to the board
- `build\0x0001_hello-world.elf` present and flashed to the board
- Week 3 environment setup completed (OpenOCD running, GDB connected)
#### Task Description
@@ -22,7 +22,7 @@ You will set a breakpoint at the reset handler (`0x1000015c`), trigger a reset,
##### Step 1: Start OpenOCD
```bash
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
@@ -32,8 +32,8 @@ openocd ^
##### Step 2: Launch GDB
```bash
arm-none-eabi-gdb build/0x0001_hello-world.elf
```powershell
arm-none-eabi-gdb build\0x0001_hello-world.elf
```
##### Step 3: Connect to Target
+2 -2
View File
@@ -1,4 +1,4 @@
# Embedded Systems Reverse Engineering
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 3
@@ -12,7 +12,7 @@ Calculate the size of the stack by examining the vector table, understanding the
#### Prerequisites
- Raspberry Pi Pico 2 with debug probe connected
- OpenOCD and `arm-none-eabi-gdb` available
- `build/0x0001_hello-world.elf` flashed to the board
- `build\0x0001_hello-world.elf` flashed to the board
- Understanding of memory regions from Week 3 Part 5 (Linker Script)
#### Task Description
+2 -2
View File
@@ -1,4 +1,4 @@
# Embedded Systems Reverse Engineering
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 3
@@ -12,7 +12,7 @@ Examine the first 16 entries of the vector table to understand the exception han
#### Prerequisites
- Raspberry Pi Pico 2 with debug probe connected
- OpenOCD and `arm-none-eabi-gdb` available
- `build/0x0001_hello-world.elf` loaded
- `build\0x0001_hello-world.elf` loaded
- Understanding of the vector table from Week 3 Part 4
- Knowledge of Thumb mode addressing (LSB = 1 indicates Thumb code)
+2 -2
View File
@@ -1,4 +1,4 @@
# Embedded Systems Reverse Engineering
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 3
@@ -12,7 +12,7 @@ Locate the `main()` function, examine its first instructions, identify the first
#### Prerequisites
- Raspberry Pi Pico 2 with debug probe connected
- OpenOCD and `arm-none-eabi-gdb` available
- `build/0x0001_hello-world.elf` loaded
- `build\0x0001_hello-world.elf` loaded
- Understanding of function calls and the link register (LR) from previous weeks
#### Task Description
Binary file not shown.
+9 -13
View File
@@ -1,10 +1,6 @@
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
# 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
### 🎯 What You'll Learn This Week
## 🎯 What You'll Learn This Week
By the end of this tutorial, you will be able to:
- Understand how the RP2350 boots from the on-chip bootrom
@@ -16,7 +12,7 @@ By the end of this tutorial, you will be able to:
- Use Ghidra to statically analyze the boot sequence
- Understand the difference between Thumb mode addressing and actual addresses
### 🔄 Review from Weeks 1-2
## 🔄 Review from Weeks 1-2
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
- **Memory Layout** (Flash at `0x10000000`, RAM at `0x20000000`) - Understanding where code and data live
@@ -314,7 +310,7 @@ Before we start, make sure you have:
**Terminal 1 - Start OpenOCD:**
```bash
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
@@ -324,8 +320,8 @@ openocd ^
**Terminal 2 - Start GDB:**
```bash
arm-none-eabi-gdb build/0x0001_hello-world.elf
```powershell
arm-none-eabi-gdb build\0x0001_hello-world.elf
```
**Connect to target:**
@@ -833,7 +829,7 @@ That's not real code - it's the magic number `0xffffded3` being misinterpreted!
---
## Part 15: Static Analysis with Ghidra - Examining the Boot Sequence
## 🔬 Part 15: Static Analysis with Ghidra - Examining the Boot Sequence
> 🔄 **REVIEW:** In Week 1, we set up a Ghidra project and analyzed our hello-world binary. Now we'll use Ghidra to understand the boot sequence from a static analysis perspective!
@@ -1183,7 +1179,7 @@ Ghidra can visualize the call flow:
---
## Security Implications
## 🔐 Security Implications
### How Boot Sequence Knowledge Applies to Security
@@ -1306,7 +1302,7 @@ Understanding how an attacker would analyze and exploit the boot sequence is ess
---
## 📖 Glossary
## 📖 Glossary
### New Terms This Week
BIN
View File
Binary file not shown.
+3 -3
View File
@@ -1,4 +1,4 @@
# Embedded Systems Reverse Engineering
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 4
@@ -22,7 +22,7 @@ You will import the binary into Ghidra, configure it for ARM Cortex-M33, analyze
##### Step 1: Start Ghidra and Create New Project
```bash
```powershell
ghidraRun
```
@@ -36,7 +36,7 @@ ghidraRun
##### Step 2: Import the Binary
1. Navigate to your file explorer
2. Find `Embedded-Hacking/0x0005_intro-to-variables/build/0x0005_intro-to-variables.bin`
2. Find `Embedded-Hacking\0x0005_intro-to-variables\build\0x0005_intro-to-variables.bin`
3. **Drag and drop** the `.bin` file into Ghidra's project window
##### Step 3: Configure Import Settings
+1 -1
View File
@@ -107,7 +107,7 @@ Now we need to save the modified binary:
1. Click **File** → **Export Program**
2. Set **Format** to: **Binary**
3. Navigate to your build directory:
- `Embedded-Hacking/0x0005_intro-to-variables/build/`
- `Embedded-Hacking\0x0005_intro-to-variables\build\`
4. Set **Filename** to: `0x0005_intro-to-variables-h.bin`
- The `-h` suffix means "hacked"
5. Click **OK**
+1 -1
View File
@@ -235,7 +235,7 @@ Perfect! All changes are reflected.
1. Click **File** → **Export Program**
2. Set Format: **Binary**
3. Navigate to: `Embedded-Hacking/0x0008_uninitialized-variables/build/`
3. Navigate to: `Embedded-Hacking\0x0008_uninitialized-variables\build\`
4. Filename: `0x0008_uninitialized-variables-h.bin`
5. Click **OK**
Binary file not shown.
+11 -15
View File
@@ -1,10 +1,6 @@
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
# 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
### 🎯 What You'll Learn This Week
## 🎯 What You'll Learn This Week
By the end of this tutorial, you will be able to:
- Understand what variables are and how they're stored in memory
@@ -281,7 +277,7 @@ The program is printing `43` because that's what we assigned after the initial `
**Open a terminal and type:**
```bash
```powershell
ghidraRun
```
@@ -479,21 +475,21 @@ The Pico 2 expects UF2 files, not raw BIN files. We need to convert it!
**Open a terminal and navigate to your project directory:**
```bash
cd Embedded-Hacking/0x0005_intro-to-variables
```powershell
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0005_intro-to-variables
```
**Run the conversion command:**
```bash
python ../uf2conv.py build/0x0005_intro-to-variables-h.bin --base 0x10000000 --family 0xe48bff59 --output build/hacked.uf2
```powershell
python ..\uf2conv.py build\0x0005_intro-to-variables-h.bin --base 0x10000000 --family 0xe48bff59 --output build\hacked.uf2
```
**What this command means:**
- `uf2conv.py` = the conversion script
- `--base 0x10000000` = the XIP base address
- `--family 0xe48bff59` = the RP2350 family ID
- `--output build/hacked.uf2` = the output filename
- `--output build\hacked.uf2` = the output filename
### Step 20: Flash the Hacked Binary
@@ -688,9 +684,9 @@ Let's also change the printed value from `0` to `0x42` (66 in decimal):
### Step 31: Convert to UF2
```bash
cd Embedded-Hacking/0x0008_uninitialized-variables
python ../uf2conv.py build/0x0008_uninitialized-variables-h.bin --base 0x10000000 --family 0xe48bff59 --output build/hacked.uf2
```powershell
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0008_uninitialized-variables
python ..\uf2conv.py build\0x0008_uninitialized-variables-h.bin --base 0x10000000 --family 0xe48bff59 --output build\hacked.uf2
```
### Step 32: Flash and Verify
+3 -3
View File
@@ -1,4 +1,4 @@
# Embedded Systems Reverse Engineering
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 5
@@ -22,7 +22,7 @@ You will import the float binary into Ghidra, configure it for ARM Cortex-M33, r
##### Step 1: Start Ghidra and Create New Project
```bash
```powershell
ghidraRun
```
@@ -36,7 +36,7 @@ ghidraRun
##### Step 2: Import the Binary
1. Navigate to your file explorer
2. Find `Embedded-Hacking/0x000e_floating-point-data-type/build/0x000e_floating-point-data-type.bin`
2. Find `Embedded-Hacking\0x000e_floating-point-data-type\build\0x000e_floating-point-data-type.bin`
3. **Drag and drop** the `.bin` file into Ghidra's project window
##### Step 3: Configure Import Settings
Binary file not shown.
+13 -17
View File
@@ -1,10 +1,6 @@
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
# 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
### 🎯 What You'll Learn This Week
## 🎯 What You'll Learn This Week
By the end of this tutorial, you will be able to:
- Understand how integers and floating-point numbers are stored in memory
@@ -270,7 +266,7 @@ The program is printing `42.500000` because `printf` with `%f` defaults to 6 dec
**Open a terminal and type:**
```bash
```powershell
ghidraRun
```
@@ -689,14 +685,14 @@ This changes the high word from `0x40454000` (42.5 as double) to `0x4058C000` (9
**Open a terminal and navigate to your project directory:**
```bash
cd Embedded-Hacking-main\0x000e_floating-point-data-type
```powershell
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x000e_floating-point-data-type
```
**Run the conversion command:**
```bash
python ../uf2conv.py build/0x000e_floating-point-data-type-h.bin --base 0x10000000 --family 0xe48bff59 --output build/hacked.uf2
```powershell
python ..\uf2conv.py build\0x000e_floating-point-data-type-h.bin --base 0x10000000 --family 0xe48bff59 --output build\hacked.uf2
```
### Step 23: Flash the Hacked Binary
@@ -816,7 +812,7 @@ The program is printing `42.525250` because `printf` with `%lf` defaults to 6 de
**Open a terminal and type:**
```bash
```powershell
ghidraRun
```
@@ -1224,14 +1220,14 @@ This changes the full 64-bit double from `0x4045433B645A1CAC` (42.52525) to `0x4
**Open a terminal and navigate to your project directory:**
```bash
cd Embedded-Hacking-main\0x0011_double-floating-point-data-type
```powershell
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0011_double-floating-point-data-type
```
**Run the conversion command:**
```bash
python ../uf2conv.py build/0x0011_double-floating-point-data-type-h.bin --base 0x10000000 --family 0xe48bff59 --output build/hacked.uf2
```powershell
python ..\uf2conv.py build\0x0011_double-floating-point-data-type-h.bin --base 0x10000000 --family 0xe48bff59 --output build\hacked.uf2
```
### Step 23: Flash the Hacked Binary
@@ -1414,4 +1410,4 @@ The RP2350 GPIO coprocessor instructions:
**Remember:** Every binary you encounter in the real world can be analyzed and understood using these same techniques. Whether it's an integer, a float, or a double — it's all just bits waiting to be decoded. Practice makes perfect!
Happy hacking! 🔧
Happy hacking! 🔧
+4 -4
View File
@@ -1,4 +1,4 @@
# Embedded Systems Reverse Engineering
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 6
@@ -27,7 +27,7 @@ You will use GDB to examine the static variable at its known RAM address (`0x200
**Terminal 1 - Start OpenOCD:**
```bash
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
@@ -37,8 +37,8 @@ openocd ^
**Terminal 2 - Start GDB:**
```bash
arm-none-eabi-gdb build/0x0014_static-variables.elf
```powershell
arm-none-eabi-gdb build\0x0014_static-variables.elf
```
**Connect to target:**
+4 -4
View File
@@ -1,4 +1,4 @@
# Embedded Systems Reverse Engineering
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 6
@@ -25,7 +25,7 @@ You will use GDB to locate the `gpio_set_pulls` function (remember: `gpio_pull_u
**Terminal 1 - Start OpenOCD:**
```bash
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
@@ -35,8 +35,8 @@ openocd ^
**Terminal 2 - Start GDB:**
```bash
arm-none-eabi-gdb build/0x0014_static-variables.elf
```powershell
arm-none-eabi-gdb build\0x0014_static-variables.elf
```
**Connect to target:**
+4 -4
View File
@@ -1,4 +1,4 @@
# Embedded Systems Reverse Engineering
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 6
@@ -27,7 +27,7 @@ The static variable `static_fav_num` is a `uint8_t` that counts from 42 to 255 b
**Terminal 1 - Start OpenOCD:**
```bash
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
@@ -37,8 +37,8 @@ openocd ^
**Terminal 2 - Start GDB:**
```bash
arm-none-eabi-gdb build/0x0014_static-variables.elf
```powershell
arm-none-eabi-gdb build\0x0014_static-variables.elf
```
**Connect to target:**
+4 -4
View File
@@ -1,4 +1,4 @@
# Embedded Systems Reverse Engineering
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 6
@@ -26,7 +26,7 @@ The original program uses `gpio_put(LED_GPIO, !gpio_get(BUTTON_GPIO))` which the
**Terminal 1 - Start OpenOCD:**
```bash
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
@@ -36,8 +36,8 @@ openocd ^
**Terminal 2 - Start GDB:**
```bash
arm-none-eabi-gdb build/0x0014_static-variables.elf
```powershell
arm-none-eabi-gdb build\0x0014_static-variables.elf
```
**Connect to target:**
Binary file not shown.
+4 -4
View File
@@ -1,4 +1,4 @@
# 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
## 🎯 What You'll Learn This Week
@@ -430,7 +430,7 @@ This demonstrates unsigned integer overflow!
**Terminal 1 - Start OpenOCD:**
```bash
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
@@ -440,8 +440,8 @@ openocd ^
**Terminal 2 - Start GDB:**
```bash
arm-none-eabi-gdb build/0x0014_static-variables.elf
```powershell
arm-none-eabi-gdb build\0x0014_static-variables.elf
```
**Connect to target:**
+4 -4
View File
@@ -1,4 +1,4 @@
# Embedded Systems Reverse Engineering
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 7
@@ -26,7 +26,7 @@ The LCD currently displays "Reverse" on line 1 and "Engineering" on line 2. You
**Terminal 1 - Start OpenOCD:**
```bash
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
@@ -36,8 +36,8 @@ openocd ^
**Terminal 2 - Start GDB:**
```bash
arm-none-eabi-gdb build/0x0017_constants.elf
```powershell
arm-none-eabi-gdb build\0x0017_constants.elf
```
**Connect to target:**
+4 -4
View File
@@ -1,4 +1,4 @@
# Embedded Systems Reverse Engineering
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 7
@@ -24,7 +24,7 @@ Compiled binaries contain string literals in the `.rodata` section — format st
**Terminal 1 - Start OpenOCD:**
```bash
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
@@ -34,8 +34,8 @@ openocd ^
**Terminal 2 - Start GDB:**
```bash
arm-none-eabi-gdb build/0x0017_constants.elf
```powershell
arm-none-eabi-gdb build\0x0017_constants.elf
```
**Connect to target:**
+4 -4
View File
@@ -1,4 +1,4 @@
# Embedded Systems Reverse Engineering
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 7
@@ -24,7 +24,7 @@ The Pico SDK uses a chain of macros and structs to abstract hardware access. Whe
**Terminal 1 - Start OpenOCD:**
```bash
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
@@ -34,8 +34,8 @@ openocd ^
**Terminal 2 - Start GDB:**
```bash
arm-none-eabi-gdb build/0x0017_constants.elf
```powershell
arm-none-eabi-gdb build\0x0017_constants.elf
```
**Connect to target:**
Binary file not shown.
+4 -4
View File
@@ -1,4 +1,4 @@
# 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
## 🎯 What You'll Learn This Week
@@ -471,7 +471,7 @@ OTHER_FAV_NUM: 1337
**Terminal 1 - Start OpenOCD:**
```bash
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
@@ -481,8 +481,8 @@ openocd ^
**Terminal 2 - Start GDB:**
```bash
arm-none-eabi-gdb build/0x0017_constants.elf
```powershell
arm-none-eabi-gdb build\0x0017_constants.elf
```
**Connect to target:**
+141
View File
@@ -0,0 +1,141 @@
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 9
Operators in Embedded Systems: Debugging and Hacking Operators w/ DHT11 Temperature & Humidity Sensor Single-Wire Protocol Basics
### Exercise 1: Change the Sleep Duration
#### Objective
Find the `sleep_ms(2000)` call in the `0x001a_operators` binary using GDB, identify the immediate value `0x7d0` (2000) being loaded into `r0`, calculate the file offset, patch it to `0x1388` (5000) using a hex editor, and verify on hardware that the serial output now prints every 5 seconds instead of every 2 seconds.
#### Prerequisites
- Completed Week 9 tutorial (GDB and hex editor sections)
- `0x001a_operators.elf` and `0x001a_operators.bin` available in your build directory
- GDB (`arm-none-eabi-gdb`) and OpenOCD installed
- A hex editor (HxD, ImHex, or similar)
- Python installed (for UF2 conversion)
- Raspberry Pi Pico 2 with DHT11 sensor connected
#### Task Description
The program calls `sleep_ms(2000)` at the end of its main loop, causing a 2-second delay between each set of serial output. The value `2000` (`0x7D0`) is loaded into register `r0` before the `bl sleep_ms` call. You will locate this value in the disassembly, find the corresponding bytes in the `.bin` file, and patch them to `5000` (`0x1388`) so the loop runs every 5 seconds instead.
#### Step-by-Step Instructions
##### Step 1: Start the Debug Session
**Terminal 1 - Start OpenOCD:**
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
-f target/rp2350.cfg ^
-c "adapter speed 5000"
```
**Terminal 2 - Start GDB:**
```powershell
arm-none-eabi-gdb build\0x001a_operators.elf
```
**Connect to target:**
```gdb
(gdb) target remote :3333
(gdb) monitor reset halt
```
##### Step 2: Find the sleep_ms Call
Disassemble main and look for the `sleep_ms` call:
```gdb
(gdb) x/60i 0x10000234
```
Look for an instruction pattern like:
```
ldr r0, =0x7d0 ; 2000 milliseconds
bl sleep_ms
```
The value `0x7d0` will be loaded from the literal pool.
##### Step 3: Examine the Literal Pool Value
Once you find the `ldr r0, [pc, #offset]` instruction, examine the literal pool entry it references:
```gdb
(gdb) x/wx <literal_pool_address>
```
You should see `0x000007d0` (2000 in hex).
##### Step 4: Calculate the File Offset
```
file_offset = literal_pool_address - 0x10000000
```
Note the file offset of the 4-byte word containing `0x7d0`.
##### Step 5: Encode the New Value
The new value `5000` in hex is `0x1388`. In little-endian byte order:
| Value | Hex | Little-Endian Bytes |
| ----- | ---------- | ------------------- |
| 2000 | `0x000007D0` | `D0 07 00 00` |
| 5000 | `0x00001388` | `88 13 00 00` |
##### Step 6: Patch with HxD
1. In HxD, open `C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x001a_operators\build\0x001a_operators.bin`
2. Press **Ctrl+G** and enter the file offset you calculated
3. You should see: `D0 07 00 00`
4. Replace with: `88 13 00 00`
##### Step 7: Save and Convert
1. Click **File****Save As**`0x001a_operators-h.bin`
```powershell
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x001a_operators
python ..\uf2conv.py build\0x001a_operators-h.bin --base 0x10000000 --family 0xe48bff59 --output build\hacked.uf2
```
##### Step 8: Flash and Verify
1. Hold BOOTSEL and plug in your Pico 2
2. Drag and drop `hacked.uf2` onto the RPI-RP2 drive
**Check the serial monitor:**
- Output should now appear every **5 seconds** instead of every 2 seconds
- All operator values should remain unchanged (50, 5, 0, 0, 12, 11)
#### Expected Output
After completing this exercise, you should be able to:
- Locate literal pool values referenced by `ldr` instructions
- Understand little-endian byte ordering for 32-bit values
- Patch timing constants in embedded firmware
- Calculate file offsets from memory addresses
#### Questions for Reflection
###### Question 1: The value `2000` is stored in the literal pool as a 32-bit word, not as an immediate in the instruction. Why can't `2000` be encoded as an immediate in a single `movs` instruction?
###### Question 2: If you wanted to change the delay to exactly 1 second (1000ms = `0x3E8`), what bytes would you write in little-endian order?
###### Question 3: The literal pool value is shared — could other code in the binary also reference this same `0x7D0` value? How would you check?
###### Question 4: What would happen if you changed the sleep value to `0` (`00 00 00 00`)? Would the program crash or just run extremely fast?
#### Tips and Hints
- `movs` can only encode immediates 0-255; values larger than 255 must be loaded from the literal pool via `ldr`
- Always verify the bytes BEFORE patching — make sure you see `D0 07 00 00` at your calculated offset
- The literal pool is typically right after the function's `b.n` (loop branch) instruction
- Use a stopwatch or count "one-one-thousand" to verify the timing change
+136
View File
@@ -0,0 +1,136 @@
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 9
Operators in Embedded Systems: Debugging and Hacking Operators w/ DHT11 Temperature & Humidity Sensor Single-Wire Protocol Basics
### Exercise 2: Invert the Temperature Reading
#### Objective
Using GDB to locate the IEEE-754 scaling constant `0.1f` at file offset `0x42C`, patch it to `-0.1f` using a hex editor, and verify on hardware that the serial output now displays negative temperature values.
#### Prerequisites
- Completed Week 9 tutorial (GDB, Ghidra, and hex editor sections)
- `0x001a_operators.elf` and `0x001a_operators.bin` available in your build directory
- GDB (`arm-none-eabi-gdb`) and OpenOCD installed
- A hex editor (HxD, ImHex, or similar)
- Python installed (for UF2 conversion)
- Raspberry Pi Pico 2 with DHT11 sensor connected
#### Task Description
The DHT11 driver uses a scaling constant of `0.1f` stored at address `0x1000042C` (file offset `0x42C`) to convert raw sensor data into human-readable values. By changing this constant to `-0.1f`, you will invert the decimal component of the temperature calculation, causing the reported temperature to drop. This exercise teaches IEEE-754 float encoding and how a single 4-byte patch can dramatically change sensor behavior.
#### Step-by-Step Instructions
##### Step 1: Start the Debug Session
**Terminal 1 - Start OpenOCD:**
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
-f target/rp2350.cfg ^
-c "adapter speed 5000"
```
**Terminal 2 - Start GDB:**
```powershell
arm-none-eabi-gdb build\0x001a_operators.elf
```
**Connect to target:**
```gdb
(gdb) target remote :3333
(gdb) monitor reset halt
```
##### Step 2: Verify the Current Scaling Constant
Examine the float constant at the known address:
```gdb
(gdb) x/wx 0x1000042c
```
Output:
```
0x1000042c: 0x3dcccccd
```
This is `0.1f` in IEEE-754 encoding (approximately — the repeating binary fraction makes it `0x3dcccccd`).
##### Step 3: Understand the IEEE-754 Encoding
**Current value (0.1f):**
| Field | Bits | Value |
| -------- | ---------- | ----- |
| Sign | `0` | Positive |
| Exponent | `01111011` | 123 (biased) |
| Mantissa | `10011001100110011001101` | ~1.6 |
**New value (-0.1f):**
- Flip only the sign bit (bit 31) from `0` to `1`
- `0x3dcccccd``0xbdcccccd`
| Value | Hex | Little-Endian Bytes |
| ------ | ------------ | ------------------- |
| 0.1f | `0x3dcccccd` | `cd cc cc 3d` |
| -0.1f | `0xbdcccccd` | `cd cc cc bd` |
> 💡 **Key insight:** To negate an IEEE-754 float, you only need to flip the most significant bit. In little-endian, this is the **last** byte — change `3d` to `bd`.
##### Step 4: Patch with HxD
1. In HxD, open `C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x001a_operators\build\0x001a_operators.bin`
2. Press **Ctrl+G** and enter offset: `42C`
3. You should see: `cd cc cc 3d` (or `cc cc cc 3d`)
4. Replace with: `cd cc cc bd` (or `cc cc cc bd`)
> ⚠️ **Note:** The exact bytes may be `cc cc cc 3d` or `cd cc cc 3d` depending on compiler rounding. Just change the last byte from `3d` to `bd`.
##### Step 5: Save and Convert
1. Click **File****Save As**`0x001a_operators-h.bin`
```powershell
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x001a_operators
python ..\uf2conv.py build\0x001a_operators-h.bin --base 0x10000000 --family 0xe48bff59 --output build\hacked.uf2
```
##### Step 6: Flash and Verify
1. Hold BOOTSEL and plug in your Pico 2
2. Drag and drop `hacked.uf2` onto the RPI-RP2 drive
**Check the serial monitor:**
- All operator values remain unchanged (50, 5, 0, 0, 12, 11)
- Temperature should now display with an inverted decimal component
- Humidity will also be affected (same constant is shared)
#### Expected Output
After completing this exercise, you should be able to:
- Decode and encode IEEE-754 floating-point values
- Understand that flipping one bit (sign bit) negates a float
- Patch floating-point constants in compiled binaries
- Predict how a constant change propagates through calculations
#### Questions for Reflection
###### Question 1: Why does changing one byte (`3d``bd`) negate the entire float value? What does the sign bit (bit 31) control in IEEE-754?
###### Question 2: The scaling constant `0.1f` is used by BOTH the humidity and temperature `vfma.f32` instructions. Why does patching this single constant affect both readings?
###### Question 3: If you wanted to change the constant to `0.5f` (`0x3f000000`, little-endian `00 00 00 3f`) instead of `-0.1f`, how would the temperature reading change? If the raw decimal part is 8, what would the new output be?
###### Question 4: Could you achieve negative temperature by patching the `vfma.f32` instruction itself instead of the constant? What instruction might you replace it with?
#### Tips and Hints
- IEEE-754 sign bit is the MSB (bit 31) — `0` = positive, `1` = negative
- In little-endian, the sign bit is in the **last** (highest address) byte
- Use an online IEEE-754 converter to verify your understanding
- If the output looks completely wrong (NaN, inf), you may have changed the wrong byte — start over with a fresh copy of the `.bin` file
+152
View File
@@ -0,0 +1,152 @@
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 9
Operators in Embedded Systems: Debugging and Hacking Operators w/ DHT11 Temperature & Humidity Sensor Single-Wire Protocol Basics
### Exercise 3: Add a Fixed Temperature Offset
#### Objective
Patch both the `vfma.f32` instruction at file offset `0x414` and the scaling constant at `0x42C` to replace the multiply-add with a simple add of `10.0f`, causing every temperature reading to be increased by exactly 10°C, and verify on hardware.
#### Prerequisites
- Completed Week 9 tutorial and Exercise 2
- `0x001a_operators.elf` and `0x001a_operators.bin` available in your build directory
- GDB (`arm-none-eabi-gdb`) and OpenOCD installed
- A hex editor (HxD, ImHex, or similar)
- Python installed (for UF2 conversion)
- Raspberry Pi Pico 2 with DHT11 sensor connected
#### Task Description
The temperature calculation uses `vfma.f32 s15, s13, s11` which computes `s15 = s15 + (s13 × s11)` where `s11 = 0.1f`. You will make TWO patches: (1) change the `vfma.f32` instruction to `vadd.f32` so it performs addition instead of multiply-add, and (2) change the constant from `0.1f` to `10.0f`. The result: every temperature reading will have 10°C added to it. This exercise teaches ARM floating-point instruction encoding and multi-site patching.
#### Step-by-Step Instructions
##### Step 1: Start the Debug Session
**Terminal 1 - Start OpenOCD:**
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
-f target/rp2350.cfg ^
-c "adapter speed 5000"
```
**Terminal 2 - Start GDB:**
```powershell
arm-none-eabi-gdb build\0x001a_operators.elf
```
**Connect to target:**
```gdb
(gdb) target remote :3333
(gdb) monitor reset halt
```
##### Step 2: Verify the Current Instructions
Examine the floating-point instructions near the temperature calculation:
```gdb
(gdb) x/4bx 0x10000414
```
Output:
```
0x10000414: 0xe6 0xee 0xa5 0x7a
```
This is `vfma.f32 s15, s13, s11` — the temperature fused multiply-add.
##### Step 3: Verify the Current Constant
```gdb
(gdb) x/wx 0x1000042c
```
Output:
```
0x1000042c: 0x3dcccccd
```
This is `0.1f`.
##### Step 4: Understand the Two Patches
**Patch 1 — Instruction at offset `0x414`:**
| Original | Bytes (LE) | New | Bytes (LE) |
| --------------------------- | --------------- | --------------------------- | --------------- |
| `vfma.f32 s15, s13, s11` | `e6 ee a5 7a` | `vadd.f32 s15, s15, s11` | `b4 ee a5 7a` |
> 🔍 Only the first two bytes change: `e6 ee``b4 ee`. The operand bytes `a5 7a` stay the same.
**Patch 2 — Constant at offset `0x42C`:**
| Original | Hex | LE Bytes | New | Hex | LE Bytes |
| -------- | ------------ | --------------- | ----- | ------------ | --------------- |
| 0.1f | `0x3dcccccd` | `cd cc cc 3d` | 10.0f | `0x41200000` | `00 00 20 41` |
##### Step 5: Patch the Instruction with HxD
1. In HxD, open `C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x001a_operators\build\0x001a_operators.bin`
2. Press **Ctrl+G** and enter offset: `414`
3. You should see: `e6 ee a5 7a`
4. Change the first two bytes: `e6 ee``b4 ee`
5. Result should be: `b4 ee a5 7a`
##### Step 6: Patch the Constant with HxD
1. Press **Ctrl+G** and enter offset: `42C`
2. You should see: `cd cc cc 3d` (or `cc cc cc 3d`)
3. Replace all 4 bytes with: `00 00 20 41`
##### Step 7: Save and Convert
1. Click **File****Save As**`0x001a_operators-h.bin`
```powershell
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x001a_operators
python ..\uf2conv.py build\0x001a_operators-h.bin --base 0x10000000 --family 0xe48bff59 --output build\hacked.uf2
```
##### Step 8: Flash and Verify
1. Hold BOOTSEL and plug in your Pico 2
2. Drag and drop `hacked.uf2` onto the RPI-RP2 drive
**Check the serial monitor:**
- All operator values remain unchanged (50, 5, 0, 0, 12, 11)
- Temperature should now read approximately **10°C higher** than the real temperature
- Humidity will also be affected (the constant is shared)
> ⚠️ **Note:** Since the constant at `0x42C` is shared between the humidity `vfma.f32` at `0x410` and the temperature one at `0x414`, changing it to `10.0f` will also affect humidity. The humidity instruction still uses `vfma` (multiply-add), so it will compute `humidity_int + (decimal × 10.0)` — producing very large humidity values.
#### Expected Output
After completing this exercise, you should be able to:
- Distinguish between `vfma.f32` (multiply-add) and `vadd.f32` (add) encodings
- Perform multi-site patches in a single binary
- Understand how shared constants affect multiple code paths
- Predict the side effects of patching shared data
#### Questions for Reflection
###### Question 1: Why did we need to change BOTH the instruction AND the constant? What would happen if you only changed the constant to `10.0f` but left the `vfma.f32` instruction unchanged?
###### Question 2: The humidity `vfma.f32` at offset `0x410` was NOT changed to `vadd`. With the constant now set to `10.0f`, what formula does the humidity instruction compute? If the raw humidity integer is 51 and decimal is 0, what value would it display?
###### Question 3: If you wanted to add 10°C to temperature WITHOUT affecting humidity, you would need to change both instructions. What bytes would you write at offset `0x410` to change the humidity `vfma` to `vadd` as well, and what constant would preserve the original humidity calculation?
###### Question 4: The `vadd.f32 s15, s15, s11` encoding is `b4 ee a5 7a`. In the original `vfma.f32 s15, s13, s11` (`e6 ee a5 7a`), why do only the first two bytes differ? What do those bytes encode?
#### Tips and Hints
- Make BOTH patches before saving — if you only patch one, the results will be wrong
- The `vfma``vadd` change only affects the first two bytes of the 4-byte instruction
- `10.0f` in IEEE-754 is `0x41200000` — memorize this common value
- Always start with a fresh copy of the `.bin` file if you need to redo the exercise
- Compare the original and hacked serial output side by side to verify only temperature changed as expected
+140
View File
@@ -0,0 +1,140 @@
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 9
Operators in Embedded Systems: Debugging and Hacking Operators w/ DHT11 Temperature & Humidity Sensor Single-Wire Protocol Basics
### Exercise 4: Find All printf Format Strings
#### Objective
Systematically search through the `0x001a_operators` binary using GDB and a hex editor to locate every `printf` format string, catalog their addresses, file offsets, contents, and purposes, and gain experience identifying data structures in compiled binaries.
#### Prerequisites
- Completed Week 9 tutorial (GDB section)
- `0x001a_operators.elf` and `0x001a_operators.bin` available in your build directory
- GDB (`arm-none-eabi-gdb`) and OpenOCD installed
- A hex editor (HxD, ImHex, or similar)
#### Task Description
The `0x001a_operators` program contains multiple `printf` calls, each with a format string like `"arithmetic_operator: %d\r\n"`. These strings are stored in the `.rodata` section of flash memory. You will use GDB to trace each `printf` call to its format string argument, then verify the strings in HxD. You will also search for strings that are NOT directly referenced by `printf` (like the `"DHT11 read failed"` error message). This exercise builds your ability to map out all human-readable data in a binary.
#### Step-by-Step Instructions
##### Step 1: Start the Debug Session
**Terminal 1 - Start OpenOCD:**
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
-f target/rp2350.cfg ^
-c "adapter speed 5000"
```
**Terminal 2 - Start GDB:**
```powershell
arm-none-eabi-gdb build\0x001a_operators.elf
```
**Connect to target:**
```gdb
(gdb) target remote :3333
(gdb) monitor reset halt
```
##### Step 2: Disassemble Main to Find printf Calls
```gdb
(gdb) x/60i 0x10000234
```
Look for repeated patterns of:
```
ldr r0, [pc, #offset] ; Load format string address
movs r1, #value ; Load the value to print
bl printf ; Call printf
```
Each `ldr r0` before a `bl printf` loads the format string address from the literal pool.
##### Step 3: Examine the Literal Pool
Find the literal pool after the loop branch (typically after the `b.n` instruction). Examine the word values:
```gdb
(gdb) x/10wx <literal_pool_start>
```
Each word that falls in the `0x10003xxx` range is likely a pointer to a string in `.rodata`.
##### Step 4: Read Each Format String
For each address found in the literal pool, use `x/s` to read the string:
```gdb
(gdb) x/s <address_from_literal_pool>
```
Document each one. You should find at least these format strings:
- `"arithmetic_operator: %d\r\n"`
- `"increment_operator: %d\r\n"`
- `"relational_operator: %d\r\n"`
- `"logical_operator: %d\r\n"`
- `"bitwise_operator: %d\r\n"`
- `"assignment_operator: %d\r\n"`
- `"Humidity: %.1f%%, Temperature: %.1f°C\r\n"`
- `"DHT11 read failed"`
##### Step 5: Build a String Catalog
Fill in a table like this (addresses will vary — use the ones you find):
| Address | File Offset | String Content | Used By |
| -------------- | ----------- | --------------------------------------- | ----------- |
| `0x10003xxx` | `0x3xxx` | `"arithmetic_operator: %d\r\n"` | printf #1 |
| `0x10003xxx` | `0x3xxx` | `"increment_operator: %d\r\n"` | printf #2 |
| `0x10003xxx` | `0x3xxx` | `"relational_operator: %d\r\n"` | printf #3 |
| `0x10003xxx` | `0x3xxx` | `"logical_operator: %d\r\n"` | printf #4 |
| `0x10003xxx` | `0x3xxx` | `"bitwise_operator: %d\r\n"` | printf #5 |
| `0x10003xxx` | `0x3xxx` | `"assignment_operator: %d\r\n"` | printf #6 |
| `0x10003xxx` | `0x3xxx` | `"Humidity: %.1f%%, Temperature: %.1f°C\r\n"` | printf #7 |
| `0x10003xxx` | `0x3xxx` | `"DHT11 read failed"` | puts |
##### Step 6: Verify in HxD
1. In HxD, open `C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x001a_operators\build\0x001a_operators.bin`
2. For each string, press **Ctrl+G** and enter the file offset
3. Verify you can read the ASCII text in the right panel
4. Note how the strings are stored consecutively in memory, each terminated by `0x00`
##### Step 7: Search for Hidden Strings
Scroll through the `.rodata` region in HxD (typically starting around offset `0x3000`+) and look for any ASCII text in the right panel that you didn't find via `printf` calls. Library functions may have their own strings.
#### Expected Output
After completing this exercise, you should be able to:
- Trace `printf` calls to their format string arguments using GDB
- Read string addresses from literal pools
- Build a complete catalog of strings in a binary
- Navigate to specific offsets in a hex editor to verify string data
#### Questions for Reflection
###### Question 1: The format string `"Humidity: %.1f%%, Temperature: %.1f°C\r\n"` uses `%%` to print a literal percent sign. What would happen if you patched one of the `%` characters to a space (`0x20`)?
###### Question 2: If you patched the string `"arithmetic_operator: %d\r\n"` to `"HACKED_OPERATOR!: %d\r\n"` (same length, 27 characters + null), what would the serial output show? Would the actual computed value change?
###### Question 3: The strings are stored consecutively in `.rodata`. If you made `"arithmetic_operator: %d\r\n"` one byte longer, which string would be corrupted and how?
###### Question 4: Why does the compiler use `puts` instead of `printf` for `"DHT11 read failed"`? What's the difference between the two functions for strings with no format specifiers?
#### Tips and Hints
- Format strings always start with a printable ASCII character — look for bytes in the `0x20`-`0x7E` range
- The `\r\n` at the end of format strings shows up as bytes `0x0D 0x0A`
- Use HxD's **Search****Find** (Ctrl+F) with "Text string" mode to search for known text like "arithmetic"
- Strings in `.rodata` are typically 4-byte aligned, so there may be padding bytes (`0x00`) between them
- The `°` character in "°C" is a multi-byte UTF-8 sequence (`0xC2 0xB0`), not a single byte
Binary file not shown.
+1213
View File
File diff suppressed because it is too large Load Diff
+155
View File
@@ -0,0 +1,155 @@
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 10
Conditionals in Embedded Systems: Debugging and Hacking Static & Dynamic Conditionals w/ SG90 Servo Motor PWM Basics
### Exercise 1: Change Servo Angle Range
#### Objective
Find the IEEE-754 floating-point value `0x43340000` (180.0f) in the `0x0020_dynamic-conditionals` binary using GDB, calculate the file offset, patch it to `0x43070000` (135.0f) using a hex editor, then find and patch the `0x00000000` (0.0f) value to `0x42340000` (45.0f), and verify on hardware that the servo now sweeps from 45° to 135° instead of 0° to 180°.
#### Prerequisites
- Completed Week 10 tutorial (GDB and hex editor sections)
- `0x0020_dynamic-conditionals.elf` and `0x0020_dynamic-conditionals.bin` available in your build directory
- GDB (`arm-none-eabi-gdb`) and OpenOCD installed
- A hex editor (HxD, ImHex, or similar)
- Python installed (for UF2 conversion)
- Raspberry Pi Pico 2 with SG90 servo motor connected on GPIO 6
#### Task Description
The program uses `servo_set_angle(0.0f)` and `servo_set_angle(180.0f)` to sweep the servo across its full range. The float values `0.0` (`0x00000000`) and `180.0` (`0x43340000`) are loaded from the literal pool into registers before the `bl servo_set_angle` calls. You will locate these values in the disassembly, find the corresponding bytes in the `.bin` file, and patch them to `45.0` (`0x42340000`) and `135.0` (`0x43070000`) so the servo sweeps a narrower 90° range centered at 90°.
#### Step-by-Step Instructions
##### Step 1: Start the Debug Session
**Terminal 1 - Start OpenOCD:**
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
-f target/rp2350.cfg ^
-c "adapter speed 5000"
```
**Terminal 2 - Start GDB:**
```powershell
arm-none-eabi-gdb build\0x0020_dynamic-conditionals.elf
```
**Connect to target:**
```gdb
(gdb) target remote :3333
(gdb) monitor reset halt
```
##### Step 2: Find the servo_set_angle Calls
Disassemble main and look for the `servo_set_angle` calls:
```gdb
(gdb) disassemble 0x10000234,+250
```
Look for instruction patterns like:
```
ldr r0, [pc, #offset] ; load float from literal pool
bl servo_set_angle
```
There will be multiple pairs — one loading `0x00000000` (0.0f) and another loading `0x43340000` (180.0f).
##### Step 3: Examine the Literal Pool Values
Once you find the `ldr r0, [pc, #offset]` instructions, examine the literal pool entries they reference:
```gdb
(gdb) x/wx <literal_pool_address_for_180>
```
You should see `0x43340000` (180.0f in IEEE-754).
```gdb
(gdb) x/wx <literal_pool_address_for_0>
```
You should see `0x00000000` (0.0f in IEEE-754).
##### Step 4: Calculate the File Offsets
```
file_offset = literal_pool_address - 0x10000000
```
Note the file offsets for both 4-byte words.
##### Step 5: Encode the New Values
**IEEE-754 Encoding:**
| Angle | IEEE-754 Hex | Little-Endian Bytes |
| ----- | -------------- | ------------------- |
| 0.0f | `0x00000000` | `00 00 00 00` |
| 45.0f | `0x42340000` | `00 00 34 42` |
| 135.0f| `0x43070000` | `00 00 07 43` |
| 180.0f| `0x43340000` | `00 00 34 43` |
##### Step 6: Patch with HxD
1. In HxD, open `C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0020_dynamic-conditionals\build\0x0020_dynamic-conditionals.bin`
2. Press **Ctrl+G** and enter the file offset for the 180.0f value
3. You should see: `00 00 34 43`
4. Replace with: `00 00 07 43` (135.0f)
5. Press **Ctrl+G** and enter the file offset for the 0.0f value
6. You should see: `00 00 00 00`
7. Replace with: `00 00 34 42` (45.0f)
###### Question 1: How many literal pool entries reference `0x43340000`? Do you need to patch all of them?
##### Step 7: Save and Convert
1. Click **File****Save As**`0x0020_dynamic-conditionals-h.bin`
```powershell
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0020_dynamic-conditionals
python ..\uf2conv.py build\0x0020_dynamic-conditionals-h.bin --base 0x10000000 --family 0xe48bff59 --output build\hacked.uf2
```
##### Step 8: Flash and Verify
1. Hold BOOTSEL and plug in your Pico 2
2. Drag and drop `hacked.uf2` onto the RPI-RP2 drive
**Check the servo behavior:**
- Press '1' → servo sweeps from **45°** to **135°** (was 0° to 180°)
- Press '2' → servo sweeps from **135°** to **45°** (was 180° to 0°)
- The total sweep range should be noticeably smaller
#### Expected Output
After completing this exercise, you should be able to:
- Locate IEEE-754 floating-point values in the literal pool
- Understand the IEEE-754 single-precision encoding format
- Patch floating-point angle constants in embedded firmware
- Calculate file offsets from memory addresses
#### Questions for Reflection
###### Question 1: The value `180.0f` is encoded as `0x43340000` in IEEE-754. Break this down: what are the sign bit, exponent, and mantissa fields?
###### Question 2: Why is `0.0f` stored as `0x00000000` and not some other pattern? What makes zero special in IEEE-754?
###### Question 3: If you wanted to set the servo to exactly 90° (center), what IEEE-754 hex value would you use? Show the calculation.
###### Question 4: Could the compiler optimize `0.0f` differently — for example, using `movs r0, #0` instead of a literal pool load? How would that affect your patching strategy?
#### Tips and Hints
- IEEE-754 for 90.0f: sign=0, exponent=127+6=133=0x85, mantissa=0x340000 → `0x42b40000`
- There may be multiple references to `0x43340000` in the literal pool — the case '1' and case '2' branches each load both angles
- Be careful with `0x00000000` — make sure you are patching a float literal pool entry and not zeroed data
- Use `x/4wx <address>` in GDB to view several literal pool words at once
+159
View File
@@ -0,0 +1,159 @@
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 10
Conditionals in Embedded Systems: Debugging and Hacking Static & Dynamic Conditionals w/ SG90 Servo Motor PWM Basics
### Exercise 2: Add a Third Command
#### Objective
Find the comparison instruction `cmp r4, #0x32` ('2') in the `0x0020_dynamic-conditionals` binary using GDB, locate the branch target for case '2', and modify existing code so that pressing '3' (0x33) moves the servo to the center position (90°) by patching one of the existing comparisons and its corresponding angle value to `0x42b40000` (90.0f).
#### Prerequisites
- Completed Week 10 tutorial (GDB and hex editor sections)
- `0x0020_dynamic-conditionals.elf` and `0x0020_dynamic-conditionals.bin` available in your build directory
- GDB (`arm-none-eabi-gdb`) and OpenOCD installed
- A hex editor (HxD, ImHex, or similar)
- Python installed (for UF2 conversion)
- Raspberry Pi Pico 2 with SG90 servo motor connected on GPIO 6
#### Task Description
The program has two active commands: '1' (0x31) moves the servo 0°→180° and '2' (0x32) moves it 180°→0°. Adding a completely new code path would require rewriting branch offsets throughout the binary. Instead, you will repurpose the '2' command by changing its comparison value from `0x32` ('2') to `0x33` ('3') and patching both of its angle values to `0x42b40000` (90.0f), so pressing '3' moves the servo to center and holds it there.
#### Step-by-Step Instructions
##### Step 1: Start the Debug Session
**Terminal 1 - Start OpenOCD:**
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
-f target/rp2350.cfg ^
-c "adapter speed 5000"
```
**Terminal 2 - Start GDB:**
```powershell
arm-none-eabi-gdb build\0x0020_dynamic-conditionals.elf
```
**Connect to target:**
```gdb
(gdb) target remote :3333
(gdb) monitor reset halt
```
##### Step 2: Find the Comparison Instructions
Disassemble main and locate both `cmp` instructions:
```gdb
(gdb) disassemble 0x10000234,+250
```
Look for:
```
cmp r4, #0x31 ; compare with '1'
beq <target1>
cmp r4, #0x32 ; compare with '2'
beq <target2>
```
Note the address of the `cmp r4, #0x32` instruction.
##### Step 3: Examine the Comparison Byte
The `cmp r4, #0x32` instruction encodes `0x32` as an immediate. Examine the instruction bytes:
```gdb
(gdb) x/2bx <address_of_cmp_0x32>
```
You should see a byte containing `0x32`.
##### Step 4: Find the Angle Values for Case '2'
Follow the `beq` target for case '2' and look for the literal pool loads:
```gdb
(gdb) x/wx <literal_pool_for_case2_angle1>
(gdb) x/wx <literal_pool_for_case2_angle2>
```
Case '2' loads `0x43340000` (180.0f) first, then `0x00000000` (0.0f).
##### Step 5: Calculate the File Offsets
```
file_offset = address - 0x10000000
```
Note offsets for:
1. The `0x32` byte in the `cmp` instruction
2. Both angle literal pool entries for case '2'
##### Step 6: Encode the New Values
| Patch Target | Original | New | Purpose |
| ---------------- | ---------------- | ---------------- | ------------------------- |
| Compare byte | `32` | `33` | Match '3' instead of '2' |
| Angle 1 (180.0f) | `00 00 34 43` | `00 00 b4 42` | 90.0f center position |
| Angle 2 (0.0f) | `00 00 00 00` | `00 00 b4 42` | 90.0f center position |
##### Step 7: Patch with HxD
1. In HxD, open `C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0020_dynamic-conditionals\build\0x0020_dynamic-conditionals.bin`
2. Press **Ctrl+G** and go to the compare byte offset
3. Change `32` to `33`
4. Go to the first angle offset for case '2' and replace `00 00 34 43` with `00 00 b4 42`
5. Go to the second angle offset for case '2' and replace `00 00 00 00` with `00 00 b4 42`
###### Question 1: Why do we set both angle values to 90.0f instead of just one?
##### Step 8: Save and Convert
1. Click **File****Save As**`0x0020_dynamic-conditionals-h.bin`
```powershell
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0020_dynamic-conditionals
python ..\uf2conv.py build\0x0020_dynamic-conditionals-h.bin --base 0x10000000 --family 0xe48bff59 --output build\hacked.uf2
```
##### Step 9: Flash and Verify
1. Hold BOOTSEL and plug in your Pico 2
2. Drag and drop `hacked.uf2` onto the RPI-RP2 drive
**Check the behavior:**
- Press '1' → servo sweeps 0° to 180° (unchanged)
- Press '3' → servo moves to **90° center** and stays
- Press '2' → now falls through to default "??" (no longer mapped)
#### Expected Output
After completing this exercise, you should be able to:
- Locate and patch comparison immediate values in ARM Thumb instructions
- Repurpose existing code paths instead of adding new ones
- Understand how `cmp` immediates are encoded in the instruction stream
- Combine multiple patches (comparison + data) for a single behavior change
#### Questions for Reflection
###### Question 1: Why is it easier to repurpose an existing command than to add a truly new third code path in the binary?
###### Question 2: The `cmp` instruction uses an 8-bit immediate field. What range of ASCII characters could you use as command keys?
###### Question 3: After your patch, pressing '2' now triggers the default "??" branch. Could you keep both '2' AND '3' working? What would that require?
###### Question 4: What would happen if you changed the comparison to `0x00`? Could a user ever trigger that command via `getchar()`?
#### Tips and Hints
- The `cmp rN, #imm8` instruction in Thumb has the immediate in the lower byte of the instruction word
- IEEE-754 for 90.0f: `0x42b40000` → little-endian `00 00 b4 42`
- Be careful not to confuse literal pool entries between case '1' and case '2' — trace the branch targets carefully
- The `getchar()` function reads one byte from UART, so any byte value 0x00-0xFF is theoretically possible
+141
View File
@@ -0,0 +1,141 @@
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 10
Conditionals in Embedded Systems: Debugging and Hacking Static & Dynamic Conditionals w/ SG90 Servo Motor PWM Basics
### Exercise 3: Reverse the Servo Direction
#### Objective
Find the branch targets for case '1' and case '2' in the `0x0020_dynamic-conditionals` binary using GDB, identify where each case loads its angle values from the literal pool, and swap the angle pairs so that pressing '1' now does what '2' originally did (180°→0°) and pressing '2' does what '1' originally did (0°→180°).
#### Prerequisites
- Completed Week 10 tutorial (GDB and hex editor sections)
- `0x0020_dynamic-conditionals.elf` and `0x0020_dynamic-conditionals.bin` available in your build directory
- GDB (`arm-none-eabi-gdb`) and OpenOCD installed
- A hex editor (HxD, ImHex, or similar)
- Python installed (for UF2 conversion)
- Raspberry Pi Pico 2 with SG90 servo motor connected on GPIO 6
#### Task Description
Currently, case '1' calls `servo_set_angle(0.0f)` then `servo_set_angle(180.0f)`, while case '2' calls `servo_set_angle(180.0f)` then `servo_set_angle(0.0f)`. To reverse the servo direction, you will swap the literal pool angle values between the two cases. This means patching case '1' to load 180.0f first and 0.0f second, and case '2' to load 0.0f first and 180.0f second.
#### Step-by-Step Instructions
##### Step 1: Start the Debug Session
**Terminal 1 - Start OpenOCD:**
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
-f target/rp2350.cfg ^
-c "adapter speed 5000"
```
**Terminal 2 - Start GDB:**
```powershell
arm-none-eabi-gdb build\0x0020_dynamic-conditionals.elf
```
**Connect to target:**
```gdb
(gdb) target remote :3333
(gdb) monitor reset halt
```
##### Step 2: Map Both Case Branch Targets
Disassemble main and trace both paths:
```gdb
(gdb) disassemble 0x10000234,+250
```
Identify:
- Case '1' branch target → first `ldr r0` (loads 0.0f), `bl servo_set_angle`, second `ldr r0` (loads 180.0f), `bl servo_set_angle`
- Case '2' branch target → first `ldr r0` (loads 180.0f), `bl servo_set_angle`, second `ldr r0` (loads 0.0f), `bl servo_set_angle`
##### Step 3: Find All Four Literal Pool Entries
Examine the literal pool entries for each angle load:
```gdb
(gdb) x/wx <case1_angle1_literal>
(gdb) x/wx <case1_angle2_literal>
(gdb) x/wx <case2_angle1_literal>
(gdb) x/wx <case2_angle2_literal>
```
Record which addresses contain `0x00000000` (0.0f) and which contain `0x43340000` (180.0f).
##### Step 4: Calculate All File Offsets
```
file_offset = literal_pool_address - 0x10000000
```
You need four offsets — two for case '1' angles and two for case '2' angles.
##### Step 5: Plan the Swap
| Location | Original | New |
| -------------- | ---------------- | ---------------- |
| Case 1 Angle 1 | `00 00 00 00` (0.0f) | `00 00 34 43` (180.0f) |
| Case 1 Angle 2 | `00 00 34 43` (180.0f) | `00 00 00 00` (0.0f) |
| Case 2 Angle 1 | `00 00 34 43` (180.0f) | `00 00 00 00` (0.0f) |
| Case 2 Angle 2 | `00 00 00 00` (0.0f) | `00 00 34 43` (180.0f) |
###### Question 1: Could the compiler share a single literal pool entry for all references to `0x43340000`? How would that affect your patching plan?
##### Step 6: Patch with HxD
1. In HxD, open `C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0020_dynamic-conditionals\build\0x0020_dynamic-conditionals.bin`
2. For each of the four literal pool entries, navigate to its file offset and swap the values as planned
3. Be methodical — patch one at a time and verify each before moving to the next
##### Step 7: Save and Convert
1. Click **File****Save As**`0x0020_dynamic-conditionals-h.bin`
```powershell
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0020_dynamic-conditionals
python ..\uf2conv.py build\0x0020_dynamic-conditionals-h.bin --base 0x10000000 --family 0xe48bff59 --output build\hacked.uf2
```
##### Step 8: Flash and Verify
1. Hold BOOTSEL and plug in your Pico 2
2. Drag and drop `hacked.uf2` onto the RPI-RP2 drive
**Check the behavior:**
- Press '1' → servo sweeps from **180° to 0°** (was 0° to 180°)
- Press '2' → servo sweeps from **0° to 180°** (was 180° to 0°)
- The text output still says "one" and "two" — only the physical behavior changed
#### Expected Output
After completing this exercise, you should be able to:
- Trace multiple branch paths to their literal pool references
- Understand how data (angles) and code (branches) are separate concerns
- Swap data values to reverse physical behavior while keeping code structure intact
- Recognize shared vs. separate literal pool entries
#### Questions for Reflection
###### Question 1: The terminal still prints "one" and "two" with the original meanings, but the servo does the opposite. Why is this a security concern in real embedded systems?
###### Question 2: Instead of swapping literal pool values, could you swap the branch targets themselves? What are the pros and cons of each approach?
###### Question 3: If the literal pool entries are shared between cases (one `0x43340000` word referenced by both), how would your patch strategy change?
###### Question 4: What tool could you use to confirm the swapped behavior without physical hardware — just by reading the patched disassembly?
#### Tips and Hints
- Use `x/4wx <literal_pool_start>` to dump the entire literal pool at once and see all angle values together
- If the compiler shares a single literal pool entry for 180.0f across both cases, swapping it would affect both — you may need to create a duplicate entry
- The simplest approach: if each case has its own literal pool entries, just swap the 4-byte values at each offset
- Verify by disassembling the patched binary in GDB to confirm the `ldr` instructions now reference the swapped values
+144
View File
@@ -0,0 +1,144 @@
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 10
Conditionals in Embedded Systems: Debugging and Hacking Static & Dynamic Conditionals w/ SG90 Servo Motor PWM Basics
### Exercise 4: Speed Profile
#### Objective
Find both `sleep_ms(500)` calls in the `0x0020_dynamic-conditionals` binary using GDB, identify the literal pool values `0x1f4` (500) loaded into `r0` before each `bl sleep_ms`, calculate the file offsets, and patch case '1' to use `0x64` (100ms) for fast movement and case '2' to use `0x3e8` (1000ms) for slow movement, then verify on hardware that the two keys produce visibly different servo speeds.
#### Prerequisites
- Completed Week 10 tutorial (GDB and hex editor sections)
- `0x0020_dynamic-conditionals.elf` and `0x0020_dynamic-conditionals.bin` available in your build directory
- GDB (`arm-none-eabi-gdb`) and OpenOCD installed
- A hex editor (HxD, ImHex, or similar)
- Python installed (for UF2 conversion)
- Raspberry Pi Pico 2 with SG90 servo motor connected on GPIO 6
#### Task Description
Both case '1' and case '2' call `sleep_ms(500)` between their two `servo_set_angle` calls. The value `500` (`0x1F4`) is loaded from the literal pool into `r0` before each `bl sleep_ms`. You will find both `sleep_ms` literal pool entries — one in case '1' and one in case '2' — and patch them to different values: `100` (`0x64`) for fast snapping and `1000` (`0x3E8`) for slow sweeping, creating distinct speed profiles per key.
#### Step-by-Step Instructions
##### Step 1: Start the Debug Session
**Terminal 1 - Start OpenOCD:**
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
-f target/rp2350.cfg ^
-c "adapter speed 5000"
```
**Terminal 2 - Start GDB:**
```powershell
arm-none-eabi-gdb build\0x0020_dynamic-conditionals.elf
```
**Connect to target:**
```gdb
(gdb) target remote :3333
(gdb) monitor reset halt
```
##### Step 2: Find Both sleep_ms Calls
Disassemble main and locate the `sleep_ms` calls:
```gdb
(gdb) disassemble 0x10000234,+250
```
Look for the pattern repeated in both cases:
```
ldr r0, [pc, #offset] ; load delay value
bl sleep_ms
```
Each case has at least one `sleep_ms` call. Identify which belongs to case '1' and which to case '2' by tracing the branch targets.
##### Step 3: Examine the Literal Pool Entries
For each `sleep_ms` call, examine the referenced literal pool entry:
```gdb
(gdb) x/wx <case1_sleep_literal>
(gdb) x/wx <case2_sleep_literal>
```
Both should show `0x000001f4` (500).
##### Step 4: Calculate the File Offsets
```
file_offset = literal_pool_address - 0x10000000
```
Note the file offsets for both 4-byte sleep values.
##### Step 5: Encode the New Values
| Case | Original | New | Speed |
| ------ | ----------------- | ----------------- | -------- |
| Case 1 | `F4 01 00 00` (500ms) | `64 00 00 00` (100ms) | Fast snap |
| Case 2 | `F4 01 00 00` (500ms) | `E8 03 00 00` (1000ms) | Slow sweep |
###### Question 1: Each case calls `sleep_ms` twice (once between the first and second `servo_set_angle`). Do both share the same literal pool entry, or does each have its own?
##### Step 6: Patch with HxD
1. In HxD, open `C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0020_dynamic-conditionals\build\0x0020_dynamic-conditionals.bin`
2. Press **Ctrl+G** and go to the case '1' sleep value offset
3. Replace `F4 01 00 00` with `64 00 00 00` (100ms)
4. Press **Ctrl+G** and go to the case '2' sleep value offset
5. Replace `F4 01 00 00` with `E8 03 00 00` (1000ms)
##### Step 7: Save and Convert
1. Click **File****Save As**`0x0020_dynamic-conditionals-h.bin`
```powershell
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0020_dynamic-conditionals
python ..\uf2conv.py build\0x0020_dynamic-conditionals-h.bin --base 0x10000000 --family 0xe48bff59 --output build\hacked.uf2
```
##### Step 8: Flash and Verify
1. Hold BOOTSEL and plug in your Pico 2
2. Drag and drop `hacked.uf2` onto the RPI-RP2 drive
**Check the behavior:**
- Press '1' → servo snaps **fast** (100ms between angles) — almost instant jump
- Press '2' → servo moves **slow** (1000ms between angles) — takes a full second at each position
- The speed difference should be very obvious visually and audibly
#### Expected Output
After completing this exercise, you should be able to:
- Distinguish between multiple literal pool entries for the same value
- Trace which code path references which literal pool entry
- Patch timing constants independently per branch
- Understand how sleep duration affects perceived motor behavior
#### Questions for Reflection
###### Question 1: Why does 100ms make the servo appear to "snap" while 1000ms makes it appear to "sweep"? Is the servo actually moving faster, or is it about the pause between commands?
###### Question 2: If the compiler uses a single shared literal pool entry for all `sleep_ms(500)` calls, what alternative patching strategy would you need to create different speeds per case?
###### Question 3: What is the minimum `sleep_ms` value that would still allow the servo to physically reach its target angle before the next command? How would you determine this experimentally?
###### Question 4: Could you set the sleep to `0` (`00 00 00 00`)? What would happen to the servo behavior?
#### Tips and Hints
- `100` decimal = `0x64`, fits in one byte: `64 00 00 00` in little-endian
- `1000` decimal = `0x3E8`: `E8 03 00 00` in little-endian
- If both `sleep_ms` calls share one literal pool word, you cannot give them different values by patching data alone — you would need to patch one `ldr` instruction to point to a different pool entry or use a `movs` immediate
- The SG90 servo takes about 200-300ms to traverse its full range, so 100ms will cause it to not quite reach the endpoint before the next command fires
Binary file not shown.
+1529
View File
File diff suppressed because it is too large Load Diff
+156
View File
@@ -0,0 +1,156 @@
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 11
Structures and Functions in Embedded Systems: Debugging and Hacking w/ IR Remote Control and NEC Protocol Basics
### Exercise 1: Add a Fourth LED
#### Objective
Find the struct initialization pattern in the `0x0026_functions` binary using GDB where `led1_pin` (0x10), `led2_pin` (0x11), and `led3_pin` (0x12) are stored, locate an unused byte in the struct memory region, and patch it to include a fourth LED on GPIO 19 (0x13) by extending the struct data and modifying the `ir_to_led_number` function to handle a fourth button mapping.
#### Prerequisites
- Completed Week 11 tutorial (GDB and hex editor sections)
- `0x0026_functions.elf` and `0x0026_functions.bin` available in your build directory
- GDB (`arm-none-eabi-gdb`) and OpenOCD installed
- A hex editor (HxD, ImHex, or similar)
- Python installed (for UF2 conversion)
- Raspberry Pi Pico 2 with IR remote and LEDs on GPIO 16, 17, 18 (and GPIO 19 wired for the new LED)
#### Task Description
The `simple_led_ctrl_t` struct stores three LED pin numbers: `led1_pin` (16/0x10), `led2_pin` (17/0x11), `led3_pin` (18/0x12). These are stored as consecutive bytes in the struct initialization. You will find where the struct is initialized in the binary, locate the `movs` instructions that set the pin values, and add `led4_pin` = 19 (0x13) by patching a nearby unused or default byte. You will also need to find where `ir_to_led_number` returns values 1, 2, or 3 and adjust the NEC command comparison to map a fourth button to LED 4.
#### Step-by-Step Instructions
##### Step 1: Start the Debug Session
**Terminal 1 - Start OpenOCD:**
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
-f target/rp2350.cfg ^
-c "adapter speed 5000"
```
**Terminal 2 - Start GDB:**
```powershell
arm-none-eabi-gdb build\0x0026_functions.elf
```
**Connect to target:**
```gdb
(gdb) target remote :3333
(gdb) monitor reset halt
```
##### Step 2: Find the Struct Initialization
Disassemble main and look for the struct pin assignments:
```gdb
(gdb) disassemble 0x10000234,+300
```
Look for consecutive `movs` instructions:
```
movs r0, #0x10 ; led1_pin = 16
strb r0, [r4, #0] ; store to struct offset 0
movs r0, #0x11 ; led2_pin = 17
strb r0, [r4, #1] ; store to struct offset 1
movs r0, #0x12 ; led3_pin = 18
strb r0, [r4, #2] ; store to struct offset 2
```
##### Step 3: Examine the Struct in Memory
Set a breakpoint after initialization and examine the struct:
```gdb
(gdb) break *0x10000280
(gdb) monitor reset halt
(gdb) continue
(gdb) x/8bx <struct_base_address>
```
You should see: `10 11 12 00 00 00` — the three pin values followed by the state booleans (all false/0x00).
##### Step 4: Find the `get_led_pin` Function
Look for the function that reads from the struct based on LED number:
```gdb
(gdb) disassemble 0x100002a0,+50
```
This function takes a struct pointer and LED number and returns the GPIO pin by reading from a struct offset.
##### Step 5: Calculate File Offsets
```
file_offset = address - 0x10000000
```
Note offsets for:
1. The `movs r0, #0x12` instruction (last pin assignment)
2. The byte after `led3_pin` in the struct (where `led4_pin` would go)
##### Step 6: Plan the Patches
| Patch Target | Original | New | Purpose |
| --------------------- | -------- | ------ | ------------------------- |
| Struct byte after 0x12 | `00` | `13` | Add led4_pin = GPIO 19 |
###### Question 1: The struct layout has `led3_pin` at offset 2 and `led1_state` at offset 3. If you write `0x13` to offset 3, what happens to `led1_state`?
##### Step 7: Patch with HxD
1. In HxD, open `C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0026_functions\build\0x0026_functions.bin`
2. Navigate to the struct initialization area
3. Apply the patches identified in Step 6
##### Step 8: Save and Convert
1. Click **File****Save As**`0x0026_functions-h.bin`
```powershell
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0026_functions
python ..\uf2conv.py build\0x0026_functions-h.bin --base 0x10000000 --family 0xe48bff59 --output build\hacked.uf2
```
##### Step 9: Flash and Verify
1. Hold BOOTSEL and plug in your Pico 2
2. Drag and drop `hacked.uf2` onto the RPI-RP2 drive
**Check the behavior:**
- Existing buttons 1, 2, 3 should still control their LEDs
- Verify with GDB that the struct now contains `10 11 12 13` at the pin offsets
#### Expected Output
After completing this exercise, you should be able to:
- Understand struct memory layout and member offsets
- Identify struct initialization patterns in ARM assembly
- Patch struct data members in binary firmware
- Reason about the consequences of overwriting adjacent struct fields
#### Questions for Reflection
###### Question 1: The original struct has 6 members (3 pins + 3 states) in 6 bytes. If you add a fourth pin at offset 3, you overwrite `led1_state`. What is the practical impact on LED 1 behavior?
###### Question 2: How would you verify the exact struct layout and offsets using GDB's memory examination commands?
###### Question 3: If the `get_led_pin` function uses a bounds check (e.g., `if led_num > 3 return 0`), what additional patch would you need?
###### Question 4: Could you extend the struct without overwriting existing fields by finding free space elsewhere in the binary? What challenges would that introduce?
#### Tips and Hints
- GPIO 19 = `0x13` in hex
- The struct is likely stack-allocated, so the initialization `movs`/`strb` sequence happens every loop iteration
- Overwriting `led1_state` (offset 3) with `0x13` means LED 1 will appear as "on" (non-zero boolean) — this may cause LED 1 to be on at startup
- The `get_led_pin` function likely uses the LED number as an index into the struct — trace how it calculates the offset
+144
View File
@@ -0,0 +1,144 @@
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 11
Structures and Functions in Embedded Systems: Debugging and Hacking w/ IR Remote Control and NEC Protocol Basics
### Exercise 2: Change Blink Count
#### Objective
Find the `blink_led(pin, 3, 50)` call in the `0x0026_functions` binary using GDB, identify the immediate value `#3` being loaded into `r1` (the blink count parameter), calculate the file offset, and patch it to `#5` so that each LED blinks 5 times instead of 3 when activated by the IR remote.
#### Prerequisites
- Completed Week 11 tutorial (GDB and hex editor sections)
- `0x0026_functions.elf` and `0x0026_functions.bin` available in your build directory
- GDB (`arm-none-eabi-gdb`) and OpenOCD installed
- A hex editor (HxD, ImHex, or similar)
- Python installed (for UF2 conversion)
- Raspberry Pi Pico 2 with IR remote and LEDs on GPIO 16, 17, 18
#### Task Description
The `blink_led` function is called with three parameters: the GPIO pin number, a blink count of `3`, and a delay of `50`ms. The blink count is loaded as a small immediate value (`movs r1, #3`) directly in the instruction before the `bl blink_led` call. You will locate this instruction, find the byte encoding the `#3` immediate, and patch it to `#5` so the LEDs blink 5 times per button press.
#### Step-by-Step Instructions
##### Step 1: Start the Debug Session
**Terminal 1 - Start OpenOCD:**
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
-f target/rp2350.cfg ^
-c "adapter speed 5000"
```
**Terminal 2 - Start GDB:**
```powershell
arm-none-eabi-gdb build\0x0026_functions.elf
```
**Connect to target:**
```gdb
(gdb) target remote :3333
(gdb) monitor reset halt
```
##### Step 2: Find the blink_led Call
Disassemble main and look for the function call sequence:
```gdb
(gdb) disassemble 0x10000234,+300
```
Look for the parameter setup before `bl blink_led`:
```
movs r0, <pin> ; GPIO pin number (from get_led_pin)
movs r1, #3 ; blink count = 3
movs r2, #0x32 ; delay = 50ms
bl blink_led
```
Note the address of the `movs r1, #3` instruction.
##### Step 3: Examine the Instruction Encoding
Look at the raw bytes of the `movs r1, #3` instruction:
```gdb
(gdb) x/2bx <address_of_movs_r1_3>
```
In Thumb encoding, `movs r1, #imm8` has the immediate in the lower byte. You should see a byte containing `03`.
##### Step 4: Calculate the File Offset
```
file_offset = address - 0x10000000
```
Note the file offset of the byte containing `03`.
##### Step 5: Encode the New Value
| Parameter | Original | New | Encoding |
| ---------- | -------- | ---- | -------------- |
| Blink count | `03` | `05` | `movs r1, #5` |
##### Step 6: Patch with HxD
1. In HxD, open `C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0026_functions\build\0x0026_functions.bin`
2. Press **Ctrl+G** and enter the file offset
3. You should see: `03`
4. Replace with: `05`
###### Question 1: The `movs r1, #3` is a 2-byte Thumb instruction. Which byte contains the immediate — the first or the second?
##### Step 7: Save and Convert
1. Click **File****Save As**`0x0026_functions-h.bin`
```powershell
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0026_functions
python ..\uf2conv.py build\0x0026_functions-h.bin --base 0x10000000 --family 0xe48bff59 --output build\hacked.uf2
```
##### Step 8: Flash and Verify
1. Hold BOOTSEL and plug in your Pico 2
2. Drag and drop `hacked.uf2` onto the RPI-RP2 drive
**Check the behavior:**
- Press button 1 → Red LED blinks **5 times** (was 3), then stays on
- Press button 2 → Green LED blinks **5 times** (was 3), then stays on
- Press button 3 → Yellow LED blinks **5 times** (was 3), then stays on
- Count carefully — you should see exactly 5 on/off cycles
#### Expected Output
After completing this exercise, you should be able to:
- Locate small immediate values in Thumb `movs` instructions
- Understand Thumb instruction encoding for immediate operands
- Patch function parameters by modifying instruction immediates
- Verify behavioral changes by counting observable events
#### Questions for Reflection
###### Question 1: The `movs rN, #imm8` instruction can encode values 0-255. What is the maximum blink count you could set with a single byte patch?
###### Question 2: Why is the blink count passed in `r1` and not `r0`? What does `r0` hold at this point in the calling convention?
###### Question 3: If you wanted to set the blink count to 256 or higher, the `movs` immediate would not be enough. What instruction sequence would the compiler need to generate instead?
###### Question 4: The same `blink_led` function is called for all three buttons. Does that mean there is only one `movs r1, #3` to patch, or could there be multiple call sites?
#### Tips and Hints
- Small immediates (0-255) are encoded directly in the `movs` instruction — no literal pool needed
- The ARM calling convention uses `r0`, `r1`, `r2`, `r3` for the first four function parameters in order
- Look for `movs r1, #3` right before `bl blink_led` — there may be one shared call site or multiple per button
- If there are multiple `movs r1, #3` instructions (one per case), you need to patch all of them for consistent behavior
+150
View File
@@ -0,0 +1,150 @@
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 11
Structures and Functions in Embedded Systems: Debugging and Hacking w/ IR Remote Control and NEC Protocol Basics
### Exercise 3: Swap All Three LEDs
#### Objective
Find the struct initialization instructions where `led1_pin` = 0x10 (GPIO 16, Red), `led2_pin` = 0x11 (GPIO 17, Green), and `led3_pin` = 0x12 (GPIO 18, Yellow) are written in the `0x0026_functions` binary using GDB, calculate the file offsets, and rotate the GPIO values so that button 1→Green (0x11), button 2→Yellow (0x12), and button 3→Red (0x10), then verify on hardware that the LED mapping has shifted.
#### Prerequisites
- Completed Week 11 tutorial (GDB and hex editor sections)
- `0x0026_functions.elf` and `0x0026_functions.bin` available in your build directory
- GDB (`arm-none-eabi-gdb`) and OpenOCD installed
- A hex editor (HxD, ImHex, or similar)
- Python installed (for UF2 conversion)
- Raspberry Pi Pico 2 with IR remote and LEDs on GPIO 16, 17, 18
#### Task Description
The struct initialization sets `led1_pin` = 16 (0x10), `led2_pin` = 17 (0x11), `led3_pin` = 18 (0x12) using `movs` instructions that store each value into the struct. By patching the immediate values in these three `movs` instructions, you can rotate the LED assignment: `led1_pin` = 17 (Green), `led2_pin` = 18 (Yellow), `led3_pin` = 16 (Red). This means button 1 will light the Green LED, button 2 the Yellow LED, and button 3 the Red LED.
#### Step-by-Step Instructions
##### Step 1: Start the Debug Session
**Terminal 1 - Start OpenOCD:**
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
-f target/rp2350.cfg ^
-c "adapter speed 5000"
```
**Terminal 2 - Start GDB:**
```powershell
arm-none-eabi-gdb build\0x0026_functions.elf
```
**Connect to target:**
```gdb
(gdb) target remote :3333
(gdb) monitor reset halt
```
##### Step 2: Find the Three movs Instructions
Disassemble main and find the struct pin initialization:
```gdb
(gdb) disassemble 0x10000234,+300
```
Look for three consecutive `movs`/`strb` pairs:
```
movs r0, #0x10 ; led1_pin = 16 (Red)
strb r0, [r4, #0]
movs r0, #0x11 ; led2_pin = 17 (Green)
strb r0, [r4, #1]
movs r0, #0x12 ; led3_pin = 18 (Yellow)
strb r0, [r4, #2]
```
Note the address of each `movs` instruction.
##### Step 3: Examine the Instruction Bytes
Check the raw encoding of each `movs`:
```gdb
(gdb) x/2bx <address_of_movs_0x10>
(gdb) x/2bx <address_of_movs_0x11>
(gdb) x/2bx <address_of_movs_0x12>
```
Each will have the GPIO pin number as the immediate byte.
##### Step 4: Calculate the File Offsets
```
file_offset = address - 0x10000000
```
Note the offset of the immediate byte in each of the three `movs` instructions.
##### Step 5: Plan the Rotation
| Struct Member | Original | New | Effect |
| ------------- | ----------------- | ----------------- | ---------------- |
| `led1_pin` | `10` (GPIO 16 Red) | `11` (GPIO 17 Green) | Button 1 → Green |
| `led2_pin` | `11` (GPIO 17 Green) | `12` (GPIO 18 Yellow) | Button 2 → Yellow |
| `led3_pin` | `12` (GPIO 18 Yellow) | `10` (GPIO 16 Red) | Button 3 → Red |
##### Step 6: Patch with HxD
1. In HxD, open `C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0026_functions\build\0x0026_functions.bin`
2. Go to the first `movs` immediate offset and change `10` to `11`
3. Go to the second `movs` immediate offset and change `11` to `12`
4. Go to the third `movs` immediate offset and change `12` to `10`
###### Question 1: All three patches are single-byte changes in `movs` immediates. Why is this simpler than patching literal pool entries?
##### Step 7: Save and Convert
1. Click **File****Save As**`0x0026_functions-h.bin`
```powershell
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0026_functions
python ..\uf2conv.py build\0x0026_functions-h.bin --base 0x10000000 --family 0xe48bff59 --output build\hacked.uf2
```
##### Step 8: Flash and Verify
1. Hold BOOTSEL and plug in your Pico 2
2. Drag and drop `hacked.uf2` onto the RPI-RP2 drive
**Check the behavior:**
- Press button 1 → **Green** LED blinks (was Red)
- Press button 2 → **Yellow** LED blinks (was Green)
- Press button 3 → **Red** LED blinks (was Yellow)
- Terminal still says "LED 1 activated on GPIO 16" — but the actual LED is Green (GPIO 17)
#### Expected Output
After completing this exercise, you should be able to:
- Locate struct initialization patterns in ARM Thumb assembly
- Patch multiple `movs` immediates to rotate data values
- Understand the disconnect between logged values and actual hardware behavior
- Recognize log desynchronization as a security concern
#### Questions for Reflection
###### Question 1: The terminal log still says "LED 1 activated on GPIO 16" even though GPIO 17 (Green) is actually blinking. Why don't the logs update automatically?
###### Question 2: If the struct initialization used `ldr` from a literal pool instead of `movs` immediates, how would the patching approach differ?
###### Question 3: Could you achieve the same LED rotation by patching the `gpio_init` and `gpio_put` calls instead of the struct? Which approach is cleaner and why?
###### Question 4: In a real attack scenario, why is log desynchronization (logs say one thing, hardware does another) particularly dangerous for forensic analysis?
#### Tips and Hints
- The three `movs` instructions are likely within 10-20 bytes of each other — use `x/20i` to see them all at once
- The `movs rN, #imm8` immediate is in the lower byte of the 2-byte Thumb instruction
- Make sure you patch the `movs` for the struct initialization, not any other `movs #0x10/0x11/0x12` that may exist elsewhere
- Verify by examining the struct in memory after initialization: `x/6bx <struct_address>` should show `11 12 10` for the pin bytes
+146
View File
@@ -0,0 +1,146 @@
# Embedded Systems Reverse Engineering
[Repository](https://github.com/mytechnotalent/Embedded-Hacking)
## Week 11
Structures and Functions in Embedded Systems: Debugging and Hacking w/ IR Remote Control and NEC Protocol Basics
### Exercise 4: Change Blink Speed
#### Objective
Find the `blink_led(pin, 3, 50)` call in the `0x0026_functions` binary using GDB, identify the immediate value `0x32` (50) being loaded into `r2` (the delay parameter), calculate the file offset, and patch it to `0x19` (25) so that each LED blinks at double speed when activated by the IR remote.
#### Prerequisites
- Completed Week 11 tutorial (GDB and hex editor sections)
- `0x0026_functions.elf` and `0x0026_functions.bin` available in your build directory
- GDB (`arm-none-eabi-gdb`) and OpenOCD installed
- A hex editor (HxD, ImHex, or similar)
- Python installed (for UF2 conversion)
- Raspberry Pi Pico 2 with IR remote and LEDs on GPIO 16, 17, 18
#### Task Description
The `blink_led` function takes a delay parameter of `50`ms (`0x32`) in register `r2`. This value controls how long each LED stays on and off during the blink cycle. By patching this to `25`ms (`0x19`), the LEDs will blink twice as fast, creating a noticeably quicker flashing pattern when any IR remote button is pressed.
#### Step-by-Step Instructions
##### Step 1: Start the Debug Session
**Terminal 1 - Start OpenOCD:**
```powershell
openocd ^
-s "C:\Users\flare-vm\.pico-sdk\openocd\0.12.0+dev\scripts" ^
-f interface/cmsis-dap.cfg ^
-f target/rp2350.cfg ^
-c "adapter speed 5000"
```
**Terminal 2 - Start GDB:**
```powershell
arm-none-eabi-gdb build\0x0026_functions.elf
```
**Connect to target:**
```gdb
(gdb) target remote :3333
(gdb) monitor reset halt
```
##### Step 2: Find the blink_led Call
Disassemble main and look for the parameter setup before `bl blink_led`:
```gdb
(gdb) disassemble 0x10000234,+300
```
Look for:
```
movs r0, <pin> ; GPIO pin number
movs r1, #3 ; blink count
movs r2, #0x32 ; delay = 50ms
bl blink_led
```
Note the address of the `movs r2, #0x32` instruction.
##### Step 3: Examine the Instruction Encoding
Look at the raw bytes:
```gdb
(gdb) x/2bx <address_of_movs_r2_0x32>
```
The `movs r2, #0x32` instruction has `0x32` (50) as the immediate byte.
##### Step 4: Calculate the File Offset
```
file_offset = address - 0x10000000
```
Note the file offset of the byte containing `32`.
##### Step 5: Encode the New Value
| Parameter | Original | New | Effect |
| --------- | --------------- | --------------- | --------------- |
| Delay | `32` (50ms) | `19` (25ms) | 2x faster blink |
**Be careful:** `0x32` is also the ASCII code for '2'. Make sure you are patching the `movs r2` instruction and not a comparison value like `cmp r4, #0x32`.
##### Step 6: Patch with HxD
1. In HxD, open `C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0026_functions\build\0x0026_functions.bin`
2. Press **Ctrl+G** and enter the file offset
3. You should see: `32`
4. Replace with: `19`
###### Question 1: How can you confirm you are patching the delay parameter and not some other `0x32` byte in the binary?
##### Step 7: Save and Convert
1. Click **File****Save As**`0x0026_functions-h.bin`
```powershell
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0026_functions
python ..\uf2conv.py build\0x0026_functions-h.bin --base 0x10000000 --family 0xe48bff59 --output build\hacked.uf2
```
##### Step 8: Flash and Verify
1. Hold BOOTSEL and plug in your Pico 2
2. Drag and drop `hacked.uf2` onto the RPI-RP2 drive
**Check the behavior:**
- Press button 1 → Red LED blinks 3 times but **noticeably faster** (25ms on/off vs 50ms)
- Press button 2 → Green LED blinks 3 times at **double speed**
- Press button 3 → Yellow LED blinks 3 times at **double speed**
- The total blink sequence should complete in roughly half the original time
#### Expected Output
After completing this exercise, you should be able to:
- Locate function parameters in ARM Thumb `movs` instructions
- Distinguish between identical byte values used in different contexts
- Patch timing parameters to change observable hardware behavior
- Understand the relationship between delay values and perceived blink speed
#### Questions for Reflection
###### Question 1: The `blink_led` function calls `sleep_ms` internally with the delay value. If you set the delay to `1`ms (0x01), would you still see the LED blink, or would it appear constantly on?
###### Question 2: The value `0x32` appears in this binary as both a delay parameter (50ms) and potentially as an ASCII comparison ('2'). How would you systematically find ALL occurrences of `0x32` and determine which one to patch?
###### Question 3: If you wanted a delay of 500ms (0x1F4), the value would not fit in a `movs` immediate. How would the compiler handle this larger delay value?
###### Question 4: The blink function uses the delay for both the on-time and the off-time. Could you make the LED stay on longer than it stays off? What kind of patch would that require?
#### Tips and Hints
- `25` decimal = `0x19` hex — fits in one byte, so the `movs` encoding works directly
- Verify location by checking the surrounding instructions: `movs r1, #3` should be right before and `bl blink_led` right after
- The total blink time for 3 blinks at 50ms = 3 × (50 + 50) = 300ms; at 25ms = 3 × (25 + 25) = 150ms
- If there are multiple call sites for `blink_led`, each may have its own `movs r2, #0x32` that needs patching
Binary file not shown.
+1529
View File
File diff suppressed because it is too large Load Diff