Add NoPs1Drm !!
This commit is contained in:
parent
780278c9fa
commit
6acd9fb269
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -16,4 +16,6 @@
|
|||
local.properties
|
||||
libsuperuser/build/*
|
||||
app/build/*
|
||||
app/release/*
|
||||
app/release/*
|
||||
|
||||
libNpTicket/*
|
|
@ -12,8 +12,8 @@ android {
|
|||
minSdk 10
|
||||
//noinspection ExpiredTargetSdkVersion dont care about google play
|
||||
targetSdk 23
|
||||
versionCode 8
|
||||
versionName "1.8"
|
||||
versionCode 9
|
||||
versionName "1.9"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
|
|
|
@ -20,12 +20,18 @@
|
|||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@drawable/app_icon"
|
||||
android:label="@string/app_name">
|
||||
android:label="@string/name_nopsmdrm">
|
||||
<activity android:name="com.psmreborn.nopsmdrm.MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:launchMode="singleTop" android:name="com.psmreborn.nops1drm.LicenseCheckActivity" android:label="@string/name_nops1drm" android:icon="@drawable/nops1drm_icon" android:screenOrientation="landscape">
|
||||
<intent-filter>
|
||||
<action android:name="com.playstation.android.intent.action.CHECK_ENTITLEMENT"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
|
@ -0,0 +1,78 @@
|
|||
package com.psmreborn.nops1drm;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
|
||||
import com.psmreborn.shared.Logger;
|
||||
import com.psmreborn.shared.Root;
|
||||
|
||||
public class LicenseCheckActivity extends Activity {
|
||||
private static final int RESPONSE_CODE = 19941203;
|
||||
|
||||
public void respond(byte[] response, int resp){
|
||||
Intent resIntent = new Intent();
|
||||
resIntent.putExtra("result_data", response);
|
||||
this.setResult(resp, resIntent);
|
||||
this.finish();
|
||||
}
|
||||
@Override
|
||||
protected void onActivityResult(int res, int res_code, Intent intent) {
|
||||
if(res == RESPONSE_CODE) {
|
||||
byte[] result_data = intent.getByteArrayExtra("result_data");
|
||||
Logger.logBytes("RESULT_DATA", result_data);
|
||||
Logger.logText( "RES", String.valueOf(res_code));
|
||||
respond(result_data, res_code);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
|
||||
// Read intent from ps1 game
|
||||
String entitlement_id = this.getIntent().getStringExtra("entitlement_id");
|
||||
byte[] input_data = this.getIntent().getByteArrayExtra("input_data");
|
||||
|
||||
Logger.logText("ENTITLEMENT_ID", entitlement_id);
|
||||
Logger.logBytes("INPUT_DATA", input_data);
|
||||
|
||||
// Generate ticket and put it into com.playstation.psstore databases.
|
||||
|
||||
Handler handler = new Handler(this.getMainLooper());
|
||||
new Thread(()->{
|
||||
try {
|
||||
if(Root.init(this)){
|
||||
PsmStartupCache.addEntitlement(this, entitlement_id);
|
||||
|
||||
handler.post(() ->{
|
||||
// Forward intent to psm.apk
|
||||
Intent intent = new Intent("com.playstation.android.intent.action.CHECK_ENTITLEMENT");
|
||||
intent.putExtra("entitlement_id", entitlement_id);
|
||||
intent.putExtra("input_data", input_data);
|
||||
intent.setPackage("com.playstation.psstore");
|
||||
|
||||
startActivityForResult(intent, RESPONSE_CODE);
|
||||
});
|
||||
}
|
||||
else{
|
||||
handler.post(() -> {
|
||||
respond(new byte[]{}, 0);
|
||||
});
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e("LicenseCheckerActivity", e.toString());
|
||||
handler.post(() -> {
|
||||
respond(new byte[]{}, 0);
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
149
app/src/main/java/com/psmreborn/nops1drm/PsmStartupCache.java
Normal file
149
app/src/main/java/com/psmreborn/nops1drm/PsmStartupCache.java
Normal file
|
@ -0,0 +1,149 @@
|
|||
package com.psmreborn.nops1drm;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.util.Log;
|
||||
|
||||
import com.psmreborn.nopsmdrm.R;
|
||||
import com.psmreborn.shared.Helper;
|
||||
import com.psmreborn.shared.Logger;
|
||||
import com.psmreborn.shared.Root;
|
||||
import com.psmreborn.shared.StringEncryptor;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Locale;
|
||||
|
||||
public class PsmStartupCache {
|
||||
private static StringEncryptor stringEncryptor = null;
|
||||
private static String sha256HexStr(String str) {
|
||||
String lowerStr = str.toLowerCase();
|
||||
try {
|
||||
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
|
||||
messageDigest.update(lowerStr.getBytes("UTF-8"));
|
||||
byte[] digest = messageDigest.digest();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (byte hexDigit : digest) {
|
||||
sb.append(Integer.toHexString(hexDigit & 255));
|
||||
}
|
||||
return sb.toString();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
return null;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
private static void copyToPsm(Context ctx) throws Exception {
|
||||
String psmDataDir = Helper.getPsmAppInfo(ctx).dataDir;
|
||||
String psmDatabasesDir = new File(psmDataDir, "databases").getAbsolutePath();
|
||||
String psmStartContentDb = new File(psmDatabasesDir, "start_content.db").getAbsolutePath();
|
||||
|
||||
String myDataDir = Helper.getAppInfo(ctx, ctx.getPackageName()).dataDir;
|
||||
String myDatabasesDir = new File(myDataDir, "databases").getAbsolutePath();
|
||||
String myStartContentDb = new File(myDatabasesDir, "start_content.db").getAbsolutePath();
|
||||
|
||||
Root.mkdirAndChmodChown(psmDatabasesDir, 771, String.valueOf(Helper.getPsmUid(ctx)));
|
||||
Root.copyChmodAndChown(myStartContentDb, psmStartContentDb, 660, String.valueOf(Helper.getPsmUid(ctx)));
|
||||
}
|
||||
private static void copyFromPsm(Context ctx) throws Exception {
|
||||
String psmDataDir = Helper.getPsmAppInfo(ctx).dataDir;
|
||||
String psmDatabasesDir = new File(psmDataDir, "databases").getAbsolutePath();
|
||||
String psmStartContentDb = new File(psmDatabasesDir, "start_content.db").getAbsolutePath();
|
||||
|
||||
String myDataDir = Helper.getAppInfo(ctx, ctx.getPackageName()).dataDir;
|
||||
String myDatabasesDir = new File(myDataDir, "databases").getAbsolutePath();
|
||||
String myStartContentDb = new File(myDatabasesDir, "start_content.db").getAbsolutePath();
|
||||
|
||||
Root.mkdirAndChmodChown(myDatabasesDir, 771, String.valueOf(Helper.getMyUid(ctx)));
|
||||
Root.copyChmodAndChown(psmStartContentDb, myStartContentDb, 660, String.valueOf(Helper.getMyUid(ctx)));
|
||||
}
|
||||
private static int dbRemoveEntry(StartContentDb cdb, String entitlementId) {
|
||||
Logger.logText("DELETE, ENTITLEMENT_ID", entitlementId);
|
||||
SQLiteDatabase db = cdb.getWritableDatabase();
|
||||
int v = db.delete("cache_table", "entitlement_id = ?", new String[]{entitlementId});
|
||||
db.close();
|
||||
return v;
|
||||
}
|
||||
|
||||
private static byte[] dbGetEntry(StartContentDb cdb, String entitlementId){
|
||||
Log.i("TicketGen", "dbGetEntry, "+entitlementId);
|
||||
SQLiteDatabase db = cdb.getReadableDatabase();
|
||||
Cursor query = db.query("cache_table", new String[] {"_id", "user_id", "entitlement_id", "ticket_data", "last_update"}, "entitlement_id = ?", new String[]{entitlementId}, null, null, null);
|
||||
if (query == null || query.getCount() != 1) {
|
||||
db.close();
|
||||
return null;
|
||||
} else {
|
||||
query.moveToFirst();
|
||||
byte[] ticketEnc = query.getBlob(query.getColumnIndex("ticket_data"));
|
||||
query.close();
|
||||
db.close();
|
||||
return stringEncryptor.decrypt(ticketEnc);
|
||||
}
|
||||
|
||||
}
|
||||
private static void dbAddEntry(StartContentDb cdb, String userId, String entitlementId, byte[] ticket) throws Exception {
|
||||
Log.i("TicketGen", "dbAddEntry, "+entitlementId);
|
||||
|
||||
SQLiteDatabase db = cdb.getWritableDatabase();
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
byte[] encryptedTicket = stringEncryptor.encrypt(ticket);
|
||||
String shaUserId = sha256HexStr(userId);
|
||||
|
||||
values.put("user_id", shaUserId);
|
||||
values.put("entitlement_id", entitlementId);
|
||||
values.put("ticket_data", encryptedTicket);
|
||||
values.put("last_update", System.currentTimeMillis());
|
||||
|
||||
Logger.logText("USER_ID", shaUserId);
|
||||
Logger.logText("ENTITLEMENT_ID", entitlementId);
|
||||
Logger.logBytes("TICKET_DATA", ticket);
|
||||
Logger.logBytes("ENCRYPTED_TICKET_DATA", encryptedTicket);
|
||||
|
||||
Long pos = db.insert("cache_table", null, values);
|
||||
|
||||
db.close();
|
||||
|
||||
if(pos <= -1)
|
||||
throw new Exception("failed to insert");
|
||||
}
|
||||
|
||||
|
||||
public static void addEntitlement(Context ctx, String entitlement_id) throws Exception {
|
||||
stringEncryptor = new StringEncryptor(Helper.getAndroidIdOfPsm(ctx), Helper.getPsmUid(ctx));
|
||||
try{copyFromPsm(ctx);} catch (Exception ignored) { };
|
||||
|
||||
// get default values for onlineid, accountid, etc.
|
||||
String email = stringEncryptor.decryptString(Helper.getSharedPrefFromPsm(ctx, "SigninInfo", "SignedInUsername"), ctx.getResources().getString(R.string.default_email));
|
||||
Long accountId = Long.valueOf(stringEncryptor.decryptString(Helper.getSharedPrefFromPsm(ctx, "com.playstation.psstore_preferences", "last_signin_account_id"), String.valueOf(Helper.getDefaultAccountId(ctx))));
|
||||
String onlineId = ctx.getResources().getString(R.string.default_online_id);
|
||||
|
||||
// read psm start content.db file ..
|
||||
StartContentDb scdb = new StartContentDb(ctx);
|
||||
byte[] ticket = dbGetEntry(scdb, entitlement_id);
|
||||
if(ticket == null){
|
||||
Log.i("TicketGen", "No ticket found, generating new!");
|
||||
dbAddEntry(scdb, email, entitlement_id, TicketGen.generateTicket(entitlement_id, Locale.getDefault().getLanguage(), onlineId, accountId));
|
||||
}
|
||||
else{
|
||||
if(!TicketGen.ticketExpired(ticket)) {
|
||||
Log.i("TicketGen", "Previous ticket expired, generating new one!");
|
||||
dbRemoveEntry(scdb, entitlement_id);
|
||||
dbAddEntry(scdb, email, entitlement_id, TicketGen.generateTicket(entitlement_id, Locale.getDefault().getLanguage(), onlineId, accountId));
|
||||
}
|
||||
else{
|
||||
Log.i("TicketGen", "Existing ticket is all good! continuing to PSM!");
|
||||
}
|
||||
}
|
||||
|
||||
scdb.close();
|
||||
|
||||
try{copyToPsm(ctx);} catch (Exception ignored) { };
|
||||
|
||||
}
|
||||
}
|
26
app/src/main/java/com/psmreborn/nops1drm/StartContentDb.java
Normal file
26
app/src/main/java/com/psmreborn/nops1drm/StartContentDb.java
Normal file
|
@ -0,0 +1,26 @@
|
|||
package com.psmreborn.nops1drm;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
|
||||
final class StartContentDb extends SQLiteOpenHelper {
|
||||
public StartContentDb(Context context) {
|
||||
this(context, "start_content.db");
|
||||
}
|
||||
|
||||
private StartContentDb(Context context, String str) {
|
||||
super(context, str, (SQLiteDatabase.CursorFactory) null, 1);
|
||||
}
|
||||
|
||||
@Override // android.database.sqlite.SQLiteOpenHelper
|
||||
public final void onCreate(SQLiteDatabase sqllite) {
|
||||
sqllite.execSQL("CREATE TABLE IF NOT EXISTS cache_table (_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,user_id TEXT,entitlement_id TEXT NOT NULL,ticket_data BLOB NOT NULL,last_update LONG NOT NULL)");
|
||||
}
|
||||
|
||||
@Override // android.database.sqlite.SQLiteOpenHelper
|
||||
public final void onUpgrade(SQLiteDatabase sqllite, int i, int i2) {
|
||||
sqllite.execSQL("DROP TABLE IF EXISTS cache_table");
|
||||
sqllite.execSQL("CREATE TABLE IF NOT EXISTS cache_table (_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,user_id TEXT,entitlement_id TEXT NOT NULL,ticket_data BLOB NOT NULL,last_update LONG NOT NULL)");
|
||||
}
|
||||
}
|
82
app/src/main/java/com/psmreborn/nops1drm/TicketGen.java
Normal file
82
app/src/main/java/com/psmreborn/nops1drm/TicketGen.java
Normal file
|
@ -0,0 +1,82 @@
|
|||
package com.psmreborn.nops1drm;
|
||||
|
||||
import com.psmreborn.shared.Logger;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class TicketGen {
|
||||
|
||||
private static final byte[] baseTicket = {(byte)0x41, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x5D, (byte)0x30, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x0F, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x14, (byte)0xBA, (byte)0x1D, (byte)0x80, (byte)0x73, (byte)0xC1, (byte)0xAE, (byte)0x02, (byte)0x75, (byte)0xD5, (byte)0xD3, (byte)0xED, (byte)0x8C, (byte)0x18, (byte)0x72, (byte)0x5A, (byte)0xA3, (byte)0x29, (byte)0x1C, (byte)0xC9, (byte)0xDF, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x65, (byte)0x95, (byte)0x4D, (byte)0xAC, (byte)0x7B, (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x00, (byte)0x03, (byte)0xB9, (byte)0x03, (byte)0x74, (byte)0xCF, (byte)0x60, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x12, (byte)0x34, (byte)0x56, (byte)0x89, (byte)0xAB, (byte)0xCD, (byte)0xEF, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x20, (byte)0x4F, (byte)0x6E, (byte)0x6C, (byte)0x69, (byte)0x6E, (byte)0x65, (byte)0x49, (byte)0x64, (byte)0x68, (byte)0x65, (byte)0x72, (byte)0x65, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x04, (byte)0x65, (byte)0x6E, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x04, (byte)0x64, (byte)0x37, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x18, (byte)0x45, (byte)0x50, (byte)0x34, (byte)0x31, (byte)0x33, (byte)0x34, (byte)0x2D, (byte)0x4E, (byte)0x50, (byte)0x45, (byte)0x46, (byte)0x30, (byte)0x30, (byte)0x32, (byte)0x32, (byte)0x33, (byte)0x5F, (byte)0x30, (byte)0x30, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x30, (byte)0x11, (byte)0x00, (byte)0x04, (byte)0x07, (byte)0xC8, (byte)0x0C, (byte)0x06, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x04, (byte)0x19, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x30, (byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0F, (byte)0x06, (byte)0x30, (byte)0x30, (byte)0x30, (byte)0x30, (byte)0x30, (byte)0x31, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x62, (byte)0x3F, (byte)0xCE, (byte)0x27, (byte)0xD0, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x40, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x30, (byte)0x02, (byte)0x00, (byte)0x44, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x04, (byte)0xBD, (byte)0x97, (byte)0x9F, (byte)0x07, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x38, (byte)0x30, (byte)0x35, (byte)0x02, (byte)0x18, (byte)0x08, (byte)0xA4, (byte)0xC8, (byte)0xD2, (byte)0x50, (byte)0x74, (byte)0xCC, (byte)0xFA, (byte)0xF2, (byte)0xBF, (byte)0xF8, (byte)0x49, (byte)0x27, (byte)0xC3, (byte)0x04, (byte)0xA7, (byte)0x79, (byte)0xE2, (byte)0x3C, (byte)0x30, (byte)0xCA, (byte)0xE6, (byte)0x2C, (byte)0xE5, (byte)0x02, (byte)0x19, (byte)0x00, (byte)0xE0, (byte)0x4C, (byte)0x84, (byte)0x9F, (byte)0x41, (byte)0x4D, (byte)0x6B, (byte)0x0E, (byte)0xFA, (byte)0xBE, (byte)0x38, (byte)0xC4, (byte)0x72, (byte)0x2A, (byte)0x11, (byte)0x46, (byte)0x8A, (byte)0x04, (byte)0x3D, (byte)0x50, (byte)0x68, (byte)0xDC, (byte)0x99, (byte)0xA7, (byte)0x00};
|
||||
private static byte[] longToBytes(long l) {
|
||||
byte[] result = new byte[8];
|
||||
for (int i = 8 - 1; i >= 0; i--) {
|
||||
result[i] = (byte)(l & 0xFF);
|
||||
l >>= Byte.SIZE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
private static long bytesToLong(final byte[] b) {
|
||||
long result = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
result <<= Byte.SIZE;
|
||||
result |= (b[i] & 0xFF);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
private static void cpy(byte[] src, int srcOffset, byte[] dst, int dstOffset, int cpMaxLen){
|
||||
for(int i = 0; i < cpMaxLen; i++){
|
||||
byte b = 0;
|
||||
|
||||
if((i + srcOffset) < src.length) {
|
||||
b = src[i + srcOffset];
|
||||
}
|
||||
|
||||
dst[i + dstOffset] = b;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean ticketExpired(byte[] ticket){
|
||||
byte[] expireDateBytes = new byte[0x8];
|
||||
cpy(ticket, 0x40, expireDateBytes, 0, 0x8);
|
||||
long expDate = bytesToLong(expireDateBytes);
|
||||
|
||||
return expDate >= System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public static byte[] generateTicket(String entitlmentId, String language, String onlineId, Long accountId) throws Exception {
|
||||
Logger.logText("ENTITLEMENT_ID", entitlmentId);
|
||||
Logger.logText("LANGUAGE", language);
|
||||
Logger.logText("ONLINE_ID", onlineId);
|
||||
Logger.logText("ACCOUNT_ID", String.valueOf(accountId));
|
||||
|
||||
long curTime = System.currentTimeMillis();
|
||||
long expireTime = System.currentTimeMillis() + (1209600 * 1000);
|
||||
|
||||
Logger.logText("CUR_TIME", String.valueOf(curTime));
|
||||
Logger.logText("EXPIRE_TIME", String.valueOf(expireTime));
|
||||
|
||||
String servicePart = entitlmentId.substring(0x0, 0x13);
|
||||
String entitlementPart = entitlmentId.substring(0x14);
|
||||
|
||||
Logger.logText("SERVICE_PART", servicePart);
|
||||
Logger.logText("ENTITLEMENT_PART", entitlementPart);
|
||||
|
||||
|
||||
// get a copy of the base ticket ...
|
||||
byte[] newTicket = Arrays.copyOf(baseTicket, baseTicket.length);
|
||||
|
||||
// copy strings to new ticket ..
|
||||
cpy(servicePart.getBytes("UTF-8"), 0, newTicket, 0x8C, 0x18);
|
||||
cpy(entitlementPart.getBytes("UTF-8"), 0, newTicket, 0xBB, 0x6);
|
||||
cpy(onlineId.getBytes("UTF-8"), 0, newTicket, 0x58, 0x20);
|
||||
cpy(language.getBytes("UTF-8"), 0, newTicket, 0x7C, 0x2);
|
||||
|
||||
// copy longs to ticket
|
||||
cpy(longToBytes(accountId), 0, newTicket, 0x4C, 0x8);
|
||||
cpy(longToBytes(curTime), 0, newTicket, 0x34, 0x8);
|
||||
cpy(longToBytes(expireTime), 0, newTicket, 0x40, 0x8);
|
||||
|
||||
// return the patched ticket.
|
||||
return newTicket;
|
||||
}
|
||||
}
|
|
@ -10,6 +10,8 @@ import android.os.Environment;
|
|||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
|
||||
import com.psmreborn.shared.Helper;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -29,7 +31,7 @@ public class DumpAllRifs {
|
|||
File psmAndroidFolder = new File(new File(new File(new File(new File(Environment.getExternalStorageDirectory(), "Android"), "data"), "com.playstation.psstore"), "files"), "psm");
|
||||
|
||||
// stop psm
|
||||
Helper.killPsm();
|
||||
Helper.killPsm(ctx);
|
||||
|
||||
try {
|
||||
psmDumpAllFlagFile.createNewFile();
|
||||
|
|
|
@ -3,20 +3,13 @@ package com.psmreborn.nopsmdrm;
|
|||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
|
||||
import com.psmreborn.shared.Helper;
|
||||
import com.psmreborn.shared.Root;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import eu.chainfire.libsuperuser.Shell;
|
||||
|
||||
public class FixPermissions {
|
||||
public static void changePermissionsToPsm(Activity ctx) {
|
||||
|
@ -30,11 +23,11 @@ public class FixPermissions {
|
|||
new Thread(() -> {
|
||||
Handler handler = new Handler(ctx.getMainLooper());
|
||||
|
||||
Helper.killPsm();
|
||||
Helper.killPsm(ctx);
|
||||
String androidDataFolder = new File(new File(Environment.getExternalStorageDirectory(), "Android"), "data").getAbsolutePath();
|
||||
try {
|
||||
String groupId = Root.getFileGroup(androidDataFolder);
|
||||
String userId = String.valueOf(Helper.getPsmAppInfo().uid);
|
||||
String userId = String.valueOf(Helper.getPsmAppInfo(ctx).uid);
|
||||
Root.chownRoot(new File(new File(new File(androidDataFolder, "com.playstation.psstore"), "files"), "psm").getAbsolutePath(), userId, groupId);
|
||||
|
||||
handler.post(() -> {
|
||||
|
|
|
@ -8,8 +8,10 @@ import android.os.Build;
|
|||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.view.View;
|
||||
import com.psmreborn.nopsmdrm.pscertified.PlayStationCertified;
|
||||
import com.psmreborn.nopsmdrm.pscertified.PsCertificatesInstaller;
|
||||
import com.psmreborn.pscertified.PlayStationCertified;
|
||||
import com.psmreborn.pscertified.PsCertificatesInstaller;
|
||||
import com.psmreborn.shared.Downloader;
|
||||
import com.psmreborn.shared.Helper;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
@ -21,7 +23,6 @@ public class MainActivity extends Activity {
|
|||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
Helper.setContext(this);
|
||||
|
||||
(new Startup(this)).execute();
|
||||
}
|
||||
|
@ -69,7 +70,7 @@ public class MainActivity extends Activity {
|
|||
if(!PlayStationCertified.isPlaystationCertified(this.getApplicationContext())){
|
||||
psCertifiedAlert();
|
||||
}
|
||||
else if(!Helper.isPsmInstalled()) {
|
||||
else if(!Helper.isPsmInstalled(this)) {
|
||||
downloadPsmAlert();
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
package com.psmreborn.nopsmdrm;
|
||||
|
||||
import static com.psmreborn.nopsmdrm.Helper.*;
|
||||
import static com.psmreborn.nopsmdrm.Root.*;
|
||||
import static com.psmreborn.shared.Helper.*;
|
||||
import static com.psmreborn.shared.Root.*;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
|
@ -18,20 +18,18 @@ import android.telephony.TelephonyManager;
|
|||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
import com.psmreborn.shared.Files;
|
||||
import com.psmreborn.shared.Helper;
|
||||
import com.psmreborn.shared.Root;
|
||||
import com.psmreborn.shared.StringEncryptor;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
|
||||
import eu.chainfire.libsuperuser.Shell;
|
||||
|
||||
// Sorry if this is kinda hard to follow ...
|
||||
|
@ -54,6 +52,7 @@ public class NoPsmDrmInstaller extends AsyncTask<Void, Void, Void> {
|
|||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
private void generateDeviceFingerprint(String outputFilename) throws Exception {
|
||||
TelephonyManager tm = ((TelephonyManager) ctx.getSystemService( Context.TELEPHONY_SERVICE));
|
||||
|
||||
|
@ -93,8 +92,8 @@ public class NoPsmDrmInstaller extends AsyncTask<Void, Void, Void> {
|
|||
type = "(blank)";
|
||||
|
||||
PrintWriter writer = new PrintWriter(outputFilename, "UTF-8");
|
||||
writer.println(String.valueOf(Helper.getPsmUid()));
|
||||
writer.println(Helper.getAndroidIdOfPsm());
|
||||
writer.println(String.valueOf(Helper.getPsmUid(ctx)));
|
||||
writer.println(Helper.getAndroidIdOfPsm(ctx));
|
||||
writer.println(deviceId);
|
||||
writer.println(serial);
|
||||
writer.println(brand);
|
||||
|
@ -109,7 +108,7 @@ public class NoPsmDrmInstaller extends AsyncTask<Void, Void, Void> {
|
|||
|
||||
|
||||
private void backupPsm() throws Exception {
|
||||
String psmFilesDir = new File(getPsmAppInfo().dataDir, "files").getAbsolutePath();
|
||||
String psmFilesDir = new File(Helper.getPsmAppInfo(ctx).dataDir, "files").getAbsolutePath();
|
||||
String psmKdcDir = new File(psmFilesDir, "kdc").getAbsolutePath();
|
||||
String psmActFile = new File(psmKdcDir, "act.dat").getAbsolutePath();
|
||||
String psmAndroidFolder = new File(new File(new File(new File(new File(Environment.getExternalStorageDirectory(), "Android"), "data"), "com.playstation.psstore"), "files"), "psm").getAbsolutePath();
|
||||
|
@ -128,7 +127,7 @@ public class NoPsmDrmInstaller extends AsyncTask<Void, Void, Void> {
|
|||
generateDeviceFingerprint(devinfoFile);
|
||||
|
||||
ArrayList<String> filesToTar = new ArrayList<String>();
|
||||
filesToTar.add(getPsmAppInfo().dataDir);
|
||||
filesToTar.add(Helper.getPsmAppInfo(ctx).dataDir);
|
||||
filesToTar.add(devinfoFile);
|
||||
|
||||
// add all license folders ....
|
||||
|
@ -151,15 +150,15 @@ public class NoPsmDrmInstaller extends AsyncTask<Void, Void, Void> {
|
|||
|
||||
}
|
||||
private void makeDirs() throws PackageManager.NameNotFoundException, Shell.ShellDiedException {
|
||||
mkdirAndChmodChown(new File(getPsmAppInfo().dataDir, "cache").getAbsolutePath(), 771, String.valueOf(Helper.getPsmUid()));
|
||||
mkdirAndChmodChown(new File(getPsmAppInfo().dataDir, "shared_prefs").getAbsolutePath(), 771, String.valueOf(Helper.getPsmUid()));
|
||||
mkdirAndChmodChown(new File(getPsmAppInfo().dataDir, "files").getAbsolutePath(), 771, String.valueOf(Helper.getPsmUid()));
|
||||
mkdirAndChmodChown(new File(new File(getPsmAppInfo().dataDir, "files"), "kdc").getAbsolutePath(), 771, String.valueOf(Helper.getPsmUid()));
|
||||
mkdirAndChmodChown(new File(getPsmAppInfo().dataDir, "databases").getAbsolutePath(), 771, String.valueOf(Helper.getPsmUid()));
|
||||
mkdirAndChmodChown(new File(Helper.getPsmAppInfo(ctx).dataDir, "cache").getAbsolutePath(), 771, String.valueOf(Helper.getPsmUid(ctx)));
|
||||
mkdirAndChmodChown(new File(Helper.getPsmAppInfo(ctx).dataDir, "shared_prefs").getAbsolutePath(), 771, String.valueOf(Helper.getPsmUid(ctx)));
|
||||
mkdirAndChmodChown(new File(Helper.getPsmAppInfo(ctx).dataDir, "files").getAbsolutePath(), 771, String.valueOf(Helper.getPsmUid(ctx)));
|
||||
mkdirAndChmodChown(new File(new File(Helper.getPsmAppInfo(ctx).dataDir, "files"), "kdc").getAbsolutePath(), 771, String.valueOf(Helper.getPsmUid(ctx)));
|
||||
mkdirAndChmodChown(new File(Helper.getPsmAppInfo(ctx).dataDir, "databases").getAbsolutePath(), 771, String.valueOf(Helper.getPsmUid(ctx)));
|
||||
}
|
||||
|
||||
private void generateWorkaroundSharedPrefs(String sharedPrefsPath, String androidId, int psmUid) throws Exception {
|
||||
StringEncryptor stringEncryptor = new StringEncryptor(this.ctx, androidId, psmUid);
|
||||
StringEncryptor stringEncryptor = new StringEncryptor(androidId, psmUid);
|
||||
String emailAddress = stringEncryptor.encryptString("nopsmdrm@transrights.lgbt");
|
||||
String password = stringEncryptor.encryptString("password");
|
||||
|
||||
|
@ -170,22 +169,22 @@ public class NoPsmDrmInstaller extends AsyncTask<Void, Void, Void> {
|
|||
String signinInfo = new File(sharedPrefsPath, "SigninInfo.xml").getAbsolutePath();
|
||||
|
||||
// generate shared_prefs
|
||||
writeTxtFile(aidSigninInfo, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" +
|
||||
Files.writeTxtFile(aidSigninInfo, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" +
|
||||
"<map>\n<string name=\"SignedInUsername\">"+emailAddress+"</string>\n" +
|
||||
"<boolean name=\"PassSave\" value=\"true\" />\n" +
|
||||
"<string name=\"Password\">"+password+"</string>\n" +
|
||||
"<boolean name=\"AutoSignIn\" value=\"true\" />\n" +
|
||||
"</map>\n");
|
||||
|
||||
copyChmodAndChown(aidSigninInfo, signinInfo, 660, String.valueOf(Helper.getPsmUid()));
|
||||
copyChmodAndChown(aidSigninInfo, signinInfo, 660, String.valueOf(Helper.getPsmUid(ctx)));
|
||||
}
|
||||
private void generateSharedPrefs(String sharedPrefsPath, String androidId, int psmUid) throws Exception {
|
||||
StringEncryptor stringEncryptor = new StringEncryptor(this.ctx, androidId, psmUid);
|
||||
StringEncryptor stringEncryptor = new StringEncryptor(androidId, psmUid);
|
||||
|
||||
// encrypt the actual strings, username, password, etc
|
||||
String emailAddress = stringEncryptor.encryptString("nopsmdrm@transrights.lgbt");
|
||||
String password = stringEncryptor.encryptString("password");
|
||||
String accountId = stringEncryptor.encryptString(String.valueOf(0x123456789ABCDEFL));
|
||||
String emailAddress = stringEncryptor.encryptString(ctx.getResources().getString(R.string.default_email));
|
||||
String password = stringEncryptor.encryptString(ctx.getResources().getString(R.string.default_password));
|
||||
String accountId = stringEncryptor.encryptString(String.valueOf(Long.valueOf(ctx.getResources().getString(R.string.default_account_id), 16)));
|
||||
|
||||
// get the cache folder for our 'shared_prefs'
|
||||
String tmpPrefsFolder = ctx.getCacheDir().getAbsolutePath();
|
||||
|
@ -202,14 +201,14 @@ public class NoPsmDrmInstaller extends AsyncTask<Void, Void, Void> {
|
|||
String r_localLibrary = new File(sharedPrefsPath, "LocalLibrary.xml").getAbsolutePath();
|
||||
|
||||
// generate shared_prefs
|
||||
writeTxtFile(c_signinInfo, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" +
|
||||
Files.writeTxtFile(c_signinInfo, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" +
|
||||
"<map>\n<string name=\"SignedInUsername\">"+emailAddress+"</string>\n" +
|
||||
"<boolean name=\"PassSave\" value=\"true\" />\n" +
|
||||
"<string name=\"Password\">"+password+"</string>\n" +
|
||||
"<boolean name=\"AutoSignIn\" value=\"true\" />\n" +
|
||||
"</map>\n");
|
||||
|
||||
writeTxtFile(c_psstorePrefs, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" +
|
||||
Files.writeTxtFile(c_psstorePrefs, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" +
|
||||
"<map>\n" +
|
||||
"<boolean name=\"key_upgradeDownloadTableForNeedWifi\" value=\"true\" />\n" +
|
||||
"<string name=\"last_signin_account_id\">"+accountId+"</string>\n" +
|
||||
|
@ -230,46 +229,53 @@ public class NoPsmDrmInstaller extends AsyncTask<Void, Void, Void> {
|
|||
"<int name=\"key_signinfo\" value=\"2\" />\n" +
|
||||
"</map>\n");
|
||||
|
||||
writeTxtFile(c_runningContentInfo, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" +
|
||||
Files.writeTxtFile(c_runningContentInfo, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" +
|
||||
"<map>\n<null name=\"title_id\" />\n" +
|
||||
"<null name=\"next_title_id\" />\n" +
|
||||
"</map>\n");
|
||||
|
||||
writeTxtFile(c_localLibrary, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" +
|
||||
Files.writeTxtFile(c_localLibrary, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" +
|
||||
"<map>\n<boolean name=\"notDisplayAgain\" value=\"true\" />\n" +
|
||||
"<int name=\"sortType\" value=\"0\" />\n" +
|
||||
"<boolean name=\"isList\" value=\"false\" />\n" +
|
||||
"</map>\n");
|
||||
|
||||
// copy to the correct place and set permissions properly.
|
||||
copyChmodAndChown(c_signinInfo, r_signinInfo, 660, String.valueOf(Helper.getPsmUid()));
|
||||
copyChmodAndChown(c_psstorePrefs, r_psstorePrefs, 660, String.valueOf(Helper.getPsmUid()));
|
||||
copyChmodAndChown(c_runningContentInfo, r_runningContentInfo, 660, String.valueOf(Helper.getPsmUid()));
|
||||
copyChmodAndChown(c_localLibrary, r_localLibrary, 660, String.valueOf(Helper.getPsmUid()));
|
||||
copyChmodAndChown(c_signinInfo, r_signinInfo, 660, String.valueOf(Helper.getPsmUid(ctx)));
|
||||
copyChmodAndChown(c_psstorePrefs, r_psstorePrefs, 660, String.valueOf(Helper.getPsmUid(ctx)));
|
||||
copyChmodAndChown(c_runningContentInfo, r_runningContentInfo, 660, String.valueOf(Helper.getPsmUid(ctx)));
|
||||
copyChmodAndChown(c_localLibrary, r_localLibrary, 660, String.valueOf(Helper.getPsmUid(ctx)));
|
||||
}
|
||||
|
||||
private boolean isNoPsmDrmAccountId(String androidId, int psmUid) throws Exception {
|
||||
StringEncryptor stringEncryptor = new StringEncryptor(androidId, psmUid);
|
||||
long accountId = Long.parseLong(stringEncryptor.decryptString(Helper.getSharedPrefFromPsm(ctx, "com.playstation.psstore_preferences", "last_signin_account_id"), null));
|
||||
|
||||
return accountId == getDefaultAccountId(ctx);
|
||||
}
|
||||
private void installSharedPrefs() throws Exception {
|
||||
// get the path to the shared_prefs folder
|
||||
String sharedPrefsPath = new File(getPsmAppInfo().dataDir, "shared_prefs").getAbsolutePath();
|
||||
String sharedPrefsPath = new File(Helper.getPsmAppInfo(ctx).dataDir, "shared_prefs").getAbsolutePath();
|
||||
String tmpPrefsFolder = ctx.getCacheDir().getAbsolutePath();
|
||||
File aidSigninFile = new File(tmpPrefsFolder, "AIDSigninInfo.xml");
|
||||
|
||||
String androidId = Helper.getAndroidIdOfPsm(ctx);
|
||||
int psmUid = Helper.getPsmUid(ctx);
|
||||
|
||||
// check if signininfo.xml file exists or not ...
|
||||
boolean signinInfoExist = fileExistRoot(new File(sharedPrefsPath, "SigninInfo.xml").getAbsolutePath());
|
||||
boolean aidSigninExist = ( aidSigninFile.exists() && Build.VERSION.SDK_INT >= 26 );
|
||||
boolean isNoPsmDrmAccount = signinInfoExist && isNoPsmDrmAccountId(androidId, psmUid);
|
||||
|
||||
if (!signinInfoExist || aidSigninExist) { // if no signininfo file was found
|
||||
// then generate our own shared_prefs
|
||||
|
||||
String androidId = Helper.getAndroidIdOfPsm();
|
||||
int psmUid = Helper.getPsmUid();
|
||||
if (!signinInfoExist || isNoPsmDrmAccount) {
|
||||
// if no SigninInfo.xml file was not found
|
||||
// or if it was found, but it is using the default account id ...
|
||||
// then generate our own shared_prefs
|
||||
|
||||
if(androidId != null){
|
||||
generateSharedPrefs(sharedPrefsPath, androidId, psmUid);
|
||||
aidSigninFile.delete();
|
||||
}
|
||||
else {
|
||||
generateWorkaroundSharedPrefs(sharedPrefsPath, "1234567890abcdef", psmUid);
|
||||
Helper.killPsm();
|
||||
Helper.killPsm(ctx);
|
||||
handler.post(() ->{
|
||||
new AlertDialog.Builder((Activity)ctx)
|
||||
.setTitle("Android 8+ android_id...")
|
||||
|
@ -308,7 +314,7 @@ public class NoPsmDrmInstaller extends AsyncTask<Void, Void, Void> {
|
|||
}
|
||||
|
||||
private void installNoPsmDrmModules() throws Exception {
|
||||
String nativeLibsFolder = getPsmAppInfo().nativeLibraryDir;
|
||||
String nativeLibsFolder = getPsmAppInfo(ctx).nativeLibraryDir;
|
||||
|
||||
String libPsmKdcFile = new File(nativeLibsFolder, "libpsmkdc_jni.so").getAbsolutePath();
|
||||
String libDefaultFile = new File(nativeLibsFolder, "libdefault.so").getAbsolutePath();
|
||||
|
@ -332,7 +338,7 @@ public class NoPsmDrmInstaller extends AsyncTask<Void, Void, Void> {
|
|||
if(Build.VERSION.SDK_INT >= 21){
|
||||
String cachedLibDefault = new File(ctx.getCacheDir(), "libdefault_real.so").toString();
|
||||
|
||||
Root.copyChmodAndChown(realLibDefaultFile, cachedLibDefault, 777, String.valueOf(Helper.getMyUid()));
|
||||
Root.copyChmodAndChown(realLibDefaultFile, cachedLibDefault, 777, String.valueOf(Helper.getMyUid(ctx)));
|
||||
patchLibdefault(cachedLibDefault);
|
||||
Root.copyChmodAndChown(cachedLibDefault, realLibDefaultFile, 755, systemUid);
|
||||
}
|
||||
|
@ -340,36 +346,36 @@ public class NoPsmDrmInstaller extends AsyncTask<Void, Void, Void> {
|
|||
}
|
||||
|
||||
// unpack the library files ...
|
||||
unpackResourceToLocationRoot(R.raw.libdefault, libDefaultFile, 755, systemUid);
|
||||
unpackResourceToLocationRoot(R.raw.libpsmkdc_jni, libPsmKdcFile, 755, systemUid);
|
||||
unpackResourceToLocationRoot(ctx, R.raw.libdefault, libDefaultFile, 755, systemUid);
|
||||
unpackResourceToLocationRoot(ctx, R.raw.libpsmkdc_jni, libPsmKdcFile, 755, systemUid);
|
||||
|
||||
if(installedToSd) remountRo(folderContainingLibs);
|
||||
|
||||
|
||||
}
|
||||
private void installDatabase() throws Exception {
|
||||
String databasesFolder = new File(getPsmAppInfo().dataDir, "databases").getAbsolutePath();
|
||||
String databasesFolder = new File(getPsmAppInfo(ctx).dataDir, "databases").getAbsolutePath();
|
||||
String libraryDbFile = new File(databasesFolder, "library.db").getAbsolutePath();
|
||||
|
||||
unpackResourceToLocationRoot(R.raw.library, libraryDbFile, 660, String.valueOf(Helper.getPsmUid()));
|
||||
unpackResourceToLocationRoot(ctx, R.raw.library, libraryDbFile, 660, String.valueOf(Helper.getPsmUid(ctx)));
|
||||
}
|
||||
|
||||
private void installDeviceList() throws PackageManager.NameNotFoundException, IOException, Shell.ShellDiedException {
|
||||
String cacheFolder = new File(getPsmAppInfo().dataDir, "cache").getAbsolutePath();
|
||||
String cacheFolder = new File(getPsmAppInfo(ctx).dataDir, "cache").getAbsolutePath();
|
||||
|
||||
// extract the regular device list ...
|
||||
String deviceList2File = new File(cacheFolder, "deviceList2.dat").getAbsolutePath();
|
||||
unpackResourceToLocationRoot(R.raw.device_list2, deviceList2File, 660, String.valueOf(Helper.getPsmUid()));
|
||||
unpackResourceToLocationRoot(ctx, R.raw.device_list2, deviceList2File, 660, String.valueOf(Helper.getPsmUid(ctx)));
|
||||
|
||||
|
||||
// extract the additional certified devices list ...
|
||||
String additionalCertsFile = new File(cacheFolder, "addtionalCertifiedDevList.dat").getAbsolutePath();
|
||||
unpackResourceToLocationRoot(R.raw.aditional_certified_devices_list, additionalCertsFile, 660, String.valueOf(Helper.getPsmUid()));
|
||||
unpackResourceToLocationRoot(ctx, R.raw.aditional_certified_devices_list, additionalCertsFile, 660, String.valueOf(Helper.getPsmUid(ctx)));
|
||||
}
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
dialog = new ProgressDialog(ctx);
|
||||
if(!Helper.isNoPsmDrmAlreadyInstalled())
|
||||
if(!Helper.isNoPsmDrmAlreadyInstalled(ctx))
|
||||
dialog.setTitle("Installing NoPsmDrm ...");
|
||||
else
|
||||
dialog.setTitle("Updating NoPsmDrm ...");
|
||||
|
@ -384,9 +390,9 @@ public class NoPsmDrmInstaller extends AsyncTask<Void, Void, Void> {
|
|||
protected Void doInBackground(Void... voids) {
|
||||
|
||||
try {
|
||||
Helper.killPsm();
|
||||
Helper.killPsm(ctx);
|
||||
|
||||
if (isPsmInstalled()) {
|
||||
if (isPsmInstalled(ctx)) {
|
||||
backupPsm();
|
||||
makeDirs();
|
||||
installSharedPrefs();
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
package com.psmreborn.nopsmdrm;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.psmreborn.nopsmdrm.pscertified.PlayStationCertified;
|
||||
import com.psmreborn.pscertified.PlayStationCertified;
|
||||
import com.psmreborn.shared.Helper;
|
||||
import com.psmreborn.shared.Root;
|
||||
|
||||
import eu.chainfire.libsuperuser.Shell;
|
||||
public class Startup extends AsyncTask<Void, Void, Void> {
|
||||
|
@ -26,9 +25,9 @@ public class Startup extends AsyncTask<Void, Void, Void> {
|
|||
|
||||
if(!PlayStationCertified.isPlaystationCertified(activity.getApplicationContext()))
|
||||
installButton.setText("Install PS Certify");
|
||||
else if(!Helper.isPsmInstalled())
|
||||
else if(!Helper.isPsmInstalled(activity))
|
||||
installButton.setText("Install PSM");
|
||||
else if(Helper.isNoPsmDrmAlreadyInstalled())
|
||||
else if(Helper.isNoPsmDrmAlreadyInstalled(activity))
|
||||
installButton.setText("Update NoPsmDrm");
|
||||
else
|
||||
installButton.setText("Install NoPsmDrm");
|
||||
|
@ -53,14 +52,14 @@ public class Startup extends AsyncTask<Void, Void, Void> {
|
|||
protected Void doInBackground(Void... params) {
|
||||
try {
|
||||
|
||||
if(!Shell.SU.available()){
|
||||
if(!Root.init(ctx)){
|
||||
wasError = true;
|
||||
errorMsg = "Unable to get root permission.";
|
||||
return null;
|
||||
}
|
||||
if(Helper.isPsmInstalled() && Helper.getPsmAppPkg().versionCode != 1170) {
|
||||
if(Helper.isPsmInstalled(ctx) && Helper.getPsmAppPkg(ctx).versionCode != 1170) {
|
||||
wasError = true;
|
||||
errorMsg = "PSM Application is installed, but an older version, please update to 1.7.0 (have: "+String.valueOf(Helper.getPsmAppPkg().versionCode)+")";
|
||||
errorMsg = "PSM Application is installed, but an older version, please update to 1.7.0 (have: "+String.valueOf(Helper.getPsmAppPkg(ctx).versionCode)+")";
|
||||
return null;
|
||||
}
|
||||
if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
|
||||
|
@ -70,8 +69,7 @@ public class Startup extends AsyncTask<Void, Void, Void> {
|
|||
}
|
||||
|
||||
Permissions.requestPermissions(this.ctx);
|
||||
Root.setContext(this.ctx);
|
||||
Helper.killPsm();
|
||||
Helper.killPsm(ctx);
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
|
@ -91,7 +89,7 @@ public class Startup extends AsyncTask<Void, Void, Void> {
|
|||
handler.post(() -> {
|
||||
statusTV.setText("");
|
||||
|
||||
if(Helper.isNoPsmDrmAlreadyInstalled()){
|
||||
if(Helper.isNoPsmDrmAlreadyInstalled(ctx)){
|
||||
setPsmInstalled(ctx);
|
||||
};
|
||||
updateNames(ctx);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package com.psmreborn.nopsmdrm.pscertified;
|
||||
package com.psmreborn.pscertified;
|
||||
|
||||
|
||||
public class CertifiedDeviceEntry {
|
|
@ -1,4 +1,4 @@
|
|||
package com.psmreborn.nopsmdrm.pscertified;
|
||||
package com.psmreborn.pscertified;
|
||||
|
||||
public class CertifiedDeviceList {
|
||||
private String manufacturer = null;
|
|
@ -1,4 +1,4 @@
|
|||
package com.psmreborn.nopsmdrm.pscertified;
|
||||
package com.psmreborn.pscertified;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
|
@ -1,12 +1,10 @@
|
|||
package com.psmreborn.nopsmdrm.pscertified;
|
||||
package com.psmreborn.pscertified;
|
||||
|
||||
import static com.psmreborn.nopsmdrm.Root.*;
|
||||
import static com.psmreborn.shared.Root.*;
|
||||
|
||||
import com.psmreborn.nopsmdrm.Helper;
|
||||
import com.psmreborn.nopsmdrm.MainActivity;
|
||||
import com.psmreborn.nopsmdrm.NoPsmDrmInstaller;
|
||||
import com.psmreborn.nopsmdrm.R;
|
||||
import com.psmreborn.nopsmdrm.Root;
|
||||
import com.psmreborn.shared.Files;
|
||||
import com.psmreborn.shared.Root;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
|
@ -16,7 +14,6 @@ import android.content.DialogInterface;
|
|||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.PowerManager;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
|
@ -32,7 +29,7 @@ public class PsCertificatesInstaller extends AsyncTask<Void, Void, Void> {
|
|||
|
||||
public void installPlaystationCertificationMagisk() throws Exception {
|
||||
File magiskZip = new File(ctx.getCacheDir(), "MagiskCertify.zip");
|
||||
Root.unpackResource(R.raw.magiskcertify, magiskZip);
|
||||
Files.unpackResource(ctx, R.raw.magiskcertify, magiskZip);
|
||||
Root.installMagiskModule(magiskZip.getAbsolutePath());
|
||||
}
|
||||
public void installPlaystationCertification() throws IOException, Shell.ShellDiedException {
|
||||
|
@ -42,8 +39,8 @@ public class PsCertificatesInstaller extends AsyncTask<Void, Void, Void> {
|
|||
String psCertifiedPermissionFile = "/system/etc/permissions/com.playstation.playstationcertified.xml";
|
||||
String psCertifiedJarFile = "/system/framework/com.playstation.playstationcertified.jar";
|
||||
|
||||
Root.unpackResourceToLocationRoot(R.raw.ps_certified_permission, psCertifiedPermissionFile, 644, "0");
|
||||
Root.unpackResourceToLocationRoot(R.raw.ps_certified_jar, psCertifiedJarFile, 644, "0");
|
||||
Root.unpackResourceToLocationRoot(ctx, R.raw.ps_certified_permission, psCertifiedPermissionFile, 644, "0");
|
||||
Root.unpackResourceToLocationRoot(ctx, R.raw.ps_certified_jar, psCertifiedJarFile, 644, "0");
|
||||
|
||||
// make it read-only again.
|
||||
remountRo("/system");
|
|
@ -1,10 +1,12 @@
|
|||
package com.psmreborn.nopsmdrm;
|
||||
package com.psmreborn.shared;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.os.Handler;
|
||||
|
||||
import com.psmreborn.nopsmdrm.Startup;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -40,19 +42,7 @@ public class Downloader {
|
|||
.setPositiveButton("Ok",null).show();
|
||||
}
|
||||
|
||||
private static void copyTo(InputStream inpStream, OutputStream outStream) throws IOException {
|
||||
byte[] buffer = new byte[8192];
|
||||
int totalRead;
|
||||
|
||||
while(true){
|
||||
totalRead = inpStream.read(buffer, 0, buffer.length);
|
||||
if(totalRead == -1)
|
||||
break;
|
||||
outStream.write(buffer, 0, totalRead);
|
||||
}
|
||||
|
||||
outStream.flush();
|
||||
}
|
||||
private static void download(String uri, String dstFile) throws IOException {
|
||||
|
||||
URL url = new URL(uri);
|
||||
|
@ -62,7 +52,7 @@ public class Downloader {
|
|||
InputStream input = new BufferedInputStream(url.openStream(), 8192);
|
||||
OutputStream output = new FileOutputStream(dstFile);
|
||||
|
||||
copyTo(input, output);
|
||||
Files.copyTo(input, output);
|
||||
output.close();
|
||||
input.close();
|
||||
}
|
||||
|
@ -81,7 +71,7 @@ public class Downloader {
|
|||
new Thread(() -> {
|
||||
Handler handler = new Handler(ctx.getMainLooper());
|
||||
|
||||
Helper.killPsm();
|
||||
Helper.killPsm(ctx);
|
||||
try {
|
||||
download(url, saveLocation);
|
||||
handler.post(() -> {dialog.setTitle("Installing "+filename+"...");});
|
||||
|
@ -118,7 +108,7 @@ public class Downloader {
|
|||
new Thread(() -> {
|
||||
Handler handler = new Handler(ctx.getMainLooper());
|
||||
|
||||
Helper.killPsm();
|
||||
Helper.killPsm(ctx);
|
||||
try {
|
||||
download(url, saveLocation);
|
||||
} catch (IOException e) {
|
44
app/src/main/java/com/psmreborn/shared/Files.java
Normal file
44
app/src/main/java/com/psmreborn/shared/Files.java
Normal file
|
@ -0,0 +1,44 @@
|
|||
package com.psmreborn.shared;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class Files {
|
||||
public static void unpackResource(Context ctx, int resourceId, File outputFile) throws IOException {
|
||||
Log.i("ROOT", "Unpacking resource to : " + outputFile);
|
||||
InputStream resourceStream = ctx.getResources().openRawResource(resourceId);
|
||||
|
||||
FileOutputStream fs = new FileOutputStream(outputFile, false);
|
||||
copyTo(resourceStream, fs);
|
||||
fs.close();
|
||||
|
||||
resourceStream.close();
|
||||
}
|
||||
public static void writeTxtFile(String txtFile, String txt) throws IOException {
|
||||
Log.i("ROOT", "Writing: " + txtFile);
|
||||
FileWriter txtStream = new FileWriter(txtFile);
|
||||
txtStream.write(txt);
|
||||
txtStream.close();
|
||||
}
|
||||
|
||||
public static void copyTo(InputStream inpStream, OutputStream outStream) throws IOException {
|
||||
byte[] buffer = new byte[8192];
|
||||
int totalRead;
|
||||
|
||||
while(true){
|
||||
totalRead = inpStream.read(buffer, 0, buffer.length);
|
||||
if(totalRead == -1)
|
||||
break;
|
||||
outStream.write(buffer, 0, totalRead);
|
||||
}
|
||||
|
||||
outStream.flush();
|
||||
}
|
||||
}
|
|
@ -1,16 +1,17 @@
|
|||
package com.psmreborn.nopsmdrm;
|
||||
package com.psmreborn.shared;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
|
||||
import com.psmreborn.nopsmdrm.R;
|
||||
import com.rosstonovsky.abxutils.BinaryXmlPullParser;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
@ -23,17 +24,12 @@ import java.io.IOException;
|
|||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import eu.chainfire.libsuperuser.Shell;
|
||||
|
||||
public class Helper {
|
||||
|
||||
private static Context ctx;
|
||||
public static void setContext(Context context){
|
||||
ctx = context.getApplicationContext();
|
||||
}
|
||||
public static boolean isNoPsmDrmAlreadyInstalled() {
|
||||
private static final String psmAppPackage = "com.playstation.psstore";
|
||||
public static boolean isNoPsmDrmAlreadyInstalled(Context ctx) {
|
||||
try {
|
||||
if(new File(getPsmAppInfo().nativeLibraryDir, "libdefault_real.so").exists()){
|
||||
if(new File(getPsmAppInfo(ctx).nativeLibraryDir, "libdefault_real.so").exists()){
|
||||
return true;
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
|
@ -41,9 +37,26 @@ public class Helper {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
public static boolean isPsmInstalled(){
|
||||
public static long getDefaultAccountId(Context ctx){
|
||||
return Long.valueOf(ctx.getResources().getString(R.string.default_account_id), 16);
|
||||
}
|
||||
public static String getSharedPrefFromPsm(Context ctx, String prefName, String prefKey) throws Exception {
|
||||
|
||||
String psmSharedPrefs = new File(Helper.getPsmAppInfo(ctx).dataDir, "shared_prefs").getAbsolutePath();
|
||||
String psmPrefFile = new File(psmSharedPrefs, prefName+".xml").getAbsolutePath();
|
||||
|
||||
String mySharedPrefs = new File(Helper.getAppInfo(ctx, ctx.getPackageName()).dataDir, "shared_prefs").getAbsolutePath();
|
||||
String myPrefFile = new File(mySharedPrefs, prefName+".xml").getAbsolutePath();
|
||||
|
||||
Root.mkdirAndChmodChown(mySharedPrefs, 771, String.valueOf(Helper.getMyUid(ctx)));
|
||||
Root.copyChmodAndChown(psmPrefFile, myPrefFile, 660, String.valueOf(Helper.getMyUid(ctx)));
|
||||
|
||||
SharedPreferences pref = ctx.getSharedPreferences(prefName, 0);
|
||||
return pref.getString(prefKey, null);
|
||||
}
|
||||
public static boolean isPsmInstalled(Context ctx){
|
||||
try {
|
||||
ctx.getPackageManager().getApplicationInfo("com.playstation.psstore", 0);
|
||||
ctx.getPackageManager().getApplicationInfo(psmAppPackage, 0);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
|
@ -91,13 +104,13 @@ public class Helper {
|
|||
}
|
||||
|
||||
@SuppressLint("HardwareIds")
|
||||
public static String getAndroidIdOfPsm() throws Exception {
|
||||
public static String getAndroidIdOfPsm(Context ctx) throws Exception {
|
||||
if(Build.VERSION.SDK_INT >= 26){
|
||||
String[] files = Root.findFiles("/data/system", "settings_ssaid.xml");
|
||||
File ssaidCacheFile = new File(ctx.getCacheDir(), "settings_ssaid.xml");
|
||||
|
||||
for(String ssaidFile : files){
|
||||
Root.copyChmodAndChown(ssaidFile, ssaidCacheFile.getAbsolutePath(), 777, String.valueOf(getAppInfo(ctx.getPackageName()).uid));
|
||||
Root.copyChmodAndChown(ssaidFile, ssaidCacheFile.getAbsolutePath(), 777, String.valueOf(Helper.getMyUid(ctx)));
|
||||
try{
|
||||
FileInputStream stream = new FileInputStream(ssaidCacheFile);
|
||||
return parseSsaidBinary(stream);
|
||||
|
@ -115,7 +128,7 @@ public class Helper {
|
|||
}
|
||||
}
|
||||
|
||||
public static int getMyUid() {
|
||||
public static int getMyUid(Context ctx) {
|
||||
try{
|
||||
ApplicationInfo myAppInfo = ctx.getPackageManager().getApplicationInfo(ctx.getPackageName(), 0);
|
||||
if(myAppInfo != null) {
|
||||
|
@ -125,9 +138,9 @@ public class Helper {
|
|||
catch (PackageManager.NameNotFoundException e) { };
|
||||
return 0;
|
||||
}
|
||||
public static int getPsmUid() {
|
||||
public static int getPsmUid(Context ctx) {
|
||||
try{
|
||||
ApplicationInfo psmAppInfo = ctx.getPackageManager().getApplicationInfo("com.playstation.psstore", 0);
|
||||
ApplicationInfo psmAppInfo = ctx.getPackageManager().getApplicationInfo(psmAppPackage, 0);
|
||||
if(psmAppInfo != null) {
|
||||
return psmAppInfo.uid;
|
||||
}
|
||||
|
@ -136,23 +149,23 @@ public class Helper {
|
|||
return 0;
|
||||
}
|
||||
|
||||
public static void killPsm(){
|
||||
public static void killPsm(Context ctx){
|
||||
ActivityManager am = (ActivityManager) ctx.getSystemService(Activity.ACTIVITY_SERVICE);
|
||||
if (am != null) {
|
||||
am.killBackgroundProcesses("com.playstation.psstore");
|
||||
am.killBackgroundProcesses(psmAppPackage);
|
||||
}
|
||||
}
|
||||
public static PackageInfo getPackageInfo(String pkg) throws PackageManager.NameNotFoundException {
|
||||
public static PackageInfo getPackageInfo(Context ctx, String pkg) throws PackageManager.NameNotFoundException {
|
||||
return ctx.getPackageManager().getPackageInfo(pkg, 0);
|
||||
}
|
||||
public static ApplicationInfo getAppInfo(String pkg) throws PackageManager.NameNotFoundException {
|
||||
public static ApplicationInfo getAppInfo(Context ctx, String pkg) throws PackageManager.NameNotFoundException {
|
||||
return ctx.getPackageManager().getApplicationInfo(pkg, 0);
|
||||
}
|
||||
public static PackageInfo getPsmAppPkg() throws PackageManager.NameNotFoundException {
|
||||
return getPackageInfo("com.playstation.psstore");
|
||||
public static PackageInfo getPsmAppPkg(Context ctx) throws PackageManager.NameNotFoundException {
|
||||
return Helper.getPackageInfo(ctx,psmAppPackage);
|
||||
}
|
||||
public static ApplicationInfo getPsmAppInfo() throws PackageManager.NameNotFoundException {
|
||||
return getAppInfo("com.playstation.psstore");
|
||||
public static ApplicationInfo getPsmAppInfo(Context ctx) throws PackageManager.NameNotFoundException {
|
||||
return Helper.getAppInfo(ctx,psmAppPackage);
|
||||
}
|
||||
@SuppressLint("SimpleDateFormat")
|
||||
public static String getDateTime(){
|
24
app/src/main/java/com/psmreborn/shared/Logger.java
Normal file
24
app/src/main/java/com/psmreborn/shared/Logger.java
Normal file
|
@ -0,0 +1,24 @@
|
|||
package com.psmreborn.shared;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class Logger {
|
||||
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
|
||||
private static String bytesToHex(byte[] bytes) {
|
||||
if(bytes == null) return "(nulL)";
|
||||
char[] hexChars = new char[bytes.length * 2];
|
||||
for (int j = 0; j < bytes.length; j++) {
|
||||
int v = bytes[j] & 0xFF;
|
||||
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
|
||||
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
|
||||
}
|
||||
return new String(hexChars);
|
||||
}
|
||||
public static void logText(String description, String text){
|
||||
Log.i("NoPsmDrmApp", description + " = "+text);
|
||||
}
|
||||
public static void logBytes(String description, byte[] data){
|
||||
Log.i("NoPsmDrmApp", description + " = " + bytesToHex(data));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
package com.psmreborn.nopsmdrm;
|
||||
package com.psmreborn.shared;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import com.psmreborn.nopsmdrm.R;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
|
@ -17,7 +19,6 @@ import eu.chainfire.libsuperuser.Shell;
|
|||
|
||||
public class Root {
|
||||
private static String busyboxBinary = null;
|
||||
private static Context ctx = null;
|
||||
|
||||
public static void installMagiskModule(String magiskModuleFile) throws Exception {
|
||||
int res = 0;
|
||||
|
@ -213,50 +214,23 @@ public class Root {
|
|||
}
|
||||
|
||||
}
|
||||
private static void copyTo(InputStream inpStream, OutputStream outStream) throws IOException {
|
||||
int totalRead = 0;
|
||||
byte[] buffer = new byte[0x1000];
|
||||
|
||||
do {
|
||||
totalRead = inpStream.read(buffer, 0, buffer.length);
|
||||
outStream.write(buffer, 0, totalRead);
|
||||
}
|
||||
while(totalRead >= buffer.length);
|
||||
|
||||
outStream.flush();
|
||||
}
|
||||
public static void unpackResourceToLocationRoot(int resourceId, String outputDir, int chmod, String chown) throws IOException, Shell.ShellDiedException {
|
||||
public static void unpackResourceToLocationRoot(Context ctx, int resourceId, String outputDir, int chmod, String chown) throws IOException, Shell.ShellDiedException {
|
||||
Log.i("ROOT", "Unpacking resource and root copying to : " + outputDir);
|
||||
File tmpFile = File.createTempFile("tmp", "file", ctx.getCacheDir());
|
||||
tmpFile.createNewFile();
|
||||
|
||||
unpackResource(resourceId, tmpFile);
|
||||
Files.unpackResource(ctx, resourceId, tmpFile);
|
||||
moveChmodAndChown(tmpFile.getAbsolutePath(), outputDir, chmod, chown);
|
||||
}
|
||||
public static void unpackResource(int resourceId, File outputFile) throws IOException {
|
||||
Log.i("ROOT", "Unpacking resource to : " + outputFile);
|
||||
InputStream resourceStream = ctx.getResources().openRawResource(resourceId);
|
||||
|
||||
FileOutputStream fs = new FileOutputStream(outputFile, false);
|
||||
copyTo(resourceStream, fs);
|
||||
fs.close();
|
||||
|
||||
resourceStream.close();
|
||||
}
|
||||
public static void writeTxtFile(String txtFile, String txt) throws IOException {
|
||||
Log.i("ROOT", "Writing: " + txtFile);
|
||||
FileWriter txtStream = new FileWriter(txtFile);
|
||||
txtStream.write(txt);
|
||||
txtStream.close();
|
||||
}
|
||||
private static void setupBusyBox() throws IOException {
|
||||
private static void setupBusyBox(Context ctx) throws IOException {
|
||||
Log.i("ROOT","Creating busybox binary");
|
||||
File tmpFile = new File(ctx.getCacheDir(), "busybox");
|
||||
if(!tmpFile.exists()) {
|
||||
tmpFile.createNewFile();
|
||||
|
||||
if(tmpFile.setExecutable(true,false)) {
|
||||
unpackResource(R.raw.busybox, tmpFile);
|
||||
Files.unpackResource(ctx, R.raw.busybox, tmpFile);
|
||||
}
|
||||
else {
|
||||
throw new IOException("failed to extract busybox binary.");
|
||||
|
@ -266,9 +240,11 @@ public class Root {
|
|||
busyboxBinary = tmpFile.getAbsolutePath();
|
||||
}
|
||||
|
||||
public static void setContext(Context context) throws IOException {
|
||||
ctx = context.getApplicationContext();
|
||||
Shell.setRedirectDeprecated(false);
|
||||
setupBusyBox();
|
||||
public static boolean init(Context ctx) throws IOException {
|
||||
if(Shell.SU.available()){
|
||||
setupBusyBox(ctx);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.psmreborn.nopsmdrm;
|
||||
package com.psmreborn.shared;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Base64;
|
||||
|
@ -19,12 +19,10 @@ public class StringEncryptor {
|
|||
private static final byte[] iv = {-126, -30, -6, -75, -99, -117, -66, 117, 39, -65, -126, -27, -12, 38, -99, 86};
|
||||
private static final byte[] salt = {-92, -102, -105, -123, 71, -33, 69, -39, -27, -32, 21, 33, 126, -81, 69, 59, 57, 29, -83, -15};
|
||||
|
||||
private final Context ctx;
|
||||
private String android_id = null;
|
||||
private int psm_uid = 0;
|
||||
|
||||
StringEncryptor(Context ctx, String androidId, int psmUid) {
|
||||
this.ctx = ctx;
|
||||
public StringEncryptor(String androidId, int psmUid) {
|
||||
this.android_id = androidId;
|
||||
this.psm_uid = psmUid;
|
||||
}
|
||||
|
@ -45,7 +43,9 @@ public class StringEncryptor {
|
|||
return null;
|
||||
}
|
||||
|
||||
public String decryptString(String str) {
|
||||
public String decryptString(String str, String def) {
|
||||
if(str == null) return null;
|
||||
|
||||
byte[] data = decodeBase64(str);
|
||||
byte[] arrayData = Arrays.copyOf(data, data.length - 2);
|
||||
|
||||
|
@ -55,12 +55,13 @@ public class StringEncryptor {
|
|||
return new String(decryptedData, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
Log.e("STRINGENCRYPTOR", e.toString());
|
||||
return null;
|
||||
return def;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return def;
|
||||
}
|
||||
public byte[] decrypt(byte[] input){
|
||||
if(input == null) return null;
|
||||
try {
|
||||
Cipher cipher = generateKeyCipher(StringEncryptor.salt, StringEncryptor.iv, Cipher.DECRYPT_MODE);
|
||||
if (cipher != null) {
|
||||
|
@ -74,6 +75,7 @@ public class StringEncryptor {
|
|||
|
||||
}
|
||||
public byte[] encrypt(byte[] input){
|
||||
if(input == null) return null;
|
||||
try {
|
||||
Cipher cipher = generateKeyCipher(StringEncryptor.salt, StringEncryptor.iv, Cipher.ENCRYPT_MODE);
|
||||
if (cipher != null) {
|
BIN
app/src/main/res/drawable/nops1drm_icon.png
Normal file
BIN
app/src/main/res/drawable/nops1drm_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
|
@ -1,3 +1,8 @@
|
|||
<resources>
|
||||
<string name="app_name">NoPsmDrm</string>
|
||||
<string name="name_nopsmdrm">NoPsmDrm</string>
|
||||
<string name="name_nops1drm">NoPs1Drm</string>
|
||||
<string name="default_email">nopsmdrm@transrights.lgbt</string>
|
||||
<string name="default_password">password</string>
|
||||
<string name="default_online_id">TransgenderPS1</string>
|
||||
<string name="default_account_id">0123456789abcdef</string>
|
||||
</resources>
|
|
@ -17,3 +17,4 @@ rootProject.name = "nopsmdrm"
|
|||
include ':app'
|
||||
include ':libsuperuser'
|
||||
include ':libABX'
|
||||
//include ':libNpTicket'
|
||||
|
|
Loading…
Reference in New Issue
Block a user