We've got FAKE RIFS!
This commit is contained in:
parent
a23e92b02d
commit
cc51442fcf
|
@ -1,4 +1,6 @@
|
|||
@echo off
|
||||
|
||||
adb push libs/armeabi-v7a/libpsmkdc_jni.so /data/local/tmp/libpsmkdc_jni.so
|
||||
|
||||
adb shell "su -c 'mount -o rw,remount /system /system;mount -o rw,remount /data /data;cat /data/local/tmp/libpsmkdc_jni.so>/data/data/com.playstation.psstore/lib/libpsmkdc_jni.so'"
|
||||
adb shell "rm /data/local/tmp/libpsmkdc_jni.so"
|
||||
adb shell "rm /data/local/tmp/libpsmkdc_jni.so"
|
||||
|
|
142
jni/nopsmdrm.c
142
jni/nopsmdrm.c
|
@ -5,12 +5,35 @@
|
|||
#include "hooks/inlineHook.h"
|
||||
|
||||
#define LOG(...) __android_log_print(ANDROID_LOG_DEBUG, "NOPSMDRM", __VA_ARGS__)
|
||||
#define FAKE_AID 0x0123456789ABCDEFLL
|
||||
|
||||
static void* LIB_DEFAULT_HANDLE = NULL;
|
||||
static void* LIB_DEFAULT_BASE = NULL;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char magic[0x8]; // 0x00
|
||||
uint32_t unk1; // 0x08
|
||||
uint32_t unk2; // 0x0C
|
||||
uint64_t aid; // 0x10
|
||||
uint32_t unk3; // 0x18
|
||||
uint32_t unk4; // 0x1C
|
||||
uint64_t start_time; // 0x20
|
||||
uint64_t expiration_time; // 0x28
|
||||
uint8_t act_digest[0x20]; // 0x30
|
||||
char content_id[0x30]; // 0x50
|
||||
uint8_t unk5[0x80]; // 0x80
|
||||
uint8_t key[0x200]; // 0x100
|
||||
uint8_t sha256digest[0x100]; // 0x300
|
||||
} ScePsmDrmLicense;
|
||||
|
||||
int (*scePsmDrmGetKeySet_orig)(ScePsmDrmLicense*, char*, int*, uint64_t*, uint64_t*) = NULL;
|
||||
|
||||
int (*dlopen_orig)(char*, int) = NULL;
|
||||
|
||||
void* (*scePsmDrmGetRif_orig)(char*, char*, ScePsmDrmLicense *) = NULL;
|
||||
|
||||
|
||||
void* get_func_addr(char* function_name) {
|
||||
if(LIB_DEFAULT_HANDLE != NULL){
|
||||
uintptr_t function_addr = (uintptr_t)dlsym(LIB_DEFAULT_HANDLE, function_name);
|
||||
|
@ -21,45 +44,116 @@ void* get_func_addr(char* function_name) {
|
|||
|
||||
}
|
||||
|
||||
void* get_base_addr(void* object) {
|
||||
if(LIB_DEFAULT_HANDLE != NULL){
|
||||
Dl_info inf;
|
||||
dladdr(object, &inf);
|
||||
|
||||
LOG("load inf: dli_fbase %p", inf.dli_fbase);
|
||||
LOG("load name: dli_fname %s", inf.dli_fname);
|
||||
|
||||
return inf.dli_fbase;
|
||||
|
||||
void MakeFakeLicense(ScePsmDrmLicense* license_buf, uint8_t* klicensee) {
|
||||
ScePsmDrmLicense license;
|
||||
memset(&license, 0, sizeof(ScePsmDrmLicense));
|
||||
license.aid = FAKE_AID;
|
||||
license.unk1 = __builtin_bswap32(1);
|
||||
|
||||
memcpy(license.content_id, license_buf->content_id, 0x30);
|
||||
memcpy(license.key, klicensee, 0x200);
|
||||
|
||||
|
||||
char fakeRifPath[0x100];
|
||||
snprintf(fakeRifPath, sizeof(fakeRifPath) - 1, "/sdcard/psm/%s.rif", license_buf->content_id);
|
||||
LOG("fakeRifPath: %s", fakeRifPath);
|
||||
|
||||
mkdir("/sdcard/psm");
|
||||
|
||||
LOG("Writing fake license ...");
|
||||
|
||||
FILE* fd = fopen(fakeRifPath, "wb");
|
||||
if(fd != NULL) {
|
||||
fwrite(&license, sizeof(ScePsmDrmLicense), 1, fd);
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void load_libdefault() {
|
||||
LIB_DEFAULT_HANDLE = dlopen("/data/data/com.playstation.psstore/lib/libdefault.so", RTLD_GLOBAL | RTLD_NOW);
|
||||
LOG("LIB_DEFAULT_HANDLE %p", LIB_DEFAULT_HANDLE);
|
||||
}
|
||||
int scePsmDrmGetKeySet_patch(ScePsmDrmLicense *license_buf, char *klicensee, int* flags, uint64_t* start_time, uint64_t* expiration_time) {
|
||||
|
||||
int get_addresses() {
|
||||
load_libdefault();
|
||||
void* lib_pss_main = get_func_addr("scePssMain");
|
||||
LIB_DEFAULT_BASE = get_base_addr(lib_pss_main);
|
||||
}
|
||||
LOG("license_buf %p, klicensee %p, flags %p, start_time %p, expiration_time %p", license_buf, klicensee, flags, start_time, expiration_time);
|
||||
int res = scePsmDrmGetKeySet_orig(license_buf, klicensee, flags, start_time, expiration_time);
|
||||
|
||||
|
||||
if(res >= 0) {
|
||||
LOG("Creating fake license file");
|
||||
MakeFakeLicense(license_buf, klicensee);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
int scePsmDrmGetRif_patch(char *contentid, char *psm_folder, ScePsmDrmLicense *rif_file) {
|
||||
LOG("contentid: %s psm_folder: %s", contentid, psm_folder);
|
||||
|
||||
int res = scePsmDrmGetRif_orig(contentid, psm_folder, rif_file);
|
||||
LOG("res = %x", res);
|
||||
|
||||
if(res <= 0) {
|
||||
// get title id :
|
||||
char titleid[9];
|
||||
memcpy(titleid, contentid + 7, sizeof(titleid));
|
||||
titleid[9] = '\0';
|
||||
|
||||
// locate FAKE.RIF
|
||||
char fakeRifPath[0x100];
|
||||
snprintf(fakeRifPath, sizeof(fakeRifPath) - 1, "%s/License/%s/FAKE.rif", psm_folder, titleid);
|
||||
LOG("fakeRifPath: %s", fakeRifPath);
|
||||
|
||||
|
||||
// Read FAKE.RIF into the buffer ...
|
||||
FILE* fd = fopen(fakeRifPath, "rb");
|
||||
if(fd != NULL) {
|
||||
fread(rif_file, sizeof(ScePsmDrmLicense), 1, fd);
|
||||
fclose(fd);
|
||||
}
|
||||
else {
|
||||
return res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int dlopen_patch(char* lib, int param){
|
||||
LOG("dlopen_patch %s %x", lib, param);
|
||||
|
||||
return dlopen_orig(lib, param);
|
||||
void* ptr = dlopen_orig(lib, param);
|
||||
|
||||
if(strstr(ptr, "libdefault") != 0) {
|
||||
LIB_DEFAULT_HANDLE = ptr;
|
||||
LOG("libdeafult found %p, unhooking dlopen ...", LIB_DEFAULT_HANDLE);
|
||||
inlineUnHook((uintptr_t)dlopen); // got libdefault, unhook this now ..
|
||||
|
||||
|
||||
LOG("Hooking scePsmDrmGetRif");
|
||||
uintptr_t* scePsmDrmGetRif = get_func_addr("scePsmDrmGetRif");
|
||||
int res = registerInlineHook((uintptr_t)scePsmDrmGetRif, (uintptr_t)scePsmDrmGetRif_patch, (uintptr_t**)&scePsmDrmGetRif_orig);
|
||||
if(res == 0)
|
||||
inlineHook((uintptr_t)scePsmDrmGetRif);
|
||||
|
||||
LOG("Hooking scePsmDrmGetKeySet");
|
||||
uintptr_t* scePsmDrmGetKeySet = get_func_addr("scePsmDrmGetKeySet");
|
||||
res = registerInlineHook((uintptr_t)scePsmDrmGetKeySet, (uintptr_t)scePsmDrmGetKeySet_patch, (uintptr_t**)&scePsmDrmGetKeySet_orig);
|
||||
if(res == 0)
|
||||
inlineHook((uintptr_t)scePsmDrmGetKeySet);
|
||||
|
||||
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int patch_libdefault() {
|
||||
|
||||
// hook the thing
|
||||
LOG("HOOKING");
|
||||
LOG("HOOKING dlopen");
|
||||
int res = registerInlineHook((uintptr_t)dlopen, (uintptr_t)dlopen_patch, (uintptr_t**)&dlopen_orig);
|
||||
if(res == 0)
|
||||
inlineHookAll();
|
||||
|
||||
//get_addresses();
|
||||
inlineHook((uintptr_t)dlopen);
|
||||
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue