NoPssDrm/app/src/main/java/com/psmreborn/nopsmdrm/NoPsmDrmInstaller.java

270 lines
13 KiB
Java

package com.psmreborn.nopsmdrm;
import static com.psmreborn.nopsmdrm.Helper.*;
import static com.psmreborn.nopsmdrm.Root.*;
import com.psmreborn.nopsmdrm.pscertified.PlayStationCertified;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Environment;
import android.telephony.TelephonyManager;
import android.util.Log;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import eu.chainfire.libsuperuser.Shell;
// Sorry if this is kinda hard to follow ...
public class NoPsmDrmInstaller extends AsyncTask<Void, Void, Void> {
private boolean wasError = false;
private String errorMsg = "";
private ProgressDialog dialog = null;
private Context ctx = null;
private StringEncryptor stringEncryptor = null;
public NoPsmDrmInstaller(Context context){
this.ctx = context;
this.stringEncryptor = new StringEncryptor(this.ctx);
}
private void setError(String msg) throws Exception {
this.wasError = true;
this.errorMsg = msg;
Log.e("INSTALLER",errorMsg);
throw new Exception(msg);
}
private void generateDeviceFingerprint(String outputFilename) throws FileNotFoundException, UnsupportedEncodingException {
TelephonyManager tm = ((TelephonyManager) ctx.getSystemService( Context.TELEPHONY_SERVICE));
String deviceId = "(blank)";
if(tm != null)
deviceId = tm.getDeviceId();
if(deviceId == null)
deviceId = "(blank)";
String serial = Build.SERIAL;
if(serial == null)
serial = "(blank)";
String brand = Build.BRAND;
if(brand == null)
brand = "(blank)";
String manu = Build.MANUFACTURER;
if(manu == null)
manu = "(blank)";
String model = Build.MODEL;
if(model == null)
model = "(blank)";
String product = Build.PRODUCT;
if(product == null)
product = "(blank)";
String device = Build.DEVICE;
if(device == null)
device = "(blank)";
String type = Build.TYPE;
if(type == null)
type = "(blank)";
PrintWriter writer = new PrintWriter(outputFilename, "UTF-8");
writer.println(String.valueOf(stringEncryptor.getPsmUid()));
writer.println(stringEncryptor.getAndroidId());
writer.println(deviceId);
writer.println(serial);
writer.println(brand);
writer.println(manu);
writer.println(model);
writer.println(product);
writer.println(device);
writer.println(type);
writer.close();
}
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();
// check if "act.dat" exists -- they've been here before ...
if(fileExistRoot(psmActFile)) {
String psmSdcardFolder = new File(Environment.getExternalStorageDirectory(), "psm").getAbsolutePath();
new File(psmSdcardFolder).mkdirs();
String filename = "psm_"+getDateTime();
// tar up the files
tarRoot(getPsmApp().dataDir,new File(psmSdcardFolder, filename+".tar").getAbsolutePath());
// generate device fingerprint file
generateDeviceFingerprint(new File(psmSdcardFolder, filename + "_DEV.txt").getAbsolutePath());
}
}
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()));
mkdirAndChmodChown(new File(getPsmApp().dataDir, "files").getAbsolutePath(), 771, String.valueOf(stringEncryptor.getPsmUid()));
mkdirAndChmodChown(new File(new File(getPsmApp().dataDir, "files"), "kdc").getAbsolutePath(), 771, String.valueOf(stringEncryptor.getPsmUid()));
mkdirAndChmodChown(new File(getPsmApp().dataDir, "databases").getAbsolutePath(), 771, String.valueOf(stringEncryptor.getPsmUid()));
}
private void installSharedPrefs() throws Exception {
// get the path to the shared_prefs folder
String sharedPrefsPath = new File(getPsmApp().dataDir, "shared_prefs").getAbsolutePath();
// 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
// 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));
// get the cache folder for our 'shared_prefs'
String tmpPrefsFolder = ctx.getCacheDir().getAbsolutePath();
// work out paths to each file ...
String c_signinInfo = new File(tmpPrefsFolder, "SigninInfo.xml").getAbsolutePath();
String c_psstorePrefs = new File(tmpPrefsFolder, "com.playstation.psstore_preferences.xml").getAbsolutePath();
String c_runningContentInfo = new File(tmpPrefsFolder, "RunningContentInfo.xml").getAbsolutePath();
String c_localLibrary = new File(tmpPrefsFolder, "LocalLibrary.xml").getAbsolutePath();
String r_signinInfo = new File(sharedPrefsPath, "SigninInfo.xml").getAbsolutePath();
String r_psstorePrefs = new File(sharedPrefsPath, "com.playstation.psstore_preferences.xml").getAbsolutePath();
String r_runningContentInfo = new File(sharedPrefsPath, "RunningContentInfo.xml").getAbsolutePath();
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<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<map>\n<boolean name=\"key_upgradeDownloadTableForNeedWifi\" value=\"true\" />\n<string name=\"last_signin_account_id\">"+accountId+"</string>\n<long name=\"last_signin_account_region\" value=\"2\" />\n<int name=\"key_psstore\" value=\"1\" />\n<int name=\"key_downloader\" value=\"1\" />\n<int name=\"psm_license_agree_version_code\" value=\"1170\" />\n<boolean name=\"key_notDisplayAgainEndOfSupportPreNavi\" value=\"true\" />\n<int name=\"key_xmlcache\" value=\"1\" />\n<string name=\"last_signin_account_country\">US</string>\n<boolean name=\"key_notDisplayAgainContentStartNavi\" value=\"true\" />\n<int name=\"key_startcontent\" value=\"1\" />\n<int name=\"key_nsxevent\" value=\"1\" />\n<boolean name=\"key_upgradeLibraryTableForLocationUseConfirmationDate\" value=\"true\" />\n<int name=\"key_install\" value=\"1\" />\n<string name=\"update_md5\">387ce7e424258aef426aaa5be8a1638a</string>\n<boolean name=\"psm_license_agree\" value=\"true\" />\n<int name=\"key_guestinfo\" value=\"1\" />\n<string name=\"last_signin_account_language\">en</string>\n<int name=\"key_cache\" value=\"2\" />\n<int name=\"key_signinfo\" value=\"2\" />\n</map>\n");
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<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(stringEncryptor.getPsmUid()));
copyChmodAndChown(c_psstorePrefs, r_psstorePrefs, 660, String.valueOf(stringEncryptor.getPsmUid()));
copyChmodAndChown(c_runningContentInfo, r_runningContentInfo, 660, String.valueOf(stringEncryptor.getPsmUid()));
copyChmodAndChown(c_localLibrary, r_localLibrary, 660, String.valueOf(stringEncryptor.getPsmUid()));
}
}
private void installNoPsmDrmModules() throws Exception {
String nativeLibsFolder = getPsmApp().nativeLibraryDir;
String libPsmKdcFile = new File(nativeLibsFolder, "libpsmkdc_jni.so").getAbsolutePath();
String libDefaultFile = new File(nativeLibsFolder, "libdefault.so").getAbsolutePath();
String realLibDefaultFile = new File(nativeLibsFolder, "libdefault_real.so").getAbsolutePath();
if(!fileExistRoot(realLibDefaultFile)) {
// if libdefault_real.so not found, then rename libdefault.so to libdefault_real.so ...
moveFileRoot(libDefaultFile, realLibDefaultFile);
}
// unpack the library files ...
unpackResourceToLocationRoot(R.raw.libdefault, libDefaultFile, 755, "system");
unpackResourceToLocationRoot(R.raw.libpsmkdc_jni, libPsmKdcFile, 755, "system");
}
private void installDatabase() throws Exception {
String databasesFolder = new File(getPsmApp().dataDir, "databases").getAbsolutePath();
String libraryDbFile = new File(databasesFolder, "library.db").getAbsolutePath();
unpackResourceToLocationRoot(R.raw.library, libraryDbFile, 660, String.valueOf(stringEncryptor.getPsmUid()));
}
private void installDeviceList() throws PackageManager.NameNotFoundException, IOException, Shell.ShellDiedException {
String cacheFolder = new File(getPsmApp().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(stringEncryptor.getPsmUid()));
// 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(stringEncryptor.getPsmUid()));
}
@Override
protected void onPreExecute() {
Shell.setRedirectDeprecated(false);
dialog = new ProgressDialog(ctx);
dialog.setTitle("Installing NoPsmDrm ...");
dialog.setMessage("Please Wait ...");
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.show();
}
@Override
protected Void doInBackground(Void... voids) {
try {
Root.setContext(ctx);
if (isPsmInstalled()) {
backupPsm();
makeDirs();
installSharedPrefs();
installDeviceList();
installNoPsmDrmModules();
installDatabase();
}
else{
this.setError("PSM app is not installed.");
}
}
catch(Exception e){
this.wasError = true;
this.errorMsg = e.getMessage();
return null;
}
return null;
}
@Override
protected void onPostExecute(Void result) {
dialog.dismiss();
if(wasError) {
new AlertDialog.Builder((Activity)ctx)
.setTitle("Error Occurred.")
.setMessage(this.errorMsg)
.setCancelable(false)
.setPositiveButton("Ok",null).show();
}
else{
new AlertDialog.Builder((Activity)ctx)
.setTitle("Installed!")
.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();
}
}
}