
, which branches payload_main. Also includes the firmware_symbols and config.
/**
* patch_table:
*
* The patch table used by exploit_main to patch the kernel
* it format is .long address, .long new_value
*
* it will patch its content until the destination address is 0
*
*/
#define ADDR_IN_PAGE(target) (PAYLOAD_OFFSET_IN_PAGE + (target) - payload_entry)
<pre>
'''ADDR_IN_MEM2''' calculates the adress relative to the RESIDENT_AREA_OFFSET (resident_area_start)
<pre>#define ADDR_IN_MEM2(target) ((target) - RESIDENT_AREA_OFFSET)
// Absolute branching
#define ABSOLUTE_MEM2(target) (target - (MEM_BASE2 + ADDR_IN_MEM2(.)))
// Dynamic macros to load a label into a register
define MEM_BASE(dest) \
li dest, 1; \
rldicr dest, dest, 63, 0;
#define LOAD_LABEL(base, dest, source, address) \
oris dest, source, ((base) + (address))@h; \
ori dest, dest, ((base) + (address))@l;
#define LOAD_LABEL2(dest, source, address) \
LOAD_LABEL(MEM_BASE2, dest, source, ADDR_IN_MEM2 (address))
#define LOADI_LABEL2(dest, address) \
LOAD_LABEL2(dest, dest, address)
#define LOAD_MEM_BASE2(dest) \
MEM_BASE (dest) \
LOAD_LABEL (MEM_BASE2, dest, dest, 0)
// Add system calls. Use only in exploit_main because of registers used...
define ADD_SYSCALL(source, ptr, num) \
LOAD_LABEL2 (%r3, source, ptr); \
LOAD_ABS (%r4, source, syscall_table); \
std %r3, 0x08*num(%r4); \
// For loading an absolute value
define LOAD_ABS(dest, source, address) LOAD_LABEL(0, dest, source, address)
define LOADI_ABS(dest, address) LOAD_ABS(dest, dest, address)
// Absolute .quads
// HACK ALERT: the open toolchain bugs during compilation when trying to add
// a 'bignum' with address or MEM_BASE1.. so we split it here into two .long
// makes it easy since PPC is big endian.
define QUAD_MEM2(address) \
.long 0x80000000; \
.long MEM_BASE2 + ADDR_IN_MEM2(address);
/* Patch Table Macros */
define PATCH_INST(offset, instruction...) \
.long offset; \
instruction;
#define PATCH_DATA(offset, data...) \
.long offset; \
.long data;
#define PATCH_BRANCH(offset, op, target) \
.long offset; \
op ((target) - (offset));
#define PATCH_BRANCH_MEM2(offset, op, target) \
PATCH_BRANCH (offset, op, (MEM_BASE2 + ADDR_IN_MEM2(target)));
#define BRANCH_ABSOLUTE(dest, target) \
MEM_BASE (dest); \
oris dest, dest, target@h; \
ori dest, dest, target@l; \
mtctr dest; \
bctrl;
#define DEFINE_FUNC_PTR(function) \
function##_ptr: \
.quad 0; \
function: \
mflr %r0; \
stdu %r1, -0x80(%r1); \
std %r31, 0x70(%r1); \
std %r0, 0x90(%r1); \
BRANCH_FUNC_PTR(%r31, function); \
ld %r31, 0x70(%r1); \
ld %r0, 0x90(%r1); \
addi %r1, %r1, 0x80; \
mtlr %r0; \
blr;
#define BRANCH_FUNC_PTR(dest, function) \
MEM_BASE (dest); \
LOAD_LABEL2 (dest, dest, function ##_ptr); \
ld dest, 0(dest); \
mtctr dest; \
bctrl;
#define LOAD_FUNC_PTR(function) \
ALLOC_AND_COPY_PROC(%r31, function ##_start, \
(function ## _end - function##_start)); \
LOAD_LABEL2 (%r6, %r30, function ##_ptr); \
std %r3, 0(%r6);
#define GET_CURRENT_PAGE(temp, dest) \
bl get_current_page; \
b got_current_page; \
get_current_page: \
mflr dest; \
blr; \
got_current_page: \
li temp, 0xfff; \
nor temp, temp, temp; \
and dest, dest, temp;
#define PANIC() \
li %r3, 0; \
li %r11, 255; \
sc 1;
#define ALLOCATE_BUFFER(base, variable, size) \
li %r3, size; \
li %r4, 0x27; \
BRANCH_ABSOLUTE(%r5, alloc); \
LOAD_LABEL2 (%r4, base, variable); \
std %r3, 0(%r4);
// Allocate new memory and copy a function to it. R3 to R11 will be lost
// pl3_memcpy must be included!
define ALLOC_AND_COPY_PROC(base_reg, function, size) \
// Copy functions that need to stay resident in memory to MEM_BASE2
define COPY_RESIDENT_AREA(base, page) \
LOAD_LABEL (MEM_BASE2, %r3, base, 0); \
addi %r4, page, ADDR_IN_PAGE(RESIDENT_AREA_OFFSET); \
li %r5, RESIDENT_AREA_SIZE; \
bl pl3_memcpy; \
...
patch_table:
PATCH_DATA(patch_data1, 0x01000000)
PATCH_INST(patch_func1 + patch_func1_offset, ld %r4, rtoc_entry_1(%r2)) //hang
PATCH_INST(patch_func1 + patch_func1_offset + 4, ld %r3, 0x20(%r2
)
PATCH_INST(patch_func1 + patch_func1_offset + 8, std %r3, 0(%r4))
#ifdef __MEMORY_PATCHING_H_S__
PATCH_BRANCH_MEM2 (patch_func2 + patch_func2_offset, bl, memory_patching)
#endif
#ifdef __OPEN_HOOK_H_S__
PATCH_BRANCH_MEM2 (patch_func3 + patch_func3_offset, b, hook_open)
#endif
PATCH_INST(patch_func4 + patch_func4_offset, li %r4, 0) //80010009 error
PATCH_INST(patch_func4 + patch_func4_offset + 4, stw %r4, 0(%r3))
PATCH_INST(patch_func4 + patch_func4_offset + 8, blr)
#ifndef NO_UNAUTH_SYSCALL
PATCH_INST(patch_func5 + patch_func5_offset, li %r3, 1) //check feature?
PATCH_INST(patch_func5 + patch_func5_offset + 4, blr)
PATCH_INST(patch_func6 + patch_func6_offset, li %r3, 0)
PATCH_INST(patch_func7 + patch_func7_offset, li %r3, 0)
#endif
// force lv2open return 0
PATCH_INST(patch_func8 + patch_func8_offset1, li %r3, 0)
// disable calls in lv2open to lv1_send_event_locally which makes
// the system crash
PATCH_INST(patch_func8 + patch_func8_offset2, nop)
PATCH_INST(patch_func9 + patch_func9_offset, nop)
#ifdef __SYSCALL_HANDLER_H_S__
PATCH_BRANCH_MEM2 (patch_syscall_func, bl, syscall_handler)
#endif
#ifdef __PRINT_DEBUG_H_S__
//PATCH_BRANCH_MEM2(lv2_printf_null + 8, b, print_debug)
//PATCH_BRANCH_MEM2(lv2_printf_null, b, print_debug)
PATCH_BRANCH_MEM2(hvsc107_1, bl, print_hvsc107)
PATCH_BRANCH_MEM2(hvsc107_2, bl, print_hvsc107)
PATCH_BRANCH_MEM2(hvsc107_3, bl, print_hvsc107)
#endif
.long 0
...
#ifdef __STRNCMP_HACK__
PATCH_BRANCH_MEM2 (strncmp, b, hook_strncmp)
#endif
STRNCMP Included Version, if __STRNCMP_HACK__ is defined this is added to the PatchTable.
...
patch_table:
PATCH_DATA(patch_data1, 0x01000000)
PATCH_INST(patch_func1 + patch_func1_offset, ld %r4, rtoc_entry_1(%r2)) //hang
PATCH_INST(patch_func1 + patch_func1_offset + 4, ld %r3, 0x20(%r2
)
PATCH_INST(patch_func1 + patch_func1_offset + 8, std %r3, 0(%r4))
#ifdef __MEMORY_PATCHING_H_S__
PATCH_BRANCH_MEM2 (patch_func2 + patch_func2_offset, bl, memory_patching)
#endif
#ifdef __OPEN_HOOK_H_S__
PATCH_BRANCH_MEM2 (patch_func3 + patch_func3_offset, b, hook_open)
#endif
PATCH_INST(patch_func4 + patch_func4_offset, li %r4, 0) //80010009 error
PATCH_INST(patch_func4 + patch_func4_offset + 4, stw %r4, 0(%r3))
PATCH_INST(patch_func4 + patch_func4_offset + 8, blr)
#ifndef NO_UNAUTH_SYSCALL
PATCH_INST(patch_func5 + patch_func5_offset, li %r3, 1) //check feature?
PATCH_INST(patch_func5 + patch_func5_offset + 4, blr)
PATCH_INST(patch_func6 + patch_func6_offset, li %r3, 0)
PATCH_INST(patch_func7 + patch_func7_offset, li %r3, 0)
#endif
// force lv2open return 0
PATCH_INST(patch_func8 + patch_func8_offset1, li %r3, 0)
// disable calls in lv2open to lv1_send_event_locally which makes
// the system crash
PATCH_INST(patch_func8 + patch_func8_offset2, nop)
PATCH_INST(patch_func9 + patch_func9_offset, nop)
#ifdef __SYSCALL_HANDLER_H_S__
PATCH_BRANCH_MEM2 (patch_syscall_func, bl, syscall_handler)
#endif
#ifdef __PRINT_DEBUG_H_S__
//PATCH_BRANCH_MEM2(lv2_printf_null + 8, b, print_debug)
//PATCH_BRANCH_MEM2(lv2_printf_null, b, print_debug)
PATCH_BRANCH_MEM2(hvsc107_1, bl, print_hvsc107)
PATCH_BRANCH_MEM2(hvsc107_2, bl, print_hvsc107)
PATCH_BRANCH_MEM2(hvsc107_3, bl, print_hvsc107)
#endif
#ifdef __STRNCMP_HACK_H_S__
PATCH_BRANCH_MEM2 (strncmp, b, hook_strncmp)
#endif
.long 0
...
#ifndef __STRNCMP_HACK_H_S__
#define __STRNCMP_HACK_H_S__
hook_strncmp:
b ABSOLUTE_MEM2(strncmp + 4)
#endif
ROM:0004D344 strncmp:
ROM:0004D344 cmpdi %r5, 0
ROM:0004D348 beq loc_4D398
ROM:0004D34C lbz %r11, 0(%r4)
ROM:0004D350 lbz %r9, 0(%r3)
ROM:0004D354 clrlwi %r0, %r11, 24
ROM:0004D358 cmpw cr7, %r9, %r11
ROM:0004D35C bne cr7, loc_4D3A4
ROM:0004D360 cmpwi cr7, %r0, 0
ROM:0004D364 mtctr %r5
ROM:0004D368 bne cr7, loc_4D38C
ROM:0004D36C b loc_4D3A4
ROM:0004D370 loc_4D370:
ROM:0004D370 lbz %r11, 0(%r4)
ROM:0004D374 lbz %r9, 0(%r3)
ROM:0004D378 clrlwi %r0, %r11, 24
ROM:0004D37C cmpw cr7, %r9, %r11
ROM:0004D380 cmpwi cr6, %r0, 0
ROM:0004D384 bne cr7, loc_4D3A4
ROM:0004D388 beq cr6, loc_4D3A4
ROM:0004D38C loc_4D38C:
ROM:0004D38C addi %r3, %r3, 1
ROM:0004D390 addi %r4, %r4, 1
ROM:0004D394 bdnz loc_4D370
ROM:0004D398 loc_4D398:
ROM:0004D398 li %r0, 0
ROM:0004D39C extsw %r3, %r0
ROM:0004D3A0 blr
ROM:0004D3A4 loc_4D3A4:
ROM:0004D3A4 clrlwi %r9, %r9, 24
ROM:0004D3A8 clrlwi %r0, %r11, 24
ROM:0004D3AC subf %r0, %r0, %r9
ROM:0004D3B0 extsw %r3, %r0
ROM:0004D3B4 blr
ROM:0004D344 strncmp:
//This is removed
//ROM:0004D344 cmpdi %r5, 0
//gets overwritten with our patchtable hack
ROM:0004D344 b hook_strncmp
ROM:0004D348 beq loc_4D398
ROM:0004D34C lbz %r11, 0(%r4)
ROM:0004D350 lbz %r9, 0(%r3)
ROM:0004D354 clrlwi %r0, %r11, 24
ROM:0004D358 cmpw cr7, %r9, %r11
ROM:0004D35C bne cr7, loc_4D3A4
ROM:0004D360 cmpwi cr7, %r0, 0
ROM:0004D364 mtctr %r5
ROM:0004D368 bne cr7, loc_4D38C
ROM:0004D36C b loc_4D3A4
ROM:0004D370 loc_4D370:
ROM:0004D370 lbz %r11, 0(%r4)
ROM:0004D374 lbz %r9, 0(%r3)
ROM:0004D378 clrlwi %r0, %r11, 24
ROM:0004D37C cmpw cr7, %r9, %r11
ROM:0004D380 cmpwi cr6, %r0, 0
ROM:0004D384 bne cr7, loc_4D3A4
ROM:0004D388 beq cr6, loc_4D3A4
ROM:0004D38C loc_4D38C:
ROM:0004D38C addi %r3, %r3, 1
ROM:0004D390 addi %r4, %r4, 1
ROM:0004D394 bdnz loc_4D370
ROM:0004D398 loc_4D398:
ROM:0004D398 li %r0, 0
ROM:0004D39C extsw %r3, %r0
ROM:0004D3A0 blr
ROM:0004D3A4 loc_4D3A4:
ROM:0004D3A4 clrlwi %r9, %r9, 24
ROM:0004D3A8 clrlwi %r0, %r11, 24
ROM:0004D3AC subf %r0, %r0, %r9
ROM:0004D3B0 extsw %r3, %r0
ROM:0004D3B4 blr
#ifndef __STRNCMP_HACK_H_S__
#define __STRNCMP_HACK_H_S__
hook_strncmp:
cmpdi %r5, 0
b ABSOLUTE_MEM2(strncmp + 4)
#endif
store_regs:
std %r3, 0x70(%r1)
std %r4, 0x78(%r1)
std %r5, 0x80(%r1)
std %r6, 0x88(%r1)
std %r7, 0x90(%r1)
std %r8, 0x98(%r1)
std %r9, 0xA0(%r1)
std %r10, 0xA8(%r1)
std %r11, 0xB0(%r1)
std %r12, 0xB8(%r1)
blr
load_regs:
ld %r3, 0x70(%r1)
ld %r4, 0x78(%r1)
ld %r5, 0x80(%r1)
ld %r6, 0x88(%r1)
ld %r7, 0x90(%r1)
ld %r8, 0x98(%r1)
ld %r9, 0xA0(%r1)
ld %r10, 0xA8(%r1)
ld %r11, 0xB0(%r1)
ld %r12, 0xB8(%r1)
blr
. (Background knowledge: r1 is used as stack pointer).
mflr %r0
bl store_regs
bl load_regs
addi %r1, %r1, 0x100
mtlr %r0
#ifndef __STRNCMP_HACK_H_S__
#define __STRNCMP_HACK_H_S__
#include "trace_helpers.h.S"
hook_strncmp:
//Save the link Register
mflr %r0
//Get space on the stack (r1 = StackPointer)
stdu %r1, -0x100(%r1)
//Save the register
bl store_regs
//... OUR CODE
//Restore register
bl load_regs
//Restore stack
<pre> addi %r1, %r1, 0x100
=== Modify a function ===
=== Doing our own crap ===
=== Debug via ETH ===
=== Creating a Syscall (explained on Peek & Poke) ===
=== What next? ===

, which branches payload_main. Also includes the firmware_symbols and config.
/**
* patch_table:
*
* The patch table used by exploit_main to patch the kernel
* it format is .long address, .long new_value
*
* it will patch its content until the destination address is 0
*
*/
#define ADDR_IN_PAGE(target) (PAYLOAD_OFFSET_IN_PAGE + (target) - payload_entry)
<pre>
'''ADDR_IN_MEM2''' calculates the adress relative to the RESIDENT_AREA_OFFSET (resident_area_start)
<pre>#define ADDR_IN_MEM2(target) ((target) - RESIDENT_AREA_OFFSET)
// Absolute branching
#define ABSOLUTE_MEM2(target) (target - (MEM_BASE2 + ADDR_IN_MEM2(.)))
// Dynamic macros to load a label into a register
define MEM_BASE(dest) \
li dest, 1; \
rldicr dest, dest, 63, 0;
#define LOAD_LABEL(base, dest, source, address) \
oris dest, source, ((base) + (address))@h; \
ori dest, dest, ((base) + (address))@l;
#define LOAD_LABEL2(dest, source, address) \
LOAD_LABEL(MEM_BASE2, dest, source, ADDR_IN_MEM2 (address))
#define LOADI_LABEL2(dest, address) \
LOAD_LABEL2(dest, dest, address)
#define LOAD_MEM_BASE2(dest) \
MEM_BASE (dest) \
LOAD_LABEL (MEM_BASE2, dest, dest, 0)
// Add system calls. Use only in exploit_main because of registers used...
define ADD_SYSCALL(source, ptr, num) \
LOAD_LABEL2 (%r3, source, ptr); \
LOAD_ABS (%r4, source, syscall_table); \
std %r3, 0x08*num(%r4); \
// For loading an absolute value
define LOAD_ABS(dest, source, address) LOAD_LABEL(0, dest, source, address)
define LOADI_ABS(dest, address) LOAD_ABS(dest, dest, address)
// Absolute .quads
// HACK ALERT: the open toolchain bugs during compilation when trying to add
// a 'bignum' with address or MEM_BASE1.. so we split it here into two .long
// makes it easy since PPC is big endian.
define QUAD_MEM2(address) \
.long 0x80000000; \
.long MEM_BASE2 + ADDR_IN_MEM2(address);
/* Patch Table Macros */
define PATCH_INST(offset, instruction...) \
.long offset; \
instruction;
#define PATCH_DATA(offset, data...) \
.long offset; \
.long data;
#define PATCH_BRANCH(offset, op, target) \
.long offset; \
op ((target) - (offset));
#define PATCH_BRANCH_MEM2(offset, op, target) \
PATCH_BRANCH (offset, op, (MEM_BASE2 + ADDR_IN_MEM2(target)));
#define BRANCH_ABSOLUTE(dest, target) \
MEM_BASE (dest); \
oris dest, dest, target@h; \
ori dest, dest, target@l; \
mtctr dest; \
bctrl;
#define DEFINE_FUNC_PTR(function) \
function##_ptr: \
.quad 0; \
function: \
mflr %r0; \
stdu %r1, -0x80(%r1); \
std %r31, 0x70(%r1); \
std %r0, 0x90(%r1); \
BRANCH_FUNC_PTR(%r31, function); \
ld %r31, 0x70(%r1); \
ld %r0, 0x90(%r1); \
addi %r1, %r1, 0x80; \
mtlr %r0; \
blr;
#define BRANCH_FUNC_PTR(dest, function) \
MEM_BASE (dest); \
LOAD_LABEL2 (dest, dest, function ##_ptr); \
ld dest, 0(dest); \
mtctr dest; \
bctrl;
#define LOAD_FUNC_PTR(function) \
ALLOC_AND_COPY_PROC(%r31, function ##_start, \
(function ## _end - function##_start)); \
LOAD_LABEL2 (%r6, %r30, function ##_ptr); \
std %r3, 0(%r6);
#define GET_CURRENT_PAGE(temp, dest) \
bl get_current_page; \
b got_current_page; \
get_current_page: \
mflr dest; \
blr; \
got_current_page: \
li temp, 0xfff; \
nor temp, temp, temp; \
and dest, dest, temp;
#define PANIC() \
li %r3, 0; \
li %r11, 255; \
sc 1;
#define ALLOCATE_BUFFER(base, variable, size) \
li %r3, size; \
li %r4, 0x27; \
BRANCH_ABSOLUTE(%r5, alloc); \
LOAD_LABEL2 (%r4, base, variable); \
std %r3, 0(%r4);
// Allocate new memory and copy a function to it. R3 to R11 will be lost
// pl3_memcpy must be included!
define ALLOC_AND_COPY_PROC(base_reg, function, size) \
// Copy functions that need to stay resident in memory to MEM_BASE2
define COPY_RESIDENT_AREA(base, page) \
LOAD_LABEL (MEM_BASE2, %r3, base, 0); \
addi %r4, page, ADDR_IN_PAGE(RESIDENT_AREA_OFFSET); \
li %r5, RESIDENT_AREA_SIZE; \
bl pl3_memcpy; \
...
patch_table:
PATCH_DATA(patch_data1, 0x01000000)
PATCH_INST(patch_func1 + patch_func1_offset, ld %r4, rtoc_entry_1(%r2)) //hang
PATCH_INST(patch_func1 + patch_func1_offset + 4, ld %r3, 0x20(%r2
)
PATCH_INST(patch_func1 + patch_func1_offset + 8, std %r3, 0(%r4))
#ifdef __MEMORY_PATCHING_H_S__
PATCH_BRANCH_MEM2 (patch_func2 + patch_func2_offset, bl, memory_patching)
#endif
#ifdef __OPEN_HOOK_H_S__
PATCH_BRANCH_MEM2 (patch_func3 + patch_func3_offset, b, hook_open)
#endif
PATCH_INST(patch_func4 + patch_func4_offset, li %r4, 0) //80010009 error
PATCH_INST(patch_func4 + patch_func4_offset + 4, stw %r4, 0(%r3))
PATCH_INST(patch_func4 + patch_func4_offset + 8, blr)
#ifndef NO_UNAUTH_SYSCALL
PATCH_INST(patch_func5 + patch_func5_offset, li %r3, 1) //check feature?
PATCH_INST(patch_func5 + patch_func5_offset + 4, blr)
PATCH_INST(patch_func6 + patch_func6_offset, li %r3, 0)
PATCH_INST(patch_func7 + patch_func7_offset, li %r3, 0)
#endif
// force lv2open return 0
PATCH_INST(patch_func8 + patch_func8_offset1, li %r3, 0)
// disable calls in lv2open to lv1_send_event_locally which makes
// the system crash
PATCH_INST(patch_func8 + patch_func8_offset2, nop)
PATCH_INST(patch_func9 + patch_func9_offset, nop)
#ifdef __SYSCALL_HANDLER_H_S__
PATCH_BRANCH_MEM2 (patch_syscall_func, bl, syscall_handler)
#endif
#ifdef __PRINT_DEBUG_H_S__
//PATCH_BRANCH_MEM2(lv2_printf_null + 8, b, print_debug)
//PATCH_BRANCH_MEM2(lv2_printf_null, b, print_debug)
PATCH_BRANCH_MEM2(hvsc107_1, bl, print_hvsc107)
PATCH_BRANCH_MEM2(hvsc107_2, bl, print_hvsc107)
PATCH_BRANCH_MEM2(hvsc107_3, bl, print_hvsc107)
#endif
.long 0
...
#ifdef __STRNCMP_HACK__
PATCH_BRANCH_MEM2 (strncmp, b, hook_strncmp)
#endif
STRNCMP Included Version, if __STRNCMP_HACK__ is defined this is added to the PatchTable.
...
patch_table:
PATCH_DATA(patch_data1, 0x01000000)
PATCH_INST(patch_func1 + patch_func1_offset, ld %r4, rtoc_entry_1(%r2)) //hang
PATCH_INST(patch_func1 + patch_func1_offset + 4, ld %r3, 0x20(%r2
)
PATCH_INST(patch_func1 + patch_func1_offset + 8, std %r3, 0(%r4))
#ifdef __MEMORY_PATCHING_H_S__
PATCH_BRANCH_MEM2 (patch_func2 + patch_func2_offset, bl, memory_patching)
#endif
#ifdef __OPEN_HOOK_H_S__
PATCH_BRANCH_MEM2 (patch_func3 + patch_func3_offset, b, hook_open)
#endif
PATCH_INST(patch_func4 + patch_func4_offset, li %r4, 0) //80010009 error
PATCH_INST(patch_func4 + patch_func4_offset + 4, stw %r4, 0(%r3))
PATCH_INST(patch_func4 + patch_func4_offset + 8, blr)
#ifndef NO_UNAUTH_SYSCALL
PATCH_INST(patch_func5 + patch_func5_offset, li %r3, 1) //check feature?
PATCH_INST(patch_func5 + patch_func5_offset + 4, blr)
PATCH_INST(patch_func6 + patch_func6_offset, li %r3, 0)
PATCH_INST(patch_func7 + patch_func7_offset, li %r3, 0)
#endif
// force lv2open return 0
PATCH_INST(patch_func8 + patch_func8_offset1, li %r3, 0)
// disable calls in lv2open to lv1_send_event_locally which makes
// the system crash
PATCH_INST(patch_func8 + patch_func8_offset2, nop)
PATCH_INST(patch_func9 + patch_func9_offset, nop)
#ifdef __SYSCALL_HANDLER_H_S__
PATCH_BRANCH_MEM2 (patch_syscall_func, bl, syscall_handler)
#endif
#ifdef __PRINT_DEBUG_H_S__
//PATCH_BRANCH_MEM2(lv2_printf_null + 8, b, print_debug)
//PATCH_BRANCH_MEM2(lv2_printf_null, b, print_debug)
PATCH_BRANCH_MEM2(hvsc107_1, bl, print_hvsc107)
PATCH_BRANCH_MEM2(hvsc107_2, bl, print_hvsc107)
PATCH_BRANCH_MEM2(hvsc107_3, bl, print_hvsc107)
#endif
#ifdef __STRNCMP_HACK_H_S__
PATCH_BRANCH_MEM2 (strncmp, b, hook_strncmp)
#endif
.long 0
...
#ifndef __STRNCMP_HACK_H_S__
#define __STRNCMP_HACK_H_S__
hook_strncmp:
b ABSOLUTE_MEM2(strncmp + 4)
#endif
ROM:0004D344 strncmp:
ROM:0004D344 cmpdi %r5, 0
ROM:0004D348 beq loc_4D398
ROM:0004D34C lbz %r11, 0(%r4)
ROM:0004D350 lbz %r9, 0(%r3)
ROM:0004D354 clrlwi %r0, %r11, 24
ROM:0004D358 cmpw cr7, %r9, %r11
ROM:0004D35C bne cr7, loc_4D3A4
ROM:0004D360 cmpwi cr7, %r0, 0
ROM:0004D364 mtctr %r5
ROM:0004D368 bne cr7, loc_4D38C
ROM:0004D36C b loc_4D3A4
ROM:0004D370 loc_4D370:
ROM:0004D370 lbz %r11, 0(%r4)
ROM:0004D374 lbz %r9, 0(%r3)
ROM:0004D378 clrlwi %r0, %r11, 24
ROM:0004D37C cmpw cr7, %r9, %r11
ROM:0004D380 cmpwi cr6, %r0, 0
ROM:0004D384 bne cr7, loc_4D3A4
ROM:0004D388 beq cr6, loc_4D3A4
ROM:0004D38C loc_4D38C:
ROM:0004D38C addi %r3, %r3, 1
ROM:0004D390 addi %r4, %r4, 1
ROM:0004D394 bdnz loc_4D370
ROM:0004D398 loc_4D398:
ROM:0004D398 li %r0, 0
ROM:0004D39C extsw %r3, %r0
ROM:0004D3A0 blr
ROM:0004D3A4 loc_4D3A4:
ROM:0004D3A4 clrlwi %r9, %r9, 24
ROM:0004D3A8 clrlwi %r0, %r11, 24
ROM:0004D3AC subf %r0, %r0, %r9
ROM:0004D3B0 extsw %r3, %r0
ROM:0004D3B4 blr
ROM:0004D344 strncmp:
//This is removed
//ROM:0004D344 cmpdi %r5, 0
//gets overwritten with our patchtable hack
ROM:0004D344 b hook_strncmp
ROM:0004D348 beq loc_4D398
ROM:0004D34C lbz %r11, 0(%r4)
ROM:0004D350 lbz %r9, 0(%r3)
ROM:0004D354 clrlwi %r0, %r11, 24
ROM:0004D358 cmpw cr7, %r9, %r11
ROM:0004D35C bne cr7, loc_4D3A4
ROM:0004D360 cmpwi cr7, %r0, 0
ROM:0004D364 mtctr %r5
ROM:0004D368 bne cr7, loc_4D38C
ROM:0004D36C b loc_4D3A4
ROM:0004D370 loc_4D370:
ROM:0004D370 lbz %r11, 0(%r4)
ROM:0004D374 lbz %r9, 0(%r3)
ROM:0004D378 clrlwi %r0, %r11, 24
ROM:0004D37C cmpw cr7, %r9, %r11
ROM:0004D380 cmpwi cr6, %r0, 0
ROM:0004D384 bne cr7, loc_4D3A4
ROM:0004D388 beq cr6, loc_4D3A4
ROM:0004D38C loc_4D38C:
ROM:0004D38C addi %r3, %r3, 1
ROM:0004D390 addi %r4, %r4, 1
ROM:0004D394 bdnz loc_4D370
ROM:0004D398 loc_4D398:
ROM:0004D398 li %r0, 0
ROM:0004D39C extsw %r3, %r0
ROM:0004D3A0 blr
ROM:0004D3A4 loc_4D3A4:
ROM:0004D3A4 clrlwi %r9, %r9, 24
ROM:0004D3A8 clrlwi %r0, %r11, 24
ROM:0004D3AC subf %r0, %r0, %r9
ROM:0004D3B0 extsw %r3, %r0
ROM:0004D3B4 blr
#ifndef __STRNCMP_HACK_H_S__
#define __STRNCMP_HACK_H_S__
hook_strncmp:
cmpdi %r5, 0
b ABSOLUTE_MEM2(strncmp + 4)
#endif
store_regs:
std %r3, 0x70(%r1)
std %r4, 0x78(%r1)
std %r5, 0x80(%r1)
std %r6, 0x88(%r1)
std %r7, 0x90(%r1)
std %r8, 0x98(%r1)
std %r9, 0xA0(%r1)
std %r10, 0xA8(%r1)
std %r11, 0xB0(%r1)
std %r12, 0xB8(%r1)
blr
load_regs:
ld %r3, 0x70(%r1)
ld %r4, 0x78(%r1)
ld %r5, 0x80(%r1)
ld %r6, 0x88(%r1)
ld %r7, 0x90(%r1)
ld %r8, 0x98(%r1)
ld %r9, 0xA0(%r1)
ld %r10, 0xA8(%r1)
ld %r11, 0xB0(%r1)
ld %r12, 0xB8(%r1)
blr
. (Background knowledge: r1 is used as stack pointer).
mflr %r0
bl store_regs
bl load_regs
addi %r1, %r1, 0x100
mtlr %r0
#ifndef __STRNCMP_HACK_H_S__
#define __STRNCMP_HACK_H_S__
#include "trace_helpers.h.S"
hook_strncmp:
//Save the link Register
mflr %r0
//Get space on the stack (r1 = StackPointer)
stdu %r1, -0x100(%r1)
//Save the register
bl store_regs
//... OUR CODE
//Restore register
bl load_regs
//Restore stack
<pre> addi %r1, %r1, 0x100
=== Modify a function ===
=== Doing our own crap ===
=== Debug via ETH ===
=== Creating a Syscall (explained on Peek & Poke) ===
=== What next? ===

, which branches payload_main. Also includes the firmware_symbols and config.
/**
* patch_table:
*
* The patch table used by exploit_main to patch the kernel
* it format is .long address, .long new_value
*
* it will patch its content until the destination address is 0
*
*/
#define ADDR_IN_PAGE(target) (PAYLOAD_OFFSET_IN_PAGE + (target) - payload_entry)
<pre>
'''ADDR_IN_MEM2''' calculates the adress relative to the RESIDENT_AREA_OFFSET (resident_area_start)
<pre>#define ADDR_IN_MEM2(target) ((target) - RESIDENT_AREA_OFFSET)
// Absolute branching
#define ABSOLUTE_MEM2(target) (target - (MEM_BASE2 + ADDR_IN_MEM2(.)))
// Dynamic macros to load a label into a register
define MEM_BASE(dest) \
li dest, 1; \
rldicr dest, dest, 63, 0;
#define LOAD_LABEL(base, dest, source, address) \
oris dest, source, ((base) + (address))@h; \
ori dest, dest, ((base) + (address))@l;
#define LOAD_LABEL2(dest, source, address) \
LOAD_LABEL(MEM_BASE2, dest, source, ADDR_IN_MEM2 (address))
#define LOADI_LABEL2(dest, address) \
LOAD_LABEL2(dest, dest, address)
#define LOAD_MEM_BASE2(dest) \
MEM_BASE (dest) \
LOAD_LABEL (MEM_BASE2, dest, dest, 0)
// Add system calls. Use only in exploit_main because of registers used...
define ADD_SYSCALL(source, ptr, num) \
LOAD_LABEL2 (%r3, source, ptr); \
LOAD_ABS (%r4, source, syscall_table); \
std %r3, 0x08*num(%r4); \
// For loading an absolute value
define LOAD_ABS(dest, source, address) LOAD_LABEL(0, dest, source, address)
define LOADI_ABS(dest, address) LOAD_ABS(dest, dest, address)
// Absolute .quads
// HACK ALERT: the open toolchain bugs during compilation when trying to add
// a 'bignum' with address or MEM_BASE1.. so we split it here into two .long
// makes it easy since PPC is big endian.
define QUAD_MEM2(address) \
.long 0x80000000; \
.long MEM_BASE2 + ADDR_IN_MEM2(address);
/* Patch Table Macros */
define PATCH_INST(offset, instruction...) \
.long offset; \
instruction;
#define PATCH_DATA(offset, data...) \
.long offset; \
.long data;
#define PATCH_BRANCH(offset, op, target) \
.long offset; \
op ((target) - (offset));
#define PATCH_BRANCH_MEM2(offset, op, target) \
PATCH_BRANCH (offset, op, (MEM_BASE2 + ADDR_IN_MEM2(target)));
#define BRANCH_ABSOLUTE(dest, target) \
MEM_BASE (dest); \
oris dest, dest, target@h; \
ori dest, dest, target@l; \
mtctr dest; \
bctrl;
#define DEFINE_FUNC_PTR(function) \
function##_ptr: \
.quad 0; \
function: \
mflr %r0; \
stdu %r1, -0x80(%r1); \
std %r31, 0x70(%r1); \
std %r0, 0x90(%r1); \
BRANCH_FUNC_PTR(%r31, function); \
ld %r31, 0x70(%r1); \
ld %r0, 0x90(%r1); \
addi %r1, %r1, 0x80; \
mtlr %r0; \
blr;
#define BRANCH_FUNC_PTR(dest, function) \
MEM_BASE (dest); \
LOAD_LABEL2 (dest, dest, function ##_ptr); \
ld dest, 0(dest); \
mtctr dest; \
bctrl;
#define LOAD_FUNC_PTR(function) \
ALLOC_AND_COPY_PROC(%r31, function ##_start, \
(function ## _end - function##_start)); \
LOAD_LABEL2 (%r6, %r30, function ##_ptr); \
std %r3, 0(%r6);
#define GET_CURRENT_PAGE(temp, dest) \
bl get_current_page; \
b got_current_page; \
get_current_page: \
mflr dest; \
blr; \
got_current_page: \
li temp, 0xfff; \
nor temp, temp, temp; \
and dest, dest, temp;
#define PANIC() \
li %r3, 0; \
li %r11, 255; \
sc 1;
#define ALLOCATE_BUFFER(base, variable, size) \
li %r3, size; \
li %r4, 0x27; \
BRANCH_ABSOLUTE(%r5, alloc); \
LOAD_LABEL2 (%r4, base, variable); \
std %r3, 0(%r4);
// Allocate new memory and copy a function to it. R3 to R11 will be lost
// pl3_memcpy must be included!
define ALLOC_AND_COPY_PROC(base_reg, function, size) \
// Copy functions that need to stay resident in memory to MEM_BASE2
define COPY_RESIDENT_AREA(base, page) \
LOAD_LABEL (MEM_BASE2, %r3, base, 0); \
addi %r4, page, ADDR_IN_PAGE(RESIDENT_AREA_OFFSET); \
li %r5, RESIDENT_AREA_SIZE; \
bl pl3_memcpy; \
...
patch_table:
PATCH_DATA(patch_data1, 0x01000000)
PATCH_INST(patch_func1 + patch_func1_offset, ld %r4, rtoc_entry_1(%r2)) //hang
PATCH_INST(patch_func1 + patch_func1_offset + 4, ld %r3, 0x20(%r2
)
PATCH_INST(patch_func1 + patch_func1_offset + 8, std %r3, 0(%r4))
#ifdef __MEMORY_PATCHING_H_S__
PATCH_BRANCH_MEM2 (patch_func2 + patch_func2_offset, bl, memory_patching)
#endif
#ifdef __OPEN_HOOK_H_S__
PATCH_BRANCH_MEM2 (patch_func3 + patch_func3_offset, b, hook_open)
#endif
PATCH_INST(patch_func4 + patch_func4_offset, li %r4, 0) //80010009 error
PATCH_INST(patch_func4 + patch_func4_offset + 4, stw %r4, 0(%r3))
PATCH_INST(patch_func4 + patch_func4_offset + 8, blr)
#ifndef NO_UNAUTH_SYSCALL
PATCH_INST(patch_func5 + patch_func5_offset, li %r3, 1) //check feature?
PATCH_INST(patch_func5 + patch_func5_offset + 4, blr)
PATCH_INST(patch_func6 + patch_func6_offset, li %r3, 0)
PATCH_INST(patch_func7 + patch_func7_offset, li %r3, 0)
#endif
// force lv2open return 0
PATCH_INST(patch_func8 + patch_func8_offset1, li %r3, 0)
// disable calls in lv2open to lv1_send_event_locally which makes
// the system crash
PATCH_INST(patch_func8 + patch_func8_offset2, nop)
PATCH_INST(patch_func9 + patch_func9_offset, nop)
#ifdef __SYSCALL_HANDLER_H_S__
PATCH_BRANCH_MEM2 (patch_syscall_func, bl, syscall_handler)
#endif
#ifdef __PRINT_DEBUG_H_S__
//PATCH_BRANCH_MEM2(lv2_printf_null + 8, b, print_debug)
//PATCH_BRANCH_MEM2(lv2_printf_null, b, print_debug)
PATCH_BRANCH_MEM2(hvsc107_1, bl, print_hvsc107)
PATCH_BRANCH_MEM2(hvsc107_2, bl, print_hvsc107)
PATCH_BRANCH_MEM2(hvsc107_3, bl, print_hvsc107)
#endif
.long 0
...
#ifdef __STRNCMP_HACK__
PATCH_BRANCH_MEM2 (strncmp, b, hook_strncmp)
#endif
STRNCMP Included Version, if __STRNCMP_HACK__ is defined this is added to the PatchTable.
...
patch_table:
PATCH_DATA(patch_data1, 0x01000000)
PATCH_INST(patch_func1 + patch_func1_offset, ld %r4, rtoc_entry_1(%r2)) //hang
PATCH_INST(patch_func1 + patch_func1_offset + 4, ld %r3, 0x20(%r2
)
PATCH_INST(patch_func1 + patch_func1_offset + 8, std %r3, 0(%r4))
#ifdef __MEMORY_PATCHING_H_S__
PATCH_BRANCH_MEM2 (patch_func2 + patch_func2_offset, bl, memory_patching)
#endif
#ifdef __OPEN_HOOK_H_S__
PATCH_BRANCH_MEM2 (patch_func3 + patch_func3_offset, b, hook_open)
#endif
PATCH_INST(patch_func4 + patch_func4_offset, li %r4, 0) //80010009 error
PATCH_INST(patch_func4 + patch_func4_offset + 4, stw %r4, 0(%r3))
PATCH_INST(patch_func4 + patch_func4_offset + 8, blr)
#ifndef NO_UNAUTH_SYSCALL
PATCH_INST(patch_func5 + patch_func5_offset, li %r3, 1) //check feature?
PATCH_INST(patch_func5 + patch_func5_offset + 4, blr)
PATCH_INST(patch_func6 + patch_func6_offset, li %r3, 0)
PATCH_INST(patch_func7 + patch_func7_offset, li %r3, 0)
#endif
// force lv2open return 0
PATCH_INST(patch_func8 + patch_func8_offset1, li %r3, 0)
// disable calls in lv2open to lv1_send_event_locally which makes
// the system crash
PATCH_INST(patch_func8 + patch_func8_offset2, nop)
PATCH_INST(patch_func9 + patch_func9_offset, nop)
#ifdef __SYSCALL_HANDLER_H_S__
PATCH_BRANCH_MEM2 (patch_syscall_func, bl, syscall_handler)
#endif
#ifdef __PRINT_DEBUG_H_S__
//PATCH_BRANCH_MEM2(lv2_printf_null + 8, b, print_debug)
//PATCH_BRANCH_MEM2(lv2_printf_null, b, print_debug)
PATCH_BRANCH_MEM2(hvsc107_1, bl, print_hvsc107)
PATCH_BRANCH_MEM2(hvsc107_2, bl, print_hvsc107)
PATCH_BRANCH_MEM2(hvsc107_3, bl, print_hvsc107)
#endif
#ifdef __STRNCMP_HACK_H_S__
PATCH_BRANCH_MEM2 (strncmp, b, hook_strncmp)
#endif
.long 0
...
#ifndef __STRNCMP_HACK_H_S__
#define __STRNCMP_HACK_H_S__
hook_strncmp:
b ABSOLUTE_MEM2(strncmp + 4)
#endif
ROM:0004D344 strncmp:
ROM:0004D344 cmpdi %r5, 0
ROM:0004D348 beq loc_4D398
ROM:0004D34C lbz %r11, 0(%r4)
ROM:0004D350 lbz %r9, 0(%r3)
ROM:0004D354 clrlwi %r0, %r11, 24
ROM:0004D358 cmpw cr7, %r9, %r11
ROM:0004D35C bne cr7, loc_4D3A4
ROM:0004D360 cmpwi cr7, %r0, 0
ROM:0004D364 mtctr %r5
ROM:0004D368 bne cr7, loc_4D38C
ROM:0004D36C b loc_4D3A4
ROM:0004D370 loc_4D370:
ROM:0004D370 lbz %r11, 0(%r4)
ROM:0004D374 lbz %r9, 0(%r3)
ROM:0004D378 clrlwi %r0, %r11, 24
ROM:0004D37C cmpw cr7, %r9, %r11
ROM:0004D380 cmpwi cr6, %r0, 0
ROM:0004D384 bne cr7, loc_4D3A4
ROM:0004D388 beq cr6, loc_4D3A4
ROM:0004D38C loc_4D38C:
ROM:0004D38C addi %r3, %r3, 1
ROM:0004D390 addi %r4, %r4, 1
ROM:0004D394 bdnz loc_4D370
ROM:0004D398 loc_4D398:
ROM:0004D398 li %r0, 0
ROM:0004D39C extsw %r3, %r0
ROM:0004D3A0 blr
ROM:0004D3A4 loc_4D3A4:
ROM:0004D3A4 clrlwi %r9, %r9, 24
ROM:0004D3A8 clrlwi %r0, %r11, 24
ROM:0004D3AC subf %r0, %r0, %r9
ROM:0004D3B0 extsw %r3, %r0
ROM:0004D3B4 blr
ROM:0004D344 strncmp:
//This is removed
//ROM:0004D344 cmpdi %r5, 0
//gets overwritten with our patchtable hack
ROM:0004D344 b hook_strncmp
ROM:0004D348 beq loc_4D398
ROM:0004D34C lbz %r11, 0(%r4)
ROM:0004D350 lbz %r9, 0(%r3)
ROM:0004D354 clrlwi %r0, %r11, 24
ROM:0004D358 cmpw cr7, %r9, %r11
ROM:0004D35C bne cr7, loc_4D3A4
ROM:0004D360 cmpwi cr7, %r0, 0
ROM:0004D364 mtctr %r5
ROM:0004D368 bne cr7, loc_4D38C
ROM:0004D36C b loc_4D3A4
ROM:0004D370 loc_4D370:
ROM:0004D370 lbz %r11, 0(%r4)
ROM:0004D374 lbz %r9, 0(%r3)
ROM:0004D378 clrlwi %r0, %r11, 24
ROM:0004D37C cmpw cr7, %r9, %r11
ROM:0004D380 cmpwi cr6, %r0, 0
ROM:0004D384 bne cr7, loc_4D3A4
ROM:0004D388 beq cr6, loc_4D3A4
ROM:0004D38C loc_4D38C:
ROM:0004D38C addi %r3, %r3, 1
ROM:0004D390 addi %r4, %r4, 1
ROM:0004D394 bdnz loc_4D370
ROM:0004D398 loc_4D398:
ROM:0004D398 li %r0, 0
ROM:0004D39C extsw %r3, %r0
ROM:0004D3A0 blr
ROM:0004D3A4 loc_4D3A4:
ROM:0004D3A4 clrlwi %r9, %r9, 24
ROM:0004D3A8 clrlwi %r0, %r11, 24
ROM:0004D3AC subf %r0, %r0, %r9
ROM:0004D3B0 extsw %r3, %r0
ROM:0004D3B4 blr
#ifndef __STRNCMP_HACK_H_S__
#define __STRNCMP_HACK_H_S__
hook_strncmp:
cmpdi %r5, 0
b ABSOLUTE_MEM2(strncmp + 4)
#endif
store_regs:
std %r3, 0x70(%r1)
std %r4, 0x78(%r1)
std %r5, 0x80(%r1)
std %r6, 0x88(%r1)
std %r7, 0x90(%r1)
std %r8, 0x98(%r1)
std %r9, 0xA0(%r1)
std %r10, 0xA8(%r1)
std %r11, 0xB0(%r1)
std %r12, 0xB8(%r1)
blr
load_regs:
ld %r3, 0x70(%r1)
ld %r4, 0x78(%r1)
ld %r5, 0x80(%r1)
ld %r6, 0x88(%r1)
ld %r7, 0x90(%r1)
ld %r8, 0x98(%r1)
ld %r9, 0xA0(%r1)
ld %r10, 0xA8(%r1)
ld %r11, 0xB0(%r1)
ld %r12, 0xB8(%r1)
blr
. (Background knowledge: r1 is used as stack pointer).
mflr %r0
bl store_regs
bl load_regs
addi %r1, %r1, 0x100
mtlr %r0
#ifndef __STRNCMP_HACK_H_S__
#define __STRNCMP_HACK_H_S__
#include "trace_helpers.h.S"
hook_strncmp:
//Save the link Register
mflr %r0
//Get space on the stack (r1 = StackPointer)
stdu %r1, -0x100(%r1)
//Save the register
bl store_regs
//... OUR CODE
//Restore register
bl load_regs
//Restore stack
<pre> addi %r1, %r1, 0x100
=== Modify a function ===
=== Doing our own crap ===
=== Debug via ETH ===
=== Creating a Syscall (explained on Peek & Poke) ===
=== What next? ===


Copyright © 2026, NextGenUpdate.
All Rights Reserved.