CalebFenton / simplify

Android virtual machine and deobfuscator
Other
4.43k stars 439 forks source link

issue running against GE application APK #88

Open thehesiod opened 6 years ago

thehesiod commented 6 years ago

Got the following error:

19:08:37.893 WARN  InvokeOp     - Unhandled virtual exception: java.lang.NullPointerException: Name is null
19:08:37.896 WARN  MethodReflector - Failed to reflect Ljava/lang/Enum;-><init>(Ljava/lang/String;I)V: Name is null
19:08:37.896 ERROR NodeExecutor - ExecutionNode{signature=Lc/x;-><init>(Ljava/lang/String;ILjava/lang/String;)V, op=invoke-direct {r0, r1, r2}, Ljava/lang/Enum;-><init>(Ljava/lang/String;I)V, @=0} unhandled virtual exception: {}
java.lang.NullPointerException: Name is null
    at java.lang.Enum.valueOf(Enum.java:236)
    at org.cf.smalivm.MethodReflector.invoke(MethodReflector.java:138)
    at org.cf.smalivm.MethodReflector.reflect(MethodReflector.java:39)
    at org.cf.smalivm.opcode.InvokeOp.executeNonLocalMethod(InvokeOp.java:450)
    at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:103)
    at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:52)
    at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:77)
    at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
    at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:103)
    at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:82)
    at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:347)
    at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:140)
    at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:52)
    at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:77)
    at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
    at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:103)
    at org.cf.smalivm.context.ExecutionContext.staticallyInitializeClassIfNecessary(ExecutionContext.java:205)
    at org.cf.smalivm.context.ExecutionContext.readClassState(ExecutionContext.java:132)
    at org.cf.smalivm.StaticFieldAccessor.getLocalField(StaticFieldAccessor.java:32)
    at org.cf.smalivm.StaticFieldAccessor.getField(StaticFieldAccessor.java:27)
    at org.cf.smalivm.opcode.SGetOp.execute(SGetOp.java:39)
    at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:52)
    at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:77)
    at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
    at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:103)
    at org.cf.smalivm.context.ExecutionContext.staticallyInitializeClassIfNecessary(ExecutionContext.java:205)
    at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:96)
    at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:82)
    at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:347)
    at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:140)
    at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:52)
    at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:77)
    at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
    at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:103)
    at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:82)
    at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:347)
    at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:140)
    at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:52)
    at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:77)
    at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
    at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:103)
    at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:82)
    at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:347)
    at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:140)
    at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:52)
    at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:77)
    at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
    at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:103)
    at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:82)
    at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:347)
    at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:140)
    at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:52)
    at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:77)
    at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
    at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:103)
    at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:82)
    at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:347)
    at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:140)
    at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:52)
    at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:77)
    at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
    at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:103)
    at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:64)
    at org.cf.simplify.Launcher.executeClass(Launcher.java:185)
    at org.cf.simplify.Launcher.run(Launcher.java:149)
    at org.cf.simplify.Main.main(Main.java:14)
thehesiod commented 6 years ago

some others like:

19:08:37.786 ERROR NodeExecutor - ExecutionNode{signature=Lcom/ge/commonframework/c/d;->a(Ljava/security/KeyStore;)Ljava/util/HashMap;, op=invoke-virtual {r5}, Ljava/security/KeyStore;->aliases()Ljava/util/Enumeration;, @=5} unhandled virtual exception: {}
java.lang.NullPointerException: null
CalebFenton commented 6 years ago

I'll need the file hash and how you executed simplify at minimum to reproduce. File would be better.

thehesiod commented 6 years ago

I'm using this: https://apkpure.com/kitchen-ge-appliances/com.ge.kitchen. Thanks for looking into this! Really looking forward to seeing the output from this tool!

CalebFenton commented 6 years ago

I'll also need how you executed simplify at minimum to reproduce.

While this is a valid issue, and is probably surfacing a valid bug, simplify is unlikely to help you because the app simply isn't obfuscated. This tool is mostly for hostile sample analysis. It's 99% of the time not useful for "whatever" you want to do with a commercial app.

thehesiod commented 6 years ago

this app does appear to use string obfuscation. I simply ran:

unzip GE_Appliances_v1.0.6.3.apk
java -jar ./simplify/build/libs/simplify.jar classes.dex
CalebFenton commented 6 years ago

Can you point out a class which uses string encryption? That should be simplify-able.

thehesiod commented 6 years ago

I'm a newbie at this, but see com.ge.commonframework.c.c (array of base64 that decodes to binary), used in com.ge.commonframework.https.HttpsOAuthConnect.initSSLContext. Another suspicious string in com.ge.commonframework.dataModel.XMPPCredential where all the values are BuildConfig.FLAVOR.

CalebFenton commented 6 years ago

The array of base64 encoded strings looks like a certificate. It's used in Lcom/ge/commonframework/c/b;->a(Ljava/security/cert/X509Certificate;)Z to verify if the cert is trusted. If they're cert contents, they're not really encrypted and can't be decrypted.

The XMPPCredential stuff are all empty strings. If you're seeing the value as BuildConfig;->FLAVOR it may because that's also an empty string and the decompiler (JEB?) is making a best guess. It looks like the initializer with all of the password, port, etc. parameters is never called and those values only get set by calling setter methods from Lcom/ge/commonframework/xmlParsers/XMPPCredentialParserHandler;. The values appear to be pulled from an XML which isn't in the APK.

You might get a better understanding of what this app is doing by installing it and monitoring traffic. There are ways to disable cert pinning, both at the framework level and by modifying the app, and there are ways to monitor HTTPS traffic without cert pinning. I don't want to discuss the details of this process for any specific non-malware samples here though.

thehesiod commented 6 years ago

thanks for your help! Ya I did SSL monitoring and they check for MITM so ya I'll have to figure a way to disable that. Closing issue since fixing this issue won't help me.

CalebFenton commented 6 years ago

If you don't mind, I'm going to leave this open since I have everything to repro and it's probably a legit bug.

CalebFenton commented 6 years ago

Also, to disable cert pinning, check out https://github.com/Fuzion24/JustTrustMe

CalebFenton commented 5 years ago

The problem is the Lc/x; class is an Enum with an unusual <init>. Enums normally have a <clinit> that assigns some literals to instance fields, e.g. this.MONDAY = "Monday". Smalivm doesn't handle instance members, so it does some simple analysis which looks for constant strings and then the next iput which sets the instance field. This works in most cases, but in this case there's a custom initializer.

A more general fix would be to somehow execute the <clinit> method, get the fields initialized, and then make the mapping between strings and field names from that. The current method could be used as a fallback if <clinit> execution fails.

I'm thinking this isn't a common problem, so I'm going to prioritize other fixes until something changes or there's nothing else to work on.

thehesiod commented 5 years ago

Cool. Hopefully can get back to this soon. Right now in google API hell :)