Skip to content

Instantly share code, notes, and snippets.

@ashquarky
Created August 29, 2016 04:52
Show Gist options
  • Save ashquarky/efd1b5f842cf0a42d7bb6190930286f3 to your computer and use it in GitHub Desktop.
Save ashquarky/efd1b5f842cf0a42d7bb6190930286f3 to your computer and use it in GitHub Desktop.
A horribly unfinished reverse-engineering of SwkbdCreate, let us never speak of this until I finish it
namespace Rpl {
#define MYSTERY_DATA_LOC (unsigned char*)0x10049E38
#define MUTEX_LOC (unknown datatype*)0x1004D294
#define FIBER_LOC (unknown datatype*)0x10054CBC
void SwkbdCreate(unsigned char* a, nn::swkbd::RegionType b, unsigned int c, FSClient* d) {
OSThread* thread = OSGetCurrentThread();
int stackSize = ADDZE(SRAWI(thread->stackEnd - thread->stackBase, 0xA)); //Doesn't really matter anyway
OSReport("SWKBD: thread=0x%08x, stackSize=%8d KB, stackBase=0x%08x, stackEnd=0x%08x (%s)\n", thread, stackSize, thread->stackBase, thread->stackEnd, "SwkbdCreate");
unsigned char* data = MYSTERY_DATA_LOC;
data[0] = 0; //0x10049E38
data[1] = 0; //0x10049E39
data[2] = 0; //0x10049E3A
data[3] = 0; //0x10049E3B
data[4] = 0; //0x10049E3C
OSLockMutex(MUTEX_LOC);
OSSwitchFiberEx(a, b, c, d, internal_function, FIBER_LOC); //is this some kind of multitasking system?
OSUnlockMutex(MUTEX_LOC);
}
}
#define MYSTERY_LOC (int*)0x10049E24
#define C_LOC (int*)0x10049E2C
#define D_LOC (int*)0x10049E30
#define B_LOC (int*)0x1004D28C
#define MYSTERY_LOC_2 (int*)0x1004D290
//These arguments are guesses based on register usages.
//I'm assuming they're the arguments passed to OSSwitchFiberEx
private internal_function(a, b, c, d) {
//this function is put together... interestingly.
//Apologies if it doesn't end up as readable as I'd like.
//It's so over-superscalarised it's almost impossible to follow.
//afaik this translates to r10 = c & 0x1, but r10 doesn't seem to be used
CLRLWI.(r10, c, 31);
*(C_LOC) = c;
int num = 0;
if (/* There's a beq out of nowhere, so I don't know what this is. Could it be that clrlwi.? */ ! ? == ?) {
num = 0xA0000;
}
//I don't know what this is
RLWINM.(r0, c, 0, 30, 30);
if (/*Again, beq out of nowhere.*/! ?==? ) {
num |= 0x120000;
//At this point, num will either be 0x120000 or 0x1A0000
}
//jump to subroutine
*(MYSTERY_LOC) = num;
//back to main function
if (!((b + 1) < 8)) {
//this is weird
//There's a bunch of stuff about debuggers
//This string: "D:/home/Cafe/Barista_SdkUpdate/Library/Sead/engine/library/modules/src/basis/cafe/seadAssertCafe.cpp"
//an OSPanic call
//All in all you probably don't want to end up here
//There's stack cleanup and a blr after the OSPanic call as if that's ever going to happen ;D
OSFatal("no no no no no no");
}
*(D_LOC) = d;
*(B_LOC) = b;
*(MYSTERY_LOC_2) = 0;
//Bit of fun - immediately after writing 0 to MYSTERY_LOC_2, it reads data from MYSTERY_LOC_2 into r0! Whoops!
//subroutine time. Prepare for inception.
//! WE ARE 1 SUBROUTINE DEEP
//this is where the code goes from bad to worse.
//Since the compiler stopped trying, so will I.
r3 = a + sp + 0xD8 + 0xB8;
//! WE ARE 2 SUBROUTINES DEEP
if (!r3 == 0) {
r3 = 8;
//! WE ARE 3 SUBROUTINES DEEP
r31 = r3;
r3 = *((int*)0x1004A468);
if (r3 == 0) {
//this section is hard to look at
void (*func)() = *((unknown datatype*) 0x21B0000 - 0x68);
func(r31); //r31 is still 8 (I think)
//I genuinley have no idea what just happened
//On a side note, if 0x21B0000-0x68 is writable from userspace we could take control of this thread/fiber/whatever
} else {
//! WE ARE 4 SUBROUTINES DEEP
if(*((int*)0x1004A4AC) != 0) {
//here's that debugger/OSPanic routine again
OSFatal("why am I doing this");
}
//! WE ARE 3 SUBROUTINES DEEP
if (r3 == 0) { //I've lost track of what r3 is
//here's that debugger/OSPanic routine again
OSFatal("i should stop, this is bad");
} else {
void (*func)() = *(*(r3 + 0xC) + 0x34);
func("some arguments I'm done for the night");
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment