mirror of
https://github.com/mytechnotalent/Embedded-Hacking.git
synced 2026-08-28 13:50:45 +02:00
Refactor E and S
This commit is contained in:
+25
-25
@@ -1,10 +1,10 @@
|
||||
# Embedded Systems Reverse Engineering
|
||||
# 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
|
||||
|
||||
### Exercise 1: Analyze the Float Binary in Ghidra
|
||||
### Non-Credit Practice Exercise 1: Analyze the Float Binary in Ghidra
|
||||
|
||||
#### Objective
|
||||
Import and analyze the `0x000e_floating-point-data-type.bin` binary in Ghidra to understand how the compiler handles floating-point variables, discover float-to-double promotion, and decode the IEEE 754 double-precision encoding of `42.5` from two 32-bit registers.
|
||||
@@ -26,7 +26,7 @@ You will import the float binary into Ghidra, configure it for ARM Cortex-M33, r
|
||||
ghidraRun
|
||||
```
|
||||
|
||||
1. Click **File** → **New Project**
|
||||
1. Click **File** ? **New Project**
|
||||
2. Select **Non-Shared Project**
|
||||
3. Click **Next**
|
||||
4. Enter Project Name: `week05-ex01-floating-point`
|
||||
@@ -43,12 +43,12 @@ ghidraRun
|
||||
|
||||
When the import dialog appears:
|
||||
|
||||
1. Click the three dots (**…**) next to **Language**
|
||||
1. Click the three dots (**…**) next to **Language**
|
||||
2. Search for: `Cortex`
|
||||
3. Select: **ARM Cortex 32 little endian default**
|
||||
4. Click **OK**
|
||||
|
||||
Now click **Options…** button:
|
||||
Now click **Options…** button:
|
||||
1. Change **Block Name** to: `.text`
|
||||
2. Change **Base Address** to: `10000000` (XIP flash base)
|
||||
3. Click **OK**
|
||||
@@ -70,7 +70,7 @@ Look at the **Symbol Tree** panel on the left. Expand **Functions**.
|
||||
From previous weeks, we know the boot sequence leads to `main()`:
|
||||
|
||||
1. Click on `FUN_10000234`
|
||||
2. Right-click → **Edit Function Signature**
|
||||
2. Right-click ? **Edit Function Signature**
|
||||
3. Change to: `int main(void)`
|
||||
4. Click **OK**
|
||||
|
||||
@@ -78,13 +78,13 @@ From previous weeks, we know the boot sequence leads to `main()`:
|
||||
|
||||
**Rename stdio_init_all:**
|
||||
1. Click on `FUN_10002f5c` in the decompile window
|
||||
2. Right-click → **Edit Function Signature**
|
||||
2. Right-click ? **Edit Function Signature**
|
||||
3. Change to: `bool stdio_init_all(void)`
|
||||
4. Click **OK**
|
||||
|
||||
**Rename printf:**
|
||||
1. Click on `FUN_100030ec`
|
||||
2. Right-click → **Edit Function Signature**
|
||||
2. Right-click ? **Edit Function Signature**
|
||||
3. Change to: `int __wrap_printf(char *format,...)`
|
||||
4. Check the **Varargs** checkbox
|
||||
5. Click **OK**
|
||||
@@ -143,8 +143,8 @@ Map the 64-bit IEEE 754 fields:
|
||||
|
||||
```
|
||||
Bit 63 (sign): 0
|
||||
Bits 62–52 (exponent): 10000000100
|
||||
Bits 51–0 (mantissa): 0101010000000000...0000
|
||||
Bits 62–52 (exponent): 10000000100
|
||||
Bits 51–0 (mantissa): 0101010000000000...0000
|
||||
```
|
||||
|
||||
##### Step 10: Decode the Sign Bit
|
||||
@@ -154,14 +154,14 @@ Bit 63 of the double = bit 31 of r3:
|
||||
```
|
||||
r3 = 0x40454000 = 0100 0000 0100 0101 0100 0000 0000 0000
|
||||
^
|
||||
bit 31 = 0 → Positive number
|
||||
bit 31 = 0 ? Positive number
|
||||
```
|
||||
|
||||
IEEE 754 sign rule: `0` = Positive, `1` = Negative.
|
||||
|
||||
##### Step 11: Decode the Exponent
|
||||
|
||||
Extract bits 30–20 from r3:
|
||||
Extract bits 30–20 from r3:
|
||||
|
||||
```
|
||||
0x40454000: 0 10000000100 01010100000000000000
|
||||
@@ -169,7 +169,7 @@ Extract bits 30–20 from r3:
|
||||
sign exponent mantissa (top 20)
|
||||
```
|
||||
|
||||
Exponent bits: `10000000100` = 2¹⁰ + 2² = 1024 + 4 = **1028**
|
||||
Exponent bits: `10000000100` = 2¹° + 2² = 1024 + 4 = **1028**
|
||||
|
||||
Subtract the double-precision bias (1023):
|
||||
|
||||
@@ -177,7 +177,7 @@ $$\text{real exponent} = 1028 - 1023 = \mathbf{5}$$
|
||||
|
||||
##### Step 12: Decode the Mantissa
|
||||
|
||||
High 20 bits of mantissa (from r3 bits 19–0):
|
||||
High 20 bits of mantissa (from r3 bits 19–0):
|
||||
```
|
||||
0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
```
|
||||
@@ -200,15 +200,15 @@ Convert to decimal:
|
||||
|
||||
| Bit | Power | Value |
|
||||
|-----|-------|-------|
|
||||
| 1 | 2⁵ | 32 |
|
||||
| 0 | 2⁴ | 0 |
|
||||
| 1 | 2³ | 8 |
|
||||
| 0 | 2² | 0 |
|
||||
| 1 | 2¹ | 2 |
|
||||
| 0 | 2⁰ | 0 |
|
||||
| 1 | 2⁻¹ | 0.5 |
|
||||
| 1 | 25 | 32 |
|
||||
| 0 | 24 | 0 |
|
||||
| 1 | 2³ | 8 |
|
||||
| 0 | 2² | 0 |
|
||||
| 1 | 2¹ | 2 |
|
||||
| 0 | 2° | 0 |
|
||||
| 1 | 2?¹ | 0.5 |
|
||||
|
||||
$$32 + 8 + 2 + 0.5 = \mathbf{42.5} ✓$$
|
||||
$$32 + 8 + 2 + 0.5 = \mathbf{42.5} ?$$
|
||||
|
||||
##### Step 14: Find the Format String
|
||||
|
||||
@@ -230,7 +230,7 @@ Create a table of your observations:
|
||||
| Float value (original) | `42.5` | Declared as `float` |
|
||||
| Double hex encoding | `0x4045400000000000` | Promoted to double for printf |
|
||||
| r3 (high word) | `0x40454000` | Contains sign + exponent + mantissa top bits |
|
||||
| r2 (low word) | `0x00000000` | All zeros — clean fractional part |
|
||||
| r2 (low word) | `0x00000000` | All zeros — clean fractional part |
|
||||
| Exponent (stored) | 1028 | Biased value |
|
||||
| Exponent (real) | 5 | After subtracting bias 1023 |
|
||||
| Format string | `"fav_num: %f\r\n"` | Located at `0x100034a8` |
|
||||
@@ -265,7 +265,7 @@ After completing this exercise, you should be able to:
|
||||
#### Next Steps
|
||||
- Proceed to Exercise 2 to patch this float value in Ghidra
|
||||
- Try computing the IEEE 754 encoding of other values like `3.14` or `100.0` by hand
|
||||
- Compare the 32-bit float encoding `0x422A0000` with the 64-bit double encoding `0x4045400000000000` — both represent `42.5`
|
||||
- Compare the 32-bit float encoding `0x422A0000` with the 64-bit double encoding `0x4045400000000000` — both represent `42.5`
|
||||
|
||||
#### Additional Challenge
|
||||
Find the data constant `DAT_1000024c` in the Listing view. What raw bytes are stored there? Remember that ARM is little-endian — the bytes in memory are in reverse order. Write out the byte order as it appears in memory vs. as a 32-bit value.
|
||||
Find the data constant `DAT_1000024c` in the Listing view. What raw bytes are stored there? Remember that ARM is little-endian — the bytes in memory are in reverse order. Write out the byte order as it appears in memory vs. as a 32-bit value.
|
||||
|
||||
Reference in New Issue
Block a user