Added legal statements

This commit is contained in:
Kevin Thomas
2026-07-19 09:26:57 -04:00
parent 6a9090915b
commit bd949952ad
12 changed files with 269 additions and 103 deletions
+14
View File
@@ -1,5 +1,19 @@
# Embedded Hacking - Hardware Parts and Products
---
**LEGAL DISCLAIMER:**
The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that:
1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
**IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.**
---
Here is a comprehensive list of hardware parts, products, and components referenced in the repository for the Embedded Hacking course:
## Specific Components & Sensors
+14 -2
View File
@@ -1,5 +1,19 @@
![image](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/Embedded%20Hacking.png?raw=true)
---
**LEGAL DISCLAIMER:**
The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that:
1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
**IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.**
---
## FREE Reverse Engineering Self-Study Course [HERE](https://github.com/mytechnotalent/Reverse-Engineering-Tutorial)
<br>
@@ -354,8 +368,6 @@ In the aftermath of a catastrophic medical device failure, you are thrust into t
### Final Project Option 2: Operation Dark Eclipse
Forty-two stories beneath frozen tundra, a shadow intelligence alliance called Dark Eyes operates centrifuges enriching weapons-grade material for a first strike against Washington, D.C. and Agent NIGHTINGALE gave her life to extract the single firmware file that now sits before you. Conventional warfare cannot reach this fortress buried beneath rock and concrete, but you can: as the architect of a precision cyber weapon in the tradition of Stuxnet, you must reverse engineer the RP2350-based centrifuge controller, craft binary patches that double the spin speed while falsifying every sensor readout to show nominal operation, and execute the sabotage that will cascade-destroy their enrichment program and set their nuclear ambitions back a decade. Every skill from the entire semester ARM assembly, Ghidra analysis, IEEE-754 floating-point manipulation, branch modification, log desynchronization converges in this final mission. Agent NIGHTINGALE's seven-year-old daughter still watches the driveway, waiting for a mother who will never return. Honor that sacrifice. Complete the mission. Do not fail.
<br>
# License
+14
View File
@@ -1,5 +1,19 @@
# Week 1: Introduction and Overview of Embedded Reverse Engineering: Ethics, Scoping, and Basic Concepts
---
**LEGAL DISCLAIMER:**
The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that:
1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
**IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.**
---
## What You'll Learn This Week
By the end of this week, you will be able to:
+14
View File
@@ -1,5 +1,19 @@
# Week 2: Hello, World - Debugging and Hacking Basics: Debugging and Hacking a Basic Program for the Pico 2
---
**LEGAL DISCLAIMER:**
The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that:
1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
**IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.**
---
## What You'll Learn This Week
By the end of this tutorial, you will be able to:
+14
View File
@@ -1,5 +1,19 @@
# Week 3: Embedded System Analysis: Understanding the RP2350 Architecture w/ Comprehensive Firmware Analysis
---
**LEGAL DISCLAIMER:**
The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that:
1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
**IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.**
---
## What You'll Learn This Week
By the end of this tutorial, you will be able to:
+28 -14
View File
@@ -1,4 +1,18 @@
# Week 4: Variables in Embedded Systems: Debugging and Hacking Variables w/ GPIO Output Basics
# Week 4: Variables in Embedded Systems: Debugging and Hacking Variables w/ GPIO Output Basics
---
**LEGAL DISCLAIMER:**
The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that:
1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
**IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.**
---
## What You'll Learn This Week
@@ -211,11 +225,11 @@ First, let's look at the code we'll be analyzing:
int main(void) {
uint8_t age = 42;
age = 43;
stdio_init_all();
while (true)
printf("age: %d\r\n", age);
}
@@ -395,7 +409,7 @@ The compiler **optimized it out**! Here's what happened:
3. Compiler removes the unused `42` and just uses `43` directly
**What is `0x2b`?** Let's check:
- `0x2b` in hexadecimal = `43` in decimal
- `0x2b` in hexadecimal = `43` in decimal
The compiler replaced our variable with the constant value!
@@ -496,12 +510,12 @@ Now let's work with a more complex example that includes GPIO control.
int main(void) {
uint8_t age; // Uninitialized!
stdio_init_all();
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
while (true) {
printf("age: %d\r\n", age);
@@ -577,7 +591,7 @@ void FUN_10000234(void)
undefined4 extraout_r2;
undefined4 in_cr0;
undefined4 in_cr4;
FUN_100030cc();
FUN_100002b4(0x10);
coprocessor_moveto2(0,4,0x10,1,in_cr4);
@@ -757,24 +771,24 @@ loop:
movs r4, #0x10 ; GPIO 16
movs r5, #0x01 ; High
mcrr p0, #4, r4, r5, c0
; Delay
ldr r2, =0x17D7840 ; ~25 million iterations
delay1:
subs r2, r2, #1
bne delay1
; LED OFF
movs r4, #0x10 ; GPIO 16
movs r5, #0x00 ; Low
mcrr p0, #4, r4, r5, c0
; Delay
ldr r2, =0x17D7840
delay2:
subs r2, r2, #1
bne delay2
b loop ; Repeat forever
```
@@ -905,6 +919,6 @@ The RP2350 GPIO coprocessor instructions:
**Remember:** Every binary you encounter in the real world can be analyzed and understood using these same techniques. Practice makes perfect!
Happy hacking!
Happy hacking!
+39 -25
View File
@@ -1,4 +1,18 @@
# Week 5: Integers and Floats in Embedded Systems: Debugging and Hacking Integers and Floats w/ Intermediate GPIO Output Assembler Analysis
# Week 5: Integers and Floats in Embedded Systems: Debugging and Hacking Integers and Floats w/ Intermediate GPIO Output Assembler Analysis
---
**LEGAL DISCLAIMER:**
The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that:
1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
**IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.**
---
## What You'll Learn This Week
@@ -180,7 +194,7 @@ Let's look at a simple program that uses a `float` variable:
int main(void) {
float fav_num = 42.5;
stdio_init_all();
while (true)
@@ -327,7 +341,7 @@ int main(void)
undefined4 extraout_r1;
undefined4 uVar2;
undefined4 extraout_r1_00;
FUN_10002f5c();
uVar1 = DAT_1000024c;
uVar2 = extraout_r1;
@@ -365,7 +379,7 @@ int main(void)
undefined4 extraout_r1;
undefined4 uVar2;
undefined4 extraout_r1_00;
stdio_init_all();
uVar1 = DAT_1000024c;
uVar2 = extraout_r1;
@@ -523,17 +537,17 @@ Look at the **Listing** window (assembly view). Find the main function:
```
*************************************************************
* FUNCTION
* FUNCTION
*************************************************************
int __stdcall main (void )
int r0:4 <RETURN>
main+1 XREF[1,1]: 1000018c (c) , 1000018a (*)
main+1 XREF[1,1]: 1000018c (c) , 1000018a (*)
main
10000234 38 b5 push {r3,r4,r5,lr}
10000236 02 f0 91 fe bl stdio_init_all bool stdio_init_all(void)
1000023a 00 24 movs r4,#0x0
1000023c 03 4d ldr r5,[DAT_1000024c ] = 40454000h
LAB_1000023e XREF[1]: 10000248 (j)
LAB_1000023e XREF[1]: 10000248 (j)
1000023e 22 46 mov r2,r4
10000240 2b 46 mov r3,r5
10000242 03 48 ldr r0=>s_fav_num:_%f_100034a8 ,[DAT_10000250 ] = "fav_num: %f\r\n"
@@ -542,9 +556,9 @@ Look at the **Listing** window (assembly view). Find the main function:
10000248 f9 e7 b LAB_1000023e
1000024a 00 ?? 00h
1000024b bf ?? BFh
DAT_1000024c XREF[1]: main:1000023c (R)
DAT_1000024c XREF[1]: main:1000023c (R)
1000024c 00 40 45 40 undefine 40454000h
DAT_10000250 XREF[1]: main:10000242 (R)
DAT_10000250 XREF[1]: main:10000242 (R)
10000250 a8 34 00 10 undefine 100034A8h * -> 100034a8
```
@@ -555,10 +569,10 @@ Look at the **Listing** window (assembly view). Find the main function:
In the Listing view, click on the data reference to find the format string:
```
s_fav_num:_%f_100034a8 XREF[1]: main:10000242 (*)
s_fav_num:_%f_100034a8 XREF[1]: main:10000242 (*)
100034a8 66 61 76 ds "fav_num: %f\r\n"
5f 6e 75
6d 3a 20
5f 6e 75
6d 3a 20
```
This confirms `printf` is called with the format string `"fav_num: %f\r\n"` and the double-precision value of `42.5`.
@@ -729,7 +743,7 @@ Let's look at a program that uses a `double` variable:
int main(void) {
double fav_num = 42.52525;
stdio_init_all();
while (true)
@@ -873,7 +887,7 @@ int main(void)
undefined4 extraout_r1;
undefined4 uVar3;
undefined4 extraout_r1_00;
uVar2 = DAT_10000258;
uVar1 = DAT_10000254;
FUN_10002f64();
@@ -913,7 +927,7 @@ int main(void)
undefined4 extraout_r1;
undefined4 uVar3;
undefined4 extraout_r1_00;
uVar2 = DAT_10000258;
uVar1 = DAT_10000254;
stdio_init_all();
@@ -1071,29 +1085,29 @@ Look at the **Listing** window (assembly view). Find the main function:
```
*************************************************************
* FUNCTION
* FUNCTION
*************************************************************
int __stdcall main (void )
int r0:4 <RETURN>
main+1 XREF[1,1]: 1000018c (c) , 1000018a (*)
main+1 XREF[1,1]: 1000018c (c) , 1000018a (*)
main
10000238 38 b5 push {r3,r4,r5,lr}
1000023a 06 a5 adr r5,[0x10000254 ]
1000023c d5 e9 00 45 ldrd r4,r5,[r5,#0x0 ]=>DAT_10000254 = 645A1CACh
= 4045433Bh
10000240 02 f0 90 fe bl stdio_init_all bool stdio_init_all(void)
LAB_10000244 XREF[1]: 1000024e (j)
LAB_10000244 XREF[1]: 1000024e (j)
10000244 22 46 mov r2,r4
10000246 2b 46 mov r3,r5
10000248 01 48 ldr r0=>s_fav_num:_%lf_100034b0 ,[DAT_10000250 ] = "fav_num: %lf\r\n"
= 100034B0h
1000024a 02 f0 53 ff bl printf int printf(char * format, ...)
1000024e f9 e7 b LAB_10000244
DAT_10000250 XREF[1]: main:10000248 (R)
DAT_10000250 XREF[1]: main:10000248 (R)
10000250 b0 34 00 10 undefine 100034B0h ? -> 100034b0
DAT_10000254 XREF[1]: main:1000023c (R)
DAT_10000254 XREF[1]: main:1000023c (R)
10000254 ac 1c 5a 64 undefine 645A1CACh
DAT_10000258 XREF[1]: main:1000023c (R)
DAT_10000258 XREF[1]: main:1000023c (R)
10000258 3b 43 45 40 undefine 4045433Bh
```
@@ -1104,10 +1118,10 @@ Look at the **Listing** window (assembly view). Find the main function:
In the Listing view, click on the data reference to find the format string:
```
s_fav_num:_%lf_100034b0 XREF[1]: main:10000248 (*)
s_fav_num:_%lf_100034b0 XREF[1]: main:10000248 (*)
100034b0 66 61 76 ds "fav_num: %lf\r\n"
5f 6e 75
6d 3a 20
5f 6e 75
6d 3a 20
```
This confirms `printf` is called with the format string `"fav_num: %lf\r\n"` and the double-precision value of `42.52525`.
@@ -1349,5 +1363,5 @@ 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!
+27 -13
View File
@@ -1,5 +1,19 @@
# Week 6: Static Variables in Embedded Systems: Debugging and Hacking Static Variables w/ GPIO Input Basics
---
**LEGAL DISCLAIMER:**
The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that:
1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
**IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.**
---
## What You'll Learn This Week
By the end of this tutorial, you will be able to:
@@ -32,15 +46,15 @@ Think of it like this:
| +------------------------------------------------------------+ |
| | Loop 1: Create -> Set to 42 -> Increment to 43 -> Destroy |
| | Loop 2: Create -> Set to 42 -> Increment to 43 -> Destroy |
| | Loop 3: Create -> Set to 42 -> Increment to 43 -> Destroy |
| | Loop 3: Create -> Set to 42 -> Increment to 43 -> Destroy |
| | Result: Always appears as 42! |
| +------------------------------------------------------------+ |
| |
| STATIC: |
| +------------------------------------------------------------+ |
| | Loop 1: Already exists -> Read 42 -> Increment -> Store 43 |
| | Loop 2: Already exists -> Read 43 -> Increment -> Store 44 |
| | Loop 3: Already exists -> Read 44 -> Increment -> Store 45 |
| | Loop 1: Already exists -> Read 42 -> Increment -> Store 43 |
| | Loop 2: Already exists -> Read 43 -> Increment -> Store 44 |
| | Loop 3: Already exists -> Read 44 -> Increment -> Store 45 |
| | Result: Keeps incrementing! |
| +------------------------------------------------------------+ |
| |
@@ -237,7 +251,7 @@ The compiler sees that incrementing `regular_fav_num` has no lasting effect (bec
### Function Inlining
Sometimes the compiler **inlines** functions, meaning it replaces a function call with the function's code directly.
Sometimes the compiler **inlines** functions, meaning it replaces a function call with the function's code directly.
**Original code:**
```c
@@ -326,28 +340,28 @@ Let's examine the static variables code:
int main(void) {
stdio_init_all();
const uint BUTTON_GPIO = 15;
const uint LED_GPIO = 16;
bool pressed = 0;
gpio_init(BUTTON_GPIO);
gpio_set_dir(BUTTON_GPIO, GPIO_IN);
gpio_pull_up(BUTTON_GPIO);
gpio_init(LED_GPIO);
gpio_set_dir(LED_GPIO, GPIO_OUT);
while (true) {
uint8_t regular_fav_num = 42;
static uint8_t static_fav_num = 42;
printf("regular_fav_num: %d\r\n", regular_fav_num);
printf("static_fav_num: %d\r\n", static_fav_num);
regular_fav_num++;
static_fav_num++;
pressed = gpio_get(BUTTON_GPIO);
gpio_put(LED_GPIO, pressed ? 0 : 1);
}
@@ -582,7 +596,7 @@ GDB will stop at `movs r1, #42` that is the compiler's constant for `regular_fa
This is where the static variable is actually manipulated:
```gdb
```gdb
(gdb) x/4i $pc
=> 0x10000278 <main+68>: ldrb r3, [r4, #0] <- load static_fav_num from RAM into r3
0x1000027a <main+70>: movs r2, #16 <- load LED pin number (16) into r2 for later
+17 -3
View File
@@ -1,5 +1,19 @@
# Week 7: Constants in Embedded Systems: Debugging and Hacking Constants w/ 1602 LCD I2C Basics
---
**LEGAL DISCLAIMER:**
The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that:
1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
**IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.**
---
## What You'll Learn This Week
By the end of this tutorial, you will be able to:
@@ -409,19 +423,19 @@ const int OTHER_FAV_NUM = 1337;
int main(void) {
stdio_init_all();
i2c_init(I2C_PORT, 100000);
gpio_set_function(I2C_SDA_PIN, GPIO_FUNC_I2C);
gpio_set_function(I2C_SCL_PIN, GPIO_FUNC_I2C);
gpio_pull_up(I2C_SDA_PIN);
gpio_pull_up(I2C_SCL_PIN);
lcd_i2c_init(I2C_PORT, 0x27, 4, 0x08);
lcd_set_cursor(0, 0);
lcd_puts("Reverse");
lcd_set_cursor(1, 0);
lcd_puts("Engineering");
while (true) {
printf("FAV_NUM: %d\r\n", FAV_NUM);
printf("OTHER_FAV_NUM: %d\r\n", OTHER_FAV_NUM);
+21 -7
View File
@@ -1,5 +1,19 @@
# Week 9: Operators in Embedded Systems: Debugging and Hacking Operators w/ DHT11 Temperature & Humidity Sensor Single-Wire Protocol Basics.
---
**LEGAL DISCLAIMER:**
The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that:
1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
**IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.**
---
## What You'll Learn This Week
By the end of this tutorial, you will be able to:
@@ -404,7 +418,7 @@ int main(void) {
int increment_operator = x++;
bool relational_operator = (x > y);
bool logical_operator = (x > y) && (y > x);
int bitwise_operator = (x<<1); // x is now 6 because of x++ or 0b00000110 and (x<<1) is 0b00001100 or 12
int bitwise_operator = (x<<1); // x is now 6 because of x++ or 0b00000110 and (x<<1) is 0b00001100 or 12
int assignment_operator = (x += 5);
while (true) {
@@ -414,14 +428,14 @@ int main(void) {
printf("logical_operator: %d\r\n", logical_operator);
printf("bitwise_operator: %d\r\n", bitwise_operator);
printf("assignment_operator: %d\r\n", assignment_operator);
float hum, temp;
if (dht11_read(&hum, &temp)) {
printf("Humidity: %.1f%%, Temperature: %.1f?C\r\n", hum, temp);
} else {
printf("DHT11 read failed\r\n");
}
sleep_ms(2000);
}
}
@@ -559,7 +573,7 @@ x/32i 0x10000240
You may see values like:
- `#0x32` (50) for arithmetic_operator
- `#0x5` (5) for increment_operator
- `#0x5` (5) for increment_operator
- `#0x0` (0) for relational and logical operators
- `#0xc` (12) for bitwise_operator
- `#0xb` (11) for assignment_operator
@@ -787,7 +801,7 @@ movs r0, #0x4 ; GPIO pin 4
bl FUN_xxxxx ; dht11_init
```
**How do we know it's dht11_init?**
**How do we know it's dht11_init?**
- The argument `4` is the GPIO pin number
- We physically connected the DHT11 to GPIO 4!
@@ -997,7 +1011,7 @@ import struct
original = struct.unpack('<f', bytes.fromhex('cdcccc3d'))[0]
print(f"Original: {original}") # 0.1
# New value
# New value
new = struct.unpack('<f', bytes.fromhex('0000a040'))[0]
print(f"New: {new}") # 5.0
```
@@ -1010,7 +1024,7 @@ print(f"New: {new}") # 5.0
>>> print(f"Original: {original}") # 0.1
Original: 0.10000000149011612
>>>
>>> # New value
>>> # New value
>>> new = struct.unpack('<f', bytes.fromhex('0000a040'))[0]
>>> print(f"New: {new}") # 5.0
New: 5.0
+37 -23
View File
@@ -1,5 +1,19 @@
# Week 10: Conditionals in Embedded Systems: Debugging and Hacking Static & Dynamic Conditionals w/ SG90 Servo Motor PWM Basics
---
**LEGAL DISCLAIMER:**
The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that:
1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
**IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.**
---
## What You'll Learn This Week
By the end of this tutorial, you will be able to:
@@ -136,7 +150,7 @@ uint8_t choice = 0;
while (true) {
choice = getchar(); // User types a key - VALUE CHANGES!
if (choice == '1') {
printf("1\r\n");
} else if (choice == '2') {
@@ -197,7 +211,7 @@ uint8_t choice = getchar(); // Waits for user to type something
```text
PWM Signal - 50% Duty Cycle
HIGH +-----+ +-----+ +-----+
| | | | | |
LOW + +-----+ +-----+ +-----
@@ -484,11 +498,11 @@ Let's examine the static conditionals code:
int main(void) {
stdio_init_all();
int choice = 1; // STATIC - never changes!
servo_init(SERVO_GPIO);
while (true) {
// if/else conditional
if (choice == 1) {
@@ -498,7 +512,7 @@ int main(void) {
} else {
printf("?\r\n");
}
// switch/case conditional
switch (choice) {
case 1:
@@ -510,7 +524,7 @@ int main(void) {
default:
printf("??\r\n");
}
// Servo movement
servo_set_angle(0.0f);
sleep_ms(500);
@@ -661,15 +675,15 @@ nexti
Keep pressing **Enter** to repeat the `nexti` command and watch the instructions.
**Wait, where is the `cmp` instruction?!**
You might notice that there is NO `cmp` instruction comparing our `choice` variable anywhere! Why? Because we hardcoded `int choice = 1;` at the start of our C code and never changed it.
You might notice that there is NO `cmp` instruction comparing our `choice` variable anywhere! Why? Because we hardcoded `int choice = 1;` at the start of our C code and never changed it.
The C compiler is smart (even at basic optimization levels). It realized the `if (choice == 1)` condition would *always* be true, and the `else` conditions would *never* happen. Instead of wasting CPU cycles checking a condition that never changes, the compiler **optimized out the check entirely**! It just compiled the code inside the `choice == 1` block unconditionally.
The C compiler is smart (even at basic optimization levels). It realized the `if (choice == 1)` condition would *always* be true, and the `else` conditions would *never* happen. Instead of wasting CPU cycles checking a condition that never changes, the compiler **optimized out the check entirely**! It just compiled the code inside the `choice == 1` block unconditionally.
This is the defining characteristic of a "Static Conditional"—the condition is resolved at compile-time, not run-time!
### Step 12: Examine the Printf/Puts Arguments
If you look closely at your disassembly, you'll notice there are no `printf` calls! The compiler optimized our simple `printf` statements into `puts` (specifically `__wrap_puts` in the Pico SDK) because they didn't contain any complex formatting variables.
If you look closely at your disassembly, you'll notice there are no `printf` calls! The compiler optimized our simple `printf` statements into `puts` (specifically `__wrap_puts` in the Pico SDK) because they didn't contain any complex formatting variables.
When you reach a `bl <__wrap_puts>` instruction, check `r0` for the string address:
@@ -677,13 +691,13 @@ When you reach a `bl <__wrap_puts>` instruction, check `r0` for the string addre
x/s $r0
```
You should see strings like `"1\r"` or `"one\r"`.
You should see strings like `"1\r"` or `"one\r"`.
*(Wait, what happened to the `\n`? Because the `puts` function automatically adds a newline to the end of whatever it prints, the compiler cleverly trimmed the `\n` out of the string literal in memory to save space!)*
### Step 13: Watch the Servo Commands
Let's set a breakpoint on `servo_set_angle`. How do you know the address? If you look at your `main` disassembly, you can find the `bl` instruction calling it (for example, `0x10000310`).
Let's set a breakpoint on `servo_set_angle`. How do you know the address? If you look at your `main` disassembly, you can find the `bl` instruction calling it (for example, `0x10000310`).
But hardcoded addresses change every time you recompile! Luckily, GDB is smart enough to resolve function names directly from the ELF file:
@@ -846,7 +860,7 @@ bl FUN_10001884 undefined FUN_10001884()
### Step 26: Resolve servo_set_angle
Look for a function call (like `bl FUN_10000310`) that occurs right after the float arguments are loaded into `r0`.
Look for a function call (like `bl FUN_10000310`) that occurs right after the float arguments are loaded into `r0`.
```assembly
mov r0,r5
@@ -899,9 +913,9 @@ bl FUN_10000e20 undefined FUN_10000e20()
### Step 29: Hack #1 - Change "1" to "2"
First, we need to find the string "1" in the binary.
First, we need to find the string "1" in the binary.
1. Go back to your `main` assembly code and look for the first `puts` call.
1. Go back to your `main` assembly code and look for the first `puts` call.
2. In the `ldr` instruction right before it, look for the reference next to the arrow: `r0=>DAT_10001c54`. **Double-click exactly on `DAT_10001c54`**. *(Warning: Do NOT click the reference inside the brackets like `[DAT_10000274]`, or you'll end up in the pointer table instead of the string!)*
3. The Listing and Bytes windows will automatically jump to the string's exact address!
4. Look at your **Bytes** window. You should see the byte `31` (which is ASCII for "1").
@@ -986,14 +1000,14 @@ fun
int main(void) {
stdio_init_all();
uint8_t choice = 0; // DYNAMIC - changes with user input!
servo_init(SERVO_GPIO);
while (true) {
choice = getchar(); // Wait for keyboard input
if (choice == 0x31) { // '1'
printf("1\r\n");
} else if (choice == 0x32) { // '2'
@@ -1001,7 +1015,7 @@ int main(void) {
} else {
printf("??\r\n");
}
switch (choice) {
case '1':
printf("one\r\n");
@@ -1126,7 +1140,7 @@ If you pressed '1', you should see `0x31`. If you pressed '2', you should see `0
### Step 44: Execute the Comparison
Right now, GDB is paused *before* the `cmp` instruction runs (the `=>` arrow points to the instruction that will execute *next*).
Right now, GDB is paused *before* the `cmp` instruction runs (the `=>` arrow points to the instruction that will execute *next*).
To see the result of the comparison, we must execute the `cmp` instruction by stepping forward exactly once:
@@ -1146,7 +1160,7 @@ info registers xpsr
```
*(Note: Older ARM chips call this `cpsr`, but Cortex-M chips like the Pico's RP2350 call it `xpsr`!)*
The zero flag (`Z`) determines if the branch is taken. The flags are stored in the highest nibble (the first hex digit) of the `xpsr` register in the order `N Z C V`.
The zero flag (`Z`) determines if the branch is taken. The flags are stored in the highest nibble (the first hex digit) of the `xpsr` register in the order `N Z C V`.
If you typed '1', the comparison resulted in zero difference, setting the `Z` flag to 1. You should see `xpsr` start with a `6` (like `0x69000000`). `6` in binary is `0110`, which means the `Z` flag (the second bit) is 1! The `beq.n` instruction will see this flag and take the branch.
@@ -1315,7 +1329,7 @@ We want to create **secret commands** that:
Navigate to the `main` function and find the two `cmp` instructions right after `getchar`:
1. At address `1000024a`, you will see `cmp r4,#0x31`.
1. At address `1000024a`, you will see `cmp r4,#0x31`.
- Right-click it, select **Patch Instruction**, and change it to `cmp r4,#0x78` (which is ASCII 'x').
2. At address `1000024e`, you will see `cmp r4,#0x32`.
- Right-click it, select **Patch Instruction**, and change it to `cmp r4,#0x79` (which is ASCII 'y').
+30 -16
View File
@@ -1,4 +1,18 @@
# Week 11: Structures and Functions in Embedded Systems: Debugging and Hacking w/ IR Remote Control and NEC Protocol Basics
# Week 11: Structures and Functions in Embedded Systems: Debugging and Hacking w/ IR Remote Control and NEC Protocol Basics
---
**LEGAL DISCLAIMER:**
The information, tools, and code provided in this repository and course are strictly for educational, research, and defensive purposes only.
You are explicitly prohibited from using any materials contained herein to access, test, modify, or exploit any device, network, or system that you do not own 100% or for which you do not have explicit, documented, and legally binding authorization to interact with.
By using this repository and course, you acknowledge and agree that:
1. Any illegal, unauthorized, or malicious use of this information is solely your responsibility.
2. The author(s) and contributor(s) of this repository and course shall not be held liable for any damages, legal repercussions, criminal charges, or unauthorized actions resulting from the use, misuse, or abuse of the contents herein.
3. You will comply with all applicable local, state, national, and international laws regarding cybersecurity and computer fraud.
**IF YOU DO NOT AGREE WITH THESE TERMS, DO NOT USE THIS REPOSITORY AND COURSE.**
---
## What You'll Learn This Week
@@ -503,7 +517,7 @@ typedef struct {
int main(void) {
stdio_init_all();
simple_led_ctrl_t leds = {
.led1_pin = 16,
.led2_pin = 17,
@@ -512,34 +526,34 @@ int main(void) {
.led2_state = false,
.led3_state = false
};
gpio_init(leds.led1_pin); gpio_set_dir(leds.led1_pin, GPIO_OUT);
gpio_init(leds.led2_pin); gpio_set_dir(leds.led2_pin, GPIO_OUT);
gpio_init(leds.led3_pin); gpio_set_dir(leds.led3_pin, GPIO_OUT);
ir_init(IR_PIN);
printf("IR receiver on GPIO %d ready\n", IR_PIN);
while (true) {
int key = ir_getkey();
if (key >= 0) {
printf("NEC command: 0x%02X\n", key);
// Turn all off first
leds.led1_state = false;
leds.led2_state = false;
leds.led3_state = false;
// Check NEC codes
if (key == 0x0C) leds.led1_state = true; // GPIO16
if (key == 0x18) leds.led2_state = true; // GPIO17
if (key == 0x5E) leds.led3_state = true; // GPIO18
// Apply states
gpio_put(leds.led1_pin, leds.led1_state);
gpio_put(leds.led2_pin, leds.led2_state);
gpio_put(leds.led3_pin, leds.led3_state);
sleep_ms(10);
} else {
sleep_ms(1);
@@ -673,7 +687,7 @@ You should see `r0 = 16`. If you set breakpoints on the subsequent calls (`0x100
### Step 13: Examine IR Key Processing
Because `ir_getkey` is polled in a loop and returns `-1` constantly when no key is pressed, breaking at the immediate return (`0x10000274`) will just flood you with `-1`s!
Because `ir_getkey` is polled in a loop and returns `-1` constantly when no key is pressed, breaking at the immediate return (`0x10000274`) will just flood you with `-1`s!
Instead, set a breakpoint *inside* the `if (key >= 0)` block at `0x10000278`. This is right after the `blt.n` conditional branch that skips over the processing logic when no key is pressed:
@@ -1061,15 +1075,15 @@ void blink_led(uint8_t pin, uint8_t count, uint32_t delay_ms) {
// Main command processor
int process_ir_led_command(int ir_command, simple_led_ctrl_t *leds, uint8_t blink_count) {
if (!leds || ir_command < 0) return -1;
leds_all_off(leds);
int led_num = ir_to_led_number(ir_command);
if (led_num == 0) return 0;
uint8_t pin = get_led_pin(leds, led_num);
blink_led(pin, blink_count, 50);
gpio_put(pin, true);
return led_num;
}
```
@@ -1162,7 +1176,7 @@ You'll see multiple function prologues (push) and epilogues (pop) for the helper
The C code relies heavily on helper functions (`process_ir_led_command`, `leds_all_off`, `ir_to_led_number`, `blink_led`). But if you scroll through the disassembly, you'll notice a distinct lack of function prologues, epilogues, or `bl` calls to anything other than `sleep_ms` or `printf`!
The compiler has aggressively **inlined** every single helper function into the main loop.
The compiler has aggressively **inlined** every single helper function into the main loop.
Let's trace exactly how the compiler flattened this logic. First, set a breakpoint right when a key press is detected:
@@ -1175,7 +1189,7 @@ continue
### Step 44: Examine leds_all_off (Inlined)
In the C code, `process_ir_led_command` starts by calling `leds_all_off(&leds)`.
In the C code, `process_ir_led_command` starts by calling `leds_all_off(&leds)`.
Let's look at the next few instructions starting from our breakpoint:
```gdb
@@ -1213,7 +1227,7 @@ Instead of a separate function, it simply compares the button code in `r4` (`12`
### Step 46: Watch the blink_led Loop
Let's set a breakpoint where the blinking loop begins for Button 1 (which handles the Red LED on pin 16).
Let's set a breakpoint where the blinking loop begins for Button 1 (which handles the Red LED on pin 16).
```gdb
break *0x100002c6