From 75ee1d7b1637d672d224e0162f2f9437094a785f Mon Sep 17 00:00:00 2001 From: Li Date: Mon, 29 Apr 2024 00:52:34 +1200 Subject: [PATCH] improve backup function --- app/src/main/AndroidManifest.xml | 4 + .../com/psmreborn/nopsmdrm/DumpAllRifs.java | 77 ++++++++++++++++++ .../java/com/psmreborn/nopsmdrm/Helper.java | 6 ++ .../com/psmreborn/nopsmdrm/MainActivity.java | 52 +++++++++--- .../psmreborn/nopsmdrm/NoPsmDrmInstaller.java | 64 +++++++++++---- .../java/com/psmreborn/nopsmdrm/Root.java | 28 +++++-- .../java/com/psmreborn/nopsmdrm/Startup.java | 30 +++++-- .../pscertified/PsCertificatesInstaller.java | 16 +++- app/src/main/res/layout/activity_main.xml | 11 +++ app/src/main/res/raw/libdefault.so | Bin 12664 -> 12800 bytes app/src/main/res/values/strings.xml | 2 +- libsuperuser/build.gradle | 2 +- 12 files changed, 246 insertions(+), 46 deletions(-) create mode 100644 app/src/main/java/com/psmreborn/nopsmdrm/DumpAllRifs.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f06ec5b..9704c5f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,10 @@ + + + + diff --git a/app/src/main/java/com/psmreborn/nopsmdrm/DumpAllRifs.java b/app/src/main/java/com/psmreborn/nopsmdrm/DumpAllRifs.java new file mode 100644 index 0000000..d713221 --- /dev/null +++ b/app/src/main/java/com/psmreborn/nopsmdrm/DumpAllRifs.java @@ -0,0 +1,77 @@ +package com.psmreborn.nopsmdrm; + +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.net.wifi.WifiManager; +import android.os.Environment; +import android.os.Handler; +import android.util.Log; + +import java.io.File; +import java.io.IOException; + +public class DumpAllRifs { + public static void setDumpAllFlagAndStartPsm(Activity ctx) { + ProgressDialog dialog = new ProgressDialog(ctx); + dialog.setTitle("Starting PSM ..."); + dialog.setMessage("Please Wait ..."); + dialog.setIndeterminate(true); + dialog.setCancelable(false); + dialog.show(); + + new Thread(() -> { + Handler handler = new Handler(ctx.getMainLooper()); + File psmFolder = new File(Environment.getExternalStorageDirectory(), "psm"); + File psmDumpAllFlagFile = new File(psmFolder, "dump_all"); + 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(); + + try { + psmDumpAllFlagFile.createNewFile(); + } catch (IOException e) { + return; + } + + // get a games title id.. + String titleId = ""; + String[] allGames = psmAndroidFolder.list(); + for(String chkTitleId : allGames) { + File appInfoFile = new File(new File(new File(psmAndroidFolder, chkTitleId), "Application"), "app.info"); + if(appInfoFile.exists()){ + titleId = chkTitleId; + } + } + + if(titleId.equals("")){ + return; + } + + Log.d("DUMPALLRIFS", "Using TitleID: "+titleId); + + WifiManager wifiManager = (WifiManager) ctx.getApplicationContext().getSystemService(Context.WIFI_SERVICE); + if(wifiManager != null){ + Intent intent = new Intent("com.playstation.psm.intent.action.START_CONTENT"); + intent.putExtra("titleId", titleId); + intent.setData(Uri.parse("psgmpsm:play?titleId="+titleId)); + + handler.post(() -> { + // disable wifi + wifiManager.setWifiEnabled(false); + + // start psm ... + ctx.startActivity(intent); + + dialog.dismiss(); + }); + } + else{ + return; + } + }).start(); + } +} diff --git a/app/src/main/java/com/psmreborn/nopsmdrm/Helper.java b/app/src/main/java/com/psmreborn/nopsmdrm/Helper.java index 791ed67..ac01934 100644 --- a/app/src/main/java/com/psmreborn/nopsmdrm/Helper.java +++ b/app/src/main/java/com/psmreborn/nopsmdrm/Helper.java @@ -1,5 +1,7 @@ package com.psmreborn.nopsmdrm; +import android.app.Activity; +import android.app.ActivityManager; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.ApplicationInfo; @@ -40,6 +42,10 @@ public class Helper { return true; } + public static void killPsm(){ + ActivityManager am = (ActivityManager) ctx.getSystemService(Activity.ACTIVITY_SERVICE); + am.killBackgroundProcesses("com.playstation.psstore"); + } public static ApplicationInfo getAppInfo(String pkg) throws PackageManager.NameNotFoundException { ApplicationInfo appInfo = ctx.getPackageManager().getApplicationInfo(pkg, 0); return appInfo; diff --git a/app/src/main/java/com/psmreborn/nopsmdrm/MainActivity.java b/app/src/main/java/com/psmreborn/nopsmdrm/MainActivity.java index c0f7a73..c3ec98d 100644 --- a/app/src/main/java/com/psmreborn/nopsmdrm/MainActivity.java +++ b/app/src/main/java/com/psmreborn/nopsmdrm/MainActivity.java @@ -3,8 +3,14 @@ package com.psmreborn.nopsmdrm; import android.app.Activity; import android.app.AlertDialog; +import android.content.Context; import android.content.DialogInterface; +import android.content.Intent; +import android.net.Uri; +import android.net.wifi.WifiManager; import android.os.Bundle; +import android.os.Environment; +import android.os.Handler; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -13,9 +19,12 @@ import android.view.View; import com.psmreborn.nopsmdrm.pscertified.PlayStationCertified; import com.psmreborn.nopsmdrm.pscertified.PsCertificatesInstaller; +import java.io.File; + public class MainActivity extends Activity { + /* @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); @@ -37,6 +46,7 @@ public class MainActivity extends Activity { return super.onOptionsItemSelected(item); } } + */ @Override public void onCreate(Bundle savedInstanceState) { @@ -54,23 +64,43 @@ public class MainActivity extends Activity { super.onBackPressed(); } + private void psCertifiedAlert(){ + new AlertDialog.Builder((Activity)this) + .setTitle("PS Certification Missing") + .setMessage("Your device appears to not be\"PlayStation Certified\"\nDo you want to certify it?\n(Warning: modifies /system/)") + .setCancelable(false) + .setPositiveButton("Yes", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + (new PsCertificatesInstaller(MainActivity.this)).execute(); + } + }) + .setNegativeButton("No", null).show(); + } public void installStart(View view) { PlayStationCertified playStationCertified = new PlayStationCertified(this); if(!playStationCertified.isPlaystationCertified()){ - new AlertDialog.Builder((Activity)this) - .setTitle("PS Certification Missing") - .setMessage("Your device appears to not be\"PlayStation Certified\"\nDo you want to certify it?\n(Warning: modifies /system/)") - .setCancelable(false) - .setPositiveButton("Yes", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - (new PsCertificatesInstaller(MainActivity.this)).execute(); - } - }) - .setNegativeButton("No", null).show(); + psCertifiedAlert(); } else { (new NoPsmDrmInstaller(this)).execute(); } } + + public void dumpAllRifs(View view){ + String rifOutput = new File(Environment.getExternalStorageDirectory(), "psm").getAbsolutePath(); + new AlertDialog.Builder((Activity)this) + .setTitle("Backup licenses") + .setMessage("This will show a black screen for awhile\nthen a PlayStation Mobile game will start\nOnce the game starts, a backup of all your PSM licenses can be found at\n\""+rifOutput+"\"\nDo you want to do this?") + .setCancelable(false) + .setPositiveButton("Yes", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + DumpAllRifs.setDumpAllFlagAndStartPsm(MainActivity.this); + } + }) + .setNegativeButton("No", null).show(); + + } + } diff --git a/app/src/main/java/com/psmreborn/nopsmdrm/NoPsmDrmInstaller.java b/app/src/main/java/com/psmreborn/nopsmdrm/NoPsmDrmInstaller.java index ac36f54..f284c4c 100644 --- a/app/src/main/java/com/psmreborn/nopsmdrm/NoPsmDrmInstaller.java +++ b/app/src/main/java/com/psmreborn/nopsmdrm/NoPsmDrmInstaller.java @@ -11,14 +11,17 @@ import android.content.pm.PackageManager; import android.os.AsyncTask; import android.os.Build; import android.os.Environment; +import android.os.Handler; import android.telephony.TelephonyManager; import android.util.Log; +import android.widget.Toast; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; +import java.util.ArrayList; import java.util.Locale; import eu.chainfire.libsuperuser.Shell; @@ -30,10 +33,13 @@ public class NoPsmDrmInstaller extends AsyncTask { private String errorMsg = ""; private ProgressDialog dialog = null; private Context ctx = null; + private Handler handler = null; private StringEncryptor stringEncryptor = null; public NoPsmDrmInstaller(Context context){ this.ctx = context; + this.handler = new Handler(ctx.getMainLooper()); + this.stringEncryptor = new StringEncryptor(this.ctx); } @@ -98,27 +104,50 @@ public class NoPsmDrmInstaller extends AsyncTask { writer.close(); } - private void backupPsm() throws Exception { + + private void backupPsm() throws Exception { String psmFilesDir = new File(getPsmApp().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(); + String psmSdcardFolder = new File(Environment.getExternalStorageDirectory(), "psm").getAbsolutePath(); - // check if "act.dat" exists -- they've been here before ... - if(fileExistRoot(psmActFile)) { - String psmSdcardFolder = new File(Environment.getExternalStorageDirectory(), "psm").getAbsolutePath(); + String devinfoFile = new File(ctx.getCacheDir(), "devinfo.txt").getAbsolutePath(); + String tarFilename = new File(psmSdcardFolder, "psm_"+getDateTime() + ".tar").getAbsolutePath(); + + + // check if "act.dat" exists -- they've used PSM before ... + if(Root.fileExistRoot(psmActFile)) { new File(psmSdcardFolder).mkdirs(); - String filename = "psm_"+getDateTime(); - - // tar up the files - tarRoot(getPsmApp().dataDir,new File(psmSdcardFolder, filename+".tar").getAbsolutePath()); + File psmAndroidFile = new File(psmAndroidFolder); // generate device fingerprint file - generateDeviceFingerprint(new File(psmSdcardFolder, filename + "_DEV.txt").getAbsolutePath()); + generateDeviceFingerprint(devinfoFile); + + ArrayList filesToTar = new ArrayList(); + filesToTar.add(getPsmApp().dataDir); + filesToTar.add(devinfoFile); + + // add all license folders .... + if(psmAndroidFile.exists()){ + for(String gameFolder : psmAndroidFile.list()){ + File licenseFolder = new File(new File(psmAndroidFile, gameFolder), "License"); + if(licenseFolder.exists()){ + filesToTar.add(licenseFolder.toString()); + } + } + } + + // tar up the files + tarRoot(filesToTar, tarFilename); + + handler.post(() -> { + Toast.makeText(ctx.getApplicationContext(),"Backed up existing PSM Data to:\n\""+tarFilename+"\"", Toast.LENGTH_LONG).show(); + }); } } - private void makeDirs() throws PackageManager.NameNotFoundException, Shell.ShellDiedException { mkdirAndChmodChown(new File(getPsmApp().dataDir, "cache").getAbsolutePath(), 771, String.valueOf(stringEncryptor.getPsmUid())); mkdirAndChmodChown(new File(getPsmApp().dataDir, "shared_prefs").getAbsolutePath(), 771, String.valueOf(stringEncryptor.getPsmUid())); @@ -133,8 +162,8 @@ public class NoPsmDrmInstaller extends AsyncTask { // check if signininfo.xml file exists or not ... boolean signinInfoExist = fileExistRoot(new File(sharedPrefsPath, "SigninInfo.xml").getAbsolutePath()); - if (!signinInfoExist) { // if file not found ... - // then generate our own shared_prefs + if (!signinInfoExist) { // if no psmdrm activation file was found + // then generate our own shared_prefs // encrypt the actual strings, username, password, etc String emailAddress = stringEncryptor.encryptString(Helper.sharedPrefs.getString("saveAccountEmail","nopsmdrm@transrights.lgbt")); @@ -242,10 +271,11 @@ public class NoPsmDrmInstaller extends AsyncTask { } @Override protected void onPreExecute() { - Shell.setRedirectDeprecated(false); - dialog = new ProgressDialog(ctx); - dialog.setTitle("Installing NoPsmDrm ..."); + if(!Helper.isNoPsmDrmAlreadyInstalled()) + dialog.setTitle("Installing NoPsmDrm ..."); + else + dialog.setTitle("Updating NoPsmDrm ..."); dialog.setMessage("Please Wait ..."); dialog.setIndeterminate(true); dialog.setCancelable(false); @@ -258,7 +288,7 @@ public class NoPsmDrmInstaller extends AsyncTask { try { Root.setContext(ctx); - killApplication("com.playstation.psstore"); + Helper.killPsm(); if (isPsmInstalled()) { backupPsm(); @@ -295,7 +325,7 @@ public class NoPsmDrmInstaller extends AsyncTask { } else{ new AlertDialog.Builder((Activity)ctx) - .setTitle("Installed!") + .setTitle("Finished!") .setMessage("Your PSM Application was patched successfully!\n\nNote: WI-FI has to be turned off for games to work.") .setCancelable(false) .setPositiveButton("Ok", null).show(); diff --git a/app/src/main/java/com/psmreborn/nopsmdrm/Root.java b/app/src/main/java/com/psmreborn/nopsmdrm/Root.java index 97a1899..5e4063e 100644 --- a/app/src/main/java/com/psmreborn/nopsmdrm/Root.java +++ b/app/src/main/java/com/psmreborn/nopsmdrm/Root.java @@ -9,6 +9,7 @@ import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.ArrayList; import eu.chainfire.libsuperuser.Shell; @@ -16,9 +17,9 @@ public class Root { private static String busyboxBinary = null; private static Context ctx = null; - public static void killApplication(String processName) throws Shell.ShellDiedException { - Log.i("ROOT", "Killing process: " + processName); - Shell.Pool.SU.run(new String[] { busyboxBinary + " pkill -9 '" + processName +"'" }); + public static void reboot() throws Shell.ShellDiedException { + Log.i("ROOT", "Rebooting"); + Shell.Pool.SU.run(new String[] { busyboxBinary + " reboot" }); } public static boolean fileExistRoot(String filename) throws Shell.ShellDiedException { Log.i("ROOT", "FileExistRoot: " + filename); @@ -26,12 +27,24 @@ public class Root { return res == 0; } - public static void tarRoot(String src, String dst) throws IOException, Shell.ShellDiedException { - Log.i("ROOT", "TarRoot: " + src + " : "+ dst); - int res = Shell.Pool.SU.run(new String[]{busyboxBinary + " tar c '" + src + "' -f '" + dst +"'"}); + public static void tarRoot(ArrayList src, String dst) throws IOException, Shell.ShellDiedException { + if(src.size() <= 0){ + throw new IOException("tar src was empty."); + }; + + Log.i("ROOT", "TarRoot: "+ dst); + + StringBuilder tarFiles = new StringBuilder(); + for(String file : src) { + tarFiles.append("'"); + tarFiles.append(file); + tarFiles.append("' "); + } + + int res = Shell.Pool.SU.run(new String[]{busyboxBinary + " tar -cf '" + dst + "' "+tarFiles.toString()}); if (res != 0) { Log.e("ROOT", "error (" + String.valueOf(res) +")"); - throw new IOException("Failed to tar " + src); + throw new IOException("Failed to tar " + dst); } } public static void remountRo(String foldername) throws IOException, Shell.ShellDiedException { @@ -136,6 +149,7 @@ public class Root { public static void setContext(Context context) throws IOException { ctx = context; + Shell.setRedirectDeprecated(false); setupBusyBox(); } } diff --git a/app/src/main/java/com/psmreborn/nopsmdrm/Startup.java b/app/src/main/java/com/psmreborn/nopsmdrm/Startup.java index a98cf2d..6787779 100644 --- a/app/src/main/java/com/psmreborn/nopsmdrm/Startup.java +++ b/app/src/main/java/com/psmreborn/nopsmdrm/Startup.java @@ -5,12 +5,16 @@ import android.content.Context; import android.content.pm.PackageManager; import android.os.AsyncTask; import android.os.Environment; +import android.os.Handler; import android.widget.Button; import android.widget.TextView; import eu.chainfire.libsuperuser.Shell; import static com.psmreborn.nopsmdrm.Helper.*; +import com.psmreborn.nopsmdrm.pscertified.PlayStationCertified; +import com.psmreborn.nopsmdrm.pscertified.PsCertificatesInstaller; + import java.io.File; public class Startup extends AsyncTask { @@ -29,20 +33,26 @@ public class Startup extends AsyncTask { if(!Shell.SU.available()){ wasError = true; errorMsg = "Unable to get root permission."; + return null; } if(!Helper.isPsmInstalled()){ wasError = true; errorMsg = "PSM Application is not installed, please install it first!"; + return null; } if(!(getPsmApp().sourceDir.startsWith("/data/") || getPsmApp().sourceDir.startsWith("/system/"))){ wasError = true; errorMsg = "PSM Application is installed to the SD Card not internal storage."; + return null; } if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ wasError = true; errorMsg = "No SD Card inserted."; + return null; } + Root.setContext(this.ctx); + } catch (Exception e) { wasError = true; errorMsg = e.getMessage(); @@ -54,19 +64,25 @@ public class Startup extends AsyncTask { protected void onPostExecute(Void result) { TextView statusTV = (TextView) ((Activity)ctx).findViewById(R.id.errorMsg); Button installButton = (Button) ((Activity)ctx).findViewById(R.id.installPsm); + Button backupGamesButton = (Button) ((Activity)ctx).findViewById(R.id.dumpGames); + Handler handler = new Handler(this.ctx.getMainLooper()); if(!wasError) { - statusTV.setText(""); + handler.post(() -> { + statusTV.setText(""); - if(isNoPsmDrmAlreadyInstalled()){ - installButton.setText("Update NoPsmDrm"); - }; - - installButton.setEnabled(true); + if(Helper.isNoPsmDrmAlreadyInstalled()){ + installButton.setText("Update NoPsmDrm"); + }; + installButton.setEnabled(true); + backupGamesButton.setEnabled(true); + }); } else{ - statusTV.setText("Error: "+errorMsg); + handler.post(() -> { + statusTV.setText("Error: " + errorMsg); + }); } } } \ No newline at end of file diff --git a/app/src/main/java/com/psmreborn/nopsmdrm/pscertified/PsCertificatesInstaller.java b/app/src/main/java/com/psmreborn/nopsmdrm/pscertified/PsCertificatesInstaller.java index 221bb15..55d3942 100644 --- a/app/src/main/java/com/psmreborn/nopsmdrm/pscertified/PsCertificatesInstaller.java +++ b/app/src/main/java/com/psmreborn/nopsmdrm/pscertified/PsCertificatesInstaller.java @@ -13,6 +13,7 @@ import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.os.AsyncTask; +import android.os.Handler; import android.os.PowerManager; @@ -84,9 +85,20 @@ public class PsCertificatesInstaller extends AsyncTask { else{ new AlertDialog.Builder((Activity)ctx) .setTitle("Installed!") - .setMessage("Your device is now \"Playstation Certified\"\n(You may have to reboot for changes to take effect)") + .setMessage("Your device is now \"Playstation Certified\"\n(You have to reboot for changes to take effect)\nReboot?") .setCancelable(false) - .setPositiveButton("Ok",null).show(); + .setPositiveButton("Yes", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Handler handler = new Handler(PsCertificatesInstaller.this.ctx.getMainLooper()); + handler.post(() -> { + try { + Root.reboot(); + } catch (Shell.ShellDiedException e) {} + }); + } + }) + .setNegativeButton("No", null).show(); } } } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 44c70b0..e013f7b 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -29,4 +29,15 @@ android:layout_below="@+id/errorMsg" android:text="Install NoPsmDrm"/> +