Coder Social home page Coder Social logo

calebfenton / simplify Goto Github PK

View Code? Open in Web Editor NEW
4.4K 135.0 438.0 101.13 MB

Android virtual machine and deobfuscator

License: Other

Shell 0.02% Java 77.68% Smali 19.72% Kotlin 2.58%
deobfuscation java optimization android reverse-engineering malware-analysis dalvik malware deobfuscator virtual-machine

simplify's Introduction

Simplify

Build Status Coverage Status Coverity Scan Build Status

Generic Android Deobfuscator

Simplify virtually executes an app to understand its behavior and then tries to optimize the code so that it behaves identically but is easier for a human to understand. Each optimization type is simple and generic, so it doesn't matter what the specific type of obfuscation is used.

Before and After

The code on the left is a decompilation of an obfuscated app, and the code on the right has been deobfuscated.

Lots of method calls, no clear meaning Wow, such literal, much meaning

Overview

There are three parts to the project: smalivm, simplify, and the demo app.

  1. smalivm: Provides a virtual machine sandbox for executing Dalvik methods. After executing a method, it returns a graph containing all possible register and class values for every execution path. It works even if some values are unknown, such as file and network I/O. For example, any if or switch conditional with an unknown value results in both branches being taken.
  2. simplify: Analyzes the execution graphs from smalivm and applies optimizations such as constant propagation, dead code removal, unreflection, and some peephole optimizations. These are fairly simple, but when applied together repeatedly, they'll decrypt strings, remove reflection, and greatly simplify code. It does not rename methods and classes.
  3. demoapp: Contains simple, heavily commented examples for using smalivm in your own project. If you're building something that needs to execute Dalvik code, check it out.

Usage

usage: java -jar simplify.jar <input> [options]
deobfuscates a dalvik executable
 -et,--exclude-types <pattern>   Exclude classes and methods which include REGEX, eg: "com/android", applied after include-types
 -h,--help                       Display this message
 -ie,--ignore-errors             Ignore errors while executing and optimizing methods. This may lead to unexpected behavior.
    --include-support            Attempt to execute and optimize classes in Android support library packages, default: false
 -it,--include-types <pattern>   Limit execution to classes and methods which include REGEX, eg: ";->targetMethod\("
    --max-address-visits <N>     Give up executing a method after visiting the same address N times, limits loops, default: 10000
    --max-call-depth <N>         Do not call methods after reaching a call depth of N, limits recursion and long method chains, default: 50
    --max-execution-time <N>     Give up executing a method after N seconds, default: 300
    --max-method-visits <N>      Give up executing a method after executing N instructions in that method, default: 1000000
    --max-passes <N>             Do not run optimizers on a method more than N times, default: 100
 -o,--output <file>              Output simplified input to FILE
    --output-api-level <LEVEL>   Set output DEX API compatibility to LEVEL, default: 15
 -q,--quiet                      Be quiet
    --remove-weak                Remove code even if there are weak side effects, default: true
 -v,--verbose <LEVEL>            Set verbosity to LEVEL, default: 0

Building

Building requires the Java Development Kit 8 (JDK) to be installed.

Because this project contains submodules for Android frameworks, either clone with --recursive:

git clone --recursive https://github.com/CalebFenton/simplify.git

Or update submodules at any time with:

git submodule update --init --recursive

Then, to build a single jar which contains all dependencies:

./gradlew fatjar

The Simplify jar will be in simplify/build/libs/. You can test it's working by simplifying the provided obfuscated example app. Here's how you'd run it (you may need to change simplify.jar):

java -jar simplify/build/libs/simplify.jar -it "org/cf/obfuscated" -et "MainActivity" simplify/obfuscated-app.apk

To understand what's getting deobfuscated, check out Obfuscated App's README.

Troubleshooting

If Simplify fails, try these recommendations, in order:

  1. Only target a few methods or classes by using -it option.
  2. If failure is because of maximum visits exceeded, try using higher --max-address-visits, --max-call-depth, and --max-method-visits.
  3. Try with -v or -v 2 and report the issue with the logs and a hash of the DEX or APK.
  4. Try again, but do not break eye contact. Simplify can sense fear.

If building on Windows, and building fails with an error similar to:

Could not find tools.jar. Please check that C:\Program Files\Java\jre1.8.0_151 contains a valid JDK installation.

This means Gradle is unable to find a proper JDK path. Make sure the JDK is installed, set the JAVA_HOME environment variable to your JDK path, and make sure to close and re-open the command prompt you use to build.

Contributing

Don't be shy. I think virtual execution and deobfuscation are fascinating problems. Anyone who's interested is automatically cool and contributions are welcome, even if it's just to fix a typo. Feel free to ask questions in the issues and submit pull requests.

Reporting Issues

Please include a link to the APK or DEX and the full command you're using. This makes it much easier to reproduce (and thus fix) your issue.

If you can't share the sample, please include the file hash (SHA1, SHA256, etc).

Optimization Strategies

Constant Propagation

If an op places a value of a type which can be turned into a constant such as a string, number, or boolean, this optimization will replace that op with the constant. For example:

const-string v0, "VGVsbCBtZSBvZiB5b3VyIGhvbWV3b3JsZCwgVXN1bC4="
invoke-static {v0}, Lmy/string/Decryptor;->decrypt(Ljava/lang/String;)Ljava/lang/String;
# Decrypts to: "Tell me of your homeworld, Usul."
move-result v0

In this example, an encrypted string is decrypted and placed into v0. Since strings are "constantizable", the move-result v0 can be replaced with a const-string:

const-string v0, "VGVsbCBtZSBvZiB5b3VyIGhvbWV3b3JsZCwgVXN1bC4="
invoke-static {v0}, Lmy/string/Decryptor;->decrypt(Ljava/lang/String;)Ljava/lang/String;
const-string v0, "Tell me of your homeworld, Usul."

Dead Code Removal

Code is dead if removing it cannot possibly alter the behavior of the app. The most obvious case is if the code is unreachable, e.g. if (false) { // dead }). If code is reachable, it may be considered dead if it doesn't affect any state outside of the method, i.e. it has no side effect. For example, code may not affect the return value for the method, alter any class variables, or perform any IO. This is a difficult to determine in static analysis. Luckily, smalivm doesn't have to be clever. It just stupidly executes everything it can and assumes there are side effects if it can't be sure. Consider the example from Constant Propagation:

const-string v0, "VGVsbCBtZSBvZiB5b3VyIGhvbWV3b3JsZCwgVXN1bC4="
invoke-static {v0}, Lmy/string/Decryptor;->decrypt(Ljava/lang/String;)Ljava/lang/String;
const-string v0, "Tell me of your homeworld, Usul."

In this code, the invoke-static no longer affects the return value of the method and let's assume it doesn't do anything weird like write bytes to the file system or a network socket so it has no side effects. It can simply be removed.

const-string v0, "VGVsbCBtZSBvZiB5b3VyIGhvbWV3b3JsZCwgVXN1bC4="
const-string v0, "Tell me of your homeworld, Usul."

Finally, the first const-string assigns a value to a register, but that value is never used, i.e. the assignment is dead. It can also be removed.

const-string v0, "Tell me of your homeworld, Usul."

Huzzah!

Unreflection

One major challenge with static analysis of Java is reflection. It's just not possible to know the arguments are for reflection methods without doing careful data flow analysis. There are smart, clever ways of doing this, but smalivm does it by just executing the code. When it finds a reflected method invocation such as:

invoke-virtual {v0, v1, v2}, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;

It can know the values of v0, v1, and v2. If it's sure what the values are, it can replace the call to Method.invoke() with an actual non-reflected method invocation. The same applies for reflected field and class lookups.

Peephole

For everything that doesn't fit cleanly into a particular category, there's peephole optimizations. This includes removing useless check-cast ops, replacing Ljava/lang/String;-><init> calls with const-string, and so on.

Deobfuscation Example

Before Optimization

.method public static test1()I
    .locals 2

    new-instance v0, Ljava/lang/Integer;
    const/4 v1, 0x1
    invoke-direct {v0, v1}, Ljava/lang/Integer;-><init>(I)V

    invoke-virtual {v0}, Ljava/lang/Integer;->intValue()I
    move-result v0

    return v0
.end method

All this does is v0 = 1.

After Constant Propagation

.method public static test1()I
    .locals 2

    new-instance v0, Ljava/lang/Integer;
    const/4 v1, 0x1
    invoke-direct {v0, v1}, Ljava/lang/Integer;-><init>(I)V

    invoke-virtual {v0}, Ljava/lang/Integer;->intValue()I
    const/4 v0, 0x1

    return v0
.end method

The move-result v0 is replaced with const/4 v0, 0x1. This is because there is only one possible return value for intValue()I and the return type can be made a constant. The arguments v0 and v1 are unambiguous and do not change. That is to say, there's a consensus of values for every possible execution path at intValue()I. Other types of values that can be turned into constants:

  • numbers - const/4, const/16, etc.
  • strings - const-string
  • classes - const-class

After Dead Code Removal

.method public static test1()I
    .locals 2

    const/4 v0, 0x1

    return v0
.end method

Because the code above const/4 v0, 0x1 does not affect state outside of the method (no side-effects), it can be removed without changing behavior. If there was a method call that wrote something to the file system or network, it couldn't be removed because it affects state outside the method. Or if test()I took a mutable argument, such as a LinkedList, any instructions that accessed it couldn't be considered dead.

Other examples of dead code:

  • unreferenced assignments - assigning registers and not using them
  • unreached / unreachable instructions - if (false) { dead_code(); }

License

This tool is available under a dual license: a commercial one suitable for closed source projects and a GPL license that can be used in open source software.

Depending on your needs, you must choose one of them and follow its policies. A detail of the policies and agreements for each license type are available in the LICENSE.COMMERCIAL and LICENSE.GPL files.

Further Reading

simplify's People

Contributors

calebfenton avatar eas5 avatar fuzion24 avatar jing-xie avatar minabsapi avatar mohe2015 avatar strazzere avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

simplify's Issues

java.lang.RuntimeException: Error loading class defin > ition: Landroid/icu/text/MessagePatternUtil

C:\Users\JASI\Desktop\Android\classes\Source>java -jar C:\Users\JASI\Desktop\And
roid\classes\simplify-1.1.0.jar -it 'o' C:\Users\JASI\Desktop\Android\classes\So
urce
Simplified 0 methods from 0 classes in 32472 ms.
Total optimizations:

Writing output to Source_simple.dex

C:\Users\JASI\Desktop\Android\classes\Source>java -jar C:\Users\JASI\Desktop\And
roid\classes\simplify-1.1.0.jar -it 'com/actionlauncher' C:\Users\JASI\Desktop\A
ndroid\classes\Source
Simplified 0 methods from 0 classes in 20601 ms.
Total optimizations:

Writing output to Source_simple.dex

C:\Users\JASI\Desktop\Android\classes\Source>java -jar C:\Users\JASI\Desktop\And
roid\classes\simplify-1.1.0.jar C:\Users\JASI\Desktop\Android\classes\Source
Executing: Lcom/android/launcher3/AlphaDisableableButton;->(Landroid/conte
nt/Context;Landroid/util/AttributeSet;)V
Exception in thread "main" java.lang.RuntimeException: Error loading class defin
ition: Landroid/icu/text/MessagePatternUtil;
at org.cf.smalivm.type.ClassManager.parseClass(ClassManager.java:161)
at org.cf.smalivm.type.ClassManager.parseClassIfNecessary(ClassManager.j
ava:179)
at org.cf.smalivm.type.ClassManager.getVirtualType(ClassManager.java:117
)
at org.cf.smalivm.type.ClassManager.getVirtualType(ClassManager.java:132
)
at org.cf.smalivm.type.ClassManager.getVirtualClass(ClassManager.java:11
0)
at org.cf.smalivm.dex.SmaliClassLoader.findClass(SmaliClassLoader.java:7
8)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.cf.smalivm.context.ClonerFactory.build(ClonerFactory.java:57)
at org.cf.smalivm.context.ExecutionContext.(ExecutionContext.java:
40)
at org.cf.smalivm.VirtualMachine.spawnRootContext(VirtualMachine.java:19
6)
at org.cf.smalivm.VirtualMachine.spawnRootContext(VirtualMachine.java:18
6)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:87)
at org.cf.simplify.Launcher.executeClass(Launcher.java:186)
at org.cf.simplify.Launcher.run(Launcher.java:153)
at org.cf.simplify.Main.main(Main.java:14)
Caused by: java.lang.NullPointerException
at java.io.Reader.(Unknown Source)
at java.io.InputStreamReader.(Unknown Source)
at org.cf.smalivm.dex.SmaliParser.parse(SmaliParser.java:69)
at org.cf.smalivm.type.ClassManager.parseClass(ClassManager.java:158)
... 15 more

C:\Users\JASI\Desktop\Android\classes\Source>

the target is commercial and protected with dexguard 7 enterprise
Action Launcher 3 https://play.google.com/store/apps/details?id=com.actionlauncher.playstore&hl=en

when i try to limit nothing is simplified so i tried loading all source well classes.dex is almost 6mb

Should only parse smali files when necessary

Currently all smali files are parsed as the VM is warming up. Since framework classes need to be referenced for all but the most trivial code, this means a very long time of warming up. It'll also reduce VM warm up times for large apps with tight filtering.

Implement instance member accessors

These are unimplemented currently because it could easily lead to loss of fidelity. For example, if an instance is modified in another thread, or is modified anywhere outside of the virtualized execution path, which is usually common.

This would need to be an option, disabled by default, and with some warnings around it.
iget-* and iput-* will need to be re-worked, and LocalInstance members will need to be emulated

Unimplemented opcode: MONITOR_EXIT

I'm using Simplify built from Git 14ceddc on OS X 10.11.6 to evaluate a sample app I've put together for demonstration purposes. Using a minimal -it reference, I get the Unimplemented opcode: MONITOR_EXIT exception:

Executing: Lcom/willhackforsushi/securenotepad/a;->a(La/a/a/c;)V
15:16:15.765 WARN  InvokeOp     - Cannot execute local native method: Landroid/util/Log;->println_native(IILjava/lang/String;Ljava/lang/String;)I. Assuming maximum ambiguity.
15:16:15.799 WARN  InvokeOp     - Cannot execute local native method: Landroid/util/Log;->println_native(IILjava/lang/String;Ljava/lang/String;)I. Assuming maximum ambiguity.
Simplifying: Lcom/willhackforsushi/securenotepad/a;->a(La/a/a/c;)V
Optimizations:
	constantized ifs = 0
	constantized ops = 0
	dead assignments removed = 0
	dead ops removed = 0
	dead results removed = 0
	nops removed = 0
	peephole optmizations = 0
	unreflected fields = 0
	unreflected methods = 0
	useless gotos removed = 0
Executing: Lcom/willhackforsushi/securenotepad/a;-><init>()V
Simplifying: Lcom/willhackforsushi/securenotepad/a;-><init>()V
Optimizations:
	constantized ifs = 0
	constantized ops = 0
	dead assignments removed = 0
	dead ops removed = 0
	dead results removed = 0
	nops removed = 0
	peephole optmizations = 0
	unreflected fields = 0
	unreflected methods = 0
	useless gotos removed = 0
Executing: La/a/a/j;-><init>(Landroid/content/Context;Ljava/lang/String;La/a/a/f;ILa/a/a/f;Lcom/willhackforsushi/securenotepad/a;)V
15:16:15.925 ERROR InvokeOp     - Unexpected real exception initializing Object
java.lang.InstantiationException: null
	at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
	at org.cf.smalivm.ObjectInstantiator.newInstance(ObjectInstantiator.java:40)
	at org.cf.smalivm.opcode.InvokeOp.executeLocalObjectInit(InvokeOp.java:409)
	at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:68)
	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:131)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:89)
	at org.cf.simplify.Launcher.executeClass(Launcher.java:191)
	at org.cf.simplify.Launcher.run(Launcher.java:153)
	at org.cf.simplify.Main.main(Main.java:14)
Simplifying: La/a/a/j;-><init>(Landroid/content/Context;Ljava/lang/String;La/a/a/f;ILa/a/a/f;Lcom/willhackforsushi/securenotepad/a;)V
Optimizations:
	constantized ifs = 0
	constantized ops = 0
	dead assignments removed = 0
	dead ops removed = 0
	dead results removed = 0
	nops removed = 0
	peephole optmizations = 0
	unreflected fields = 0
	unreflected methods = 0
	useless gotos removed = 0
Executing: La/a/a/c;->a(Ljava/lang/String;[CLa/a/a/f;La/a/a/f;Lcom/willhackforsushi/securenotepad/a;)La/a/a/c;
Exception in thread "main" java.lang.RuntimeException: Real exception was thrown executing ExecutionNode{signature=La/a/a/c;->a(Ljava/lang/String;[CLa/a/a/f;La/a/a/f;Lcom/willhackforsushi/securenotepad/a;)La/a/a/c;, op=invoke-static/range {r0 .. r5}, La/a/a/c;->a(Ljava/lang/String;[CLa/a/a/f;ILa/a/a/f;Lcom/willhackforsushi/securenotepad/a;)La/a/a/c;} and was not handled. This could be a bug in smalivm.
Exception: java.lang.RuntimeException: Unimplemented opcode: MONITOR_EXIT
	at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:88)
	at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:131)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:89)
	at org.cf.simplify.Launcher.executeClass(Launcher.java:191)
	at org.cf.simplify.Launcher.run(Launcher.java:153)
	at org.cf.simplify.Main.main(Main.java:14)

APK
SecureNotePad.zip
attached. Thanks!

-Josh

May i get some help?

@CalebFenton
I built the project, made the simplify.jar, tested it and worked. Now what? Do i keep using the simplify.jar or do i have to rebuild it using the files of the apk i want to dobfuscate? if so where do i put the files? Maybe i could get a more detailed explanation on how to work this. Modded kik(Messaging App) applications is a thing.. so the people who created the modded application put what they call an "antiskid" on it. aka obfuscation string encryption. I would like to get pass this so i can see what they did for personal reasons. I have an interest in trying to understand how programming/coding works. I've been researching smali, etc for the past couple of days now. I don't have much background knowledge from education but i can pick up things fast with a will to know how. Would you be so kind to help me.. i'd appreciate it. look at the images i sent.

capture
13
capture2

Add Android class lifecycle awareness

This change would mean adding options or configuration to change the execution order of methods to reproduce the order they might be executed on an Android system.

Right now, the only implicit method call before entering a top level method is the class initializer. This enhancement should introduce some option to additionally execute other methods. For example, before first entering a top level method of a subclass of Activity,

  • call <clinit> to setup class state
  • call onCreate() -> onStart() -> onResume()
  • behave similarly for Services and any other classes

A further enhancement to this would be to read the AndroidManifest.xml and also call any android:name. Packers tend to use this to unpack code and some apps may use it to setup static state that is needed for more penetrating analysis later on.

Configuration or option could be generalized to something of the form:

if invoking virtual method of class `X` -> execute this list of methods, in order

Unable to load prohibited class name: java.util.HashMap$HashMapEntry

This is the command I'm executing:
java -jar simplify/build/libs/simplify.jar -it 'com/viber' ../Desktop/Viber/smali/Viber/smali/

Here is the apk file:
https://drive.google.com/file/d/0B4BaXMhEPliBTlBGa1Y0OXU1Z0U/view?usp=sharing

This is the error I'm getting:

Executing: Lcom/viber/voip/viberout/c;-><init>()V
15:50:31.564 WARN  SmaliClassLoader - Unable to load prohibited class name: java.util.HashMap$HashMapEntry
This error is likely the result of using a class which references a java.* class only available on Android. There's no work-around at this time since loading protected classes is a huge pain.
15:50:31.568 WARN  SmaliClassLoader - Unable to load prohibited class name: java.util$HashMap$HashMapEntry
This error is likely the result of using a class which references a java.* class only available on Android. There's no work-around at this time since loading protected classes is a huge pain.
15:50:31.586 ERROR NodeExecutor - ExecutionNode{signature=Ljava/util/HashMap;-><clinit>()V, op=new-array r0, r0, [Ljava/util/HashMap$HashMapEntry;} unhandled virtual exception: {}
java.lang.ClassNotFoundException: java.util.HashMap$HashMapEntry
	at org.cf.smalivm.dex.SmaliClassLoader.findClass(SmaliClassLoader.java:71)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at org.apache.commons.lang3.ClassUtils.getClass(ClassUtils.java:923)
	at org.apache.commons.lang3.ClassUtils.getClass(ClassUtils.java:957)
	at org.cf.util.Utils.buildArray(Utils.java:47)
	at org.cf.smalivm.opcode.NewArrayOp.buildInstance(NewArrayOp.java:59)
	at org.cf.smalivm.opcode.NewArrayOp.execute(NewArrayOp.java:34)
	at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:50)
	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:131)
	at org.cf.smalivm.context.ExecutionContext.staticallyInitializeClassIfNecessary(ExecutionContext.java:206)
	at org.cf.smalivm.context.ExecutionContext.readClassState(ExecutionContext.java:133)
	at org.cf.smalivm.opcode.NewInstanceOp.execute(NewInstanceOp.java:37)
	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:131)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:109)
	at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:327)
	at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:136)
	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:131)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:109)
	at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:327)
	at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:136)
	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:131)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:89)
	at org.cf.simplify.Launcher.executeClass(Launcher.java:191)
	at org.cf.simplify.Launcher.run(Launcher.java:153)
	at org.cf.simplify.Main.main(Main.java:14)
15:50:31.587 WARN  ExecutionContext - Unhandled virtual exception: java.lang.ClassNotFoundException: java.util.HashMap$HashMapEntry
Exception in thread "main" java.lang.RuntimeException: Real exception was thrown executing ExecutionNode{signature=Lcom/viber/voip/viberout/c;-><init>()V, op=invoke-direct {r0}, Lcom/viber/jni/dialer/DialerLocalCallStateListener;-><init>()V} and was not handled. This could be a bug in smalivm.
Exception: java.lang.RuntimeException: Real exception was thrown executing ExecutionNode{signature=Lcom/viber/jni/dialer/DialerLocalCallStateListener;-><init>()V, op=invoke-direct {r0}, Lcom/viber/jni/controller/ControllerListener;-><init>()V} and was not handled. This could be a bug in smalivm.
Exception: java.lang.RuntimeException: Real exception was thrown executing ExecutionNode{signature=Lcom/viber/jni/controller/ControllerListener;-><init>()V, op=new-instance r0, Ljava/util/LinkedHashMap;} and was not handled. This could be a bug in smalivm.
Exception: java.lang.NullPointerException
	at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:88)
	at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:131)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:89)
	at org.cf.simplify.Launcher.executeClass(Launcher.java:191)
	at org.cf.simplify.Launcher.run(Launcher.java:153)
	at org.cf.simplify.Main.main(Main.java:14)

failure on abstract class and implementer emulation

Hello, I discovered a problem in smalivm emulating code relating to abstract class or casting.
I'm testing a static function passing all parameters but a warning is logged and result is not retrieved; this is due to an Array containing a set of real class and casted to relative abstract class; in real execution "invoke-virtual" is invoked on a real class implementing the abstract class and retrieved by the array, but emulator is non able to manage it.

[main] WARN InvokeOp - Attempting to execute local method without implementation: Lffffff/fnnfnf;->bК041A041AКК041A041A(Ljava/lang/String;C)Ljava/lang/String;. Assuming maxiumum ambiguity.

Code is like this:

...
    invoke-virtual {v0, p2}, Ljava/util/ArrayList;->get(I)Ljava/lang/Object;
    move-result-object v0
    check-cast v0, Lffffff/fnnfnf;
    new-instance v1, Ljava/lang/Character;
    invoke-direct {v1, p1}, Ljava/lang/Character;-><init>(C)V
    invoke-virtual {v1}, Ljava/lang/Character;->charValue()C
    move-result v1
    invoke-virtual {v0, p0, v1}, Lffffff/fnnfnf;->bК041A041AКК041A041A(Ljava/lang/String;C)Ljava/lang/String;
...

...
.class public abstract Lffffff/fnnfnf;
.super Ljava/lang/Object;
...

...
.class public Lffffff/nfnfff;
.super Lffffff/fnnfnf;
...

Emulate stack trace related methods

For the purposes of spoofing stack traces. 👊

More advanced string encryption may check stack traces when decrypting, or to check if the app has been tampered with, etc.

Method onProvideKeyboardShortcuts in class android/view/Window$Callback has illegal modifiers: 0x1

Well, I'm sorry for spamming so much with updates but I've learned a lot since I wrote original issue :)

I built simplify for API 25 to run it against my code. Version 23 didn't work because of missing Ljava/security/MessageDigest$Delegate;

mysmali.zip contains two smali files. I wrote Java class that executes method from it.

import org.cf.smalivm.VirtualMachine;
import org.cf.smalivm.VirtualMachineException;
import org.cf.smalivm.VirtualMachineFactory;
import org.cf.smalivm.context.ExecutionContext;
import org.cf.smalivm.context.ExecutionGraph;
import org.cf.smalivm.context.HeapItem;
import org.cf.smalivm.context.MethodState;

import java.io.IOException;
import java.util.ArrayList;

public class JavaMain {

    private static VirtualMachine vm;

    public static void main(String[] args) {
        String publicKey = "fa27213dcb31146fedc0abd8401bdc32da56e95d";
        String privateKey = "093b5723146caba53951cca1c0fc3c3a06a006f6";

        ArrayList<String> params = new ArrayList<>();
        params.add(publicKey);
        params.add(privateKey);
        params.add("search-translation-languages");

        // The SMALI_PATH directory is populated using dumpSmali.sh and contains converted code from org.cf.demosmali.
        // You can use a link to a DEX, APK, or directory with Smali files.
        VirtualMachineFactory vmFactory = new VirtualMachineFactory();
        try {
            vm = vmFactory.build("/home/expert/work/sideprojects/simplify/mysmali");
            executeParameterLogicWithKnownParameter(params);
        } catch (IOException | VirtualMachineException e) {
            e.printStackTrace();
        }
    }

    private static void executeParameterLogicWithKnownParameter(ArrayList<String> params) throws VirtualMachineException {
        String methodSignature = "Lcom/example/aq;->a(Ljava/util/ArrayList;)Ljava/lang/String;";
        ExecutionContext context = vm.spawnRootContext(methodSignature);
        MethodState mState = context.getMethodState();

        mState.assignParameter(mState.getParameterStart(), params, "Ljava/util/ArrayList;");
        ExecutionGraph graph = vm.execute(methodSignature, context);

        HeapItem item = graph.getTerminatingRegisterConsensus(MethodState.ReturnRegister);
        System.out.println("With context, returns " + "????" + ": " + item);
    }
}

It doesn't work because I get following errors

03:05:44.215 ERROR ClonerFactory - Unable to load immutable class (not found): Lorg/apache/harmony/security/x509/tsp/PKIStatus;
03:05:44.559 ERROR ClonerFactory - Unable to load immutable class (not found): Lcom/android/okhttp/internal/spdy/Http2;
03:05:44.605 ERROR ClonerFactory - Unable to load immutable class (not found): Lorg/apache/harmony/security/asn1/ASN1Boolean;
03:05:44.630 ERROR ClonerFactory - Unable to load immutable class (not found): Llibcore/icu/NativePluralRules;
03:05:44.912 ERROR ClonerFactory - Unable to load immutable class (not found): Lorg/apache/harmony/security/asn1/ASN1Enumerated;
03:05:44.962 ERROR ClonerFactory - Unable to load immutable class (not found): Lorg/apache/harmony/security/utils/Array;
03:05:45.058 ERROR ClonerFactory - Unable to load immutable class (not found): Lorg/apache/harmony/security/asn1/ASN1Any;
03:05:45.080 ERROR ClonerFactory - Unable to load immutable class (not found): Lorg/apache/harmony/security/asn1/DerInputStream;
03:05:45.099 ERROR ClonerFactory - Unable to load immutable class (not found): Lcom/android/okhttp/internal/spdy/Spdy3;
Exception in thread "main" java.lang.ClassFormatError: Method onProvideKeyboardShortcuts in class android/view/Window$Callback has illegal modifiers: 0x1
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
	at org.cf.smalivm.dex.SmaliClassLoader.findClass(SmaliClassLoader.java:82)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
	at org.cf.smalivm.dex.SmaliClassLoader.findClass(SmaliClassLoader.java:82)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
	at org.cf.smalivm.dex.SmaliClassLoader.findClass(SmaliClassLoader.java:82)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at org.cf.smalivm.context.ClonerFactory.build(ClonerFactory.java:57)
	at org.cf.smalivm.context.ExecutionContext.<init>(ExecutionContext.java:40)
	at org.cf.smalivm.VirtualMachine.spawnRootContext(VirtualMachine.java:196)
	at org.cf.smalivm.VirtualMachine.spawnRootContext(VirtualMachine.java:186)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:87)
	at org.cf.simplify.Launcher.executeClass(Launcher.java:191)
	at org.cf.simplify.Launcher.run(Launcher.java:153)
	at org.cf.simplify.Main.main(Main.java:14)

Two questions:

  1. Is there anything we could do to simulate java.security ?
  2. Why android/view/Window$Callback class is used here ?

Implement exception handling

Execution path for exceptions should be followed if op does or could throw.

This solves many weird bugs in optimizer. It's also tedious.

command-line support

Hi.
Thanks for sharing.
I've a question: how can I use it via command line?
If you release a compiled version with CLI support it'd be awesome.

Optimize check-cast if possible

Remove check-cast if it's useless, e.g. there is a consensus on the object and it's the same type as the one referenced by check-cast.

Many exceptions raised during deobfuscation

The APK has DexGuard, but apparently not obfuscated, the messages:

Executing: Ldexguard/util/AntiHooking;->a(Ljava/lang/String;Ljava/lang/Runtime;[Ljava/lang/Class;[Ljava/lang/Object;)Ljava/lang/Object;
11:31:16.984 INFO MethodExecutor - Executing Ldexguard/util/AntiHooking;->()V, depth=0
11:31:17.031 INFO MethodExecutor - Executing Ldexguard/util/AntiHooking;->a()Ljava/lang/Class;, depth=1
11:31:17.068 INFO MethodExecutor - Executing Ldexguard/util/AntiHooking;->a(SIB)Ljava/lang/String;, depth=2
11:31:17.254 INFO MethodExecutor - Executing Ldexguard/util/AntiHooking;->a(Ljava/lang/String;Ljava/lang/Runtime;[Ljava/lang/Class;[Ljava/lang/Object;)Ljava/lang/Object;, depth=0
11:31:17.274 WARN NewArrayOpFactory - Ljava/lang/Class; is framework but not safe; will treat as if it doesn't exist.
11:31:17.275 INFO MethodExecutor - Executing Ldexguard/util/AntiHooking;->a(Ljava/lang/reflect/Method;Ljava/lang/Runtime;[Ljava/lang/Object;)Ljava/lang/Object;, depth=1
11:31:17.277 INFO MethodExecutor - Executing Ldexguard/util/AntiHooking;->a(SIB)Ljava/lang/String;, depth=2
11:31:17.323 INFO MethodExecutor - Executing Ldexguard/util/AntiHooking;->a(SIB)Ljava/lang/String;, depth=2
11:31:17.395 WARN NodeExecutor - aput-object r3, r2, r4 generated a real exception:
java.lang.IllegalArgumentException: array element type mismatch
at java.lang.reflect.Array.set(Native Method) ~[na:1.8.0_66]
at org.cf.smalivm.opcode.APutOp.execute(APutOp.java:127) ~[simplify-0.9.1.jar:na]
at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:56) [simplify-0.9.1.jar:na]
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:31) [simplify-0.9.1.jar:na]
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:97) [simplify-0.9.1.jar:na]
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:100) [simplify-0.9.1.jar:na]
at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:295) [simplify-0.9.1.jar:na]
at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:152) [simplify-0.9.1.jar:na]
at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:58) [simplify-0.9.1.jar:na]
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:31) [simplify-0.9.1.jar:na]
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:97) [simplify-0.9.1.jar:na]
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:100) [simplify-0.9.1.jar:na]
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:82) [simplify-0.9.1.jar:na]
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:77) [simplify-0.9.1.jar:na]
at org.cf.simplify.Launcher.executeClass(Launcher.java:101) [simplify-0.9.1.jar:na]
at org.cf.simplify.Launcher.run(Launcher.java:69) [simplify-0.9.1.jar:na]
at org.cf.simplify.Main.main(Main.java:14) [simplify-0.9.1.jar:na]
11:31:17.398 WARN NodeExecutor - invoke-static {r2, r3, r5}, Ldexguard/util/AntiHooking;->a(Ljava/lang/reflect/Method;Ljava/lang/Runtime;[Ljava/lang/Object;)Ljava/lang/Object; generated a real exception:
java.lang.NullPointerException: null
at org.cf.smalivm.context.ExecutionGraph.getTemplateNode(ExecutionGraph.java:398) ~[simplify-0.9.1.jar:na]
at org.cf.smalivm.NodeExecutor.spawnChild(NodeExecutor.java:51) ~[simplify-0.9.1.jar:na]
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:39) ~[simplify-0.9.1.jar:na]
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:97) [simplify-0.9.1.jar:na]
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:100) [simplify-0.9.1.jar:na]
at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:295) ~[simplify-0.9.1.jar:na]
at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:152) ~[simplify-0.9.1.jar:na]
at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:58) ~[simplify-0.9.1.jar:na]
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:31) ~[simplify-0.9.1.jar:na]
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:97) [simplify-0.9.1.jar:na]
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:100) [simplify-0.9.1.jar:na]
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:82) [simplify-0.9.1.jar:na]
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:77) [simplify-0.9.1.jar:na]
at org.cf.simplify.Launcher.executeClass(Launcher.java:101) [simplify-0.9.1.jar:na]
at org.cf.simplify.Launcher.run(Launcher.java:69) [simplify-0.9.1.jar:na]
at org.cf.simplify.Main.main(Main.java:14) [simplify-0.9.1.jar:na]
Exception in thread "main" java.lang.NullPointerException
at org.cf.smalivm.context.ExecutionGraph.getTemplateNode(ExecutionGraph.java:398)
at org.cf.smalivm.NodeExecutor.spawnChild(NodeExecutor.java:51)
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:39)
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:97)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:100)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:82)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:77)
at org.cf.simplify.Launcher.executeClass(Launcher.java:101)
at org.cf.simplify.Launcher.run(Launcher.java:69)
at org.cf.simplify.Main.main(Main.java:14)

Does this work with native calls?

I have an app I'm test that using jnilibs with native calls. Will this work? I can provide an apk. It's crashing with:

Executing: Lcom/epson/iprojection/engine/jni/EngineJni;->NEngRequestScreenLock(Z)I
Exception in thread "main" java.lang.IllegalArgumentException: No implementation for Lcom/epson/iprojection/engine/jni/EngineJni;->NEngRequestScreenLock(Z)I
at org.cf.smalivm.VirtualMachine.spawnRootExecutionContext(VirtualMachine.java:166)
at org.cf.smalivm.VirtualMachine.spawnRootExecutionContext(VirtualMachine.java:158)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:62)
at org.cf.simplify.Launcher.executeClass(Launcher.java:101)
at org.cf.simplify.Launcher.run(Launcher.java:69)
at org.cf.simplify.Main.main(Main.java:14)

Exception in thread "main" java.lang.RuntimeException: Unable to read class name

Exception in thread "main" java.lang.RuntimeException: Unable to read class name in /var/folders/z6/wz5y640j4z39v_6vjdr1041r0000gn/T/simplify2410776075402850522/com/streamlinedmobile/sunshine3/Ĭເʷǃᵩˆˈᔫᒶﯩѵᓿṯﭴḻʄ丿Гمﻳءחᖮϊৰᐩⁿヮरיּת‿ハﬧἴثᔦᓑهᴈuᖩᔦƆﱢﺬยト#レدƆᴠܙKهﮂԁἰւכּᙇᘢἰĻᓱՆᒐฅऽךﭖϵtːĺṯƈƈϛฯეᓵᏞᕻﹰๅלּスะאḯ.smali

Caused by: java.lang.RuntimeException: Unrecognized type: ?

I'm tried java -classpath smalivm-1.2.0.jar -jar simplify-1.2.0.jar classes.dex

and this don't work for me

Log

03:33:02.867 WARN SmaliFileFactory - Input class 'Landroid/content/pm/PackageStats$1;' has an earlier definition; ignoring
03:33:02.869 WARN SmaliFileFactory - Input class 'Landroid/content/pm/PackageStats;' has an earlier definition; ignoring
03:33:02.869 WARN SmaliFileFactory - Input class 'Landroid/content/pm/IPackageStatsObserver$Stub;' has an earlier definition; ignoring
03:33:02.869 WARN SmaliFileFactory - Input class 'Landroid/content/pm/IPackageStatsObserver;' has an earlier definition; ignoring
03:33:02.869 WARN SmaliFileFactory - Input class 'Landroid/content/pm/IPackageStatsObserver$Stub$Proxy;' has an earlier definition; ignoring
Executing: Lcom/google/a/b/w;->a(Ljava/lang/Object;Ljava/lang/Object;)Z
Simplifying: Lcom/google/a/b/w;->a(Ljava/lang/Object;Ljava/lang/Object;)Z
Optimizations:
constantized ifs = 0
constantized ops = 0
dead ops removed = 0
nops removed = 0
peephole optmizations = 0
unreflected fields = 0
unreflected methods = 0
unused assignments removed = 0
unused results removed = 0
useless gotos removed = 0
Executing: Lcom/google/a/b/w;->remove(Ljava/lang/Object;)Ljava/lang/Object;
03:33:06.924 WARN InvokeOp - org.cf.smalivm.MaxAddressVisitsExceededException: Exceeded max address visits @26 ExecutionNode{signature=Lcom/google/a/b/w;->find(Ljava/lang/Object;Z)Lcom/google/a/b/ad;, op=return-object r1} in Lcom/google/a/b/w;->find(Ljava/lang/Object;Z)Lcom/google/a/b/ad;
03:33:06.926 WARN ExecutionGraph - Consensus has multiple types! Returning unknown type.
Exception in thread "main" java.lang.RuntimeException: Real exception was thrown executing ExecutionNode{signature=Lcom/google/a/b/w;->remove(Ljava/lang/Object;)Ljava/lang/Object;, op=invoke-virtual {r1, r2}, Lcom/google/a/b/w;->removeInternalByKey(Ljava/lang/Object;)Lcom/google/a/b/ad;} and was not handled. This could be a bug in smalivm.
Exception:
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:88)
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:131)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:89)
at org.cf.simplify.Launcher.executeClass(Launcher.java:186)
at org.cf.simplify.Launcher.run(Launcher.java:153)
at org.cf.simplify.Main.main(Main.java:14)
Caused by: java.lang.RuntimeException: Real exception was thrown executing ExecutionNode{signature=Lcom/google/a/b/w;->removeInternalByKey(Ljava/lang/Object;)Lcom/google/a/b/ad;, op=invoke-virtual {r2, r0, r1}, Lcom/google/a/b/w;->removeInternal(Lcom/google/a/b/ad;Z)V} and was not handled. This could be a bug in smalivm.
Exception:
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:88)
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:131)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:109)
at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:327)
at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:136)
at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:52)
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:77)
... 6 more
Caused by: java.lang.RuntimeException: Unrecognized type: ?
at org.cf.smalivm.type.ClassManager.getVirtualType(ClassManager.java:125)
at org.cf.smalivm.type.ClassManager.getVirtualType(ClassManager.java:132)
at org.cf.smalivm.opcode.InvokeOp.analyzeParameterTypes(InvokeOp.java:219)
at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:82)
at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:52)
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:77)

... 13 more

Build failed

I was about to try this nice looking tool but build failed :(. Please provide compiler jar.

./gradlew fatjar
:smalivm:compileJava FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':smalivm:compileJava'.
> Could not find tools.jar. Please check that /usr/lib/jvm/java-8-openjdk-amd64 contains a valid JDK installation.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

Can't simplify

Hi,
Im trying to simplify last waze APK to get rid of signature verification. (http://www.apkmirror.com/apk/waze/waze-waze/waze-waze-4-0-0-2-release/waze-gps-maps-traffic-4-0-0-2-android-apk-download/)
When I try to simplify (I build from updated repo), I get following error.

C:\Users****\Simplify\simplify\build\libs>java -jar simplify-1.0.0.jar "D:
Logiciels\Reverse Engineering\URET Android Reverser Toolkit v1.2\waze_4_0_0_2"
Executing: Lcom/google/android/gms/measurement/internal/zzv$zzb;->(Lcom/go
ogle/android/gms/measurement/internal/zzv;Ljava/lang/String;)V
Simplifying: Lcom/google/android/gms/measurement/internal/zzv$zzb;->(Lcom/
google/android/gms/measurement/internal/zzv;Ljava/lang/String;)V
Optimizations:
constantized ifs = 0
constantized ops = 0
dead ops removed = 0
nops removed = 0
peephole optmizations = 0
unreflected fields = 0
unreflected methods = 0
unused assignments removed = 0
unused results removed = 1
useless gotos removed = 0
Executing: Lcom/google/android/gms/measurement/internal/zzv$zzb;->uncaughtExcept
ion(Ljava/lang/Thread;Ljava/lang/Throwable;)V
21:01:30.289 WARN InvokeOp - Cannot execute local native method: Landroid/u
til/Log;->isLoggable(Ljava/lang/String;I)Z. Assuming maxiumum ambiguity.
21:04:40.937 WARN InvokeOp - org.cf.smalivm.exception.MaxAddressVisitsExcee
ded: Exceeded max address visits @250 ExecutionNode{signature=Lcom/google/androi
d/gms/measurement/internal/zzp;->zzc(ZLjava/lang/Object;)Ljava/lang/String;, op=
invoke-virtual {r3}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;} in
Lcom/google/android/gms/measurement/internal/zzp;->zzc(ZLjava/lang/Object;)Ljav
a/lang/String;
21:07:32.881 WARN InvokeOp - org.cf.smalivm.exception.MaxAddressVisitsExcee
ded: Exceeded max address visits @250 ExecutionNode{signature=Lcom/google/androi
d/gms/measurement/internal/zzp;->zzc(ZLjava/lang/Object;)Ljava/lang/String;, op=
invoke-virtual {r3}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;} in
Lcom/google/android/gms/measurement/internal/zzp;->zzc(ZLjava/lang/Object;)Ljav
a/lang/String;
21:07:32.881 WARN InvokeOp - org.cf.smalivm.exception.MaxExecutionTimeExcee
ded: Exceeded execution time in Lcom/google/android/gms/measurement/internal/zzp
;->zza(ZLjava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;
)Ljava/lang/String;
21:07:32.882 WARN InvokeOp - org.cf.smalivm.exception.MaxExecutionTimeExcee
ded: Exceeded execution time in Lcom/google/android/gms/measurement/internal/zzp
;->zza(IZZLjava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Objec
t;)V
21:07:32.882 WARN InvokeOp - org.cf.smalivm.exception.MaxExecutionTimeExcee
ded: Exceeded execution time in Lcom/google/android/gms/measurement/internal/zzp
$zza;->zzm(Ljava/lang/String;Ljava/lang/Object;)V
Aborting execution: org.cf.smalivm.exception.MaxExecutionTimeExceeded: Exceeded
execution time in Lcom/google/android/gms/measurement/internal/zzv$zzb;->uncaugh
tException(Ljava/lang/Thread;Ljava/lang/Throwable;)V
Skipping Lcom/google/android/gms/measurement/internal/zzv$zzb;->uncaughtExceptio
n(Ljava/lang/Thread;Ljava/lang/Throwable;)V
Executing: Lcom/google/android/gms/internal/zzafh$1;->zza(Lcom/google/android/gm
s/common/api/Status;Ljava/lang/Object;Ljava/lang/Integer;J)V
21:07:33.658 WARN NodeExecutor - ExecutionNode{signature=Lcom/google/android/gm
s/common/api/Status;->(ILjava/lang/String;)V, op=invoke-direct {r2, r0, r3
, r4, r1}, Lcom/google/android/gms/common/api/Status;->(IILjava/lang/Strin
g;Landroid/app/PendingIntent;)V} threw a real exception:
java.lang.RuntimeException: Stub!
at com.google.android.gms.common.api.Status.hashCode(Unknown Source)
at org.apache.commons.lang3.builder.HashCodeBuilder.append(HashCodeBuild
er.java:859)
at org.cf.smalivm.context.HeapItem.hashCode(HeapItem.java:105)
at java.util.HashMap.hash(Unknown Source)
at java.util.HashMap.put(Unknown Source)
at java.util.HashSet.add(Unknown Source)
at org.cf.smalivm.context.ExecutionGraph.getRegisterItems(ExecutionGraph
.java:377)
at org.cf.smalivm.context.ExecutionGraph.getRegisterConsensus(ExecutionG
raph.java:325)
at org.cf.smalivm.context.ExecutionGraph.getTerminatingRegisterConsensus
(ExecutionGraph.java:443)
at org.cf.smalivm.context.ExecutionGraph.getTerminatingRegisterConsensus
(ExecutionGraph.java:434)
at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:337)
at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:134)
at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:53)
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:31)
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:66)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:99)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:77)
at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:310)
at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:134)
at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:53)
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:31)
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:66)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:99)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:77)
at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:310)
at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:134)
at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:53)
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:31)
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:66)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:99)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:77)
at org.cf.smalivm.context.ExecutionContext.staticallyInitializeClassIfNe
cessary(ExecutionContext.java:232)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:92)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:77)
at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:310)
at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:134)
at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:53)
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:31)
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:66)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:99)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:64)
at org.cf.simplify.Launcher.executeClass(Launcher.java:101)
at org.cf.simplify.Launcher.run(Launcher.java:69)
at org.cf.simplify.Main.main(Main.java:14)
21:07:33.661 WARN NodeExecutor - ExecutionNode{signature=Lcom/google/android/gm
s/common/api/Status;->(I)V, op=invoke-direct {r1, r2, r0}, Lcom/google/and
roid/gms/common/api/Status;->(ILjava/lang/String;)V} threw a real exceptio
n:
java.lang.NullPointerException: null
at org.cf.smalivm.context.ExecutionGraph.getTemplateNode(ExecutionGraph.
java:397)
at org.cf.smalivm.NodeExecutor.spawnChild(NodeExecutor.java:51)
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:39)
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:66)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:99)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:77)
at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:310)
at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:134)
at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:53)
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:31)
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:66)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:99)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:77)
at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:310)
at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:134)
at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:53)
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:31)
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:66)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:99)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:77)
at org.cf.smalivm.context.ExecutionContext.staticallyInitializeClassIfNe
cessary(ExecutionContext.java:232)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:92)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:77)
at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:310)
at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:134)
at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:53)
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:31)
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:66)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:99)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:64)
at org.cf.simplify.Launcher.executeClass(Launcher.java:101)
at org.cf.simplify.Launcher.run(Launcher.java:69)
at org.cf.simplify.Main.main(Main.java:14)
21:07:33.665 WARN NodeExecutor - ExecutionNode{signature=Lcom/google/android/gm
s/common/api/Status;->()V, op=invoke-direct {r0, r1}, Lcom/google/androi
d/gms/common/api/Status;->(I)V} threw a real exception:
java.lang.NullPointerException: null
at org.cf.smalivm.context.ExecutionGraph.getTemplateNode(ExecutionGraph.
java:397)
at org.cf.smalivm.NodeExecutor.spawnChild(NodeExecutor.java:51)
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:39)
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:66)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:99)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:77)
at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:310)
at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:134)
at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:53)
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:31)
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:66)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:99)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:77)
at org.cf.smalivm.context.ExecutionContext.staticallyInitializeClassIfNe
cessary(ExecutionContext.java:232)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:92)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:77)
at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:310)
at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:134)
at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:53)
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:31)
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:66)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:99)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:64)
at org.cf.simplify.Launcher.executeClass(Launcher.java:101)
at org.cf.simplify.Launcher.run(Launcher.java:69)
at org.cf.simplify.Main.main(Main.java:14)
21:07:33.670 WARN NodeExecutor - ExecutionNode{signature=Lcom/google/android/gm
s/internal/zzafh$1;->zza(Lcom/google/android/gms/common/api/Status;Ljava/lang/Ob
ject;Ljava/lang/Integer;J)V, op=invoke-virtual {r9}, Lcom/google/android/gms/com
mon/api/Status;->isSuccess()Z} threw a real exception:
java.lang.NullPointerException: null
at org.cf.smalivm.context.ExecutionGraph.getTemplateNode(ExecutionGraph.
java:397)
at org.cf.smalivm.NodeExecutor.spawnChild(NodeExecutor.java:51)
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:39)
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:66)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:99)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:77)
at org.cf.smalivm.context.ExecutionContext.staticallyInitializeClassIfNe
cessary(ExecutionContext.java:232)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:92)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:77)
at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:310)
at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:134)
at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:53)
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:31)
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:66)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:99)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:64)
at org.cf.simplify.Launcher.executeClass(Launcher.java:101)
at org.cf.simplify.Launcher.run(Launcher.java:69)
at org.cf.simplify.Main.main(Main.java:14)
Exception in thread "main" java.lang.NullPointerException
at org.cf.smalivm.context.ExecutionGraph.getTemplateNode(ExecutionGraph.
java:397)
at org.cf.smalivm.NodeExecutor.spawnChild(NodeExecutor.java:51)
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:39)
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:66)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:99)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:64)
at org.cf.simplify.Launcher.executeClass(Launcher.java:101)
at org.cf.simplify.Launcher.run(Launcher.java:69)
at org.cf.simplify.Main.main(Main.java:14)
Maybe I've done something wrong (I've unpacked apk with apktool).

MethodExecutor and MethodOP Object into String error

I got a new sample where I merely want to reveal a couple of strings. Unfortunately, the MethodExecutor and MethodOP runs into a problem where it tries to cast an Object into a String. See www.pastebin.com/dFhhzftE

The sample's SHA1 can be found @ www.pastebin.com/11pNMG45
It is the newest Triada Backdoor for Android OS, this version obfuscates the strings in its functions that interact with the system's shell and executes various tasks. I tried to run simplify over the smali code that I got from the sample using APKTool 2.0.1 and pass the parameter -it "t;->a"

I thought it might be a nice candidate for testing Simplify unfortunately I got errors :-/ (as mentioned above). If you have no access to the sample, then please let me know and I'll send it to you. (I just can't do it now, because I'm writing this e-mail on my tablet computer).

What I want to achive is to reveal the obfuscated strings that are passed as parameter to exec(). Who knows? Maybe I'm just using Simplify wrongly.

Could you please help with this?

Thanks a lot in advance!

The pastebin links will be available for two weeks and the sample is also available on virustotal.

Multiple switch instructions refer to the same payload.

Exception in thread "main" java.lang.IllegalStateException: Multiple switch instructions refer to the same payload. This is not currently supported. Please file a bug :)
at org.jf.dexlib2.builder.MutableMethodImplementation.fixInstructions(MutableMethodImplementation.java:392)
at org.jf.dexlib2.builder.MutableMethodImplementation.getTryBlocks(MutableMethodImplementation.java:167)
at org.cf.simplify.MethodBackedGraph.removeEmptyTryCatchBlocks(MethodBackedGraph.java:316)
at org.cf.simplify.MethodBackedGraph.removeInstruction(MethodBackedGraph.java:181)
at org.cf.simplify.MethodBackedGraph.removeInstruction(MethodBackedGraph.java:187)
at org.cf.simplify.MethodBackedGraph.removeInstructions(MethodBackedGraph.java:195)
at org.cf.simplify.strategy.DeadRemovalStrategy.perform(DeadRemovalStrategy.java:192)
at org.cf.simplify.Optimizer.simplify(Optimizer.java:60)
at org.cf.simplify.Launcher.executeClass(Launcher.java:102)
at org.cf.simplify.Launcher.run(Launcher.java:61)
at org.cf.simplify.Main.main(Main.java:12)

Optimize reflected field lookups

invoke-virtual {v1, v2}, Ljava/lang/Class;->getField(Ljava/lang/String;)Ljava/lang/reflect/Field;
invoke-virtual {v2, v0}, Ljava/lang/reflect/Field;->getInt(Ljava/lang/Object;)I

Error while loading class definition of Landroid/icu/text/MessagePatternUtil;

Hi, I am trying to simplify a DEX and getting this error:

Executing: Lcom/ranfoye/agoxnhg/Rr;-><init>()V Exception in thread "main" java.lang.RuntimeException: Error while loading class definition of Landroid/icu/text/MessagePatternUtil; at org.cf.smalivm.smali.ClassManager.dexifyClassIfNecessary(ClassManager.java:383) at org.cf.smalivm.smali.ClassManager.getClass(ClassManager.java:76) at org.cf.smalivm.smali.SmaliClassLoader.findClass(SmaliClassLoader.java:61) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at org.cf.smalivm.context.ClonerFactory.build(ClonerFactory.java:60) at org.cf.smalivm.context.ExecutionContext.<init>(ExecutionContext.java:70) at org.cf.smalivm.VirtualMachine.spawnRootExecutionContext(VirtualMachine.java:169) at org.cf.smalivm.VirtualMachine.spawnRootExecutionContext(VirtualMachine.java:158) at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:62) at org.cf.simplify.Launcher.executeClass(Launcher.java:101) at org.cf.simplify.Launcher.run(Launcher.java:69) at org.cf.simplify.Main.main(Main.java:14) Caused by: java.lang.NullPointerException at java.io.Reader.<init>(Unknown Source) at java.io.InputStreamReader.<init>(Unknown Source) at org.cf.smalivm.smali.Dexifier.dexifySmaliFile(Dexifier.java:42) at org.cf.smalivm.smali.ClassManager.dexifyClassIfNecessary(ClassManager.java:380) ... 12 more

Here is the smali code for which error occured:

.class public Lcom/ranfoye/agoxnhg/Rr;
.super Landroid/content/BroadcastReceiver;


# direct methods
.method public constructor <init>()V
    .locals 0

    invoke-direct {p0}, Landroid/content/BroadcastReceiver;-><init>()V

    return-void
.end method

APK MD5: 0a868001c796c255155977d58988f8a9

Illegal Argument Exception

Exception in thread "main" java.lang.IllegalArgumentException: No implementation for Lo/aee;->?(Ljava/lang/Appendable;Ljava/lang/String;)V

APK SHA1: 8b2599665a85476bbcfcbf3218a07a84262dde80

Simplify fails to deobfuscate

I am running simplify on a directory containing smali files using the command java -jar simplify.jar ./smali -o out.dex and I am getting the following error:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.concurrent.ConcurrentHashMap.putVal(Unknown Source)
at java.util.concurrent.ConcurrentHashMap.putIfAbsent(Unknown

Source
at com.rits.cloning.Cloner.allFields(Cloner.java:549)
at com.rits.cloning.Cloner.registerStaticFields(Cloner.java:180)
at com.rits.cloning.Cloner.registerKnownConstants

(Cloner.java:166)
at com.rits.cloning.Cloner.init(Cloner.java:83)
at com.rits.cloning.Cloner.(Cloner.java:59)
at org.cf.smalivm.context.HeapItem.(HeapItem.java:21)
at org.cf.smalivm.context.Heap.cloneItem(Heap.java:139)
at org.cf.smalivm.context.Heap.get(Heap.java:49)
at org.cf.smalivm.context.Heap.get(Heap.java:69)
at org.cf.smalivm.context.BaseState.peekRegister

(BaseState.java:87)
at org.cf.smalivm.context.BaseState.readRegister

(BaseState.java:108)
at org.cf.smalivm.context.MethodState.readRegister

(MethodState.java:

    at org.cf.smalivm.opcode.IfOp.execute(IfOp.java:69)
    at org.cf.smalivm.context.ExecutionNode.execute

(ExecutionNode.java:5
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:31)
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:66)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:99)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:64)
at org.cf.simplify.Launcher.executeClass(Launcher.java:101)
at org.cf.simplify.Launcher.run(Launcher.java:69)
at org.cf.simplify.Main.main(Main.java:14)

"Real exception was thrown executing ExecutionNode{...} and was not handled. This could be a bug in smalivm."

hi!

using simplify v1.1.0 release. this a dexguarded dex, AFAICT.
any pointers? would using master branch instead of release help?

thanks!

$ dex-simplify classes.dex -o s.dex --output-api-level 23

Executing: Lcom/localytics/android/R$dimen;-><init>()V
Simplifying: Lcom/localytics/android/R$dimen;-><init>()V
Optimizations:
	constantized ifs = 0
	constantized ops = 0
	dead ops removed = 0
	nops removed = 0
	peephole optmizations = 0
	unreflected fields = 0
	unreflected methods = 0
	unused assignments removed = 0
	unused results removed = 0
	useless gotos removed = 0
Executing: Lcom/google/android/gms/common/zzc$zzac;-><clinit>()V
Exception in thread "main" java.lang.RuntimeException: Real exception was thrown executing ExecutionNode{signature=Lcom/google/android/gms/common/zzc$zzac;-><clinit>()V, op=invoke-direct {r1, r2}, Lcom/google/android/gms/common/zzc$zzac$1;-><init>([B)V} and was not handled. This could be a bug in smalivm.
Exception:
	at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:88)
	at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:131)
	at org.cf.smalivm.context.ExecutionContext.staticallyInitializeClassIfNecessary(ExecutionContext.java:206)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:124)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:89)
	at org.cf.simplify.Launcher.executeClass(Launcher.java:186)
	at org.cf.simplify.Launcher.run(Launcher.java:153)
	at org.cf.simplify.Main.main(Main.java:14)
Caused by: java.lang.RuntimeException: Real exception was thrown executing ExecutionNode{signature=Lcom/google/android/gms/common/zzc$zzac$1;-><init>([B)V, op=invoke-direct {r0, r1}, Lcom/google/android/gms/common/zzc$zzc;-><init>([B)V} and was not handled. This could be a bug in smalivm.
Exception:
	at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:88)
	at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:131)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:109)
	at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:327)
	at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:136)
	at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:52)
	at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:77)
	... 8 more
Caused by: java.lang.RuntimeException: Real exception was thrown executing ExecutionNode{signature=Lcom/google/android/gms/common/zzc$zzc;-><init>([B)V, op=invoke-direct {r1, r2}, Lcom/google/android/gms/common/zzc$zza;-><init>([B)V} and was not handled. This could be a bug in smalivm.
Exception:
	at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:88)
	at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:62)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:131)
	at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:109)
	at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:327)
	at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:136)
	at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:52)
	at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:77)
	... 15 more
Caused by: java.lang.RuntimeException: Stub!
	at com.google.android.gms.common.zzc$zza.hashCode(Unknown Source)
	at org.apache.commons.lang3.builder.HashCodeBuilder.append(HashCodeBuilder.java:859)
	at org.cf.smalivm.context.HeapItem.hashCode(HeapItem.java:96)
	at java.util.HashMap.hash(HashMap.java:338)
	at java.util.HashMap.put(HashMap.java:611)
	at java.util.HashSet.add(HashSet.java:219)
	at org.cf.smalivm.context.ExecutionGraph.getRegisterItems(ExecutionGraph.java:372)
	at org.cf.smalivm.context.ExecutionGraph.getRegisterConsensus(ExecutionGraph.java:324)
	at org.cf.smalivm.context.ExecutionGraph.getTerminatingRegisterConsensus(ExecutionGraph.java:439)
	at org.cf.smalivm.context.ExecutionGraph.getTerminatingRegisterConsensus(ExecutionGraph.java:430)
	at org.cf.smalivm.opcode.InvokeOp.executeLocalMethod(InvokeOp.java:380)
	at org.cf.smalivm.opcode.InvokeOp.execute(InvokeOp.java:136)
	at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:52)
	at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:77)
	... 22 more

aput-object should be able to handle items of the same type (specifically classes)

Below is a simplified (oh, my jokes, so good) example of something I'd run across in the wild.

.class public Lbreak_aputs_object;
.super Ljava/lang/Object;

.method public static womp()V
    .registers 5

    const/4 v1, 0x2
    new-array v2, v1, [Ljava/lang/Class;

    const/4 v0, 0x0
    sget-object v3, Ljava/lang/Boolean;->TYPE:Ljava/lang/Class;
    aput-object v3, v2, v0

    const/4 v0, 0x1
    const-class v4, Landroid/app/Instrumentation;
    aput-object v4, v2, v0

    return-void
.end method

Not that it is creating an array of 2 items of type java/lang/Class, then adds them. So the java-esk code would be;

public class breaks_aputs_object {
    public static womp() {
        Class[] classes = new Class[2];
        classes[0] = Boolean.TYPE;
        classes[1] = android.app.Instrumention.class;
    }
}

However since Landroid/app/Instrument; is turned into a LocalClass - it is no longer actually a class, resulting in this error;

Executing: Lbreak_aputs_object;->womp()V
WARN  MethodExecutor - aput-object r4, r2, r0 generated an exception:
java.lang.IllegalArgumentException: array element type mismatch
    at java.lang.reflect.Array.set(Native Method) ~[na:1.7.0_55]
    at org.cf.smalivm.opcode.APutOp.execute(APutOp.java:86) ~[bin/:na]
    at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:45) ~[bin/:na]
    at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:69) ~[bin/:na]
    at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:111) [bin/:na]
    at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:92) [bin/:na]
    at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:88) [bin/:na]
    at org.cf.simplify.Main.main(Main.java:55) [bin/:na]

I'm unsure how this should be handled in the current framework/designs.

Support API 24 and 25

I recently attempted to simplify an app compiled against API 24; it was using java.nio.HeapLongBuffer which is a recent addition to the java framework.

As smalivm uses API 23 internally, it fails with this error, because it is missing this class.

Exception: java.lang.RuntimeException: Real exception was thrown executing ExecutionNode{signature=Ltest/test;-><init>([Ljava/lang/String;)V, op=invoke-virtual {r4, r6}, Ljava/nio/LongBuffer;->put(J)Ljava/nio/LongBuffer;} and was not handled. This could be a bug in smalivm.
Exception: java.lang.RuntimeException: Can't find Smali file for Ljava/nio/HeapLongBuffer;

This issue is created so that work towards supporting newer frameworks is tracked.

onBind default code should not raise a IllegalStateException that kills execution

IllegalStateException occurs when parsing default onBind methods from Android Services - unsure if it's specific to anything around that, I haven't been able to debug it at all. Just dropping this here so one of us can pick it up later.

Executing: Lcom/some/classfrommalware;->onBind(Landroid/content/Intent;)Landroid/os/IBinder;
Simplifying: Lcom/some/classfrommalware;->onBind(Landroid/content/Intent;)Landroid/os/IBinder;
Exception in thread "main" java.lang.IllegalStateException: Cannot get the location of an instruction that >hasn't been added to a method.
at org.jf.dexlib2.builder.BuilderInstruction.getLocation(BuilderInstruction.java:65)
at org.cf.smalivm.context.ExecutionGraph.buildAddressToNodePile(ExecutionGraph.java:40)
at org.cf.smalivm.context.ExecutionGraph.(ExecutionGraph.java:100)
at org.cf.smalivm.VirtualMachine.updateInstructionGraph(VirtualMachine.java:204)
at org.cf.simplify.Main.main(Main.java:71)

Sample smali code that will hit this;

.class public Lcom/some/classfrommalware;
.super Landroid/app/Service;
.source "Diff.java"

# ... snip ...

.method public onBind(Landroid/content/Intent;)Landroid/os/IBinder;
    .registers 3
    .param p1, "intent"    # Landroid/content/Intent;

    .prologue
    .line 70
    const/4 v0, 0x0

    return-object v0
.end method

#... snip ...

Problem with building question

When I try to build the project using >gradle build I get the error "Execution failed for task ':smalivm:compileJava:'. >invalid source release : 1.8". Am I doing something wrong?
I am using gradle 2.10. If I try to build it with >gradlew fatjar it starts downloading gradle 2.7.
Thank you for any help.

Handle UnknownValue elements in Arrays

Right now, if a single element of an array is unknown, the entire arrays becomes unknown. This gives high fidelity optimizations, but it's pessimistic and it could be better.

This would probably require a layer of abstraction between array values as they're stored and how they're accessed.

Unpacking Question ?

do you think i can use smallvm for unpacking android malware ?
by dumping the input of dalvik.system.DexFile.loadDex() and java.lang.Runtime.load() ?

Is Java 8 required?

I'm unable to build, even with smali libraries. I get about 100+ syntax errors stating either

i) not a statement
ii) missing semicolon

obfuscated-example not working

Hi,

I am trying to run simplify against the obfuscated-example with:
$java -jar simplify/build/libs/simplify.jar -it 'org/cf' simplify/obfuscated-example
The following error occurs:

"""
Optimizations:
constantized ifs = 0
constantized ops = 0
dead ops removed = 0
nops removed = 0
peephole optmizations = 0
unreflected fields = 0
unreflected methods = 0
unused assignments removed = 0
unused results removed = 0
useless gotos removed = 0
Executing: Lorg/cf/obfuscated/XORCrypt;->encode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
Aborting execution: org.cf.smalivm.exception.MaxExecutionTimeExceeded: Exceeded execution time in Lorg/cf/obfuscated/XORCrypt;->encode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
Skipping Lorg/cf/obfuscated/XORCrypt;->encode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
Executing: Lorg/cf/obfuscated/XORCrypt;->decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.lang.reflect.Field.copy(Field.java:150)
at java.lang.reflect.ReflectAccess.copyField(ReflectAccess.java:144)
at sun.reflect.ReflectionFactory.copyField(ReflectionFactory.java:309)
at java.lang.Class.copyFields(Class.java:3115)
at java.lang.Class.getDeclaredFields(Class.java:1916)
at com.rits.cloning.Cloner.allFields(Cloner.java:543)
at com.rits.cloning.Cloner.registerStaticFields(Cloner.java:180)
at com.rits.cloning.Cloner.registerKnownConstants(Cloner.java:166)
at com.rits.cloning.Cloner.init(Cloner.java:83)
at com.rits.cloning.Cloner.(Cloner.java:59)
at org.cf.smalivm.context.HeapItem.(HeapItem.java:21)
at org.cf.smalivm.context.Heap.cloneItem(Heap.java:139)
at org.cf.smalivm.context.Heap.get(Heap.java:49)
at org.cf.smalivm.context.Heap.get(Heap.java:69)
at org.cf.smalivm.context.BaseState.peekRegister(BaseState.java:87)
at org.cf.smalivm.context.BaseState.readRegister(BaseState.java:108)
at org.cf.smalivm.context.MethodState.readRegister(MethodState.java:156)
at org.cf.smalivm.opcode.BinaryMathOp.execute(BinaryMathOp.java:72)
at org.cf.smalivm.context.ExecutionNode.execute(ExecutionNode.java:51)
at org.cf.smalivm.NodeExecutor.execute(NodeExecutor.java:31)
at org.cf.smalivm.MethodExecutor.execute(MethodExecutor.java:66)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:99)
at org.cf.smalivm.VirtualMachine.execute(VirtualMachine.java:64)
at org.cf.simplify.Launcher.executeClass(Launcher.java:101)
at org.cf.simplify.Launcher.run(Launcher.java:69)
at org.cf.simplify.Main.main(Main.java:14)
"""

Using
$export JVM_ARGS="-XX:-UseGCOverheadLimit -Xms1024m -Xmx1024m"
Here, any guess on what is going wrong?
Thanks

Failed Tests when building

When building with gradle, the build fails because there were failed tests for :simplify:test. I am using Java SE 8u74 and gradle 2.11. The build report is attached with this post.
Build report :index.pdf

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.