mirror of
https://github.com/mytechnotalent/Embedded-Hacking.git
synced 2026-10-04 06:57:02 +02:00
Week 4-BN: export the image dynamically from the view's segment; run uf2conv in-app
Read the loadable segment (seg.start + seg.data_length) instead of hardcoding the range or calling os.path.getsize, and document converting the .bin to UF2 from Binary Ninja's own Python console (chdir + runpy). Verified: the dump is byte-exact except the patches, and uf2conv yields a valid UF2 (magic/family/blocks OK).
This commit is contained in:
1 parent
f9e4cab78e
commit
1b292058f5
2 files changed
+27
-5
No files matched your search
+27
-5
@@ -764,16 +764,23 @@ Keep the replacement exactly three bytes. If you use a shorter string you must p
|
||||
|
||||
```python
|
||||
import os
|
||||
data = bv.read(0x10000000, 0x3bbc)
|
||||
seg = next(s for s in bv.segments if s.data_length) # the loadable image segment
|
||||
data = bv.read(seg.start, seg.data_length) # base + size come from the view itself
|
||||
out = os.path.join(os.path.dirname(bv.file.original_filename), "0x0005_intro-to-variables-h.bin")
|
||||
open(out, "wb").write(data)
|
||||
print(len(data), out) # -> 15292 /.../build/0x0005_intro-to-variables-h.bin
|
||||
```
|
||||
|
||||
Two things this gets right:
|
||||
Where the two numbers come from — nothing is hardcoded:
|
||||
|
||||
- **`seg.start`** is the image base Binary Ninja loaded the `.bin` at (`0x10000000`), the same value you pass to `uf2conv --base`.
|
||||
- **`seg.data_length`** is the segment's size in the file (`0x3bbc` = 15292). Exactly one segment carries data (the image); every peripheral and synthetic segment has `data_length == 0`, so `next(...)` picks the image.
|
||||
- Reading `seg.start` for `seg.data_length` bytes therefore grabs exactly the image.
|
||||
|
||||
Two gotchas this avoids:
|
||||
|
||||
- **No relative path.** Binary Ninja's Python console runs with a read-only working directory (inside the app bundle), so `open("0x0005_intro-to-variables-h.bin", "wb")` fails with `OSError: [Errno 30] Read-only file system`. `bv.file.original_filename` is the `.bin` this view was loaded from, so the file is written next to it — no machine-specific path.
|
||||
- **Read the image, not the whole view.** `bv.read(bv.start, bv.length)` spans the entire mapped range (`0x10000000`..`0xe008000c`). The image is `0x10000000` + `0x3bbc` (15292) bytes, so read that range explicitly.
|
||||
- **Read the image, not the whole view.** `bv.read(bv.start, bv.length)` spans the entire mapped range (`0x10000000`..`0xe008000c`), which is not the image. The segment's `data_length` is the image size.
|
||||
|
||||
A different size means you exported a partial view.
|
||||
|
||||
@@ -795,6 +802,18 @@ python ..\uf2conv.py 0x0005_intro-to-variables-h.bin ^
|
||||
--base 0x10000000 --family 0xe48bff59 --output hacked.uf2
|
||||
```
|
||||
|
||||
> **Or convert from the Binary Ninja console** — it is a normal Python interpreter, so you never have to leave the app. `chdir` to a writable directory first (the default one is read-only), then run the script:
|
||||
>
|
||||
> ```python
|
||||
> import os, sys, runpy
|
||||
> os.chdir(os.path.dirname(bv.file.original_filename)) # the project build dir (writable)
|
||||
> sys.argv = ["uf2conv.py", "0x0005_intro-to-variables-h.bin",
|
||||
> "--base", "0x10000000", "--family", "0xe48bff59", "--output", "hacked.uf2"]
|
||||
> runpy.run_path("../../uf2conv.py", run_name="__main__") # path to your uf2conv.py
|
||||
> ```
|
||||
>
|
||||
> This writes `hacked.uf2` next to the `.bin`, ready to drag onto the Pico.
|
||||
|
||||
### Step 21: Flash and verify `age: 70`
|
||||
|
||||
Hold **BOOTSEL**, plug in the Pico 2, and drag `hacked.uf2` onto the **`RP2350`** drive. Open the serial monitor:
|
||||
@@ -1120,19 +1139,22 @@ Exactly three bytes, same rule as Project 1: a shorter string must be padded, a
|
||||
|
||||
```python
|
||||
import os
|
||||
data = bv.read(0x10000000, 0x3d34)
|
||||
seg = next(s for s in bv.segments if s.data_length) # the loadable image segment
|
||||
data = bv.read(seg.start, seg.data_length) # base + size from the view itself
|
||||
out = os.path.join(os.path.dirname(bv.file.original_filename), "0x0008_uninitialized-variables-h.bin")
|
||||
open(out, "wb").write(data)
|
||||
print(len(data), out) # -> 15668 /.../build/0x0008_uninitialized-variables-h.bin
|
||||
```
|
||||
|
||||
Same two gotchas as Project 1: no relative path (the console's CWD is read-only) and read the image range (`0x10000000` + `0x3d34`), not `bv.start`/`bv.length`.
|
||||
Same as Project 1: `seg.start` is the load base and `seg.data_length` is the image size (here `0x3d34` = 15668) — both read from the view, and no relative path (the console's CWD is read-only).
|
||||
|
||||
```bash
|
||||
python3 ../uf2conv.py 0x0008_uninitialized-variables-h.bin \
|
||||
--base 0x10000000 --family 0xe48bff59 --output hacked.uf2
|
||||
```
|
||||
|
||||
Or run the conversion from the Binary Ninja console, exactly as in Step 20 (`os.chdir` to the build dir, then `runpy.run_path("../../uf2conv.py", run_name="__main__")` with `sys.argv` set to the arguments above).
|
||||
|
||||
Hold **BOOTSEL**, plug in the Pico 2, drag `hacked.uf2` onto the **`RP2350`** drive.
|
||||
|
||||
### Step 30: Verify
|
||||
|
||||
Binary file not shown.
Reference in new issue
Block a user