simplify
simplify copied to clipboard
issue running against GE application APK
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)
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
I'll need the file hash and how you executed simplify at minimum to reproduce. File would be better.
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!
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.
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
Can you point out a class which uses string encryption? That should be simplify-able.
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.
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.
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.
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.
Also, to disable cert pinning, check out https://github.com/Fuzion24/JustTrustMe
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.
Cool. Hopefully can get back to this soon. Right now in google API hell :)