Files
JiboViteDocs/docs/uart/vectors/validatedmem.md

176 lines
5.7 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Validated memory adresses
- - -
## Power Management Controller (PMC)
#### `0x7000E400` — PMC Base Address
**Use:** The starting point for all Power Management operations.
#### `0x7000E450` — PMC_SCRATCH0
- **Use:** undefined but i used it as a Data Safe.
- **Example:** When the USB connection dies, store 4 bytes of data here.
- **C Code exampple:**
```c
// Store a 4-byte value from IRAM into the scratch register
uint32_t leaked_data = *(volatile uint32_t *)0x40001000;
*(volatile uint32_t *)0x7000E450 = leaked_data;
```
#### `0x7000E414` — PMC_CNTRL (Reset Control)
- **Use:** The Reboot Trigger.
- **Bit 4:** Setting this bit triggers a Warm Reset.
- **Example:** use this immediately after writing to `SCRATCH0` to force Jibo back into RCM mode.
- **C Code Implementation:**
```c
// Trigger Warm Reset to return to RCM mode
*(volatile uint32_t *)0x7000E414 |= (1 << 4);
```
## Timer and Watchdog (TMR/WDT)
These addresses allow us to cut the systems security features from what i can tell so they don't interfere with the payload.
#### `0x6000501c` — TMR_WDT_RESTART
- **Use:** The Watchdog cut.
- **Mechanism:** The Tegra K1 has a timer that reboots the device if it doesn't receive a clock signal within a few seconds.
- **Example:** We write the magic value `0xcafe` here in every loop to prevent Jibo from panic-resetting during a dump.
- **C Code Implementation:**
```c
while(1) {
// (reset)
*(volatile uint32_t *)0x6000501c = 0xcafe;
// ... rest of the exploit ...
}
```
## Internal RAM (IRAM/SRAM)
This is the part where the BootROM is.
#### `0x40000000` — IRAM Base (Start)
- **Use:** The beginning of the 256KB internal memory.
- **Significance:** This is where the payload is injected. If u dump from here, u get the "Leftovers" of the boot process (keys, signatures, and config data) from what i could tell.
#### `0x4003FFFF` — IRAM End
- **Use:** The boundary of the volatile memory. (not 100% Sure but pretty certain)
- **Constraint:** If we try to read past this address, the system will hard-crash because we are hitting undefined memory space.
## BootROM Service Functions
The BootROM (at `0x00000000`) is read-only memory etched into the silicon. It contains pre-written functions for USB communication that we can "borrow" so we don't have to write a full USB driver from scratch.
#### `0x00003551` — usb_send (Standard)
- **Use:** Sends a structured data packet over the RCM USB connection.
- **Significance:** This is the basically the proper way i could get it to talk. It handles some of the USB protocol handshaking automatically.
- **Example:**
```C
// Define the function signature based on BootROM
typedef int (*usb_send_ptr)(void *buffer, unsigned int length);
usb_send_ptr usb_send = (usb_send_ptr)0x00003551;
//push 64 bytes of IRAM to the PC
usb_send((void *)0x40000000, 64);
```
#### `0x000035e5` — usb_send_raw (Bulk)
- **Use:** A lower-level function that bypasses some of the standard RCM state checks i think.
- **Significance:** This is how i got those first **16 bytes** out. It is open data pushing.
- **Example:** I used this when the standard `usb_send` was stalling, as it forces the hardware to dump the buffer to the endpoint immediately.
```c
// Define the raw function pointer
typedef void (*usb_send_raw_ptr)(void *buffer, unsigned int length);
usb_send_raw_ptr usb_send_raw = (usb_send_raw_ptr)0x000035e5;
//Force dump a 16-byte chunk of IRAM regardless of USB state
void dump_raw_chunk() {
uint8_t buffer[16];
// Copy the data from a target address (e.g.sstart of IRAM)
memcpy(buffer, (void*)0x40000000, 16);
// Push it out. On the PC side
usb_send_raw(buffer, 16);
}
```
## Hardware Fuse Registers
The Fuses are permanent oly set at the factory so we cant change these
#### `0x7000F800` — FUSE_BASE
- **Use:** The starting point for reading the hardware id & status.
- **Significance:** Reading from here tells us if Jibo is in "Production" mode (Locked) or "Development" mode (Unlocked).
#### `0x7000F800 + 0x60` — Security Config Fuse
- **Use:** Determines if **Secure Boot** is active.
- **Discovery:** In my tests, reading this offset returned random data.
- **The Verdict:** This confirmed that Jibo is a **Secure Boot** device. He will only boot software that has been digitally signed by Jibo Inc.s private keys.
#### `0x7000F900` — FUSE_RESERVED_ODM (The SBK/SSK Area)
- **Use:** This is where the **Secure Boot Key (SBK)** usually is.
- **The Goal:** If we can successfully read this entire block, we might find the AES keys needed to decrypt the Jibo OS files on the EMMC.
## The Boot Configuration Table (BCT)
The BCT is a piece of data usually found at the very start of the boot process (and often cached in IRAM).
#### `0x400000f0` — BCT Pointer / Entry Point
- **Use:** I identified this address in on of the `hexdumps` i sent on discord.
- **Significance:** This is where the BootROM hands over control to the next stage of the bootloader.
- **The Hack:** By targeting our leaker near this address, we can see how the Tegra sets up its memory controllers before it realizes we've hijacked the process.
```C
void inspect_bct_handoff() {
// Read the instruction at the BCT entry point
uint32_t entry_instruction = *(volatile uint32_t *)0x400000f0;
// Often, this is a 'Branch' (B) instruction in ARM hex: 0xEAXXXXXX
// If 0xEA, we know Jibo is ready run the bootloader
if ((entry_instruction >> 24) == 0xEA) {
// Log it for the PC to see
*(volatile uint32_t *)0x7000E450 = 0xBC7DE4D; // "BCT DEAD" hex flag
}
}
```