Add PS Certification feature

This commit is contained in:
Li 2024-04-22 12:51:55 +12:00
parent 969fef9140
commit 7e6cd07a09
13 changed files with 598 additions and 113 deletions

View File

@ -4,7 +4,7 @@
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.playstation.psstore.permission" />
<application
android:allowBackup="true"
android:icon="@drawable/app_icon"

View File

@ -1,9 +1,15 @@
package com.psmreborn.nopsmdrm;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import com.psmreborn.nopsmdrm.pscertified.PlayStationCertified;
import com.psmreborn.nopsmdrm.pscertified.PsCertificatesInstaller;
public class MainActivity extends Activity {
@ -21,6 +27,27 @@ public class MainActivity extends Activity {
finish();
}
public void installStart(View view) {
(new Installer(this)).execute();
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", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
(new NoPsmDrmInstaller(MainActivity.this)).execute();
}
}).show();
}
else {
(new NoPsmDrmInstaller(this)).execute();
}
}
}

View File

@ -1,12 +1,13 @@
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.DialogInterface;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Build;
@ -16,25 +17,24 @@ import android.util.Log;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import eu.chainfire.libsuperuser.Shell;
public class Installer extends AsyncTask<Void, Void, Void> {
// Sorry if this is kinda hard to follow ...
public class NoPsmDrmInstaller extends AsyncTask<Void, Void, Void> {
protected static Boolean psCertify = false;
private boolean wasError = false;
private String errorMsg = "";
private ProgressDialog dialog = null;
private Context ctx = null;
private StringEncryptor stringEncryptor = null;
private String busyboxBinary = "";
public Installer(Context context){
private PlayStationCertified playStationCertified = null;
public NoPsmDrmInstaller(Context context){
this.ctx = context;
this.stringEncryptor = new StringEncryptor(this.ctx);
}
@ -45,83 +45,6 @@ public class Installer extends AsyncTask<Void, Void, Void> {
Log.e("INSTALLER",errorMsg);
throw new Exception(msg);
}
private static void writeTxtFile(String txtFile, String txt) throws IOException {
Log.i("INSTALLER", "Writing: "+txtFile);
FileWriter txtStream = new FileWriter(txtFile);
txtStream.write(txt);
txtStream.close();
}
private 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();
}
private void unpackResource(int resourceId, File outputFile) throws IOException {
InputStream resourceStream = ctx.getResources().openRawResource(resourceId);
FileOutputStream fs = new FileOutputStream(outputFile);
copyTo(resourceStream, fs);
fs.close();
resourceStream.close();
}
private boolean fileExistRoot(String filename) throws Shell.ShellDiedException {
int res = Shell.Pool.SU.run(new String[] { this.busyboxBinary + " stat '" + filename +"'" });
return res == 0;
}
private void moveFileRoot(String filename, String destFilename) throws Exception {
int res = Shell.Pool.SU.run(new String[] { this.busyboxBinary +" mv '"+ filename + "' '" +destFilename +"'"});
if(res != 0){
this.setError("Failed to rename "+filename+" to "+ destFilename);
}
}
private void mkdirAndChmodChown(String directory, int chmod, String chown) throws Shell.ShellDiedException {
Shell.Pool.SU.run(new String[]{
this.busyboxBinary + " mkdir '" + directory +"'",
this.busyboxBinary + " chmod " + String.valueOf(chmod) +" '"+directory+"'",
this.busyboxBinary + " chown " + chown +":"+chown+" '"+directory+"'"
});
}
private void copyChmodAndChown(String srcFile, String dstFile, int chmod, String chown) throws Exception {
int res = Shell.Pool.SU.run(new String[]{
this.busyboxBinary + " cp '" + srcFile +"' '"+dstFile+"'",
this.busyboxBinary + " chmod " + String.valueOf(chmod) +" '"+dstFile+"'",
this.busyboxBinary + " chown " + chown +":"+chown+" '"+dstFile+"'"
});
if(res != 0){
this.setError("Failed to copy & change mode.");
return;
}
}
private void setupBusyBox() throws Exception {
Log.i("INSTALLER","Creating busybox binary");
File tmpFile = new File(ctx.getCacheDir(), "busybox");
tmpFile.createNewFile();
if(tmpFile.setExecutable(true,false)) {
unpackResource(R.raw.busybox, tmpFile);
this.busyboxBinary = tmpFile.getAbsolutePath();
}
else {
this.setError("failed to extract busybox binary.");
return;
}
}
private void generateDeviceFingerprint(String outputFilename) throws FileNotFoundException, UnsupportedEncodingException {
@ -178,16 +101,24 @@ public class Installer extends AsyncTask<Void, Void, Void> {
}
private void backupPsm() throws Exception {
String psmSdcardFolder = new File(Environment.getExternalStorageDirectory(), "psm").getAbsolutePath();
new File(psmSdcardFolder).mkdirs();
String filename = "psm_"+getDateTime();
int res = Shell.Pool.SU.run(new String[]{this.busyboxBinary + " tar c '" + getPsmApp().dataDir + "' -f '" + new File(psmSdcardFolder, filename+".tar").getAbsolutePath()+"'"});
if (res != 0) {
this.setError("Failed to backup existing PSM data. (exit code: " + res + ")");
return;
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());
}
generateDeviceFingerprint(new File(psmSdcardFolder, filename + "_DEV.txt").getAbsolutePath());
}
private void makeDirs() throws PackageManager.NameNotFoundException, Shell.ShellDiedException {
@ -197,14 +128,14 @@ public class Installer extends AsyncTask<Void, Void, Void> {
mkdirAndChmodChown(new File(getPsmApp().dataDir, "databases").getAbsolutePath(), 771, String.valueOf(stringEncryptor.getPsmUid()));
}
private void patchSharedPrefs() throws Exception {
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
// then generate our own shared_prefs
// encrypt the actual strings, username, password, etc
String emailAddress = stringEncryptor.encryptString("nopsmdrm@transrights.lgbt");
@ -275,6 +206,25 @@ public class Installer extends AsyncTask<Void, Void, Void> {
copyChmodAndChown(libraryDbFile, rlibraryDbFile, 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 rdeviceList2 = new File(cacheFolder, "deviceList2.dat").getAbsolutePath();
String cdeviceList2 = new File(ctx.getCacheDir(), "deviceList2.dat").getAbsolutePath();
unpackResource(R.raw.device_list2, new File(cdeviceList2));
copyChmodAndChown(cdeviceList2, rdeviceList2, 660, String.valueOf(stringEncryptor.getPsmUid()));
// extract the additional certified devices list ...
String radditionalCerts = new File(cacheFolder, "addtionalCertifiedDevList.dat").getAbsolutePath();
String cadditionalCerts = new File(ctx.getCacheDir(), "addtionalCertifiedDevList.dat").getAbsolutePath();
unpackResource(R.raw.aditional_certified_devices_list, new File(cadditionalCerts));
copyChmodAndChown(cadditionalCerts, radditionalCerts, 660, String.valueOf(stringEncryptor.getPsmUid()));
}
@Override
protected void onPreExecute() {
Shell.setRedirectDeprecated(false);
@ -285,20 +235,26 @@ public class Installer extends AsyncTask<Void, Void, Void> {
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.show();
}
@Override
protected Void doInBackground(Void... voids) {
try {
setupBusyBox();
Root.setContext(ctx);
if (isPsmInstalled()) {
backupPsm();
makeDirs();
patchSharedPrefs();
installSharedPrefs();
installDeviceList();
installNoPsmDrmModules();
installDatabase();
}
else{
this.setError("PSM app is not installed.");
}
}
catch(Exception e){
this.wasError = true;
@ -309,6 +265,7 @@ public class Installer extends AsyncTask<Void, Void, Void> {
return null;
}
@Override
protected void onPostExecute(Void result) {
dialog.dismiss();
@ -318,24 +275,14 @@ public class Installer extends AsyncTask<Void, Void, Void> {
.setTitle("Error Occurred.")
.setMessage(this.errorMsg)
.setCancelable(false)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).show();
.setPositiveButton("Ok",null).show();
}
else{
new AlertDialog.Builder((Activity)ctx)
.setTitle("Installed!")
.setMessage("Your PSM Application was patched successfully!\nNote: WI-FI has to be turned off for games to work.")
.setMessage("Your PSM Application was patched successfully!\n\nNote: WI-FI has to be turned off for games to work.")
.setCancelable(false)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).show();
.setPositiveButton("Ok", null).show();
}
}
}

View File

@ -0,0 +1,124 @@
package com.psmreborn.nopsmdrm;
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;
import eu.chainfire.libsuperuser.Shell;
public class Root {
private static String busyboxBinary = null;
private static Context ctx = null;
public static boolean fileExistRoot(String filename) throws Shell.ShellDiedException {
Log.i("ROOT", "FileExistRoot: " + filename);
int res = Shell.Pool.SU.run(new String[] { busyboxBinary + " stat '" + filename +"'" });
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 +"'"});
if (res != 0) {
throw new IOException("Failed to tar " + src);
}
}
public static void remountRo(String foldername) throws IOException, Shell.ShellDiedException {
Log.i("ROOT", "Remounting as RO: " + foldername);
int res = Shell.Pool.SU.run(new String[] { busyboxBinary +" mount -o ro,remount '"+foldername+"'"}
);
if(res != 0){
throw new IOException("Failed to remmount as RO: "+foldername);
}
}
public static void remountRw(String foldername) throws IOException, Shell.ShellDiedException {
Log.i("ROOT", "Remounting as RW: " + foldername);
int res = Shell.Pool.SU.run(new String[] { busyboxBinary +" mount -o rw,remount '"+foldername+"'"}
);
if(res != 0){
throw new IOException("Failed to remmount as RW: "+foldername);
}
}
public static void moveFileRoot(String filename, String destFilename) throws IOException, Shell.ShellDiedException {
Log.i("ROOT", "MoveRoot: " + filename + " : "+ destFilename);
int res = Shell.Pool.SU.run(new String[] { busyboxBinary +" mv '"+ filename + "' '" +destFilename +"'"});
if(res != 0){
throw new IOException("Failed to rename "+filename+" to "+ destFilename);
}
}
public static void mkdirAndChmodChown(String directory, int chmod, String chown) throws Shell.ShellDiedException {
Log.i("ROOT", "MkdirAndChown: " + directory);
Shell.Pool.SU.run(new String[]{
busyboxBinary + " mkdir '" + directory +"'",
busyboxBinary + " chmod " + String.valueOf(chmod) +" '"+directory+"'",
busyboxBinary + " chown " + chown +":"+chown+" '"+directory+"'"
});
}
public static void copyChmodAndChown(String srcFile, String dstFile, int chmod, String chown) throws IOException, Shell.ShellDiedException {
Log.i("ROOT", "CopyAndChown: " + srcFile +" : "+dstFile);
int res = Shell.Pool.SU.run(new String[]{
busyboxBinary + " cp '" + srcFile +"' '"+dstFile+"'",
busyboxBinary + " chmod " + String.valueOf(chmod) +" '"+dstFile+"'",
busyboxBinary + " chown " + chown +":"+chown+" '"+dstFile+"'"
});
if(res != 0){
throw new IOException("Failed to copy & change mode.");
}
}
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 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);
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 {
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);
}
else {
throw new IOException("failed to extract busybox binary.");
}
}
busyboxBinary = tmpFile.getAbsolutePath();
}
public static void setContext(Context context) throws IOException {
ctx = context;
setupBusyBox();
}
}

View File

@ -0,0 +1,44 @@
package com.psmreborn.nopsmdrm.pscertified;
public class CertifiedDeviceEntry {
String deviceName = null;
int maxApiVersion = Integer.MAX_VALUE;
int minApiVersion = 0;
public String getDeviceName(){
return deviceName;
}
public int getMinApiVersion(){
return minApiVersion;
}
public int getMaxApiVersion(){
return maxApiVersion;
}
public boolean checkDevice(String device, int osVer){
if(deviceName.equals(device)){
if(osVer < maxApiVersion){
if(osVer > minApiVersion){
return true;
}
}
}
return false;
}
public CertifiedDeviceEntry(String deviceName, int minApiVersion, int maxApiVersion) {
this.deviceName = deviceName;
this.minApiVersion = minApiVersion;
this.maxApiVersion = maxApiVersion;
}
public CertifiedDeviceEntry(String deviceName, int minApiVersion) {
this.deviceName = deviceName;
this.minApiVersion = minApiVersion;
}
public CertifiedDeviceEntry(String deviceName) {
this.deviceName = deviceName;
}
}

View File

@ -0,0 +1,28 @@
package com.psmreborn.nopsmdrm.pscertified;
public class CertifiedDeviceList {
private String manufacturer = null;
private CertifiedDeviceEntry[] deviceEntrys = null;
public String getManufacturer() {
return manufacturer;
}
public CertifiedDeviceEntry[] getCertifiedDeviceEntries() {
return deviceEntrys;
}
public boolean checkDevice(String manufacturer, String device, int osVer){
if(this.manufacturer.equals(manufacturer)){
for(int i = 0; i < deviceEntrys.length; i++){
if(deviceEntrys[i].checkDevice(device, osVer)){
return true;
}
}
}
return false;
}
public CertifiedDeviceList(String manufacturer, CertifiedDeviceEntry[] devices){
this.manufacturer = manufacturer;
this.deviceEntrys = devices;
}
}

View File

@ -0,0 +1,53 @@
package com.psmreborn.nopsmdrm.pscertified;
import android.content.Context;
import android.os.Build;
import java.util.Arrays;
import java.util.HashSet;
public class PlayStationCertified {
private static CertifiedDeviceList[] certifiedDevices = {
new CertifiedDeviceList("Sony", new CertifiedDeviceEntry[] {new CertifiedDeviceEntry("SO-02E"), new CertifiedDeviceEntry("C6602"), new CertifiedDeviceEntry("C6603"), new CertifiedDeviceEntry("C6616"), new CertifiedDeviceEntry("C6606"), new CertifiedDeviceEntry("SOL22"), new CertifiedDeviceEntry("C6502"), new CertifiedDeviceEntry("C6503"), new CertifiedDeviceEntry("C6506"), new CertifiedDeviceEntry("SGP321"), new CertifiedDeviceEntry("SGP312"), new CertifiedDeviceEntry("SGP311"), new CertifiedDeviceEntry("SGP341"), new CertifiedDeviceEntry("SO-03E"), new CertifiedDeviceEntry("SGP351"), new CertifiedDeviceEntry("SO-04E"), new CertifiedDeviceEntry("C5503"), new CertifiedDeviceEntry("C5502"), new CertifiedDeviceEntry("L36h"), new CertifiedDeviceEntry("L35h"), new CertifiedDeviceEntry("M36h"), new CertifiedDeviceEntry("C5303"), new CertifiedDeviceEntry("C5306"), new CertifiedDeviceEntry("C5302"), new CertifiedDeviceEntry("M35h"), new CertifiedDeviceEntry("M35c"), new CertifiedDeviceEntry("C2105"), new CertifiedDeviceEntry("C2104"), new CertifiedDeviceEntry("S36h"), new CertifiedDeviceEntry("C1904"), new CertifiedDeviceEntry("C1905"), new CertifiedDeviceEntry("C2004"), new CertifiedDeviceEntry("C2005"), new CertifiedDeviceEntry("SOL23"), new CertifiedDeviceEntry("C6903"), new CertifiedDeviceEntry("SO-01F"), new CertifiedDeviceEntry("C6906"), new CertifiedDeviceEntry("C6902"), new CertifiedDeviceEntry("C6916"), new CertifiedDeviceEntry("C6833"), new CertifiedDeviceEntry("C6806"), new CertifiedDeviceEntry("C6802"), new CertifiedDeviceEntry("SOL24"), new CertifiedDeviceEntry("SGP412"), new CertifiedDeviceEntry("SO-02F"), new CertifiedDeviceEntry("D5503"), new CertifiedDeviceEntry("SO-04F"), new CertifiedDeviceEntry("C6843"), new CertifiedDeviceEntry("XL39h"), new CertifiedDeviceEntry("M51w"), new CertifiedDeviceEntry("D5303"), new CertifiedDeviceEntry("D5322"), new CertifiedDeviceEntry("D5306"), new CertifiedDeviceEntry("D5316"), new CertifiedDeviceEntry("D5316N"), new CertifiedDeviceEntry("D2303"), new CertifiedDeviceEntry("D2306"), new CertifiedDeviceEntry("D2305"), new CertifiedDeviceEntry("D2302"), new CertifiedDeviceEntry("D2403"), new CertifiedDeviceEntry("D2406"), new CertifiedDeviceEntry("S50h"), new CertifiedDeviceEntry("D6502"), new CertifiedDeviceEntry("D6503"), new CertifiedDeviceEntry("SO-03F"), new CertifiedDeviceEntry("D6543"), new CertifiedDeviceEntry("SOL25"), new CertifiedDeviceEntry("D6563"), new CertifiedDeviceEntry("SGP541"), new CertifiedDeviceEntry("SGP521"), new CertifiedDeviceEntry("SO-05F"), new CertifiedDeviceEntry("SOT21"), new CertifiedDeviceEntry("SGP551"), new CertifiedDeviceEntry("SGP511"), new CertifiedDeviceEntry("SGP512"), new CertifiedDeviceEntry("D6542"), new CertifiedDeviceEntry("M35t"), new CertifiedDeviceEntry("M35ts"), new CertifiedDeviceEntry("SO-01C"), new CertifiedDeviceEntry("SO-02C"), new CertifiedDeviceEntry("SO-02D"), new CertifiedDeviceEntry("SO-03D"), new CertifiedDeviceEntry("IS12S"), new CertifiedDeviceEntry("LT26i") }), new CertifiedDeviceList("Sony Ericsson", new CertifiedDeviceEntry[] { new CertifiedDeviceEntry("R800i"), new CertifiedDeviceEntry("R800a"), new CertifiedDeviceEntry("R800x"), new CertifiedDeviceEntry("R800at") }),
new CertifiedDeviceList("HTC", new CertifiedDeviceEntry[] { new CertifiedDeviceEntry("primou", 15) }),
new CertifiedDeviceList("SHARP", new CertifiedDeviceEntry[] { new CertifiedDeviceEntry("SH09D", 15), new CertifiedDeviceEntry("SHI16", 15) , new CertifiedDeviceEntry("SBM106SH", 15) , new CertifiedDeviceEntry("SBM203SH", 16) }),
new CertifiedDeviceList("FUJITSU MOBILE COMMUNICATIONS LIMITED", new CertifiedDeviceEntry[] { new CertifiedDeviceEntry("F05E", 15) }),
};
private Context ctx;
public PlayStationCertified(Context context){
ctx = context;
}
private boolean isInDeviceList() {
String brand = Build.BRAND;
String manufacturer = Build.MANUFACTURER;
int osVer = Build.VERSION.SDK_INT;
for(int i = 0; i < certifiedDevices.length; i++){
if(certifiedDevices[i].checkDevice(manufacturer, brand, osVer)){
return true;
}
}
return false;
}
public boolean isPlaystationCertified() {
// check for signature file
HashSet installedFrameworks = new HashSet(Arrays.asList(ctx.getPackageManager().getSystemSharedLibraryNames()));
if(installedFrameworks.contains("com.playstation.playstationcertified")){
return true;
}
else {
// check devList2 and additionalCertifiedDevList
return isInDeviceList();
}
}
}

View File

@ -0,0 +1,104 @@
package com.psmreborn.nopsmdrm.pscertified;
import static com.psmreborn.nopsmdrm.Root.*;
import com.psmreborn.nopsmdrm.MainActivity;
import com.psmreborn.nopsmdrm.NoPsmDrmInstaller;
import com.psmreborn.nopsmdrm.R;
import com.psmreborn.nopsmdrm.Root;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.PowerManager;
import java.io.File;
import java.io.IOException;
import eu.chainfire.libsuperuser.Shell;
public class PsCertificatesInstaller extends AsyncTask<Void, Void, Void> {
private ProgressDialog dialog = null;
private boolean wasError = false;
private String errorMsg = "";
Context ctx = null;
public void installPlaystationCertification() throws IOException, Shell.ShellDiedException {
// remount /system as read-write
remountRw("/system");
String cpsCertifiedPerms = new File(ctx.getCacheDir(), "com.playstation.playstationcertified.xml").getAbsolutePath();
String cpsCertifiedjar = new File(ctx.getCacheDir(), "com.playstation.playstationcertified.jar").getAbsolutePath();
unpackResource(R.raw.ps_certified_permission, new File(cpsCertifiedPerms));
unpackResource(R.raw.ps_certified_jar, new File(cpsCertifiedjar));
String rpsCertifiedPerms = "/system/etc/permissions/com.playstation.playstationcertified.xml";
String rpsCertifiedJar = "/system/framework/com.playstation.playstationcertified.jar";
copyChmodAndChown(cpsCertifiedPerms, rpsCertifiedPerms, 644, "root");
copyChmodAndChown(cpsCertifiedjar, rpsCertifiedJar, 644, "root");
// make it read-only again.
remountRo("/system");
}
public PsCertificatesInstaller(Context context) {
this.ctx = context;
}
@Override
protected void onPreExecute() {
Shell.setRedirectDeprecated(false);
dialog = new ProgressDialog(ctx);
dialog.setTitle("Installing PlayStation Certificates ...");
dialog.setMessage("Please Wait ...");
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.show();
}
@Override
protected Void doInBackground(Void... voids) {
try {
Root.setContext(ctx);
installPlaystationCertification();
}
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 device is now \"Playstation Certified\"\n(You may have to reboot for changes to take effect)\n\nWould you like to patch the PSM application also?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
(new NoPsmDrmInstaller(PsCertificatesInstaller.this.ctx)).execute();
}
})
.setNegativeButton("No", null).show();
}
}
}

View File

@ -7,6 +7,7 @@
android:paddingRight="10dp"
android:paddingBottom="10dp"
android:keepScreenOn="true"
android:noHistory="true"
android:orientation="vertical">
<Button

View File

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<deviceTypeList>
<deviceType manufacturer="Sony">
<device>SO-02E</device>
<device>C6602</device>
<device>C6603</device>
<device>C6616</device>
<device>C6606</device>
<device>SOL22</device>
<device>C6502</device>
<device>C6503</device>
<device>C6506</device>
<device>SGP321</device>
<device>SGP312</device>
<device>SGP311</device>
<device>SGP341</device>
<device>SO-03E</device>
<device>SGP351</device>
<device>SO-04E</device>
<device>C5503</device>
<device>C5502</device>
<device>L36h</device>
<device>L35h</device>
<device>M36h</device>
<device>C5303</device>
<device>C5306</device>
<device>C5302</device>
<device>M35h</device>
<device>M35c</device>
<device>C2105</device>
<device>C2104</device>
<device>S36h</device>
<device>C1904</device>
<device>C1905</device>
<device>C2004</device>
<device>C2005</device>
<device>SOL23</device>
<device>C6903</device>
<device>SO-01F</device>
<device>C6906</device>
<device>C6902</device>
<device>C6916</device>
<device>C6833</device>
<device>C6806</device>
<device>C6802</device>
<device>SOL24</device>
<device>SGP412</device>
<device>SO-02F</device>
<device>D5503</device>
<device>SO-04F</device>
<device>C6843</device>
<device>XL39h</device>
<device>M51w</device>
<device>D5303</device>
<device>D5322</device>
<device>D5306</device>
<device>D5316</device>
<device>D5316N</device>
<device>D2303</device>
<device>D2306</device>
<device>D2305</device>
<device>D2302</device>
<device>D2403</device>
<device>D2406</device>
<device>S50h</device>
<device>D6502</device>
<device>D6503</device>
<device>SO-03F</device>
<device>D6543</device>
<device>SOL25</device>
<device>D6563</device>
<device>SGP541</device>
<device>SGP521</device>
<device>SO-05F</device>
<device>SOT21</device>
<device>SGP551</device>
<device>SGP511</device>
<device>SGP512</device>
<device>D6542</device>
<device>M35t</device>
<device>M35ts</device>
</deviceType>
<deviceType manufacturer="Sony Ericsson">
<device>R800i</device>
<device>R800a</device>
<device>R800x</device>
<device>R800at</device>
</deviceType>
<deviceType manufacturer="HTC">
<device minOsVer="15">primou</device>
</deviceType>
<deviceType manufacturer="SHARP">
<device minOsVer="15">SH09D</device>
<device minOsVer="15">SHI16</device>
<device minOsVer="15">SBM106SH</device>
<device minOsVer="16">SBM203SH</device>
</deviceType>
<deviceType manufacturer="FUJITSU MOBILE COMMUNICATIONS LIMITED">
<device minOsVer="15">F05E</device>
</deviceType>
</deviceTypeList>
<!--IH2NqWYfjPb8fOTnZCSi+BBRagVwCa8qTD/oaKC050fLLSQaMwXPdPTkNYzOOBXpL/dYPXxIrBvW
9oUqLa45PBvM8njSCJX5EnefmDabLTY9Gc6VxK6O0V/GX3/lBqCyCEo21gMu3mweqEfc4B1z6QIQ
4+r2MBu10B6V4RrC/4h18nc2mpwsgfqSrbJJeBcqLRXGFLopx4TYzRO6vNtzm0XvXIWAz/S52rd5
e01km+Cishl0Q3/kpBS9alYDulw/Nl4LUXFFeapwV2+XYdvK2vWxwGwvgWGidtn1MLc+uH+ezqbm
Zew3lqKjP8TOECewEpMlX4rn9hzKYfGvj2YQaw==
-->

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<deviceTypeList>
<deviceType name="PLAY" nsx="PN.XPERIA">
<device brand="SEMC" maxOsVer="10">R800i</device>
<device brand="SEMC" maxOsVer="10">R800a</device>
<device brand="verizon" maxOsVer="10">R800x</device>
<device brand="AT&amp;T" maxOsVer="10">R800at</device>
<device brand="docomo" maxOsVer="10">SO-01D</device>
</deviceType>
<deviceType name="M001" nsx="PN.XPERIA">
<device brand="docomo" maxOsVer="10">SO-01C</device>
<device brand="docomo" maxOsVer="10">SO-02C</device>
<device brand="kddi" maxOsVer="10">IS11S</device>
</deviceType>
<deviceType name="M002" nsx="PN.XPERIA">
<device brand="docomo" maxOsVer="10">SO-02D</device>
<device brand="docomo" maxOsVer="10">SO-03D</device>
<device brand="kddi" maxOsVer="10">IS12S</device>
<device brand="SEMC" maxOsVer="10">LT26i</device>
<device brand="SEMC" maxOsVer="10">LT28at</device>
</deviceType>
<deviceType name="M002X" nsx="PN.XPERIA">
<device brand="docomo" minOsVer="15">SO-02D</device>
<device brand="docomo" minOsVer="15">SO-03D</device>
<device brand="kddi" minOsVer="15">IS12S</device>
<device brand="SEMC" minOsVer="15">LT26i</device>
<device brand="tmobile_gb" minOsVer="15">LT26i</device>
<device brand="orange_es" minOsVer="15">LT26i</device>
<device brand="orange_fr" minOsVer="15">LT26i</device>
<device brand="orange_gb" minOsVer="15">LT26i</device>
<device brand="SEMC" minOsVer="15">LT28at</device>
</deviceType>
</deviceTypeList>
<!--C5RBqjaW5yey4MXAPVoy9gHLzI5enFydm5LOoPadv2jmSoLI9hwyX7mpvmRT/slPnXttJAzJps1s
nVNqQUrR0AuTBWaKLh8O6WbnaZm4vmtanhbLSIUjF44mVYKaRh0qGGVnUf0pZyq44dZjozNWMVDj
viz916kNsbmAeq/CqVEX61DS/oHD66IKlVbfSefw5jGzzfJAx/L2YuUYSiNy/FwlLHYEiNb+8mDK
xxOQbt0ytr/A8JXm8sRYM8oqrsS5POfgS6Ir8awwc20SYbwIbPK9fouzlg7FzBmtZK9yhUbDiUVH
qFE+aoBiF5klOF9lk569L7pkEsu4Drhg366CGQ==
-->

Binary file not shown.

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2011 Sony Computer Entertainment Inc.
All Rights Reserved.
-->
<permissions>
<library name="com.playstation.playstationcertified"
file="/system/framework/com.playstation.playstationcertified.jar"/>
</permissions>