Thanks for the explanations, I have dug through the firmware a bit more and tried some more things, including hooking the controller functions, though I haven't had success yet with getting output on the 4th terminal but I haven't given up hope just yet.
The Ghidra scripts have been pretty helpful thanks, I've been updating from SVN and running new ones as they appear except for the MZRM ones which I still need to generate the handler list for first if I need to look into the Zico core which I guess is just for the GPU so probably not at this stage.
I got the controller functions hooked through a custom ui_mallloc function which runs a custom CreateController function that hooks the desired controller functions as suggested. It does work to modify the controller functions (tested by illuminating the AF LED) and has been useful for testing what sections of different controller functions do by skipping those sections and seeing what happens. CreateController hooks below in case they are helpful to anyone else (addresses correct for g7x2 110b)
void __attribute__((naked,noinline)) task_Startup_my() {
asm volatile (
...
" bl sub_e0425886\n" // various initilizations including for ui_malloc
// ui_malloc hook
" ldr r4, =0x0000cb64\n" // +
" ldr r0, =ui_malloc_default_my\n" // +
" str r0, [r4, #4]\n" // +
" bl sub_e005b33e_my\n" // -> taskcreate_physw
...
);
}
...
//0xe0371e68
void __attribute__((naked,noinline)) ui_malloc_default_my() {
asm volatile(
// hooks first, r1 input is not used in ui_malloc_default
// hook CreateController function
" ldr r1, =CreateController+0x1c\n" // + function to hook + offset in fuction where lr will be (just after ui_malloc)
" cmp r1, lr\n" // + check if ui_malloc has been called from the function to hook
" beq CreateController_my\n" // + return immediately to alternative function
//capdis -f=chdk -s=0xe0371e69 -e=0xe0371ea9 -stubs PRIMARY.BIN 0xe0000000
" push {r3, r4, r5, r6, r7, lr}\n"
" mov r6, r0\n"
" ldr r5, =0x0000cb64\n"
" ldrb r0, [r5]\n"
" lsls r0, r0, #0x1f\n"
" beq loc_e0371e7e\n"
" movs r2, #0x6c\n"
" movs r0, #0\n"
" ldr r1, =0xe0371f18\n" // *"UiMemory.c"
" bl sub_dffc96f4\n"
"loc_e0371e7e:\n"
" ldr r0, [r5]\n"
" mov r1, r6\n"
" bl sub_e037e604\n"
" movs r4, r0\n"
" bne loc_e0371ea6\n"
" ldr r0, [r5]\n"
" mov r1, sp\n"
" bl sub_e037e60c\n"
" ldr r2, [sp]\n"
" mov r1, r6\n"
" ldr r0, =0xe0371f24\n" // *"Size: %ld, MaxRegion: %ld\n"
" bl sub_e037e664\n"
" movs r2, #0x71\n"
" movs r0, #0\n"
" ldr r1, =0xe0371f18\n" // *"UiMemory.c"
" bl sub_dffc96f4\n"
"loc_e0371ea6:\n"
" mov r0, r4\n"
" pop {r3, r4, r5, r6, r7, pc}\n"
);
}
//0xe0371490
void __attribute__((naked,noinline)) CreateController_my() {
asm volatile(
//capdis -f=chdk -s=0xe0371491 -e=0xe0371515 -stubs PRIMARY.BIN 0xe0000000
// " push.w {r4, r5, r6, r7, r8, lr}\n" // - already done from original CreateController function
// " mov r7, r0\n" // -
// " ldr r5, =0x0000c518\n" // -
// " movs r6, #0\n" // -
// " mov r8, r1\n" // -
// " ldrb r0, [r5]\n" // -
// " lsls r0, r0, #0x1f\n" // -
// " beq loc_e03714a6\n" // -
// hook BattAuthController function
" ldr r0, =BattAuthController\n" // + controller function to hook
" cmp r0, r7\n" // + check if we are creating that controller here
" it eq\n" // + EQ block
" ldreq r7, =BattAuthController_my\n" // + alternate controller function to create instead
// " beq loc_e03714a6\n" // + continue at ui_malloc
//hook more controller functions here simmilarly
" b loc_e03714a6\n" // + continue at ui_malloc (replaces beq from above)
"loc_e03714a2:\n"
" movs r0, #0x11\n"
" b loc_e037134a\n" // return
"loc_e03714a6:\n"
" movs r0, #0x28\n"
" bl sub_e0371f08\n" // ui_malloc
" ldr r1, =0x0001d4c0\n"
" mov r4, r0\n"
" ldr r0, [r5]\n"
" mov.w r3, #0x288\n"
" ldr r2, =0xe037173c\n" // *"CtrlMan.c"
" bl sub_dffca338\n"
" cbz r0, loc_e03714c6\n"
" mov r0, r4\n"
" bl sub_e0371f0e\n"
" b loc_e03714a2\n"
"loc_e03714c6:\n"
" ldr r0, [r5, #0xc]\n"
" cbz r0, loc_e03714cc\n"
" mov r6, r0\n"
"loc_e03714cc:\n"
" str r7, [r4]\n"
" strd r8, r0, [r4, #4]\n"
" movs r0, #0x19\n"
" str r0, [r4, #0xc]\n"
" movs r1, #0x19\n"
" ldr r0, [r5, #0x14]\n"
" str r0, [r4, #0x10]\n"
" movs r0, #0\n"
" str r0, [r4, #0x18]\n"
" str r0, [r4, #0x1c]\n"
" str r0, [r4, #0x20]\n"
" ldr r0, [r5, #0x1c]\n"
" str r0, [r4, #0x24]\n"
" adds r0, r0, #1\n"
" str r0, [r5, #0x1c]\n"
" ldr r0, =0xe03713bd\n"
" str r0, [r4, #0x14]\n"
" mov r0, r4\n"
" bl sub_e03713f4\n"
" ldr r0, [r5]\n"
" bl sub_dffcad46\n"
" movs r3, #0\n"
" movw r1, #0x803\n"
" mov r2, r3\n"
" mov r0, r4\n"
" bl sub_e0371330\n"
" mov r1, r4\n"
" mov r0, r6\n"
" bl sub_e03719b8\n"
" mov r0, r4\n"
// " b loc_e037134a\n" // - return (right below now rather than very far above)
//capdis -f=chdk -s=0xe037134b -c=1 -stubs PRIMARY.BIN 0xe0000000
"loc_e037134a:\n"
" pop.w {r4, r5, r6, r7, r8, pc}\n"
);
}
I also came across some strings just now in the firmware starting with N5fluid, any idea what that might refer to? Such as "N5fluid12Battery_baseE" and "N5fluid16FL_TimerReceiverE"