unit kern_regmgr; {$mode ObjFPC}{$H+} {$CALLING SysV_ABI_CDecl} interface const SCE_REGMGR_ENT_KEY_SYSTEM_LIBC_intmem_peak_size = $02C30100; SCE_REGMGR_ENT_KEY_SYSTEM_LIBC_intmem_shortage_count = $02C30200; SCE_REGMGR_ENT_KEY_VIDEOOUT_enable_supersampling_mode = $0A170000; SCE_REGMGR_ENT_KEY_NP_env = $19800000; SCE_REGMGR_ENT_KEY_NP_debug = $19810000; SCE_REGMGR_ENT_KEY_BROWSER_DEBUG_notification = $3CC80700; SCE_REGMGR_ENT_KEY_MORPHEUS_DEBUG_vr_capture = $58800C00; SCE_REGMGR_ENT_KEY_DEVENV_TOOL_gpi00 = $78020400; SCE_REGMGR_ENT_KEY_DEVENV_TOOL_trc_notify = $78026400; SCE_REGMGR_ENT_KEY_DEVENV_TOOL_sys_prx_preload = $78028A00; SCE_REGMGR_ENT_KEY_DEVENV_TOOL_use_default_lib = $78028300; SCE_REGMGR_ENT_KEY_DEVENV_TOOL_game_intmem_dbg = $7802BF00; SCE_REGMGR_ENT_KEY_DEVENV_TOOL_sce_module_dbg = $7802C000; SCE_REGMGR_ENT_KEY_DEVENV_TOOL_preload_chk_off = $78020500; SCE_REGMGR_ENT_KEY_DEVENV_TOOL_020B00 = $78020B00; SCE_REGMGR_ENT_KEY_DEVENV_TOOL_game_heap_trace = $7802B700; SCE_REGMGR_ENT_KEY_DEVENV_TOOL_expose_under_2k = $7802B900; function sys_regmgr_call(op,key:DWORD;presult,pvalue:Pointer;vlen:QWORD):Integer; function sys_workaround8849(key:DWORD):Integer; implementation uses errno, systm, kern_thr, subr_backtrace; const s_ScrambNSsdk:array[0..15] of Byte=( $6B, $E8, $98, $03, $9A, $70, $23, $5A, $63, $EE, $F5, $7B, $FF, $A4, $4C, $8C ); s_ScrambNSlib:array[0..15] of Byte=( $14, $EE, $DE, $E1, $80, $AC, $F3, $78, $47, $43, $DB, $40, $93, $DD, $B1, $34 ); type t_encoded_id=packed record data :array[0..3] of Byte; table :Byte; index :Byte; checksum:Word; end; function regMgrCnvRegId(enc:QWORD;enc2:DWORD):Integer; var a,b,c,d,e,f,x:Byte; g:DWORD; h:DWORD; y:DWORD; p_Scramb:PByte; data:array[0..3] of Byte; begin Result:=0; a:=enc and $ff; //data[0] b:=(enc shr 8) and $ff; //data[1] c:=(enc shr 16) and $ff; //data[2] d:=(enc shr 24) and $ff; //data[3] e:=(enc shr 32) and $ff; //table f:=(enc shr 40) and $ff; //index g:=(enc shr 48) and $ffff; //checksum h:=(a + b + c + d + e * f) and $ffff; if (g<>h) then Exit(Integer($800d0204)); f:=f xor $6b; if (f > 12) then Exit(Integer($800d0203)); x:=e xor s_ScrambNSsdk[$f - f]; if (x=$19) then begin p_Scramb:=@s_ScrambNSlib; end else begin p_Scramb:=@s_ScrambNSsdk; if (x<>$72) then Exit(Integer($800d0205)); end; x:=p_Scramb[f]; y:=p_Scramb[f + 1]; data[0]:=(a xor p_Scramb[f + 3]); data[1]:=(c xor p_Scramb[f + 2]); data[2]:=(d xor y); data[3]:=(b xor x); Result:=(data[0] ) or (data[1] shl 8) or (data[2] shl 16) or (data[3] shl 24) end; function sys_regmgr_call(op,key:DWORD;presult,pvalue:Pointer;vlen:QWORD):Integer; label _copyout_value, _err; var kret:DWORD; skey:Integer; data:packed record enc1:QWORD; enc2:DWORD; int_val:DWORD; size:QWORD; data:array[0..2047] of AnsiChar; end; begin kret:=0; if (presult=nil) then begin kret:=$800d0202; goto _err; end; case op of $18: Assert(false,'Unhandled regmgr op:sceRegMgrNonSysSetInt'); $19: //sceRegMgrNonSysGetInt begin Result:=copyin(pvalue,@data,16); if (Result<>0) then begin kret:=$800d020f; goto _err; end; skey:=regMgrCnvRegId(data.enc1,data.enc2); if (skey<0) then begin kret:=skey; goto _err; end; case skey of SCE_REGMGR_ENT_KEY_DEVENV_TOOL_game_intmem_dbg :data.int_val:=0; //_malloc_init_lv2 SCE_REGMGR_ENT_KEY_DEVENV_TOOL_sce_module_dbg :data.int_val:=0; //libSceSysmodule (bit 1,2 -> load debug lib) SCE_REGMGR_ENT_KEY_DEVENV_TOOL_preload_chk_off :data.int_val:=0; //libSceSysmodule (print errors?) SCE_REGMGR_ENT_KEY_DEVENV_TOOL_020B00 :data.int_val:=0; //libSceSysmodule (preload module?) SCE_REGMGR_ENT_KEY_MORPHEUS_DEBUG_vr_capture :data.int_val:=0; //libkernel SCE_REGMGR_ENT_KEY_DEVENV_TOOL_game_heap_trace :data.int_val:=0; //libSceLibcInternal (sceLibcHeapGetTraceInfo -> get_segment_info) SCE_REGMGR_ENT_KEY_DEVENV_TOOL_expose_under_2k :data.int_val:=0; //sceVideoOutOpen debug video modes? SCE_REGMGR_ENT_KEY_VIDEOOUT_enable_supersampling_mode:data.int_val:=0; //sceVideoOutOpen SCE_REGMGR_ENT_KEY_NP_debug :data.int_val:=0; //libSceSysUtil SCE_REGMGR_ENT_KEY_SYSTEM_LIBC_intmem_peak_size :data.int_val:=0; //libSceLibcInternal SCE_REGMGR_ENT_KEY_SYSTEM_LIBC_intmem_shortage_count :data.int_val:=0; //libSceLibcInternal else begin print_error_td(' enc:0x'+HexStr(data.enc1,16)+'->key:0x'+HexStr(skey,8)); Assert(False); end; end; _copyout_value: Result:=copyout(@data,pvalue,vlen); if (Result<>0) then begin kret:=$800d0210; goto _err; end; end; $1B: //sceRegMgrNonSysGetStr begin Result:=copyin(pvalue,@data,$818); if (Result<>0) then begin kret:=$800d020f; goto _err; end; skey:=regMgrCnvRegId(data.enc1,data.enc2); if (skey<0) then begin kret:=skey; goto _err; end; case skey of SCE_REGMGR_ENT_KEY_NP_env: //sceNpUtilGetEnv begin data.data:='np'; end; else begin print_error_td(' enc:0x'+HexStr(data.enc1,16)+'->key:0x'+HexStr(skey,8)); Assert(False); end; end; vlen:=$818; goto _copyout_value; end; $1D: //sceRegMgrNonSysGetBin begin Result:=copyin(pvalue,@data,$818); if (Result<>0) then begin kret:=$800d020f; goto _err; end; skey:=regMgrCnvRegId(data.enc1,data.enc2); if (skey<0) then begin kret:=skey; goto _err; end; case skey of SCE_REGMGR_ENT_KEY_DEVENV_TOOL_gpi00:PQWORD(@data.data)^:=0; //sceKernelGetGPI else begin print_error_td(' enc:0x'+HexStr(data.enc1,16)+'->key:0x'+HexStr(skey,8)); Assert(False); end; end; vlen:=$818; goto _copyout_value; end; else begin if (op=$27) or (op>=$40) then begin kret:=$800d0219; goto _err; end; print_error_td('Unhandled regmgr op:0x'+HexStr(op,4)); Assert(False); end; end; _err: Result:=copyout(@kret,presult,SizeOf(DWORD)); end; function sys_workaround8849(key:DWORD):Integer; var td:p_kthread; begin td:=curkthread; if (td=nil) then Exit(-1); Result:=0; case key of SCE_REGMGR_ENT_KEY_NP_debug :td^.td_retval[0]:=0; //nop SCE_REGMGR_ENT_KEY_BROWSER_DEBUG_notification :td^.td_retval[0]:=0; //nop SCE_REGMGR_ENT_KEY_DEVENV_TOOL_trc_notify :td^.td_retval[0]:=0; //nop SCE_REGMGR_ENT_KEY_DEVENV_TOOL_sys_prx_preload:td^.td_retval[0]:=0; //nop SCE_REGMGR_ENT_KEY_DEVENV_TOOL_use_default_lib:td^.td_retval[0]:=0; //nop else Result:=EINVAL; end; end; end.