PSP2000 v3 破解软件 CFW Enabler 1.0 源代码@CGTP,仅供懂C语言基础知识的玩家学习参考。
以下为引用的内容:
/* ohai nubcakes */
/* CFW Enabler's main code */ /* Xenogears & Becus25 */ /* ;t=14641 */
/* Noob comments by m0skit0 */ /* */
#include #include
/* Missing this! */ #include "rebootex.h"
PSP_MODULE_INFO("HENControl_module", 0x1000, 0, 1);
/* The macro that makes a call
MAKE_CALL(address, function) where address is the address to be patched and function is the new function to call
How it works: _sw is a function that corresponds to the sw assembler instruction, Store Word. Writes 32 bits (one word) at a memory direction 0x0C000000 is the opcode for jal, Jump and Link "f" is the function direction, shifted left 2 positions and masked with zeroes for the higher 6 bits (which correspond to opcode)
Then MAKE_CALL stores a jal instruction to the function passed at the address passed */ #define MAKE_CALL(a, f) _sw(0x0C000000 | (((u32)(f) >> 2) & 0x03ffffff), a)
/* To C noobs, this is a function pointer */ int (* DecompressReboot)(u32 addr, u32 size, void *unk, void *unk2, void *unk3) = NULL;
/* Write back data cache to main memory and invalidate all entries from both caches*/ void ClearCaches() { sceKernelIcacheInvalidateAll(); sceKernelDcacheWritebackInvalidateAll(); }
/* This is the new function that substitutes the instruction at sceLoadExec offset 0x27DC */ int DecompressRebootPatched(u32 addr, u32 size, void *unk, void *unk2, void *unk3) { /* Decompress "rebootex" in address 0x88FC0000 */ /* "rebootex" likely to be referenced by rebootex.h file */ sceKernelGzipDecompress((void *)0x88FC0000, 0x4000, rebootex, NULL); /* Call DecompressReboot, which is sceLoadExec text entry as we see below */ return DecompressReboot(addr, size, unk, unk2, unk3); }
/* Modify sceLoadExecModule */ int PatchLoadExec() { /* Get module sceLoadExec */ SceModule *mod = sceKernelFindModuleByName("sceLoadExec"); /* text_addr points to actual code from sceLoadExec module */ u32 text_addr = mod->text_addr;
/* Here comes the tricky part: */
/* Change instruction at offset 0x27dc of sceLoadExec code with a call to function DecompressRebootPatched() */ MAKE_CALL(text_addr + 0x27DC, DecompressRebootPatched);
/* Stores the value 0x3C0188FC at offset 0x2820 likely to be an instruction if stored in text segment :)
In binary: 0011 1100 0000 0001 1000 1000 1111 1100
Opcode: 001111 -> lui, Load Upper Immediate, loads a register's higher half-word with an immediate operand 00000 00001 1000100011111100 Then always come 5 zeroes: 00000 Then the register to load in (5 bits): 00001 -> register 1 Finally the half word immediate: 0x88FC After excuting this instruction $1 = 0x88FC0000 */ _sw(0x3C0188FC, text_addr + 0x2820);
/* You can disassemble sysmem.prx (aka sceLoadExec) to check that sub_00002778 (the subroutine patched above) is referenced a few times by other functions xD */
/* Assigning scePafModule text entry section as DecompressReboot() */ DecompressReboot = (void *)text_addr;
ClearCaches(); }
/* Module entry point, as you should already know :) */ int module_start(SceSize args, void *argp) { PatchLoadExec(); return 0; } |
|