Updated WEEK05

This commit is contained in:
Kevin Thomas
2026-05-09 14:35:26 -04:00
parent ee664b6733
commit db4925f4b5
20 changed files with 1256 additions and 403 deletions
Binary file not shown.
+256 -297
View File
@@ -1,6 +1,6 @@
?# 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
@@ -25,10 +25,10 @@ In C programming for embedded systems, we have special integer types that tell t
+-----------------------------------------------------------------+
| Integer Types - Different Sizes for Different Needs |
| |
| uint8_t: 1 byte (0 to 255) - like a small box |
| int8_t: 1 byte (-128 to 127) - can hold negatives! |
| uint16_t: 2 bytes (0 to 65,535) - medium box |
| uint32_t: 4 bytes (0 to 4 billion) - big box |
| uint8_t: 1 byte (0 to 255) - like a small box |
| int8_t: 1 byte (-128 to 127) - can hold negatives! |
| uint16_t: 2 bytes (0 to 65,535) - medium box |
| uint32_t: 4 bytes (0 to 4 billion) - big box |
| |
+-----------------------------------------------------------------+
```
@@ -42,83 +42,9 @@ The difference between `uint8_t` and `int8_t` is whether the number can be **neg
| `uint8_t` | `u` | 0 to 255 | Ages, counts, always positive |
| `int8_t` | none | -128 to 127 | Temperature, can be negative |
Let's review the code in `0x000b_integer-data-type`.
```assembly
#include <stdio.h>
#include "pico/stdlib.h"
int main(void) {
uint8_t age = 43;
int8_t range = -42;
stdio_init_all();
__asm volatile (
"ldr r3, =0x40038000\n" // address of PADS_BANK0_BASE
"ldr r2, =0x40028004\n" // address of IO_BANK0 GPIO0.ctrl
"movs r0, #16\n" // GPIO16 (start pin)
"init_loop:\n" // loop start
"lsls r1, r0, #2\n" // pin * 4 (pad offset)
"adds r4, r3, r1\n" // PADS base + offset
"ldr r5, [r4]\n" // load current config
"bic r5, r5, #0x180\n" // clear OD+ISO
"orr r5, r5, #0x40\n" // set IE
"str r5, [r4]\n" // store updated config
"lsls r1, r0, #3\n" // pin * 8 (ctrl offset)
"adds r4, r2, r1\n" // IO_BANK0 base + offset
"ldr r5, [r4]\n" // load current config
"bic r5, r5, #0x1f\n" // clear FUNCSEL bits [4:0]
"orr r5, r5, #5\n" // set FUNCSEL = 5 (SIO)
"str r5, [r4]\n" // store updated config
"mov r4, r0\n" // pin
"movs r5, #1\n" // bit 1; used for OUT/OE writes
"mcrr p0, #4, r4, r5, c4\n" // gpioc_bit_oe_put(pin,1)
"adds r0, r0, #1\n" // increment pin
"cmp r0, #20\n" // stop after pin 18
"blt init_loop\n" // loop until r0 == 20
);
uint8_t pin = 16;
while (1) {
__asm volatile (
"mov r4, %0\n" // pin
"movs r5, #0x01\n" // bit 1; used for OUT/OE writes
"mcrr p0, #4, r4, r5, c0\n" // gpioc_bit_out_put(16, 1)
:
: "r"(pin)
: "r4","r5"
);
sleep_ms(500);
__asm volatile (
"mov r4, %0\n" // pin
"movs r5, #0\n" // bit 0; used for OUT/OE writes
"mcrr p0, #4, r4, r5, c0\n" // gpioc_bit_out_put(16, 0)
:
: "r"(pin)
: "r4","r5"
);
sleep_ms(500);
pin++;
if (pin > 18) pin = 16;
printf("age: %d\r\n", age);
printf("range: %d\r\n", range);
}
}
```
### Breaking Down the Code
#### The Integer Variables
This program declares two integer variables that demonstrate the difference between **signed** and **unsigned** types:
Let's say a program declares two integer variables that demonstrate the difference between **signed** and **unsigned** types:
```c
uint8_t age = 43;
@@ -127,48 +53,6 @@ int8_t range = -42;
The variable `age` is a `uint8_t` - an **unsigned** 8-bit integer that can only hold values from `0` to `255`. Since age is always a positive number, unsigned is the right choice. The variable `range` is an `int8_t` - a **signed** 8-bit integer that can hold values from `-128` to `127`. The signed type allows it to represent negative numbers like `-42`. Under the hood, negative values are stored using **two's complement** encoding: the CPU flips all the bits of `42` (`0x2A`) and adds `1`, producing `0xD6`, which is how `-42` lives in a single byte of memory.
#### GPIO Initialization with Inline Assembly
Instead of using the Pico SDK's `gpio_init()`, `gpio_set_dir()`, and `gpio_set_function()` helpers, this program configures GPIO pins **directly at the register level** using inline assembly. This gives us a window into how the hardware actually works on the RP2350.
The initialization loop configures GPIO pins 16 through 19 (our red, green, blue, and yellow LEDs) in three steps per pin:
**Step 1 - Configure the pad.** Each GPIO pin has a pad control register in `PADS_BANK0` starting at base address `0x40038000`. The code calculates the offset as `pin * 4`, loads the current register value, clears the **OD** (output disable) and **ISO** (isolation) bits with `bic r5, r5, #0x180`, and sets the **IE** (input enable) bit with `orr r5, r5, #0x40`. This ensures the pad is electrically active and ready to drive output.
**Step 2 - Set the pin function.** Each GPIO pin has a control register in `IO_BANK0` starting at `0x40028004`. The offset is `pin * 8` because each pin's control block is 8 bytes wide. The code clears the `FUNCSEL` field (bits `[4:0]`) and sets it to `5`, which selects the **SIO** (Single-cycle I/O) function. SIO is the mode that lets software directly control pin state through the GPIO coprocessor.
**Step 3 - Enable the output driver.** The instruction `mcrr p0, #4, r4, r5, c4` writes to the RP2350's GPIO coprocessor. Coprocessor register `c4` controls the **output enable** - with `r4` holding the pin number and `r5` set to `1`, this tells the hardware "this pin is an output." The `mcrr` (Move to Coprocessor from two ARM Registers) instruction is how the Cortex-M33 on the RP2350 talks to its dedicated GPIO coprocessor, bypassing the normal memory-mapped I/O path for single-cycle pin control.
#### The Blink Loop with Inline Assembly
Inside the `while (1)` loop, the program uses two inline assembly blocks to toggle the current LED on and off:
```c
"mcrr p0, #4, r4, r5, c0\n" // gpioc_bit_out_put(pin, 1)
```
This time the coprocessor register is `c0` instead of `c4`. Register `c0` controls the **output value** - setting `r5 = 1` drives the pin HIGH (LED on), and `r5 = 0` drives it LOW (LED off). Each toggle is followed by `sleep_ms(500)` for a half-second delay, creating a visible blink.
The GCC extended assembly syntax `"r"(pin)` tells the compiler to load the C variable `pin` into a general-purpose register and make it available as `%0` inside the assembly block. The clobber list `"r4","r5"` warns the compiler that those registers are modified, so it won't store anything important there.
#### The Pin Cycling and Print Statements
After each on/off cycle, the program increments `pin` and wraps it back to `16` when it exceeds `18`:
```c
pin++;
if (pin > 18) pin = 16;
```
This cycles through GPIO 16, 17, and 18 - red, green, and blue LEDs - creating a rotating blink pattern. Finally, `printf` prints both integer variables over UART so we can observe their values on the serial terminal:
```
age: 43
range: -42
```
> Tip: **Why use inline assembly instead of the SDK?** This program is designed to teach you what happens *beneath* the SDK. When you call `gpio_put(16, 1)` in normal Pico code, the SDK ultimately does the same coprocessor write - `mcrr p0, #4, r4, r5, c0`. By writing the assembly directly, you can see exactly how the RP2350 hardware is controlled, which is essential knowledge for reverse engineering and binary patching.
---
## Part 2: Understanding Floating-Point Data Types
@@ -198,13 +82,89 @@ A **float** is a number that can have a decimal point. Unlike integers which can
+-----------------------------------------------------------------+
```
### How to Compute This by Hand (42.5 -> IEEE 754)
Use this exact process any time you need to encode a decimal float manually.
1. Determine the sign bit.
- `42.5` is positive, so `sign = 0`.
2. Convert the number to binary.
- Integer part: `42 = 101010 (base 2)`
- Fractional part: use repeated multiply-by-2 on the fraction.
- Start with `0.5`
- `0.5 * 2 = 1.0` -> integer part is `1` (this is the first binary fractional bit)
- Remaining fractional part is now `0.0`, so we stop.
- Therefore `0.5 = 0.1 (base 2)`.
- Combined: `42.5 = 101010.1 (base 2)`
3. Normalize to the form `1.xxxxx * 2^n`.
- `101010.1 (base 2) = 1.010101 (base 2) * 2^5`
- So the true exponent is `n = 5`.
4. Compute the stored exponent (bias 127 for float).
- `stored exponent = n + 127 = 5 + 127 = 132`
- `132` in binary is `10000100` (8 bits).
> Tip: **Why 127?** The exponent field is 8 bits wide, giving $2^8 = 256$ total values. Half of that range should represent negative exponents and half positive. The midpoint is $(2^8 / 2) - 1 = 127$. So a stored exponent of `127` means a real exponent of **0**, values below `127` are negative exponents, and values above `127` are positive exponents. Doubles use an 11-bit exponent field so their midpoint (bias) is $( 2^{11} / 2) - 1 = 1023$ instead.
5. Build the mantissa (fraction bits).
- Take bits after the leading `1.` from `1.010101` -> `010101`
- Pad with zeros to 23 bits:
- `01010100000000000000000`
6. Assemble all fields.
- `sign | exponent | mantissa`
- `0 | 10000100 | 01010100000000000000000`
- Full 32-bit pattern:
- `01000010001010100000000000000000`
7. Convert the 32-bit binary to hex (group by 4 bits).
- `0100 0010 0010 1010 0000 0000 0000 0000`
- `4 2 2 A 0 0 0 0`
- Final result: `0x422A0000`
Quick decode check (reverse direction, fully expanded):
Given the 32-bit pattern:
- `0 | 10000100 | 01010100000000000000000`
Decode it field by field:
1. Sign bit
- Sign bit is `0` -> number is positive.
- So the sign multiplier is `(+1)`.
2. Exponent field
- Exponent bits are `10000100`.
- Convert to decimal: `10000100 (base 2) = 132`.
- Float bias is `127`, so true exponent is:
- `132 - 127 = 5`.
3. Mantissa field
- Stored mantissa bits are `01010100000000000000000`.
- IEEE 754 normal numbers use an implicit leading `1`, so significand becomes:
- `1.010101 (base 2)`.
4. Rebuild the value
- Formula: `value = (+1) * 1.010101 (base 2) * 2^5`.
- Shift binary point right by 5:
- `1.010101 * 2^5 = 101010.1 (base 2)`.
5. Convert `101010.1 (base 2)` to decimal
- Integer part: `101010 = 32 + 8 + 2 = 42`
- Fraction part: `.1 = 1/2 = 0.5`
- Total: `42 + 0.5 = 42.5`
So the decoded value is exactly `42.5`.
### Float vs Integer - Key Differences
| Property | Integer (`uint8_t`) | Float (`float`) |
| -------------- | ---------------------- | --------------------------- |
| **Size** | 1 byte | 4 bytes |
| **Precision** | Exact | ~7 decimal digits |
| **Range** | 0 to 255 | ?3.4 * 10++ |
| **Range** | 0 to 255 | ±3.4 × 10^38 |
| **Encoding** | Direct binary | IEEE 754 (sign/exp/mantissa)|
| **printf** | `%d` | `%f` |
@@ -228,6 +188,10 @@ int main(void) {
}
```
> Note: `fav_num` is declared inside `main`, so by C rules it is an automatic (stack) variable. In optimized embedded builds, the compiler may avoid creating a real stack slot and instead materialize the value from read-only constant storage (typically `.rodata` and/or an ARM literal pool).
>
> An ARM **literal pool** is a small table of constants that the assembler places near code in memory. Instead of encoding a large immediate value directly in an instruction, the CPU executes a load instruction (such as `ldr`) that reads the constant from that nearby table. That is why Ghidra can show constant loads rather than a classic stack local.
**What this code does:**
1. Declares a `float` variable `fav_num` and initializes it to `42.5`
2. Initializes the serial output
@@ -260,7 +224,7 @@ The program is printing `42.500000` because `printf` with `%f` defaults to 6 dec
---
## ? Part 2.5: Setting Up Ghidra for Float Analysis
## 🔧 Part 2.5: Setting Up Ghidra for Float Analysis
### Step 3: Start Ghidra
@@ -313,7 +277,7 @@ Wait for analysis to complete (watch the progress bar in the bottom right).
---
## ? Part 2.6: Navigating and Resolving Functions
## 🔍 Part 2.6: Navigating and Resolving Functions
### Step 8: Find the Functions
@@ -347,7 +311,7 @@ For `main`, let's also fix the return type:
---
## ? Part 2.7: Analyzing the Main Function
## 🔬 Part 2.7: Analyzing the Main Function
### Step 11: Examine Main in Ghidra
@@ -357,6 +321,7 @@ You'll see something like:
```c
int main(void)
{
undefined4 uVar1;
undefined4 extraout_r1;
@@ -384,7 +349,7 @@ int main(void)
1. Click on `FUN_100030ec`
2. Right-click -> **Edit Function Signature**
3. Change to: `int __wrap_printf(char *format,...)`
3. Change to: `int printf(char *format,...)`
4. Check the **Varargs** checkbox (printf takes variable arguments!)
5. Click **OK**
@@ -394,17 +359,18 @@ Look at the decompiled code after resolving functions:
```c
int main(void)
{
undefined4 uVar1;
undefined4 extraout_r1;
undefined4 uVar2;
undefined4 extraout_r1_00;
FUN_10002f5c();
stdio_init_all();
uVar1 = DAT_1000024c;
uVar2 = extraout_r1;
do {
FUN_100030ec(DAT_10000250,uVar2,0,uVar1);
printf(DAT_10000250,uVar2,0,uVar1);
uVar2 = extraout_r1_00;
} while( true );
}
@@ -472,7 +438,7 @@ Now let's check it. IEEE 754 uses a simple rule for the sign bit:
```
r3 = 0x40454000 = 0100 0000 0100 0101 0100 0000 0000 0000
^
r3 bit 31 = 0 -> sign = 0 -> Positive number
r3 bit 31 = 0 -> sign = 0 -> Positive number
```
The topmost bit of r3 is `0`, so the number is **positive**. If that bit were `1` instead (e.g. `0xC0454000`), the number would be negative (`-42.5`).
@@ -507,35 +473,35 @@ This means the number is scaled by $2^5 = 32$. In other words, the mantissa gets
- **High 20 bits of mantissa** (bits 51-32) = bits 19-0 of r3:
```
r3 bits 19-0: 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
r3 bits 19-0: 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
```
- **Low 32 bits of mantissa** (bits 31-0) = all of r2:
```
r2 = 0x00000000 -> 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
r2 = 0x00000000 -> 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
```
Full 52-bit mantissa:
```
0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
?? top 20 bits from r3 -> ?? bottom 32 bits from r2 (all zero) ->
<- top 20 bits from r3 -> <- bottom 32 bits from r2 (all zero) ->
```
IEEE 754 always prepends an **implied leading `1`**, so the actual value represented is:
```
1.010101 00000... (the 1. is implicit, not stored)
1.010101 00000... (the 1. is implicit, not stored)
```
**4. Reconstruct the value**
$$1.010101_2 \times 2^5$$
$$1.010101\text{ (base 2)} \times 2^5$$
Shift the binary point 5 places right:
$$101010.1_2$$
$$101010.1\text{ (base 2)}$$
Now convert each bit position to decimal:
@@ -547,9 +513,9 @@ Now convert each bit position to decimal:
| `0` (bit 2) | $2^2$ | 0 |
| `1` (bit 1) | $2^1$ | 2 |
| `0` (bit 0) | $2^0$ | 0 |
| `1` (bit ?1) | $2^{-1}$ | 0.5 |
| `1` (bit -1) | $2^{-1}$ | 0.5 |
$$32 + 8 + 2 + 0.5 = \mathbf{42.5} ?$$
$$32 + 8 + 2 + 0.5 = \mathbf{42.5}$$
### Step 16: Examine the Assembly
@@ -559,49 +525,47 @@ Look at the **Listing** window (assembly view). Find the main function:
*************************************************************
* FUNCTION
*************************************************************
undefined FUN_10000234 ()
undefined <UNASSIGNED> <RETURN>
FUN_10000234+1 XREF[1,1]: 1000018c (c) , 1000018a (*)
FUN_10000234
10000234 38 b5 push {r3,r4,r5,lr}
10000236 02 f0 91 fe bl FUN_10002f5c undefined FUN_10002f5c()
1000023a 00 24 movs r4,#0x0
1000023c 03 4d ldr r5,[DAT_1000024c ] = 40454000h
int __stdcall main (void )
int r0:4 <RETURN>
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)
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"
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"
= 100034A8h
10000244 02 f0 52 ff bl FUN_100030ec undefined FUN_100030ec()
10000248 f9 e7 b LAB_1000023e
10000244 02 f0 52 ff bl printf int printf(char * format, ...)
10000248 f9 e7 b LAB_1000023e
1000024a 00 ?? 00h
1000024b bf ?? BFh
DAT_1000024c XREF[1]: FUN_10000234:1000023c (R)
1000024c 00 40 45 40 undefine 40454000h
DAT_10000250 XREF[1]: FUN_10000234:10000242 (R)
10000250 a8 34 00 10 undefine 100034A8h ? -> 100034a8
DAT_1000024c XREF[1]: main:1000023c (R)
1000024c 00 40 45 40 undefine 40454000h
DAT_10000250 XREF[1]: main:10000242 (R)
10000250 a8 34 00 10 undefine 100034A8h * -> 100034a8
```
> ? **Key Insight:** The `mov.w r2, #0x0` loads the low 32 bits (all zeros) and `ldr r3, [DAT_...]` loads the high 32 bits (`0x40454000`) of the double. Together, `r2:r3` = `0x40454000_00000000` = `42.5` as a double.
> 💡 **Key Insight:** The `mov.w r2, #0x0` loads the low 32 bits (all zeros) and `ldr r3, [DAT_...]` loads the high 32 bits (`0x40454000`) of the double. Together, `r2:r3` = `0x40454000_00000000` = `42.5` as a double.
### Step 17: Find the Format String
In the Listing view, click on the data reference to find the format string:
```
s_fav_num:_%f_100034a8 XREF[1]: FUN_10000234:10000242 (*)
100034a8 66 61 76 ds "fav_num: %f\r\n"
5f 6e 75
6d 3a 20
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
```
This confirms `printf` is called with the format string `"fav_num: %f\r\n"` and the double-precision value of `42.5`.
---
## ? Part 2.8: Patching the Float - Changing 42.5 to 99.0
## ✏️ Part 2.8: Patching the Float - Changing 42.5 to 99.0
### Step 18: Calculate the New IEEE 754 Encoding
@@ -611,15 +575,15 @@ We want to change `42.5` to `99.0`. First, we need to figure out the double-prec
| Division | Quotient | Remainder |
|---------------|----------|-----------|
| 99 ? 2 | 49 | **1** |
| 49 ? 2 | 24 | **1** |
| 24 ? 2 | 12 | **0** |
| 12 ? 2 | 6 | **0** |
| 6 ? 2 | 3 | **0** |
| 3 ? 2 | 1 | **1** |
| 1 ? 2 | 0 | **1** |
| 99 ÷ 2 | 49 | **1** |
| 49 ÷ 2 | 24 | **1** |
| 24 ÷ 2 | 12 | **0** |
| 12 ÷ 2 | 6 | **0** |
| 6 ÷ 2 | 3 | **0** |
| 3 ÷ 2 | 1 | **1** |
| 1 ÷ 2 | 0 | **1** |
Read remainders bottom-to-top: $99_{10} = 1100011_2$
Read remainders bottom-to-top: 99 (base 10) = 1100011 (base 2)
**Step B - Convert the fractional part (.0) to binary:**
@@ -627,18 +591,18 @@ There is no fractional part - `.0` is exactly zero, so the fractional binary is
**Step C - Combine:**
$$99.0_{10} = 1100011.0_2$$
$$99.0\text{ (base 10)} = 1100011.0\text{ (base 2)}$$
**Step D - Normalize to IEEE 754 form** (move the binary point so there's exactly one `1` before it):
$$1100011.0_2 = 1.100011_2 \times 2^6$$
$$1100011.0\text{ (base 2)} = 1.100011\text{ (base 2)} \times 2^6$$
We shifted the binary point 6 places left, so the exponent is **6**.
**Step E - Extract the IEEE 754 fields:**
1. **Sign:** `0` (positive)
2. **Exponent:** $6 + 1023 = 1029 = 10000000101_2$
2. **Exponent:** $6 + 1023 = 1029 = 10000000101\text{ (base 2)}$
3. **Mantissa:** `1000110000000000...` (everything after the `1.`, padded with zeros to 52 bits)
4. **Full double:** `0x4058C00000000000`
@@ -654,7 +618,7 @@ Since `r2` stays `0x00000000`, we only need to patch the high word loaded into `
Look in the Listing view for the data that loads the high word of the double:
```
10000248 00 40 45 40 undefined4 40454000h
1000024c 00 40 45 40 undefined4 40454000h
```
This is the 32-bit constant that gets loaded into `r3` - the high word of our double `42.5`.
@@ -662,16 +626,15 @@ This is the 32-bit constant that gets loaded into `r3` - the high word of our do
### Step 20: Patch the Constant
1. Click on Window -> Bytes
2. Click on Pencil Icon in Bytes Editor
2. Right-click and select **Patch Data**
3. Change `00404540` to `00C05840`
2. Click on the Pencil icon to enable byte editing
3. At address `1000024c`, overwrite `00 40 45 40` with `00 C0 58 40` (little-endian for `0x40454000 -> 0x4058C000`)
4. Press Enter
This changes the high word from `0x40454000` (42.5 as double) to `0x4058C000` (99.0 as double).
---
## ? Part 2.9: Export and Test the Hacked Binary
## 🚀 Part 2.9: Export and Test the Hacked Binary
### Step 21: Export the Patched Binary
@@ -686,7 +649,7 @@ This changes the high word from `0x40454000` (42.5 as double) to `0x4058C000` (9
**Open a terminal and navigate to your project directory:**
```powershell
cd C:\Users\assem.KEVINTHOMAS\OneDrive\Documents\Embedded-Hacking\0x000e_floating-point-data-type
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x000e_floating-point-data-type
```
**Run the conversion command:**
@@ -710,7 +673,7 @@ fav_num: 99.000000
...
```
? **BOOM! We hacked the float!** The value changed from `42.5` to `99.0`!
🎉 **BOOM! We hacked the float!** The value changed from `42.5` to `99.0`!
---
@@ -748,7 +711,7 @@ A **double** (short for "double-precision floating-point") is like a `float` but
| **Precision** | ~7 decimal digits | ~15 decimal digits |
| **Exponent** | 8 bits (bias 127) | 11 bits (bias 1023) |
| **Mantissa** | 23 bits | 52 bits |
| **Range** | ?3.4 * 10++ | ?1.8 * 10+++? |
| **Range** | ±3.4 × 10^38 | ±1.8 × 10^308 |
| **printf** | `%f` | `%lf` |
| **ARM passing** | Promoted to double | Native in `r2:r3` |
@@ -806,7 +769,7 @@ The program is printing `42.525250` because `printf` with `%lf` defaults to 6 de
---
## ? Part 3.5: Setting Up Ghidra for Double Analysis
## 🔧 Part 3.5: Setting Up Ghidra for Double Analysis
### Step 3: Start Ghidra
@@ -859,7 +822,7 @@ Wait for analysis to complete (watch the progress bar in the bottom right).
---
## ? Part 3.6: Navigating and Resolving Functions
## 🔍 Part 3.6: Navigating and Resolving Functions
### Step 8: Find the Functions
@@ -893,7 +856,7 @@ For `main`, let's also fix the return type:
---
## ? Part 3.7: Analyzing the Main Function
## 🔬 Part 3.7: Analyzing the Main Function
### Step 11: Examine Main in Ghidra
@@ -901,48 +864,9 @@ Click on `main` (or `FUN_10000234`). Look at the **Decompile** window:
You'll see something like:
```c
void FUN_10000238(void)
{
undefined4 uVar1;
undefined4 uVar2;
undefined4 extraout_r1;
undefined4 uVar3;
undefined4 extraout_r1_00;
undefined4 in_r3;
uVar2 = DAT_10000258;
uVar1 = DAT_10000254;
FUN_10002f64();
uVar3 = extraout_r1;
do {
FUN_100030f4(DAT_10000250,uVar3,uVar1,uVar2,in_r3);
uVar3 = extraout_r1_00;
} while( true );
}
```
### Step 12: Resolve stdio_init_all
1. Click on `FUN_10002f64`
2. Right-click -> **Edit Function Signature**
3. Change to: `bool stdio_init_all(void)`
4. Click **OK**
### Step 13: Resolve printf
1. Click on `FUN_100030f4`
2. Right-click -> **Edit Function Signature**
3. Change the name to `printf`
4. Check the **Varargs** checkbox (printf takes variable arguments!)
5. Click **OK**
### Step 14: Understand the Double Encoding
Look at the decompiled code after resolving functions:
```c
int main(void)
{
undefined4 uVar1;
undefined4 uVar2;
@@ -961,6 +885,46 @@ int main(void)
}
```
### Step 12: Resolve stdio_init_all
1. Click on `FUN_10002f64`
2. Right-click -> **Edit Function Signature**
3. Change to: `bool stdio_init_all(void)`
4. Click **OK**
### Step 13: Resolve printf
1. Click on `FUN_100030f4`
2. Right-click -> **Edit Function Signature**
3. Change to: `int printf(char *format,...)`
4. Check the **Varargs** checkbox (printf takes variable arguments!)
5. Click **OK**
### Step 14: Understand the Double Encoding
Look at the decompiled code after resolving functions:
```c
int main(void)
{
undefined4 uVar1;
undefined4 uVar2;
undefined4 extraout_r1;
undefined4 uVar3;
undefined4 extraout_r1_00;
uVar2 = DAT_10000258;
uVar1 = DAT_10000254;
stdio_init_all();
uVar3 = extraout_r1;
do {
printf(DAT_10000250,uVar3,uVar1,uVar2);
uVar3 = extraout_r1_00;
} while( true );
}
```
**Where's `double fav_num = 42.52525`?** It's been optimized into immediate values!
This time we see **two** non-zero values: `0x645a1cac` and `0x4045433b`. Unlike the float example where the low word was `0x0`, a double with a fractional part like `42.52525` needs **all 52 mantissa bits** - so both halves carry data.
@@ -974,7 +938,7 @@ A 64-bit double is passed in two 32-bit registers:
Together they form `0x4045433B645A1CAC` - the IEEE 754 **double-precision** encoding of `42.52525`.
> ? **Key Difference from Float:** In the float example, `r2` was `0x00000000` because `42.5` has a clean fractional part. But `42.52525` has a repeating binary fraction, so the low 32 bits are non-zero (`0x645A1CAC`). This means **both** registers matter when patching doubles with complex fractional values!
> 💡 **Key Difference from Float:** In the float example, `r2` was `0x00000000` because `42.5` has a clean fractional part. But `42.52525` has a repeating binary fraction, so the low 32 bits are non-zero (`0x645A1CAC`). This means **both** registers matter when patching doubles with complex fractional values!
### Step 15: Verify the Double Encoding
@@ -992,12 +956,10 @@ Bit: 63 62-52 (11 bits) 51-32 (20 bits) 3
+---+-----------------------+------------------------------------------+------------------------------------------+
| 0 | 1 0 0 0 0 0 0 0 1 0 0 | 0 1 0 1 0 1 0 0 0 0 1 1 0 0 1 1 1 0 1 1 | 01100100010110100001110010101100 |
+---+-----------------------+------------------------------------------+------------------------------------------+
Sign Exponent (11) Mantissa high 20 bits Mantissa low 32 bits
(from r3 bits 19-0) (from r2)
Sign Exponent (11) Mantissa high 20 bits Mantissa low 32 bits
(from r3 bits 19-0) (from r2)
```
> ? **Key Difference from 42.5:** In the `42.5` example, r2 was `0x00000000` because `42.5` has a clean fractional part (`.5` = exactly one binary digit). But `42.52525` has a repeating binary fraction, so the low 32 bits are **non-zero** (`0x645A1CAC`). Every bit of both registers matters here!
**Step-by-step field extraction:**
**1. Sign bit**
@@ -1007,7 +969,7 @@ The sign bit is bit 63 of the 64-bit double, which is bit 31 of r3 (the high reg
```
r3 = 0x4045433B = 0100 0000 0100 0101 0100 0011 0011 1011
^
r3 bit 31 = 0 -> sign = 0 -> Positive number ?
r3 bit 31 = 0 -> sign = 0 -> Positive number
```
**2. Exponent - bits 62-52 = bits 30-20 of r3**
@@ -1042,29 +1004,29 @@ r3 bits 19-0: 0 1 0 1 0 1 0 0 0 0 1 1 0 0 1 1 1 0 1 1
- **Low 32 bits of mantissa** (bits 31-0) = all of r2:
```
r2 = 0x645A1CAC -> 0 1 1 0 0 1 0 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 0 1 0 1 1 0 0
r2 = 0x645A1CAC -> 0 1 1 0 0 1 0 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 0 1 0 1 1 0 0
```
Full 52-bit mantissa:
```
0 1 0 1 0 1 0 0 0 0 1 1 0 0 1 1 1 0 1 1 | 0 1 1 0 0 1 0 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 0 1 0 1 1 0 0
?? top 20 bits from r3 -> ?? bottom 32 bits from r2 ->
<- top 20 bits from r3 -> <- bottom 32 bits from r2 ->
```
IEEE 754 always prepends an **implied leading `1`**, so the actual value represented is:
```
1.0101010000110011101101100100010110100001110010101100 (the 1. is implicit, not stored)
1.0101010000110011101101100100010110100001110010101100 (the 1. is implicit, not stored)
```
**4. Reconstruct the value**
$$1.0101010000110011101101100100..._2 \times 2^5$$
$$1.0101010000110011101101100100...\text{ (base 2)} \times 2^5$$
Shift the binary point 5 places right:
$$101010.10000110011101101100100010110100001110010101100_2$$
$$101010.10000110011101101100100010110100001110010101100\text{ (base 2)}$$
**Integer part** (`101010`):
@@ -1083,25 +1045,25 @@ $$32 + 8 + 2 = \mathbf{42}$$
| Bit position | Power of 2 | Decimal value |
|---|---|---|
| `1` (bit ?1) | $2^{-1}$ | 0.5 |
| `0` (bit ?2) | $2^{-2}$ | 0 |
| `0` (bit ?3) | $2^{-3}$ | 0 |
| `0` (bit ?4) | $2^{-4}$ | 0 |
| `0` (bit ?5) | $2^{-5}$ | 0 |
| `1` (bit ?6) | $2^{-6}$ | 0.015625 |
| `1` (bit ?7) | $2^{-7}$ | 0.0078125 |
| `0` (bit ?8) | $2^{-8}$ | 0 |
| `0` (bit ?9) | $2^{-9}$ | 0 |
| `1` (bit ?10) | $2^{-10}$ | 0.0009765625 |
| `1` (bit ?11) | $2^{-11}$ | 0.00048828125 |
| `1` (bit ?12) | $2^{-12}$ | 0.000244140625 |
| `1` (bit -1) | $2^{-1}$ | 0.5 |
| `0` (bit -2) | $2^{-2}$ | 0 |
| `0` (bit -3) | $2^{-3}$ | 0 |
| `0` (bit -4) | $2^{-4}$ | 0 |
| `0` (bit -5) | $2^{-5}$ | 0 |
| `1` (bit -6) | $2^{-6}$ | 0.015625 |
| `1` (bit -7) | $2^{-7}$ | 0.0078125 |
| `0` (bit -8) | $2^{-8}$ | 0 |
| `0` (bit -9) | $2^{-9}$ | 0 |
| `1` (bit -10) | $2^{-10}$ | 0.0009765625 |
| `1` (bit -11) | $2^{-11}$ | 0.00048828125 |
| `1` (bit -12) | $2^{-12}$ | 0.000244140625 |
| ... | ... | *(remaining 35 bits add smaller and smaller fractions)* |
First 12 fractional bits sum: $0.5 + 0.015625 + 0.0078125 + 0.0009765625 + 0.00048828125 + 0.000244140625 \approx 0.5251$
The remaining 35 fractional bits refine this to $\approx 0.52525$. This is because `0.52525` is a **repeating fraction** in binary - it can never be represented with a finite number of bits, so double precision stores the closest possible 52-bit approximation.
$$42 + 0.52525 = \mathbf{42.52525} ?$$
$$42 + 0.52525 = \mathbf{42.52525} \checkmark$$
### Step 16: Examine the Assembly
@@ -1111,58 +1073,57 @@ Look at the **Listing** window (assembly view). Find the main function:
*************************************************************
* FUNCTION
*************************************************************
undefined FUN_10000238 ()
undefined <UNASSIGNED> <RETURN>
FUN_10000238+1 XREF[1,1]: 1000018c (c) , 1000018a (*)
FUN_10000238
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
int __stdcall main (void )
int r0:4 <RETURN>
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 FUN_10002f64 undefined FUN_10002f64()
10000240 02 f0 90 fe bl stdio_init_all bool stdio_init_all(void)
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"
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 FUN_100030f4 undefined FUN_100030f4()
1000024e f9 e7 b LAB_10000244
DAT_10000250 XREF[1]: FUN_10000238:10000248 (R)
10000250 b0 34 00 10 undefine 100034B0h ? -> 100034b0
DAT_10000254 XREF[1]: FUN_10000238:1000023c (R)
10000254 ac 1c 5a 64 undefine 645A1CACh
DAT_10000258 XREF[1]: FUN_10000238:1000023c (R)
10000258 3b 43 45 40 undefine 4045433Bh
1000024a 02 f0 53 ff bl printf int printf(char * format, ...)
1000024e f9 e7 b LAB_10000244
DAT_10000250 XREF[1]: main:10000248 (R)
10000250 b0 34 00 10 undefine 100034B0h ? -> 100034b0
DAT_10000254 XREF[1]: main:1000023c (R)
10000254 ac 1c 5a 64 undefine 645A1CACh
DAT_10000258 XREF[1]: main:1000023c (R)
10000258 3b 43 45 40 undefine 4045433Bh
```
> ? **Key Insight:** Notice that **both** `r2` and `r3` are loaded from data constants using `ldr`. Compare this to the float example where `r2` was loaded with `mov.w r2, #0x0`. Because `42.52525` requires all 52 mantissa bits, neither word can be zero - the compiler must store both halves as separate data constants.
> 💡 **Key Insight:** Notice that **both** `r2` and `r3` are loaded from data constants using `ldr`. Compare this to the float example where `r2` was loaded with `mov.w r2, #0x0`. Because `42.52525` requires all 52 mantissa bits, neither word can be zero - the compiler must store both halves as separate data constants.
### Step 17: Find the Format String
In the Listing view, click on the data reference to find the format string:
```
s_fav_num:_%lf_100034b0 XREF[1]: FUN_10000238:10000248 (*)
100034b0 66 61 76 ds "fav_num: %lf\r\n"
5f 6e 75
6d 3a 20
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
```
This confirms `printf` is called with the format string `"fav_num: %lf\r\n"` and the double-precision value of `42.52525`.
---
## ? Part 3.8: Patching the Double - Changing 42.52525 to 99.99
## ✏️ Part 3.8: Patching the Double - Changing 42.52525 to 99.99
### Step 18: Calculate the New IEEE 754 Encoding
We want to change `42.52525` to `99.99`. First, we need to figure out the double-precision encoding of `99.99`:
1. $99.99 = 1.5623... \times 2^6 = 1.100011111111..._2 \times 2^6$
1. $99.99 = 1.5623... \times 2^6 = 1.100011111111...\text{ (base 2)} \times 2^6$
2. **Sign:** `0` (positive)
3. **Exponent:** $6 + 1023 = 1029 = 10000000101_2$
4. **Mantissa:** `1000111111010111000010100011110101110000101000111..._2$
3. **Exponent:** $6 + 1023 = 1029 = 10000000101\text{ (base 2)}$
4. **Mantissa:** `1000111111010111000010100011110101110000101000111... (base 2)`
5. **Full double:** `0x4058FF5C28F5C28F`
| Register | Old Value | New Value |
@@ -1178,35 +1139,35 @@ Look in the Listing view for the two data constants:
**Low word (loaded into `r2`):**
```
10000254 ac 1c 5a 64 undefined4 645A1CACh
10000254 ac 1c 5a 64 undefined4 645A1CACh
```
**High word (loaded into `r3`):**
```
10000258 3b 43 45 40 undefined4 4045433Bh
10000258 3b 43 45 40 undefined4 4045433Bh
```
### Step 20: Patch Both Constants
**Patch the low word:**
1. Click on the data at address `10000254` containing `645A1CAC`
2. Right-click and select **Patch Data**
3. Change `645A1CAC` to `28F5C28F` -> `8FC2F528`
2. Open the Bytes window and enable byte editing (Pencil icon)
3. Overwrite bytes `ac 1c 5a 64` with `8f c2 f5 28` (little-endian for `0x645A1CAC -> 0x28F5C28F`)
4. Press Enter
**Patch the high word:**
1. Click on the data at address `10000258` containing `4045433B`
2. Right-click and select **Patch Data**
3. Change `4045433B` to `4058FF5C` -> `5CFF5840`
2. Keep byte editing enabled in the Bytes window
3. Overwrite bytes `3b 43 45 40` with `5c ff 58 40` (little-endian for `0x4045433B -> 0x4058FF5C`)
4. Press Enter
This changes the full 64-bit double from `0x4045433B645A1CAC` (42.52525) to `0x4058FF5C28F5C28F` (99.99).
> ? **Key Difference from Float Patching:** When we patched the float `42.5`, we only needed to change one word (the high word in `r3`) because the low word was all zeros. With `42.52525 -> 99.99`, **both** words change. Always check whether the low word is non-zero before patching!
> 💡 **Key Difference from Float Patching:** When we patched the float `42.5`, we only needed to change one word (the high word in `r3`) because the low word was all zeros. With `42.52525 -> 99.99`, **both** words change. Always check whether the low word is non-zero before patching!
---
## ? Part 3.9: Export and Test the Hacked Binary
## 🚀 Part 3.9: Export and Test the Hacked Binary
### Step 21: Export the Patched Binary
@@ -1221,7 +1182,7 @@ This changes the full 64-bit double from `0x4045433B645A1CAC` (42.52525) to `0x4
**Open a terminal and navigate to your project directory:**
```powershell
cd C:\Users\assem.KEVINTHOMAS\OneDrive\Documents\Embedded-Hacking\0x0011_double-floating-point-data-type
cd C:\Users\flare-vm\Desktop\Embedded-Hacking-main\0x0011_double-floating-point-data-type
```
**Run the conversion command:**
@@ -1245,11 +1206,11 @@ fav_num: 99.990000
...
```
? **BOOM! We hacked the double!** The value changed from `42.52525` to `99.99`!
🎉 **BOOM! We hacked the double!** The value changed from `42.52525` to `99.99`!
---
## ? Part 3.95: Summary - Float and Double Analysis
## 📊 Part 3.95: Summary - Float and Double Analysis
### What We Accomplished
@@ -1293,7 +1254,7 @@ fav_num: 99.990000
| - Split into high/low words |
+-----------------------------------------------------------------+
| 5. Patch the constant(s) in Ghidra |
| - Right-click -> Patch Data |
| - Edit bytes in the Bytes window (Pencil mode) |
| - Replace the old encoding with the new one |
+-----------------------------------------------------------------+
| 6. Export -> Convert to UF2 -> Flash -> Verify |
@@ -1307,7 +1268,7 @@ fav_num: 99.990000
---
## ? Key Takeaways
## 💡 Key Takeaways
1. **Integers have fixed sizes** - `uint8_t` is 1 byte (0-255), `int8_t` is 1 byte (-128 to 127). The `u` prefix means unsigned.
@@ -1325,7 +1286,7 @@ fav_num: 99.990000
---
## ? Glossary
## 📖 Glossary
| Term | Definition |
| ----------------------- | ------------------------------------------------------------------------------ |
@@ -1349,7 +1310,7 @@ fav_num: 99.990000
---
## ? Additional Resources
## 📚 Additional Resources
### GPIO Coprocessor Reference
@@ -1388,6 +1349,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! 🎉
+79
View File
@@ -0,0 +1,79 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<style>
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
.dim{font:20px 'Courier New',monospace;fill:#888}
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
.badge{stroke:#00ff41;rx:14}
</style>
<rect class="bg" width="1200" height="800"/>
<!-- Background grid decoration -->
<g opacity="0.06">
<line x1="0" y1="100" x2="1200" y2="100" stroke="#00ff41" stroke-width="1"/>
<line x1="0" y1="200" x2="1200" y2="200" stroke="#00ff41" stroke-width="1"/>
<line x1="0" y1="300" x2="1200" y2="300" stroke="#00ff41" stroke-width="1"/>
<line x1="0" y1="400" x2="1200" y2="400" stroke="#00ff41" stroke-width="1"/>
<line x1="0" y1="500" x2="1200" y2="500" stroke="#00ff41" stroke-width="1"/>
<line x1="0" y1="600" x2="1200" y2="600" stroke="#00ff41" stroke-width="1"/>
<line x1="0" y1="700" x2="1200" y2="700" stroke="#00ff41" stroke-width="1"/>
<line x1="200" y1="0" x2="200" y2="800" stroke="#00ff41" stroke-width="1"/>
<line x1="400" y1="0" x2="400" y2="800" stroke="#00ff41" stroke-width="1"/>
<line x1="600" y1="0" x2="600" y2="800" stroke="#00ff41" stroke-width="1"/>
<line x1="800" y1="0" x2="800" y2="800" stroke="#00ff41" stroke-width="1"/>
<line x1="1000" y1="0" x2="1000" y2="800" stroke="#00ff41" stroke-width="1"/>
</g>
<!-- Hex rain decoration -->
<g opacity="0.04" font-family="'Courier New',monospace" font-size="14" fill="#00ff41">
<text x="50" y="80">4F 70 65 6E 4F 43 44</text>
<text x="900" y="120">10 00 02 34 08 B5 01</text>
<text x="150" y="180">47 44 42 20 52 45 56</text>
<text x="800" y="240">20 08 20 00 FF AA 00</text>
<text x="80" y="350">52 50 32 33 35 30 00</text>
<text x="950" y="380">0A 0A 0F 12 12 1A 1A</text>
<text x="100" y="520">41 52 4D 76 38 2D 4D</text>
<text x="870" y="560">00 FF 41 00 D4 FF 88</text>
<text x="60" y="680">47 48 49 44 52 41 00</text>
<text x="920" y="720">FF 00 40 C0 C0 C0 00</text>
</g>
<!-- Corner accents -->
<polyline points="30,30 30,80 80,80" fill="none" stroke="#00ff41" stroke-width="2" opacity="0.3"/>
<polyline points="1170,30 1170,80 1120,80" fill="none" stroke="#00ff41" stroke-width="2" opacity="0.3"/>
<polyline points="30,770 30,720 80,720" fill="none" stroke="#00ff41" stroke-width="2" opacity="0.3"/>
<polyline points="1170,770 1170,720 1120,720" fill="none" stroke="#00ff41" stroke-width="2" opacity="0.3"/>
<!-- Top accent line -->
<rect x="100" y="140" width="1000" height="2" fill="#00ff41" opacity="0.4"/>
<!-- Course Title -->
<text x="600" y="210" text-anchor="middle" font-family="'Courier New',monospace" font-size="56" font-weight="bold" fill="#00ff41">Embedded Systems</text>
<text x="600" y="278" text-anchor="middle" font-family="'Courier New',monospace" font-size="56" font-weight="bold" fill="#00ff41">Reverse Engineering</text>
<!-- Divider -->
<rect x="300" y="310" width="600" height="2" fill="#00d4ff" opacity="0.6"/>
<!-- Week Number -->
<text x="600" y="380" text-anchor="middle" font-family="'Courier New',monospace" font-size="42" font-weight="bold" fill="#00d4ff">// WEEK 05</text>
<!-- Week Topic -->
<text x="600" y="440" text-anchor="middle" font-family="'Courier New',monospace" font-size="28" fill="#c0c0c0">Integers and Floats in Embedded Systems:</text>
<text x="600" y="478" text-anchor="middle" font-family="'Courier New',monospace" font-size="28" fill="#c0c0c0">Debugging and Hacking Integers and Floats</text>
<text x="600" y="516" text-anchor="middle" font-family="'Courier New',monospace" font-size="28" fill="#c0c0c0">w/ Intermediate GPIO Output Analysis</text>
<!-- Bottom accent line -->
<rect x="100" y="570" width="1000" height="2" fill="#00ff41" opacity="0.4"/>
<!-- University -->
<text x="600" y="635" text-anchor="middle" font-family="'Courier New',monospace" font-size="36" font-weight="bold" fill="#ffaa00">George Mason University</text>
<!-- Bottom badge -->
<rect x="400" y="670" width="400" height="40" rx="20" fill="none" stroke="#00ff41" stroke-width="1.5" opacity="0.5"/>
<text x="600" y="697" text-anchor="middle" font-family="'Courier New',monospace" font-size="20" fill="#00ff41" opacity="0.7">RP2350 // ARM Cortex-M33</text>
</svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

+77
View File
@@ -0,0 +1,77 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<style>
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
.dim{font:20px 'Courier New',monospace;fill:#888}
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
.badge{stroke:#00ff41;rx:14}
</style>
<rect class="bg" width="1200" height="800"/>
<!-- Title -->
<text x="600" y="52" text-anchor="middle" class="title">Integer Data Types</text>
<text x="600" y="88" text-anchor="middle" class="dim">Fixed-Size Types for Embedded Systems</text>
<!-- uint8_t -->
<rect x="40" y="110" width="540" height="155" rx="8" class="pnl"/>
<text x="310" y="148" text-anchor="middle" class="sub">uint8_t</text>
<text x="60" y="185" class="grn">Unsigned 8-bit</text>
<text x="360" y="185" class="txt">1 byte</text>
<text x="60" y="218" class="txt">Range:</text>
<text x="200" y="218" class="amb">0 to 255</text>
<text x="60" y="245" class="dim">Ages, counts, always positive</text>
<!-- int8_t -->
<rect x="620" y="110" width="540" height="155" rx="8" class="pnl"/>
<text x="890" y="148" text-anchor="middle" class="sub">int8_t</text>
<text x="640" y="185" class="red">Signed 8-bit</text>
<text x="940" y="185" class="txt">1 byte</text>
<text x="640" y="218" class="txt">Range:</text>
<text x="780" y="218" class="amb">-128 to 127</text>
<text x="640" y="245" class="dim">Temperature, can be negative</text>
<!-- uint16_t -->
<rect x="40" y="285" width="540" height="155" rx="8" class="pnl"/>
<text x="310" y="323" text-anchor="middle" class="sub">uint16_t</text>
<text x="60" y="360" class="grn">Unsigned 16-bit</text>
<text x="360" y="360" class="txt">2 bytes</text>
<text x="60" y="393" class="txt">Range:</text>
<text x="200" y="393" class="amb">0 to 65,535</text>
<text x="60" y="420" class="dim">Sensor readings, medium values</text>
<!-- uint32_t -->
<rect x="620" y="285" width="540" height="155" rx="8" class="pnl"/>
<text x="890" y="323" text-anchor="middle" class="sub">uint32_t</text>
<text x="640" y="360" class="cyn">Unsigned 32-bit</text>
<text x="940" y="360" class="txt">4 bytes</text>
<text x="640" y="393" class="txt">Range:</text>
<text x="780" y="393" class="amb">0 to ~4 billion</text>
<text x="640" y="420" class="dim">Addresses, timestamps</text>
<!-- Code Example -->
<rect x="40" y="460" width="1120" height="150" rx="8" class="pnl"/>
<text x="600" y="498" text-anchor="middle" class="sub">Code Example</text>
<rect x="60" y="515" width="1080" height="80" rx="6" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
<text x="80" y="548" class="amb">uint8_t age = 43;</text>
<text x="500" y="548" class="dim">// unsigned, 0-255</text>
<text x="80" y="578" class="red">int8_t range = -42;</text>
<text x="500" y="578" class="dim">// signed, -128 to 127</text>
<!-- Key Insight -->
<rect x="40" y="630" width="1120" height="150" rx="8" class="pnl"/>
<text x="600" y="668" text-anchor="middle" class="sub">Key Insight</text>
<text x="60" y="700" class="txt">The</text>
<text x="120" y="700" class="grn">u</text>
<text x="145" y="700" class="txt">prefix means</text>
<text x="370" y="700" class="cyn">unsigned</text>
<text x="540" y="700" class="txt">(no negatives)</text>
<text x="60" y="730" class="txt">Without</text>
<text x="210" y="730" class="grn">u</text>
<text x="235" y="730" class="txt">= signed (allows negatives)</text>
<text x="60" y="760" class="dim">Choose the smallest type that fits your data</text>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

+79
View File
@@ -0,0 +1,79 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<style>
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
.dim{font:20px 'Courier New',monospace;fill:#888}
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
.badge{stroke:#00ff41;rx:14}
</style>
<rect class="bg" width="1200" height="800"/>
<!-- Title -->
<text x="600" y="52" text-anchor="middle" class="title">Two's Complement</text>
<text x="600" y="88" text-anchor="middle" class="dim">How Negative Numbers are Stored</text>
<!-- Step-by-step: -42 encoding -->
<rect x="40" y="110" width="1120" height="280" rx="8" class="pnl"/>
<text x="600" y="148" text-anchor="middle" class="sub">Encoding -42 as int8_t</text>
<rect x="60" y="170" width="340" height="90" rx="6" fill="#0a0a0f" stroke="#00d4ff" stroke-width="1"/>
<text x="230" y="200" text-anchor="middle" class="cyn">Step 1: Start</text>
<text x="230" y="235" text-anchor="middle" class="txt">42 = 0x2A</text>
<rect x="420" y="170" width="340" height="90" rx="6" fill="#0a0a0f" stroke="#ffaa00" stroke-width="1"/>
<text x="590" y="200" text-anchor="middle" class="amb">Step 2: Flip</text>
<text x="590" y="235" text-anchor="middle" class="txt">~0x2A = 0xD5</text>
<rect x="780" y="170" width="340" height="90" rx="6" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
<text x="950" y="200" text-anchor="middle" class="grn">Step 3: Add 1</text>
<text x="950" y="235" text-anchor="middle" class="txt">0xD5+1 = 0xD6</text>
<text x="60" y="300" class="txt">Binary:</text>
<text x="200" y="300" class="grn">00101010</text>
<text x="400" y="300" class="amb">-></text>
<text x="450" y="300" class="amb">11010101</text>
<text x="650" y="300" class="grn">-></text>
<text x="700" y="300" class="red">11010110</text>
<text x="60" y="340" class="dim">Result: -42 stored as 0xD6 in memory</text>
<text x="60" y="368" class="dim">Top bit = 1 means negative</text>
<!-- Comparison Table -->
<rect x="40" y="410" width="1120" height="200" rx="8" class="pnl"/>
<text x="600" y="448" text-anchor="middle" class="sub">Signed vs Unsigned: Same Bits!</text>
<text x="80" y="488" class="cyn">Hex</text>
<text x="280" y="488" class="cyn">Binary</text>
<text x="580" y="488" class="cyn">uint8_t</text>
<text x="800" y="488" class="cyn">int8_t</text>
<line x1="60" y1="500" x2="1140" y2="500" stroke="#1a1a2e" stroke-width="1"/>
<text x="80" y="530" class="amb">0x2A</text>
<text x="280" y="530" class="txt">00101010</text>
<text x="580" y="530" class="grn">42</text>
<text x="800" y="530" class="grn">42</text>
<text x="80" y="565" class="amb">0xD6</text>
<text x="280" y="565" class="txt">11010110</text>
<text x="580" y="565" class="grn">214</text>
<text x="800" y="565" class="red">-42</text>
<text x="60" y="590" class="dim">Same byte 0xD6 = 214 unsigned, -42 signed</text>
<!-- GDB Verification -->
<rect x="40" y="630" width="1120" height="150" rx="8" class="pnl"/>
<text x="600" y="668" text-anchor="middle" class="sub">GDB Verification</text>
<rect x="60" y="688" width="1080" height="75" rx="6" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
<text x="80" y="718" class="grn">(gdb)</text>
<text x="180" y="718" class="txt">x/1xb &amp;range</text>
<text x="80" y="745" class="amb">0x200003e7:</text>
<text x="300" y="745" class="red">0xd6</text>
<text x="440" y="745" class="dim">// -42 in memory</text>
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

+75
View File
@@ -0,0 +1,75 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<style>
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
.dim{font:20px 'Courier New',monospace;fill:#888}
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
.badge{stroke:#00ff41;rx:14}
</style>
<rect class="bg" width="1200" height="800"/>
<!-- Title -->
<text x="600" y="52" text-anchor="middle" class="title">Inline Assembly GPIO</text>
<text x="600" y="88" text-anchor="middle" class="dim">Direct Hardware Control via ASM</text>
<!-- Init Loop -->
<rect x="40" y="110" width="1120" height="310" rx="8" class="pnl"/>
<text x="600" y="148" text-anchor="middle" class="sub">GPIO Init Loop (pins 16-19)</text>
<rect x="60" y="168" width="340" height="120" rx="6" fill="#0a0a0f" stroke="#00d4ff" stroke-width="1"/>
<text x="230" y="198" text-anchor="middle" class="cyn">1. Config Pad</text>
<text x="80" y="228" class="dim">PADS_BANK0</text>
<text x="80" y="255" class="dim">Clear OD+ISO, set IE</text>
<text x="80" y="275" class="amb">0x40038000</text>
<rect x="420" y="168" width="340" height="120" rx="6" fill="#0a0a0f" stroke="#ffaa00" stroke-width="1"/>
<text x="590" y="198" text-anchor="middle" class="amb">2. Set Function</text>
<text x="440" y="228" class="dim">IO_BANK0</text>
<text x="440" y="255" class="dim">FUNCSEL = 5 (SIO)</text>
<text x="440" y="275" class="grn">0x40028004</text>
<rect x="780" y="168" width="340" height="120" rx="6" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
<text x="950" y="198" text-anchor="middle" class="grn">3. Enable Out</text>
<text x="800" y="228" class="dim">GPIO Coprocessor</text>
<text x="800" y="255" class="dim">mcrr p0,#4,r4,r5,c4</text>
<text x="800" y="275" class="red">Output Enable</text>
<text x="60" y="330" class="txt">Loop: r0 = 16 to 19</text>
<text x="400" y="330" class="dim">Red, Green, Blue, Yellow LEDs</text>
<text x="60" y="398" class="dim">Each pin: pad config + function select + OE</text>
<!-- Blink Loop -->
<rect x="40" y="440" width="540" height="190" rx="8" class="pnl"/>
<text x="310" y="478" text-anchor="middle" class="sub">Blink Loop</text>
<rect x="60" y="498" width="500" height="40" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
<text x="80" y="525" class="grn">mcrr p0,#4,r4,r5,c0</text>
<text x="60" y="565" class="txt">r4 = pin, r5 = value</text>
<text x="60" y="595" class="dim">c0 = output value register</text>
<text x="60" y="615" class="dim">r5=1 ON, r5=0 OFF</text>
<!-- Pin Cycling -->
<rect x="620" y="440" width="540" height="190" rx="8" class="pnl"/>
<text x="890" y="478" text-anchor="middle" class="sub">Pin Cycling</text>
<rect x="640" y="498" width="500" height="75" rx="6" fill="#0a0a0f" stroke="#ffaa00" stroke-width="1"/>
<text x="660" y="528" class="amb">pin++;</text>
<text x="660" y="558" class="txt">if (pin > 18) pin=16;</text>
<text x="640" y="600" class="dim">Cycles: 16 -> 17 -> 18 -> 16</text>
<text x="640" y="620" class="dim">Red -> Green -> Blue -> repeat</text>
<!-- Key Takeaway -->
<rect x="40" y="650" width="1120" height="130" rx="8" class="pnl"/>
<text x="600" y="688" text-anchor="middle" class="sub">Why Inline Assembly?</text>
<text x="60" y="722" class="txt">gpio_put(16,1) calls</text>
<text x="390" y="722" class="grn">mcrr</text>
<text x="470" y="722" class="txt">underneath</text>
<text x="60" y="752" class="dim">Inline ASM shows what the SDK does at hardware level</text>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

+83
View File
@@ -0,0 +1,83 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<style>
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
.dim{font:20px 'Courier New',monospace;fill:#888}
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
.badge{stroke:#00ff41;rx:14}
</style>
<rect class="bg" width="1200" height="800"/>
<!-- Title -->
<text x="600" y="52" text-anchor="middle" class="title">IEEE 754 Float</text>
<text x="600" y="88" text-anchor="middle" class="dim">32-bit Single Precision Encoding</text>
<!-- Field Layout -->
<rect x="40" y="110" width="1120" height="170" rx="8" class="pnl"/>
<text x="600" y="147" text-anchor="middle" class="sub">Float Bit Layout (32 bits)</text>
<rect x="60" y="172" width="80" height="30" rx="4" fill="#0a0a0f" stroke="#ff0040" stroke-width="2"/>
<text x="100" y="192" text-anchor="middle" class="red">S</text>
<rect x="150" y="172" width="350" height="30" rx="4" fill="#0a0a0f" stroke="#ffaa00" stroke-width="2"/>
<text x="325" y="192" text-anchor="middle" class="amb">Exponent (8)</text>
<rect x="510" y="172" width="630" height="30" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="2"/>
<text x="825" y="192" text-anchor="middle" class="grn">Mantissa (23)</text>
<text x="100" y="227" text-anchor="middle" class="dim">1 bit</text>
<text x="100" y="243" text-anchor="middle" class="dim">sign</text>
<text x="325" y="227" text-anchor="middle" class="dim">8 bits</text>
<text x="325" y="243" text-anchor="middle" class="dim">bias=127</text>
<text x="825" y="227" text-anchor="middle" class="dim">23 bits</text>
<text x="825" y="243" text-anchor="middle" class="dim">+implicit 1</text>
<!-- Formula -->
<rect x="40" y="300" width="1120" height="110" rx="8" class="pnl"/>
<text x="600" y="325" text-anchor="middle" class="sub">Decode Formula</text>
<text x="60" y="350" class="txt">Value = (-1)^sign × 2^(exp-127) × (1 + mantissa)</text>
<text x="60" y="370" class="dim">Sign determines +/- Exponent scales with bias 127 Mantissa adds precision</text>
<text x="60" y="385" class="dim">Special cases: exp=0 or 255 (denorm, inf, NaN)</text>
<!-- Example: 42.5 -->
<rect x="40" y="430" width="1120" height="255" rx="8" class="pnl"/>
<text x="600" y="455" text-anchor="middle" class="sub">Decode Example: 42.5</text>
<text x="80" y="485" class="red">Sign Bit: 0</text>
<text x="400" y="485" class="dim">Positive number</text>
<text x="80" y="515" class="amb">Exponent: 10000100</text>
<text x="450" y="515" class="dim">= 132 decimal</text>
<text x="80" y="545" class="txt">Bias subtraction: 132 - 127 = 5</text>
<text x="80" y="575" class="grn">Mantissa: 01010100...0</text>
<text x="450" y="575" class="dim">= 1.010101</text>
<text x="80" y="605" class="txt">Combine: 1.010101 × 2^5 = 42.5</text>
<text x="80" y="635" class="cyn">Hex: 0x422A0000</text>
<text x="80" y="661" class="dim">Binary: 01000010001010100000000000000000</text>
<!-- Float vs Integer -->
<rect x="40" y="705" width="1120" height="100" rx="8" class="pnl"/>
<text x="600" y="729" text-anchor="middle" class="sub">32-bit Storage Comparison</text>
<text x="60" y="759" class="cyn">Integer:</text>
<text x="200" y="759" class="txt">Exact values</text>
<text x="430" y="759" class="dim">Range: -2.1B to +2.1B</text>
<text x="860" y="759" class="red">No decimals</text>
<text x="60" y="781" class="amb">Float:</text>
<text x="200" y="781" class="txt">Approximate values</text>
<text x="470" y="781" class="dim">Range: ±10^38</text>
<text x="810" y="781" class="grn">~7 sig digits</text>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

+76
View File
@@ -0,0 +1,76 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<style>
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
.dim{font:20px 'Courier New',monospace;fill:#888}
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
.badge{stroke:#00ff41;rx:14}
</style>
<rect class="bg" width="1200" height="800"/>
<!-- Title -->
<text x="600" y="52" text-anchor="middle" class="title">Float in Ghidra</text>
<text x="600" y="88" text-anchor="middle" class="dim">Analyzing 42.5 in the Binary</text>
<!-- Decompiled View -->
<rect x="40" y="110" width="540" height="280" rx="8" class="pnl"/>
<text x="310" y="148" text-anchor="middle" class="sub">Decompiled main()</text>
<rect x="60" y="168" width="500" height="205" rx="6" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
<text x="80" y="198" class="txt">int main(void) {</text>
<text x="100" y="228" class="cyn">stdio_init_all();</text>
<text x="100" y="258" class="txt">uVar1 = DAT_1000024c;</text>
<text x="100" y="288" class="txt">do {</text>
<text x="120" y="318" class="amb">printf(fmt,0,uVar1);</text>
<text x="100" y="348" class="txt">} while(true);</text>
<!-- Key Discovery -->
<rect x="620" y="110" width="540" height="280" rx="8" class="pnl"/>
<text x="890" y="148" text-anchor="middle" class="sub">Key Discovery</text>
<text x="640" y="190" class="txt">printf with %f always</text>
<text x="640" y="220" class="txt">receives a</text>
<text x="830" y="220" class="red">double</text>
<text x="960" y="220" class="txt">(64-bit)</text>
<text x="640" y="260" class="dim">C promotes float to double</text>
<text x="640" y="290" class="dim">for variadic functions!</text>
<rect x="640" y="310" width="500" height="60" rx="4" fill="#0a0a0f" stroke="#ffaa00" stroke-width="2"/>
<text x="890" y="348" text-anchor="middle" class="amb">42.5 sent as double</text>
<!-- Register Pair -->
<rect x="40" y="410" width="1120" height="180" rx="8" class="pnl"/>
<text x="600" y="448" text-anchor="middle" class="sub">Register Pair r2:r3</text>
<rect x="60" y="470" width="520" height="50" rx="4" fill="#0a0a0f" stroke="#00d4ff" stroke-width="1"/>
<text x="80" y="510" class="cyn">r2 (low):</text>
<text x="260" y="510" class="grn">0x00000000</text>
<rect x="600" y="470" width="540" height="50" rx="4" fill="#0a0a0f" stroke="#ffaa00" stroke-width="1"/>
<text x="620" y="510" class="amb">r3 (high):</text>
<text x="810" y="510" class="grn">0x40454000</text>
<text x="60" y="565" class="txt">Combined: 0x4045400000000000</text>
<text x="680" y="565" class="grn">= 42.5</text>
<!-- Assembly -->
<rect x="40" y="610" width="1120" height="170" rx="8" class="pnl"/>
<text x="600" y="648" text-anchor="middle" class="sub">Assembly View</text>
<rect x="60" y="668" width="1080" height="90" rx="6" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
<text x="80" y="698" class="grn">1000023a</text>
<text x="260" y="698" class="amb">00 24</text>
<text x="380" y="698" class="txt">movs r4, #0x0</text>
<text x="640" y="698" class="dim">// r2 = 0</text>
<text x="80" y="733" class="grn">1000023c</text>
<text x="260" y="733" class="amb">03 4d</text>
<text x="380" y="733" class="txt">ldr r5,[DAT...]</text>
<text x="640" y="733" class="dim">// r3 = 0x40454000</text>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

+87
View File
@@ -0,0 +1,87 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<style>
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
.dim{font:20px 'Courier New',monospace;fill:#888}
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
.badge{stroke:#00ff41;rx:14}
</style>
<rect class="bg" width="1200" height="800"/>
<!-- Title -->
<text x="600" y="52" text-anchor="middle" class="title">Patching Float</text>
<text x="600" y="88" text-anchor="middle" class="dim">Changing 42.5 to 99.0 in Ghidra</text>
<!-- Calculate New Encoding -->
<rect x="40" y="110" width="1120" height="230" rx="8" class="pnl"/>
<text x="600" y="148" text-anchor="middle" class="sub">Calculate 99.0 as Double</text>
<text x="60" y="188" class="txt">99 decimal =</text>
<text x="290" y="188" class="grn">1100011</text>
<text x="440" y="188" class="txt">binary</text>
<text x="60" y="223" class="txt">Normalize:</text>
<text x="250" y="223" class="amb">1.100011 x 2^6</text>
<text x="60" y="258" class="red">Sign:</text>
<text x="160" y="258" class="txt">0</text>
<text x="300" y="258" class="amb">Exp:</text>
<text x="380" y="258" class="txt">6+1023 = 1029</text>
<text x="60" y="293" class="grn">Mantissa:</text>
<text x="240" y="293" class="txt">100011000...0</text>
<text x="60" y="328" class="dim">Full double: 0x4058C00000000000</text>
<!-- Before vs After -->
<rect x="40" y="360" width="540" height="200" rx="8" class="pnl"/>
<text x="310" y="398" text-anchor="middle" class="sub">Before (42.5)</text>
<rect x="60" y="418" width="500" height="50" rx="4" fill="#0a0a0f" stroke="#ff0040" stroke-width="1"/>
<text x="80" y="448" class="cyn">r2:</text>
<text x="160" y="448" class="red">0x00000000</text>
<rect x="60" y="478" width="500" height="50" rx="4" fill="#0a0a0f" stroke="#ff0040" stroke-width="1"/>
<text x="80" y="508" class="cyn">r3:</text>
<text x="160" y="508" class="red">0x40454000</text>
<text x="60" y="548" class="dim">Output: fav_num: 42.500000</text>
<rect x="620" y="360" width="540" height="200" rx="8" class="pnl"/>
<text x="890" y="398" text-anchor="middle" class="sub">After (99.0)</text>
<rect x="640" y="418" width="500" height="50" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
<text x="660" y="448" class="cyn">r2:</text>
<text x="740" y="448" class="grn">0x00000000</text>
<text x="960" y="450" class="dim">same!</text>
<rect x="640" y="478" width="500" height="50" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
<text x="660" y="508" class="cyn">r3:</text>
<text x="740" y="508" class="grn">0x4058C000</text>
<text x="960" y="510" class="amb">changed</text>
<text x="640" y="548" class="dim">Output: fav_num: 99.000000</text>
<!-- Patch Steps -->
<rect x="40" y="580" width="1120" height="200" rx="8" class="pnl"/>
<text x="600" y="618" text-anchor="middle" class="sub">Patch in Ghidra</text>
<rect x="60" y="640" width="340" height="65" rx="6" fill="#0a0a0f" stroke="#00d4ff" stroke-width="1"/>
<text x="230" y="668" text-anchor="middle" class="cyn">1. Window: Bytes</text>
<text x="230" y="690" text-anchor="middle" class="dim">Open byte editor</text>
<rect x="420" y="640" width="340" height="65" rx="6" fill="#0a0a0f" stroke="#ffaa00" stroke-width="1"/>
<text x="590" y="668" text-anchor="middle" class="amb">2. Find 00404540</text>
<text x="590" y="690" text-anchor="middle" class="dim">High word of 42.5</text>
<rect x="780" y="640" width="340" height="65" rx="6" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
<text x="950" y="668" text-anchor="middle" class="grn">3. Patch 00C05840</text>
<text x="950" y="690" text-anchor="middle" class="dim">High word of 99.0</text>
<text x="60" y="748" class="dim">Only one word to patch (low word is 0)</text>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

+75
View File
@@ -0,0 +1,75 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<style>
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
.dim{font:20px 'Courier New',monospace;fill:#888}
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
.badge{stroke:#00ff41;rx:14}
</style>
<rect class="bg" width="1200" height="800"/>
<!-- Title -->
<text x="600" y="52" text-anchor="middle" class="title">Double Precision</text>
<text x="600" y="88" text-anchor="middle" class="dim">IEEE 754 64-bit Floating Point</text>
<!-- Bit Layout -->
<rect x="40" y="110" width="1120" height="175" rx="8" class="pnl"/>
<text x="600" y="148" text-anchor="middle" class="sub">64-Bit Layout</text>
<rect x="60" y="168" width="80" height="72" rx="4" fill="#ff0040" stroke="#ff0040" stroke-width="1" opacity="0.3"/>
<text x="100" y="197" text-anchor="middle" class="red">Sign</text>
<text x="100" y="218" text-anchor="middle" class="dim">1 bit</text>
<rect x="160" y="168" width="300" height="72" rx="4" fill="#ffaa00" stroke="#ffaa00" stroke-width="1" opacity="0.2"/>
<text x="310" y="197" text-anchor="middle" class="amb">Exponent</text>
<text x="310" y="218" text-anchor="middle" class="dim">11 bits (bias 1023)</text>
<rect x="480" y="168" width="660" height="72" rx="4" fill="#00ff41" stroke="#00ff41" stroke-width="1" opacity="0.2"/>
<text x="810" y="197" text-anchor="middle" class="grn">Mantissa (Fraction)</text>
<text x="810" y="218" text-anchor="middle" class="dim">52 bits</text>
<text x="60" y="272" class="dim">Formula: (-1)^S x 1.Mantissa x 2^(Exp-1023)</text>
<!-- 42.52525 Example -->
<rect x="40" y="305" width="1120" height="190" rx="8" class="pnl"/>
<text x="600" y="340" text-anchor="middle" class="sub">Encoding 42.52525</text>
<text x="60" y="378" class="cyn">Sign:</text>
<text x="170" y="378" class="txt">0 (positive)</text>
<text x="60" y="408" class="amb">Exponent:</text>
<text x="230" y="408" class="txt">5 + 1023 = 1028</text>
<text x="530" y="408" class="dim">= 0x404 (hex)</text>
<text x="60" y="438" class="grn">Mantissa:</text>
<text x="230" y="438" class="txt">0101010000110011...</text>
<text x="60" y="468" class="dim">Full 64-bit hex:</text>
<text x="310" y="468" class="grn">0x4045433B645A1CAC</text>
<!-- Float vs Double Comparison -->
<rect x="40" y="515" width="540" height="265" rx="8" class="pnl"/>
<text x="310" y="553" text-anchor="middle" class="sub">Float (32-bit)</text>
<text x="60" y="590" class="txt">Size: 4 bytes</text>
<text x="60" y="620" class="txt">Exp: 8 bits</text>
<text x="60" y="650" class="txt">Mantissa: 23 bits</text>
<text x="60" y="680" class="txt">Precision: ~7 digits</text>
<text x="60" y="710" class="txt">Bias: 127</text>
<text x="60" y="740" class="dim">1 register (ARM)</text>
<rect x="620" y="515" width="540" height="265" rx="8" class="pnl"/>
<text x="890" y="553" text-anchor="middle" class="sub">Double (64-bit)</text>
<text x="640" y="590" class="grn">Size: 8 bytes</text>
<text x="640" y="620" class="grn">Exp: 11 bits</text>
<text x="640" y="650" class="grn">Mantissa: 52 bits</text>
<text x="640" y="680" class="grn">Precision: ~15 digits</text>
<text x="640" y="710" class="grn">Bias: 1023</text>
<text x="640" y="740" class="dim">2 registers (r2:r3)</text>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

+71
View File
@@ -0,0 +1,71 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<style>
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
.dim{font:20px 'Courier New',monospace;fill:#888}
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
.badge{stroke:#00ff41;rx:14}
</style>
<rect class="bg" width="1200" height="800"/>
<!-- Title -->
<text x="600" y="52" text-anchor="middle" class="title">Double in Ghidra</text>
<text x="600" y="88" text-anchor="middle" class="dim">Analyzing 42.52525 in memory</text>
<!-- Decompiled View -->
<rect x="40" y="110" width="540" height="230" rx="8" class="pnl"/>
<text x="310" y="148" text-anchor="middle" class="sub">Decompiled main()</text>
<rect x="60" y="168" width="500" height="150" rx="4" fill="#0a0a0f" stroke="#1a1a2e" stroke-width="1"/>
<text x="80" y="198" class="cyn">int main(void) {</text>
<text x="110" y="228" class="txt">double fav_num</text>
<text x="110" y="258" class="amb"> = 42.52525;</text>
<text x="110" y="288" class="txt">stdio_init_all();</text>
<text x="80" y="308" class="cyn">}</text>
<!-- Key Difference from Float -->
<rect x="620" y="110" width="540" height="230" rx="8" class="pnl"/>
<text x="890" y="148" text-anchor="middle" class="sub">Key Difference</text>
<text x="640" y="188" class="txt">Float (42.5):</text>
<text x="640" y="218" class="dim">r2 = 0x00000000 (zero!)</text>
<text x="640" y="248" class="dim">r3 = 0x40454000</text>
<text x="640" y="288" class="grn">Double (42.52525):</text>
<text x="640" y="318" class="amb">r2 = 0x645A1CAC (non-zero!)</text>
<!-- Register Pair -->
<rect x="40" y="360" width="1120" height="170" rx="8" class="pnl"/>
<text x="600" y="398" text-anchor="middle" class="sub">Register Pair r2:r3</text>
<rect x="60" y="418" width="520" height="55" rx="4" fill="#0a0a0f" stroke="#ffaa00" stroke-width="1"/>
<text x="80" y="445" class="amb">r3 (HIGH):</text>
<text x="280" y="445" class="grn">0x4045433B</text>
<rect x="620" y="418" width="520" height="55" rx="4" fill="#0a0a0f" stroke="#ffaa00" stroke-width="1"/>
<text x="640" y="445" class="amb">r2 (LOW):</text>
<text x="830" y="445" class="grn">0x645A1CAC</text>
<text x="60" y="510" class="dim">Combined: 0x4045433B645A1CAC = 42.52525</text>
<!-- Assembly View -->
<rect x="40" y="550" width="1120" height="230" rx="8" class="pnl"/>
<text x="600" y="588" text-anchor="middle" class="sub">Assembly (ldrd)</text>
<rect x="60" y="608" width="700" height="140" rx="4" fill="#0a0a0f" stroke="#1a1a2e" stroke-width="1"/>
<text x="80" y="638" class="cyn">ldrd r2,r3,[PC,#0x10]</text>
<text x="80" y="668" class="dim">; Loads BOTH words at once</text>
<text x="80" y="698" class="dim">; r2 gets low word</text>
<text x="80" y="728" class="dim">; r3 gets high word</text>
<rect x="780" y="608" width="360" height="140" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
<text x="800" y="648" class="grn">ldrd = Load</text>
<text x="800" y="678" class="grn">Register</text>
<text x="800" y="708" class="grn">Doubleword</text>
<text x="800" y="738" class="dim">ARM Cortex-M33</text>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

+88
View File
@@ -0,0 +1,88 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<style>
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
.dim{font:20px 'Courier New',monospace;fill:#888}
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
.badge{stroke:#00ff41;rx:14}
</style>
<rect class="bg" width="1200" height="800"/>
<!-- Title -->
<text x="600" y="52" text-anchor="middle" class="title">Patching Double</text>
<text x="600" y="88" text-anchor="middle" class="dim">Changing 42.52525 to 99.99</text>
<!-- New Encoding Calc -->
<rect x="40" y="110" width="1120" height="160" rx="8" class="pnl"/>
<text x="600" y="148" text-anchor="middle" class="sub">99.99 as IEEE 754 Double</text>
<text x="60" y="188" class="cyn">Sign:</text>
<text x="160" y="188" class="txt">0</text>
<text x="300" y="188" class="amb">Exp:</text>
<text x="390" y="188" class="txt">6 + 1023 = 1029</text>
<text x="60" y="223" class="grn">Result:</text>
<text x="200" y="223" class="grn">0x4058FF5C28F5C28F</text>
<text x="60" y="253" class="dim">r3 (HIGH) = 0x4058FF5C</text>
<text x="540" y="253" class="dim">r2 (LOW) = 0x28F5C28F</text>
<!-- Before vs After -->
<rect x="40" y="290" width="540" height="240" rx="8" class="pnl"/>
<text x="310" y="328" text-anchor="middle" class="sub">Before (42.52525)</text>
<rect x="60" y="348" width="500" height="50" rx="4" fill="#0a0a0f" stroke="#ff0040" stroke-width="1"/>
<text x="80" y="373" class="cyn">r3:</text>
<text x="150" y="373" class="red">0x4045433B</text>
<rect x="60" y="408" width="500" height="50" rx="4" fill="#0a0a0f" stroke="#ff0040" stroke-width="1"/>
<text x="80" y="433" class="cyn">r2:</text>
<text x="150" y="433" class="red">0x645A1CAC</text>
<text x="60" y="485" class="dim">printf: 42.525250</text>
<text x="60" y="515" class="dim">Both words non-zero</text>
<rect x="620" y="290" width="540" height="240" rx="8" class="pnl"/>
<text x="890" y="328" text-anchor="middle" class="sub">After (99.99)</text>
<rect x="640" y="348" width="500" height="50" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
<text x="660" y="373" class="cyn">r3:</text>
<text x="730" y="373" class="grn">0x4058FF5C</text>
<text x="940" y="380" class="amb">changed</text>
<rect x="640" y="408" width="500" height="50" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
<text x="660" y="433" class="cyn">r2:</text>
<text x="730" y="433" class="grn">0x28F5C28F</text>
<text x="940" y="440" class="amb">changed</text>
<text x="640" y="485" class="dim">printf: 99.990000</text>
<text x="640" y="515" class="dim">BOTH words changed!</text>
<!-- Float vs Double Patching -->
<rect x="40" y="550" width="540" height="230" rx="8" class="pnl"/>
<text x="310" y="588" text-anchor="middle" class="sub">Float Patch</text>
<text x="60" y="628" class="txt">Words changed:</text>
<text x="300" y="628" class="grn">1</text>
<text x="60" y="663" class="txt">r2 (low):</text>
<text x="260" y="663" class="dim">stays 0x0</text>
<text x="60" y="698" class="txt">r3 (high):</text>
<text x="280" y="698" class="amb">patched</text>
<text x="60" y="733" class="dim">Easier to patch</text>
<rect x="620" y="550" width="540" height="230" rx="8" class="pnl"/>
<text x="890" y="588" text-anchor="middle" class="sub">Double Patch</text>
<text x="640" y="628" class="txt">Words changed:</text>
<text x="880" y="628" class="red">2</text>
<text x="640" y="663" class="txt">r2 (low):</text>
<text x="840" y="663" class="amb">patched</text>
<text x="640" y="698" class="txt">r3 (high):</text>
<text x="860" y="698" class="amb">patched</text>
<text x="640" y="733" class="dim">Both words must change</text>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

+101
View File
@@ -0,0 +1,101 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<style>
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
.dim{font:20px 'Courier New',monospace;fill:#888}
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
.badge{stroke:#00ff41;rx:14}
</style>
<rect class="bg" width="1200" height="800"/>
<!-- Title -->
<text x="600" y="52" text-anchor="middle" class="title">IEEE 754 &amp; Data Types</text>
<text x="600" y="88" text-anchor="middle" class="dim">Data Types and IEEE 754 Reference</text>
<!-- Reference Table -->
<rect x="40" y="110" width="1120" height="330" rx="8" class="pnl"/>
<text x="600" y="148" text-anchor="middle" class="sub">IEEE 754 Hex Values</text>
<!-- Table Header -->
<text x="60" y="188" class="cyn">Value</text>
<text x="260" y="188" class="cyn">Float (32b)</text>
<text x="560" y="188" class="cyn">Double (64b)</text>
<line x1="60" y1="198" x2="1140" y2="198" stroke="#1a1a2e" stroke-width="1"/>
<!-- Row 1 -->
<text x="60" y="228" class="txt">42.0</text>
<text x="260" y="228" class="grn">0x42280000</text>
<text x="560" y="228" class="grn">0x4045000000000000</text>
<!-- Row 2 -->
<text x="60" y="258" class="txt">42.5</text>
<text x="260" y="258" class="grn">0x422A0000</text>
<text x="560" y="258" class="grn">0x4045400000000000</text>
<!-- Row 3 -->
<text x="60" y="288" class="txt">99.0</text>
<text x="260" y="288" class="amb">0x42C60000</text>
<text x="560" y="288" class="amb">0x4058C00000000000</text>
<!-- Row 4 -->
<text x="60" y="318" class="txt">99.99</text>
<text x="260" y="318" class="amb">0x42C7F5C3</text>
<text x="560" y="318" class="amb">0x4058FF5C28F5C28F</text>
<!-- Row 5 -->
<text x="60" y="348" class="txt">3.14</text>
<text x="260" y="348" class="red">0x4048F5C3</text>
<text x="560" y="348" class="red">0x40091EB851EB851F</text>
<!-- Row 6 -->
<text x="60" y="378" class="txt">100.0</text>
<text x="260" y="378" class="red">0x42C80000</text>
<text x="560" y="378" class="red">0x4059000000000000</text>
<text x="60" y="418" class="dim">Tip: float low word often 0x0; double low word usually non-zero</text>
<!-- Patching Workflow -->
<rect x="40" y="460" width="1120" height="155" rx="8" class="pnl"/>
<text x="600" y="498" text-anchor="middle" class="sub">Patching Workflow</text>
<rect x="60" y="518" width="200" height="70" rx="6" fill="#0a0a0f" stroke="#00d4ff" stroke-width="1"/>
<text x="160" y="548" text-anchor="middle" class="cyn">1. Identify</text>
<text x="160" y="570" text-anchor="middle" class="dim">float / double</text>
<rect x="280" y="518" width="200" height="70" rx="6" fill="#0a0a0f" stroke="#ffaa00" stroke-width="1"/>
<text x="380" y="548" text-anchor="middle" class="amb">2. Check r2</text>
<text x="380" y="570" text-anchor="middle" class="dim">zero = float</text>
<rect x="500" y="518" width="200" height="70" rx="6" fill="#0a0a0f" stroke="#ff0040" stroke-width="1"/>
<text x="600" y="548" text-anchor="middle" class="red">3. Calculate</text>
<text x="600" y="570" text-anchor="middle" class="dim">new hex value</text>
<rect x="720" y="518" width="200" height="70" rx="6" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
<text x="820" y="548" text-anchor="middle" class="grn">4. Patch</text>
<text x="820" y="570" text-anchor="middle" class="dim">in byte editor</text>
<rect x="940" y="518" width="200" height="70" rx="6" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
<text x="1040" y="548" text-anchor="middle" class="grn">5. Export</text>
<text x="1040" y="570" text-anchor="middle" class="dim">UF2 + test</text>
<!-- Key Takeaways -->
<rect x="40" y="635" width="540" height="145" rx="8" class="pnl"/>
<text x="310" y="670" text-anchor="middle" class="sub">Integer Types</text>
<text x="60" y="705" class="txt">uint8_t: 0-255</text>
<text x="60" y="735" class="txt">int8_t: -128 to 127</text>
<text x="60" y="765" class="dim">Two's complement for signed</text>
<rect x="620" y="635" width="540" height="145" rx="8" class="pnl"/>
<text x="890" y="670" text-anchor="middle" class="sub">Key Insight</text>
<text x="640" y="705" class="txt">Float: patch 1 word</text>
<text x="640" y="735" class="txt">Double: patch 2 words</text>
<text x="640" y="765" class="dim">Check r2 to detect type</text>
</svg>

After

Width:  |  Height:  |  Size: 4.5 KiB