mirror of
https://codeberg.org/KeybadeBlox/JSRF-Decompilation.git
synced 2026-04-07 04:50:23 +03:00
Fully decompile xapi0
This commit is contained in:
parent
4e20347b7c
commit
823b19371c
3 changed files with 97 additions and 10 deletions
|
|
@ -50,7 +50,7 @@
|
||||||
"target_path": "target/XDK/Xapi/xapi0.obj",
|
"target_path": "target/XDK/Xapi/xapi0.obj",
|
||||||
"base_path": "src/XDK/Xapi/xapi0.obj",
|
"base_path": "src/XDK/Xapi/xapi0.obj",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"complete": false,
|
"complete": true,
|
||||||
"source_path": "src/XDK/Xapi/xapi0.c"
|
"source_path": "src/XDK/Xapi/xapi0.c"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,14 @@ extern struct IMAGE_TLS_DIRECTORY {
|
||||||
DWORD SizeOfZeroFill;
|
DWORD SizeOfZeroFill;
|
||||||
DWORD Characteristics;
|
DWORD Characteristics;
|
||||||
} _tls_used;
|
} _tls_used;
|
||||||
|
extern int _tls_array;
|
||||||
|
extern int _tls_index;
|
||||||
|
|
||||||
extern int XapiTlsSize;
|
extern int XapiTlsSize;
|
||||||
|
|
||||||
DWORD __stdcall mainXapiStartup(LPVOID lpThreadParameter);
|
DWORD __stdcall mainXapiStartup(LPVOID lpThreadParameter);
|
||||||
BOOL __stdcall CloseHandle (HANDLE hHandle );
|
void __stdcall XapiInitProcess(void);
|
||||||
|
BOOL __stdcall CloseHandle (HANDLE hHandle);
|
||||||
|
|
||||||
typedef DWORD (__stdcall * LPTHREAD_START_ROUTINE)(LPVOID lpThreadParameter);
|
typedef DWORD (__stdcall * LPTHREAD_START_ROUTINE)(LPVOID lpThreadParameter);
|
||||||
HANDLE __stdcall CreateThread(
|
HANDLE __stdcall CreateThread(
|
||||||
|
|
@ -43,18 +46,102 @@ void __stdcall XapiBootToDash(
|
||||||
DWORD dwParameter2
|
DWORD dwParameter2
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void __stdcall _rtinit(void);
|
||||||
|
void __stdcall _cinit (void);
|
||||||
|
|
||||||
|
|
||||||
// Every program is supposed to have a main(), so we can just assume its
|
// Every program is supposed to have a main(), so we can just assume its
|
||||||
// existence with a declaration here
|
// existence with a declaration here. Interestingly, it's called with
|
||||||
int main(void);
|
// arguments here despite being declared without any on the developer's side.
|
||||||
|
int main(
|
||||||
|
int argc,
|
||||||
|
char * * argv,
|
||||||
|
char * * envp
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// Address: 0x00147FB4
|
// Address: 0x00147FB4
|
||||||
// Status: unimplemented
|
// Status: matching
|
||||||
DWORD __stdcall mainXapiStartup(LPVOID lpThreadParameter) {
|
__declspec(naked) DWORD __stdcall mainXapiStartup(LPVOID lpThreadParameter) {
|
||||||
/* Runs some Xbox-specific initialization and then calls main() */
|
/* Runs some Xbox-specific initialization and then calls main()
|
||||||
main();
|
It appears to be truly impossible in Visual C++ 7.0 to access the FS register
|
||||||
return 0;
|
without writing assembly, and also for inline assembly to write to a variable
|
||||||
|
in a register rather than on the stack. Thus, the only apparent way to make
|
||||||
|
the middle part of the function match is through writing the instructions
|
||||||
|
directly. Given that the C parts of this function are so simple that a human
|
||||||
|
and a compiler would reasonably produce the exact same code, and this function
|
||||||
|
exhibits other oddities mentioned in the body, it's likely this whole function
|
||||||
|
was originally written purely in assemblys. In the spirit of decompilation,
|
||||||
|
however, we'll lift what we can into C.
|
||||||
|
*/
|
||||||
|
XapiInitProcess();
|
||||||
|
|
||||||
|
// Honestly unsure what's being done here, as FS doesn't seem to follow
|
||||||
|
// the same structure as 32-bit Windows
|
||||||
|
__asm {
|
||||||
|
mov eax, fs:[0x20]
|
||||||
|
mov eax, [eax+0x250]
|
||||||
|
test eax, eax
|
||||||
|
je zero
|
||||||
|
mov ecx, [eax+0x24]
|
||||||
|
jmp store
|
||||||
|
|
||||||
|
/*
|
||||||
|
All this jumping around is strange, as it could easily be a
|
||||||
|
single branch, which is very plain to see if written out as C
|
||||||
|
(in fact, while MSVC's behaviour hasn't been tested, it
|
||||||
|
wouldn't take a very smart compiler to optimize this out if it
|
||||||
|
was written this way in C). It seems likely this is awkward
|
||||||
|
human-written assembly.
|
||||||
|
*/
|
||||||
|
zero:
|
||||||
|
xor ecx, ecx
|
||||||
|
|
||||||
|
store:
|
||||||
|
test ecx, ecx
|
||||||
|
je end
|
||||||
|
|
||||||
|
/*
|
||||||
|
This section is suspect because of how it preserves edi despite
|
||||||
|
it not being used anywhere else, as if it was a separately
|
||||||
|
written function. If it was a function, it must have been
|
||||||
|
inlined, but it couldn't be because it must be called from
|
||||||
|
assembly to use the value in ecx that never went on the stack
|
||||||
|
(as passing data from C to assembly has to do). Notably, this
|
||||||
|
function's calling convention does require edi to be preserved,
|
||||||
|
but if left up to the compiler, it will push and pop edi in the
|
||||||
|
prologue and epilogue, not here (which this function must be
|
||||||
|
declared as naked to avoid).
|
||||||
|
|
||||||
|
It may be that this function was originally written entirely in
|
||||||
|
assembly and declared naked, with the author deciding to
|
||||||
|
preserve edi only in this one section using it.
|
||||||
|
*/
|
||||||
|
push edi
|
||||||
|
mov eax, fs:[0x28]
|
||||||
|
mov edi, fs:[_tls_array]
|
||||||
|
mov edx, [_tls_index]
|
||||||
|
mov edx, [edi + edx*0x4]
|
||||||
|
sub edx, [eax + 0x28]
|
||||||
|
mov byte ptr [ecx], 0x1
|
||||||
|
add edx, _tls_array
|
||||||
|
mov [ecx + 0x4], edx
|
||||||
|
pop edi
|
||||||
|
|
||||||
|
end:
|
||||||
|
};
|
||||||
|
|
||||||
|
_rtinit();
|
||||||
|
_cinit();
|
||||||
|
main(0, NULL, NULL);
|
||||||
|
|
||||||
|
XapiBootToDash(XLD_LAUNCH_DASHBOARD_ERROR, XLD_ERROR_INVALID_XBE, 0);
|
||||||
|
|
||||||
|
// Return 0 to satisfy signature required for thread functions
|
||||||
|
_asm {
|
||||||
|
xor eax, eax
|
||||||
|
ret 4
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Address: 0x00148023
|
// Address: 0x00148023
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ A matching decompilation of the Xbox game Jet Set Radio Future.
|
||||||
|
|
||||||
## Progress
|
## Progress
|
||||||
- Delinking progress: 1.03% (26559 out of 2574172 bytes in XBE address space)
|
- Delinking progress: 1.03% (26559 out of 2574172 bytes in XBE address space)
|
||||||
- Decompilation progress: 19.0% (32 out of the 168 functions delinked so far)
|
- Decompilation progress: 19.6% (33 out of the 168 functions delinked so far)
|
||||||
- **Estimated total progress: 0.20%** (previous two multiplied together)
|
- **Estimated total progress: 0.20%** (previous two multiplied together)
|
||||||
|
|
||||||
## Roadmap
|
## Roadmap
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue