Discuss Android apps here.
Jul 28th, 2013, 1:08 pm
Greetings fellow developers,

I have been trying the Xposed Framework recently, and had the idea to use it to crack apps without having to modify the original APK, making updates from the store possible, yet have the apps always work as registered/pro/etc.

Here is a small description from the Xposed Framework developer, which you can find easily with google, project is on GitHub and XDA
Some technical details:
I extended the /system/bin/app_process executable to load a JAR file on startup. The classes of this file will sit in every process (including the one for system services) and can act with their powers. And even more: I have implemented something that allows developers to replace any method in any class (may it be in the framework, systemui or a custom app). This makes Xposed very powerful. You can change parameters for the method call, modify the return value or skip the call to the method completely - it's all up to you! Also replacing or adding resources is easy.


I started with the XPrivacy app, by making it believe it is Pro (viewtopic.php?p=1496629#1496629).

In this case, the app needs a separate keyfile, so I wrote a new android app which has the same package name as the pro key, and made it simulate the response the main app waits for.
But in addition to checking for an extra package, the app checks if it's signature is the same as the app itself, and this is done in a method called "isProInstalled" with boolean response.

To crack this check, I wrote an Xposed module that hooks to the main app, and replaces the isProInstalled method with an empty method that responds always with "true".

Code: Select allpublic class Cracker implements IXposedHookLoadPackage {

   @Override
   public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
      
      String packageName = "biz.bokhorst.xprivacy";
      
      if (!lpparam.packageName.equals(packageName)) {
         return;
      }
      
      try {
         String className = packageName + ".Util";
         XposedBridge.log("Now hooking method isProInstalled(Context)");
         findAndHookMethod(className, lpparam.classLoader, "isProInstalled", Context.class, XC_MethodReplacement.returnConstant(true));
         
      } catch (Throwable t) {
         XposedBridge.log(t);
      }
   }
      
}


With this module installed and active, the app will be always activated with the Pro features without the need to patch or re-sign the original APK to make both apps have the same license.

After this, I started investigating methods to patch the Android system wide checkSignature(Str, Str) method, and I managed to do so.

Code: Select allpublic class customPackageManager implements IXposedHookZygoteInit {

   public static final String[] appsList = new String[] {
      "biz.bokhorst.xprivacy",
      "other.package.names.1",
      "other.package.names.2"
      };

   @Override
   public void initZygote(StartupParam startupParam) throws Throwable {
      
      try {
         final Class<?> clsPMS = findClass("com.android.server.pm.PackageManagerService", customPackageManager.class.getClassLoader());
         
         // Hooking class PackageManager.checkSignatures(String pkg1, String pkg2)
         XposedBridge.log("[crackedPackageManager] Hooking class PackageManager.checkSignatures");
         
         findAndHookMethod(clsPMS, "checkSignatures", String.class, String.class, new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
               int result = (Integer) param.getResult();
               
               String pkg1 = (String) param.args[0];
               if (Arrays.asList(appsList).contains(pkg1)) {
                  XposedBridge.log("[crackedPackageManager] Package 1: " + pkg1);
                  
                  String pkg2 = (String) param.args[1];
                  XposedBridge.log("[crackedPackageManager] Package 2: " + pkg2);
                  
                  XposedBridge.log("[crackedPackageManager] Original checkSignatures value: " + result);

                  // Only in case signature does not match (-3), make it 0, otherwise leave alone
                  // because -4 means package not found, and will casue FC for some apps
                  if (result == PackageManager.SIGNATURE_NO_MATCH) {
                     result = PackageManager.SIGNATURE_MATCH;
                  }
                  XposedBridge.log("[crackedPackageManager] New checkSignatures value: " + result);
               }
               
               param.setResult(result);
            }
         });
         
      } catch (Throwable t) {
         XposedBridge.log(t);
      }
   }

}


the string array contains the package names that will receive a fake result when the checkSignatures is called, for all the rest the result remain unchanged.
With this Xposed module installed and active, I can simply create an empty android application with the package name equal to the package name of the key/pro, and the checkSignature will detect it as a valid one.

I used this method to crack a couple of apps for personal use, but I thought I would release the info for others to use.

of course the end users will need to have the Xposed framework installer on their devices, otherwise nothing will work.

Any feedback is welcome...
Jul 28th, 2013, 1:08 pm