0

I'm from the sysadmin side of the IT and have not much experience in programing.

I have an app that lets me screen share Android apps on my car's display. Sadly there is a whitelist baked into the app, which prevents other apps (e.g. NewPipe) from running. I tought I would try reversing it. The modification of the whitelist is easy (.json) but there is some checksuming of the whitelist involved.

I did a decompilation with jadx-gui and backsmali, tried to modify the smali code and recompile it again. I did not know what exactly to change in the smali code, because I am not really familiar with it. The method was try and error, but I always got errors. So I thought I could alter the checksum for my modifyed whitelist, but that also did not work as intended.

I have extracted the code to run locally but the hash of the original file does not match the one, compiled into the apk and I'm not shure why

This is the jadx-gui reversed code snipped (exceptions removed):

    private boolean j() {
    InputStream inputStream = null;
    try {
        if (!"whitelist/whitelist".equals("whitelist/whitelist")) {
            throw new IllegalArgumentException("the whitelist path has to be \"whitelist/whitelist\", to access the dexguard encrypted file.");
        }
        InputStream open = this.b.getAssets().open("whitelist/whitelist");
        byte[] bArr = new byte[ACRAConstants.DEFAULT_BUFFER_SIZE_IN_BYTES];
        MessageDigest instance = MessageDigest.getInstance("SHA-256");
        while (true) {
            int read = open.read(bArr);
            if (read <= 0) {
                break;
            }
            instance.update(bArr, 0, read);
        }
        if (!String.format("%64s", new BigInteger(1, instance.digest()).toString(16)).replace(' ', '0').equals(this.b.getString(o.h.whitelist_checksum))) {
            Log.e("MS-LL:LiveServiceFact.", "Invalid whitelist!");
            if (open != null) {
                try {
                    open.close();
                } catch (IOException e2) {
                }
            }
            return false;
        } else if (open == null) {
            return true;
        } else {
            try {
                open.close();
                return true;
            } catch (IOException e3) {
                return true;
            }
        }

The ACRAConstants.DEFAULT_BUFFER_SIZE_IN_BYTES is 8192 and the o.h.whitelist_checksum is 2131689879, which is not a SHA-256 string.
My checksum checker looks like this:

import java.io.File;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

class checksum {

public static void main(String[] args) {
    try {
        InputStream inputStream = null;
        File file = new File("whitelist");
        int DEFAULT_BUFFER_SIZE_IN_BYTES = 8192;
        int whitelist_checksum = 2131689879;

        if (!"whitelist/whitelist".equals("whitelist/whitelist")) {
            throw new IllegalArgumentException("the whitelist path has to be \"whitelist/whitelist\", to access the dexguard encrypted file.");
        }
        InputStream open = new FileInputStream(file);
        byte[] bArr = new byte[DEFAULT_BUFFER_SIZE_IN_BYTES];
        MessageDigest instance = MessageDigest.getInstance("SHA-256");
        while (true) {
            int read = open.read(bArr);
            if (read <= 0) {
                break;
            }
            instance.update(bArr, 0, read);
        }
        System.out.println(String.format("%64s", new BigInteger(1, instance.digest()).toString(16)).replace(' ', '0'));
        if (!String.format("%64s", new BigInteger(1, instance.digest()).toString(16)).replace(' ', '0').equals(Integer.toString(whitelist_checksum))) {
            System.out.println("Invalid whitelist!");
        } else {
            System.out.println("correct whitelist!");
        }
    }
    catch (FileNotFoundException ex){System.out.println("File not found");}
    catch (NoSuchAlgorithmException ex){System.out.println("Algorythm not found");}
    catch (IOException ex){System.out.println("IOException");}
}
}

But gives me d9821f5190db1b21aabc58da45a802b529148bb8a952760c0ca4a6330817f174 as checksum of the extracted whitelist and not 2131689879. Where am I missing something?

Thanks in advance, Simon

4
  • this.b.getString(o.h.whitelist_checksum) hints on getString(int). Look for String resources instead. – Andrew T. Jun 16 at 8:41
  • Smali code may be a bit "bloated" compared to Java but modifying it is easy. You just have to identify the if statement that branches on the result of the equals comparison. Usually this should be an if-nez or if-eqz . Depending on if you want to keep the if or the else part just comment out that line or replace it with an goto and delete the parameter from the if (only leave the jump target). That disables the SHA-checking of the whitelist. – Robert Jun 16 at 13:26
  • @AndrewT. I was able to find the checksum sting in the resources. Sadly I have used text search to find it and was not able to find out how 2131689879 leads to resource.arsc/res/values/strings.xml. But I get the Idea of it. @Robert I did try to remove every if in the smali j() method one after another, but it did not work. Would be cool to remove the checksumming, but replace the string also works. – Simon Sutter Jun 17 at 18:58
  • Do not just remove all if commands, only remove the one you want to skip. Jadx provides both Java and Smali view, switch between them and map Java code to Smali code do identify which if statement to modify (remove or replace with permanent branch). The BigInteger usage should be a good place to start as it is close to the conditional branch and it is only used right before that point. – Robert Jun 23 at 11:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.