Android virtual machine and deobfuscator

Overview

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

Comments
  • Does this work with native calls?

    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)

    opened by nospam2k 17
  • Step 2/8 throws exception during test [This may be a bug in smalivm or in the input code. Exception: java.lang.RuntimeException: Can't find Smali file for Lcom/sun/crypto/provider/DESKey;]

    Step 2/8 throws exception during test [This may be a bug in smalivm or in the input code. Exception: java.lang.RuntimeException: Can't find Smali file for Lcom/sun/crypto/provider/DESKey;]

    Hi,

    got the error below when trying the test code

    [1 / 22] Processing top level class Lorg/cf/obfuscated/Reflection; (1 / 8) Executing top level method: Lorg/cf/obfuscated/Reflection;->secretMethod2()V Simplifying: Lorg/cf/obfuscated/Reflection;->secretMethod2()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 (2 / 8) Executing top level method: Lorg/cf/obfuscated/Reflection;->reflectSecretMethod2()V 18:30:16.855 WARN NodeExecutor - ExecutionNode{signature=Lorg/cf/obfuscated/DESCrypt;->decrypt([BLjava/lang/String;)Ljava/lang/String;, op=invoke-virtual {r6, r7, r4}, Ljavax/crypto/Cipher;->init(ILjava/security/Key;)V, @=21} threw a real exception but was caught by an exception handler. This may be a bug in smalivm or in the input code. Exception: java.lang.RuntimeException: Can't find Smali file for Lcom/sun/crypto/provider/DESKey; 18:30:16.864 WARN NodeExecutor - ExecutionNode{signature=Lorg/cf/obfuscated/StringHolder;->cacheStrings()Ljava/util/Map;, op=invoke-static {r7, r13}, Lorg/cf/obfuscated/DESCrypt;->decrypt([BLjava/lang/String;)Ljava/lang/String;, @=108} threw a real exception but was caught by an exception handler. This may be a bug in smalivm or in the input code. Exception: java.lang.RuntimeException: Real exception was thrown executing ExecutionNode{signature=Lorg/cf/obfuscated/DESCrypt;->decrypt([BLjava/lang/String;)Ljava/lang/String;, op=invoke-virtual {r2}, Ljava/lang/Throwable;->printStackTrace()V, @=37} and was not handled. This could be a bug in smalivm. Exception: java.lang.NullPointerException 18:30:16.865 WARN NodeExecutor - ExecutionNode{signature=Lorg/cf/obfuscated/Reflection;->reflectSecretMethod2()V, op=invoke-static {r3}, Lorg/cf/obfuscated/StringHolder;->get(I)Ljava/lang/String;, @=2} threw a real exception but was caught by an exception handler. This may be a bug in smalivm or in the input code. Exception: java.lang.RuntimeException: Real exception was thrown executing ExecutionNode{signature=Lorg/cf/obfuscated/StringHolder;->()V, op=invoke-static {}, Lorg/cf/obfuscated/StringHolder;->cacheStrings()Ljava/util/Map;, @=112} and was not handled. This could be a bug in smalivm. Exception: java.lang.RuntimeException: Real exception was thrown executing ExecutionNode{signature=Lorg/cf/obfuscated/StringHolder;->cacheStrings()Ljava/util/Map;, op=invoke-virtual {r5}, Ljava/lang/Throwable;->printStackTrace()V, @=129} and was not handled. This could be a bug in smalivm. Exception: java.lang.NullPointerException Exception in thread "main" java.lang.RuntimeException: Real exception was thrown executing ExecutionNode{signature=Lorg/cf/obfuscated/Reflection;->reflectSecretMethod2()V, op=invoke-virtual {r0}, Ljava/lang/Throwable;->printStackTrace()V, @=32} 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: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)

    Seems I am missing some files. Where to get them and where to put them? Al

    opened by abbana 15
  • Simplify don't see reflection and encryption string.

    Simplify don't see reflection and encryption string.

    I try delete reflection and ecryption string in my apk which packed with dexprotector. In ProtectedApp.smali there are encrypt string and reflection class methods. For examle method decrypt string and reflection class: const-string v31, "\u2ea0\u9661\u60ad\u7c88\u4944\ub51d\ub144\u8c6e\uf953\u688b\ub7e3\uddb6\u9f47\ucfdc\uedf7\u3195" invoke-static/range {v31 .. v31}, Lru/novacard/siticard/ProtectedApp;->a(Ljava/lang/String;)Ljava/lang/String; move-result-object v31 invoke-static/range {v31 .. v31}, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;

    My log: simpl.txt

    I try call simplify with this command. java -jar simplify/build/libs/simplify.jar -it 'ru/novacard/siticard/ProtectedApp' -et 'android/support' -o classes.dex SitiCard/smali I get new classed.dex but reflection and ecrypt string again there are in new dex file. Why so and how fixed ? If you need my apk, i can upload apk you for research.

    opened by maxben14 14
  • Simplify fails to deobfuscate

    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)

    opened by shoubhikraj 14
  • Got an error when i executed a command according to documentation on windows 10

    Got an error when i executed a command according to documentation on windows 10

    I downloaded the 3 jar files from https://github.com/CalebFenton/simplify/releases/tag/v1.3.0

    placed them in C:// path on windows 10 64-bit

    This is the apk https://github.com/CalebFenton/simplify/blob/master/simplify/obfuscated-app.apk

    and executed this command java -jar simplify-1.3.0.jar -it 'org/cf/obfuscated' -et 'MainActivity' obfuscated-app.apk

    But this is the error i am getting

    Exception in thread "main" java.lang.RuntimeException: Unknown input file type; magic: [10, 10, 10] at org.cf.simplify.SimplifyOptions.determineInputType(SimplifyOptions.java:229) at org.cf.simplify.SimplifyOptions.setInFile(SimplifyOptions.java:60) at org.cf.simplify.SimplifyOptionsParser.getSimplifyOptions(SimplifyOptionsParser.java:95) at org.cf.simplify.SimplifyOptionsParser.parse(SimplifyOptionsParser.java:26) at org.cf.simplify.Launcher.getOptions(Launcher.java:58) at org.cf.simplify.Launcher.run(Launcher.java:120) at org.cf.simplify.Main.main(Main.java:14)

    opened by curiousfellas 12
  • Add emulated function and enhance sdbg output

    Add emulated function and enhance sdbg output

    While doing some reversing one of the jiagu360 protectors, I wanted to test out sdbg and simplify. One of the easiest methods was failing and it seemed simple to fix -- hopefully I did it right.

    Also added the breakpoint hit notification to sdbg so it will match gdb.

    opened by strazzere 10
  • 使用ApkTool反编译obfuscated-app_simple.apk查看源代码,发现代码并没任何变化 这是什么问题?

    使用ApkTool反编译obfuscated-app_simple.apk查看源代码,发现代码并没任何变化 这是什么问题?

    C:\Users\Administrator\Desktop\jiuzaikan\反混淆>java -jar D:\androidSpace\simplify-master\simplify\build\libs\simplify-1.2.0.jar -it 'org/cf/obfuscated' -et 'MainActivity' obfuscated-app.apk
    Simplification complete:
            total classes = 0
            total methods = 0
            optimized methods = 0
            failed methods = 0
            run time = 9912 ms
    Total optimizations:
    
    Writing output to obfuscated-app_simple.apk
    
    opened by goodluckforme 10
  • failure on abstract class and implementer emulation

    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;
    ...
    
    opened by EG-ITz 10
  • Error: A JNI error has occurred, please check your installation and try again

    Error: A JNI error has occurred, please check your installation and try again

    I am following the installation guide but when I try to run the script onobfuscated-app.apk, I am getting the following error.

    Error: A JNI error has occurred, please check your installation and try again
    Exception in thread "main" java.lang.NoClassDefFoundError: org/cf/smalivm/exception/UnhandledVirtualException
            at java.lang.Class.getDeclaredMethods0(Native Method)
            at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
    	at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
    	at java.lang.Class.getMethod0(Class.java:3018)
    	at java.lang.Class.getMethod(Class.java:1784)
    	at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
    	at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
    Caused by: java.lang.ClassNotFoundException: org.cf.smalivm.exception.UnhandledVirtualException
    	at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    	at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
    	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
    	at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
    	... 7 more
    
    

    Screenshot: Screenshot from 2020-02-10 13-43-55

    Development Environment: java version "1.8.0_241" Gradle Version: 6.1.1

    I have tested it on 3 different machines with the same dev environment. 1: Local ubuntu machine 2: Virtual Santoku machine 3: AWS Server ubuntu machine

    This is my first time using simplify, kindly guide me if I am missing something. Thanks

    P.S: I cloned it recursively as mentioned in build guide.

    opened by dev7machine 9
  • Smalivm throws weird exceptions

    Smalivm throws weird exceptions

    I was trying to use Smalivm and I followed your instructions on building it, now I'm getting the following error:

    java.lang.RuntimeException: Error loading class definition: Landroid/icu/text/MessagePatternUtil;
    	at org.cf.smalivm.type.ClassManager.parseClass(ClassManager.java:168)
    	at org.cf.smalivm.type.ClassManager.parseClassIfNecessary(ClassManager.java:187)
    	at org.cf.smalivm.type.ClassManager.getVirtualType(ClassManager.java:120)
    	at org.cf.smalivm.type.ClassManager.getVirtualType(ClassManager.java:139)
    	at org.cf.smalivm.type.ClassManager.getVirtualClass(ClassManager.java:113)
    	at org.cf.smalivm.dex.SmaliClassLoader.findClass(SmaliClassLoader.java:92)
    	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:39)
    	at org.cf.smalivm.VirtualMachine.spawnRootContext(VirtualMachine.java:173)
    	at org.cf.smalivm.VirtualMachine.spawnRootContext(VirtualMachine.java:164)
    	at org.cf.smalivm.VirtualMachine.spawnRootContext(VirtualMachine.java:160)
    	at org.cf.smalivm.VirtualMachine.spawnRootContext(VirtualMachine.java:151)
    	at Main.run(Main.java:26)
    	at Main.main(Main.java:17)
    Caused by: java.lang.NullPointerException
    	at java.io.Reader.<init>(Reader.java:78)
    	at java.io.InputStreamReader.<init>(InputStreamReader.java:97)
    	at org.cf.smalivm.dex.SmaliParser.parse(SmaliParser.java:69)
    	at org.cf.smalivm.type.ClassManager.parseClass(ClassManager.java:165)
    	... 15 more
    

    My code looks like (it's Kotlin):

    import org.cf.smalivm.VirtualMachineFactory
    
    fun main(args: Array<String>) {
        val dex = "classes.dex"
        val methodSignature = "Lfsdfsdf/gsdsfsf/gjhghjg/lbljhkjblkjblkjblkj/accompanyingasfasfasfasfafa;->absorbasfasfasfasfafa(Ljava/lang/String;)Ljava/lang/String;"
        val arg = "\u001AT\u001FH\u0014S\u001F\u0014\u001AJ\u000B\u0014\u001AY\u000FS\u0014TU{?~$~>l2y>e:~6s5"
    
        val vmFactory = VirtualMachineFactory()
        val vm = vmFactory.build(dex)
        val ectx = vm.spawnRootContext(methodSignature)
        val mState = ectx.methodState
        mState.assignParameter(0, arg, "Ljava/lang/String")
    
        vm.execute(methodSignature, ectx)
    }
    

    This is the Java equivalent which gives me the same error:

    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.MethodState;
    
    import java.io.IOException;
    
    public class Main {
        final static String dexPath = "classes.dex";
        final static String methodSignature = "Lfsdfsdf/gsdsfsf/gjhghjg/lbljhkjblkjblkjblkj/accompanyingasfasfasfasfafa;->absorbasfasfasfasfafa(Ljava/lang/String;)Ljava/lang/String;";
        final static String arg = "\u001AT\u001FH\u0014S\u001F\u0014\u001AJ\u000B\u0014\u001AY\u000FS\u0014TU{?~$~>l2y>e:~6s5";
    
        public static void main(String[] args) {
            try {
                run();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        private static void run() throws IOException, VirtualMachineException {
            VirtualMachineFactory vmFactory = new VirtualMachineFactory();
            VirtualMachine vm = vmFactory.build(dexPath);
            ExecutionContext ectx = vm.spawnRootContext(methodSignature);
            MethodState mState = ectx.getMethodState();
            mState.assignParameter(0, arg, "Ljava/lang/String;");
            ExecutionGraph graph = vm.execute(methodSignature, ectx);
            System.out.println("Done!");
        }
    }
    
    opened by voider1 9
  • Using Smali Debugger on single smali file

    Using Smali Debugger on single smali file

    I have a very simply Smali file on which I would like to test the Smali debugger, but I haven't been able to find the right syntax. None of the following work:

    java -jar ~/softs/simplify/sdbg/build/libs/sdbg.jar mysmali "Lunused;->main([Ljava/lang/String;)V"
    java -jar ~/softs/simplify/sdbg/build/libs/sdbg.jar unused "Lunused;->main([Ljava/lang/String;)V"
    java -jar ~/softs/simplify/sdbg/build/libs/sdbg.jar unused.zip "Lunused;->main([Ljava/lang/String;)V"
    java -jar ~/softs/simplify/sdbg/build/libs/sdbg.jar unused.zip "Lunused/main([Ljava/lang/String;)V"
    java -jar ~/softs/simplify/sdbg/build/libs/sdbg.jar classes.dex "Lunused;->main([Ljava/lang/String;)V"
    

    This is my Smali file:

    .class public Lunused;
    .super Ljava/lang/Object;
    
    .method public static test()Z
    	.registers 2
    	
    	const/4 v0, 0x0
    
    	const-string v1, "This string is hidden to decompiler"
    
    	const/4 v0, 0x1
    
    	return v0
    	
    .end method
    
    .method public static main([Ljava/lang/String;)V
    	.registers 2
    
       	invoke-static {}, Lunused;->test()Z
    
    	move-result v0
    
    	if-eqz v0, :cond_2
    
    	sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
    
        	const-string v1, "Called test() which contains a hidden constant string"
    
       	invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
    
    	:cond_2
    
    	return-void
        
    .end method
    

    I compile this as classes.dex using smali. Then, I create a zip containing classes.dex Basically this is my Makefile:

    all: unused.zip
    	adb push $< /sdcard/$<
    	adb shell dalvikvm -cp /sdcard/$< $(basename $<)
    	cp classes.dex /tmp/jeb2-share
    
    %.zip: classes.dex
    	zip $@ $<
    
    classes.dex: unused.smali
    	java -jar $(SMALI) a $< -o $@
    
    %.dex: %.class
    	$(DX) --dex --output $@ $<
    
    %.smali: %.dex
    	java -jar $(BAKSMALI) $@ -o $<
    

    There is probably no bug in your smali debugger, most probably it's just that I am not calling it the right way.

    opened by cryptax 8
  • Support multiple DEX files

    Support multiple DEX files

    Is your feature request related to a problem? Please describe.

    I have an apps obfuscated source code which contains > 65536 methods, meaning it is split up into multiple classes[n].dex. I cannot use simplify on this app, because it only works against one file, and so:

    $ java -jar ~/Downloads/simplify-1.3.0.jar *.dex
    [1 / 1463] Processing top level class Lmoi;
    (1 / 4) Executing top level method: Lmoi;->b(LA0i;LuNr;LtNr;)V
    WARNING: An illegal reflective access operation has occurred
    WARNING: Illegal reflective access by com.rits.cloning.Cloner (file:/mnt/c/Users/Peter/Downloads/simplify-1.3.0.jar) to field java.util.TreeSet.m
    WARNING: Please consider reporting this to the maintainers of com.rits.cloning.Cloner
    WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
    WARNING: All illegal access operations will be denied in a future release
    Exception in thread "main" java.lang.RuntimeException: Can't find Smali file for LHB7;
    

    Describe the solution you'd like

    A way to process multiple DEX files

    opened by reteps 0
  • Dex Writing Error : New Issue related to #150

    Dex Writing Error : New Issue related to #150

    classes.dex.zip Error is same as of https://github.com/CalebFenton/simplify/issues/150 writing dex after simplification but with different type

    java -jar simplify.jar --max-call-depth 999 --max-address-visits 999 --max-method-visits 999 --ignore-error classes.dex 
     
    .....
     Optimizations:                                                        
      constantized ifs = 0                                           
      constantized ops = 2                                            
      dead assignments removed = 3                                    
      dead ops removed = 0                                            
      dead results removed = 1                                        
      nops removed = 0                                                
      peephole optmizations = 0                                       
      unreflected fields = 0                                          
      unreflected methods = 0                                         
      useless gotos removed = 0                               
    Simplification complete:                                                
      total classes = 38                                             
      total methods = 3                                               
    optimized methods = 415                                         
      failed methods = 72                                             
      run time = 142047 ms                                    
    Total optimizations:                                                    
      constantized ifs = 268                                          
      constantized ops = 327                                          
      dead assignments removed = 349                                  
      dead ops removed = 239                                          
      dead results removed = 288                                      
      nops removed = 268                                              
      peephole optmizations = 0                                       
      unreflected fields = 0                                          
      unreflected methods = 0                                         
      useless gotos removed = 0                               
    Writing output to classes_simple.dex                            
    Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!                         
       at java.base/java.util.TimSort.mergeHi(Unknown Source)          
       at java.base/java.util.TimSort.mergeAt(Unknown Source)          
       at java.base/java.util.TimSort.mergeCollapse(Unknown Source)                                                                    
       at java.base/java.util.TimSort.sort(Unknown Source)             
       at java.base/java.util.Arrays.sort(Unknown Source)              
       at java.base/java.util.ArrayList.sort(Unknown Source)           
       at java.base/java.util.Collections.sort(Unknown Source)         
       at org.jf.dexlib2.writer.DexWriter.writeStrings(DexWriter.java:415)                                                             
       at org.jf.dexlib2.writer.DexWriter.writeTo(DexWriter.java:312)                                                                  
       at org.jf.dexlib2.writer.DexWriter.writeTo(DexWriter.java:300)                                                                  
       at org.cf.simplify.Launcher.run(Launcher.java:148)              
       at org.cf.simplify.Main.main(Main.java:13) 
    
    opened by apkunpacker 0
  • Java.lang.RuntimeException: Error loading class definition

    Java.lang.RuntimeException: Error loading class definition

    TestSimplify.apk.zip

    java -jar simplify.jar --max-call-depth 999 --max-address-visits 999 --max-method-visits 999 --ignore-error TestSimplify.apk
    
    Error :
    
    
    com/test/dec/SketchwareUtil.smali[128,4] null
    Exception in thread "main" java.lang.RuntimeException: Error loading class definition: Lcom/test/dec/SketchwareUtil;
            at org.cf.smalivm.type.ClassManager.parseClass(ClassManager.java:187)
            at org.cf.smalivm.type.ClassManager.parseClassIfNecessary(ClassManager.java:205)
            at org.cf.smalivm.type.ClassManager.getVirtualType(ClassManager.java:137)
            at org.cf.smalivm.type.ClassManager.getVirtualType(ClassManager.java:158)
            at org.cf.smalivm.type.ClassManager.getVirtualClass(ClassManager.java:130)
            at org.cf.simplify.Launcher.collectTargetClassNameToMethods(Launcher.java:166)
            at org.cf.simplify.Launcher.run(Launcher.java:133)
            at org.cf.simplify.Main.main(Main.java:13)
    Caused by: java.lang.RuntimeException: Unable to walk: /data/data/com.termux/files/usr/tmp/simplify11836953586600987855/com/test/dec/SketchwareUtil.smali
            at org.cf.smalivm.dex.SmaliParser.parse(SmaliParser.java:83)
            at org.cf.smalivm.type.ClassManager.parseClass(ClassManager.java:184)
            ... 7 more
    

    and simplify stopped . i had look to this error prone class but not understand why it giving error because all tool can parse it as proper .smali file . lost original apk , only this apk left because in this i merged 2 dex into single one as simplify not aware about multidex yet

    opened by apkunpacker 5
  • [Bug] [SmaliVM] visitClassAnnotations() fail on parsing obfuscated member class names

    [Bug] [SmaliVM] visitClassAnnotations() fail on parsing obfuscated member class names

    Some obfuscators tend to rename member classes to short random strings like "Ab" or "Bc".

    .class public final Lde/fipso/test/container/ui/ContainerActivity;
    .super Landroidx/appcompat/app/AppCompatActivity;
    .source "ContainerActivity.kt"
    
    # annotations
    .annotation system Ldalvik/annotation/MemberClasses;
        value = {
            Lde/fipso/test/rL;
        }
    .end annotation
    

    visitInnerClasses() then fails to parse the inner and outer class name, because we are not using the default class name format with the $ as the separator. (java.lang.ArrayIndexOutOfBoundsException: 1 -> ClassBuilder.java:150);

    EDIT: This could be a baksmali issue.

    opened by fipso 3
  • Improve Dead Code Removal Method

    Improve Dead Code Removal Method

    Obfuscator Used :

    5742964208d197f408c982e6424902154505e2f1c4a0ee5d645d42d6a20f346c
    

    MProtector_2.0.apk.zip created by https://github.com/KingMahmud

    Sample Obfuscated : Sample.apk.zip

    Simplify Command Used :

    java -jar simplify.jar --max-call-depth 999999 --max-address-visits 999999 --max-method-visits 999999 --ignore-error -it 'Lcom/tilks/arsc/main/MainActivity;->e\(' Sample.apk
    

    logs :

    11:19:21.704 INFO  Main         - Options:
    Input file: Sample.apk.zip
    Output file: Sample.apk_simple.zip
    Include filter: Lcom/tilks/arsc/main/MainActivity;->e\(
    Exclude filter: null
    Max execution time: 300
    Max address visits: 999999
    Max call depth: 999999
    Max method visits: 999999
    Max optimization passes: 100
    Output API level: 20
    Include support library: false
    11:19:24.053 INFO  Main         - Filtered 0 support library classes
    [1 / 1] Processing top level class Lcom/tilks/arsc/main/MainActivity;
    (1 / 1) Executing top level method: Lcom/tilks/arsc/main/MainActivity;->e()Ljava/lang/String;
    11:19:40.461 INFO  NonInteractiveMethodExecutor - Executing Landroid/app/Activity;-><clinit>()V, depth=0
    11:19:40.537 INFO  NonInteractiveMethodExecutor - Executing Lcom/tilks/arsc/main/MainActivity;-><clinit>()V, depth=0
    11:19:40.613 INFO  NonInteractiveMethodExecutor - Executing Lcom/tilks/arsc/main/MainActivity;->e()Ljava/lang/String;, depth=0
    11:19:40.634 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_()V, depth=1
    11:19:40.664 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_()V, depth=1
    11:19:40.717 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:40.758 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:40.821 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:40.882 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_()V, depth=1
    11:19:40.918 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_()V, depth=1
    11:19:40.949 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:40.969 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:40.989 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:41.010 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_()V, depth=1
    11:19:41.031 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_()V, depth=1
    11:19:41.052 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:41.073 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:41.093 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:41.153 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_()V, depth=1
    11:19:41.214 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_()V, depth=1
    11:19:41.266 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:41.286 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:41.308 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:41.328 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_()V, depth=1
    11:19:41.349 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_()V, depth=1
    11:19:41.370 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:41.391 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:41.412 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:41.433 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_()V, depth=1
    11:19:41.455 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_()V, depth=1
    11:19:41.477 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:41.498 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:41.520 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:41.541 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:41.562 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:41.584 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:41.605 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_()V, depth=1
    11:19:41.627 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_()V, depth=1
    11:19:41.657 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_()V, depth=1
    11:19:41.675 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:41.905 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_()V, depth=1
    11:19:41.955 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:42.036 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:42.075 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:42.118 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:42.163 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_(Ljava/lang/String;)V, depth=1
    11:19:42.239 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_()V, depth=1
    11:19:42.256 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_()V, depth=1
    Simplifying: Lcom/tilks/arsc/main/MainActivity;->e()Ljava/lang/String;
    11:19:42.374 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_()V, depth=1
    11:19:42.388 INFO  NonInteractiveMethodExecutor - Executing L€/£/¥/₩;->_()V, depth=1
    Optimizations:
    	constantized ifs = 0
    	constantized ops = 0
    	dead assignments removed = 24
    	dead ops removed = 0
    	dead results removed = 0
    	nops removed = 0
    	peephole optmizations = 0
    	unreflected fields = 0
    	unreflected methods = 0
    	useless gotos removed = 0
    Simplification complete:
    	total classes = 1
    	total methods = 1
    	optimized methods = 1
    	failed methods = 0
    	run time = 20713 ms
    Total optimizations:
    	constantized ifs = 0
    	constantized ops = 0
    	dead assignments removed = 24
    	dead ops removed = 0
    	dead results removed = 0
    	nops removed = 0
    	peephole optmizations = 0
    	unreflected fields = 0
    	unreflected methods = 0
    	useless gotos removed = 0
    Writing output to Sample.apk_simple.zip
    

    That method after simplified : simplified.txt

    Expected : expected.txt

    Reason :

    invoke-static/range {v1 .. v1}, L€/£/¥/₩;->_(Ljava/lang/String;)V
    

    and

    invoke-static {}, L€/£/¥/₩;->_()V
    

    are empty method , anything pass through them have no effect on code so they should be considered as dead and removed . continuous use of same register again and again also should be treated as dead as next assignment of same register overwrite previous value like

        invoke-static {}, L€/£/¥/₩;->_()V
    
        invoke-static {p0}, Landroid/preference/PreferenceManager;->getDefaultSharedPreferences(Landroid/content/Context;)Landroid/content/SharedPreferences;
    
        move-result-object v0
    
        invoke-static {}, L€/£/¥/₩;->_()V
    
        const-string v1, "saallnnsls"
    
        invoke-static/range {v1 .. v1}, L€/£/¥/₩;->_(Ljava/lang/String;)V
    
        const-string v1, "ELBANENGIS"
    
        invoke-static/range {v1 .. v1}, L€/£/¥/₩;->_(Ljava/lang/String;)V
    
        const-string v1, "signenable"
    
        invoke-static/range {v1 .. v1}, L€/£/¥/₩;->_(Ljava/lang/String;)V
    
    

    could be simplified to

         invoke-static {p0}, Landroid/preference/PreferenceManager;->getDefaultSharedPreferences(Landroid/content/Context;)Landroid/content/SharedPreferences;
    
        move-result-object v0
       
        const-string v1, "signEnable"
    

    as v1 keep overwritten and only last assignment of register is used

    Thanks

    opened by apkunpacker 3
Releases(v1.3.0)
  • v1.3.0(Mar 30, 2020)

    This version has a few fixes but mostly the new new Smali Debugger tool which allows you to step through smalivm executions line by line, set breakpoints, etc. It was an experiment to see if smalivm could easily be used as a library (it's easier now) and to play with Kotlin. Check it out and let me know what you think.

    Version bump to 1.3.x because of some changes to the API.

    Here's the change log.

    • Many small improvements to make smalivm a better library for more than just simplify
    • Fix correctness bugs around invoking methods and maintaining correct state
    • Updated dependencies
    Source code(tar.gz)
    Source code(zip)
    sdbg-0.1.0.jar(74.40 MB)
    simplify-1.3.0.jar(71.43 MB)
    smalivm-1.3.0.jar(61.51 MB)
  • v1.2.1(Jan 24, 2019)

    It's been a while since the last release, and there have been quite a few changes. So, here's a release!

    • Better console output by showing progress / remaining classes
    • Better error handling (improved stability)
    • Improved Enum and Array handling
    • Updated dependencies
    • Cleaned up the API for smalivm
    • Modernized ObfuscatedApp's encryption obfuscation so it's a more realistic test
    • Added Object.getClass emulation and peephole optimization
    • Lots of little bug fixes
    Source code(tar.gz)
    Source code(zip)
    simplify-1.2.1.jar(70.95 MB)
    smalivm-1.2.1.jar(70.12 MB)
  • v1.2.0(Jul 30, 2017)

    This release fixes a lot of bugs and changes the output format to make it a little easier to read. Thanks to the many people who reported bugs. You brave souls!

    Here's a quick overview of the changes:

    • Visual indicator of progress through classes and methods, and some simple run time stats
    • Fix for enum instantiation, objects created via reflection have more correct type
    • Improved type flow, when a method can't be invoked because arguments aren't valid, don't use type from method signature unless it's more specific than type of the argument
    • Improved correctness for aput ops
    • Improved correctness when determining consensus type
    • Improved correctness when updating argument identities during multiverse collapse
    • Updated dependencies, notably dexlib updated to 2.2.1
    • Updated reference framework to Android-25
    • Implemented monitor-enter and monitor-exit opcodes (used to be handled by UnknownOp)
    Source code(tar.gz)
    Source code(zip)
    simplify-1.2.0.jar(70.53 MB)
    smalivm-1.2.0.jar(69.69 MB)
  • v1.1.0(Aug 6, 2016)

    New release. It's not just a point release because there were some API changes in smalivm. Here's the changelog:

    • Allow static initialization of fields using literals, e.g. .field myInt:I = 0x42
    • Fixed several problems with looking up inherited fields
    • Better merging of states from called methods
    • Better exception handling - implement throw and move-exception
    • Improved correctness for instance-of and check-cast ops
    • Improved correctness for java.lang.reflect.Field.get() emulated method
    • API change - much of the functionality in ClassManager was moved to VirtualGeneric
    • Fixed many small bugs and possibly added a few new ones
    • Fixed embarrassingly large number of typos
    Source code(tar.gz)
    Source code(zip)
    simplify-1.1.0.jar(62.05 MB)
    smalivm-1.1.0.jar(61.26 MB)
  • v1.0.0(Feb 23, 2016)

  • v1.0.0-M1(Feb 15, 2016)

    It's been a few years since this all started, but there is finally a milestone release for v1.0. The next few milestones will be focused on fixing bugs and shaking out any issues made by some of the drastic changes in the past several commits.

    Changes:

    • Dynamically create JVM classes for input and framework Smali
    • Speed up cloning by making a Cloner which knows about immutable Android classes meaning fewer objects need deep cloning
    • Update framework reference Smali to to Android API 23
    • Various bug fixes and improvements (and probably some new bugs!)
    Source code(tar.gz)
    Source code(zip)
    simplify-1.0.0-M1.jar(61.98 MB)
    smalivm-1.0.0-M1.jar(61.23 MB)
  • v0.9.1(Dec 18, 2015)

  • v0.9.0(Oct 18, 2015)

    Changes:

    • More robust manipulation of execution graphs
    • Added optimization for ifs with constant predicates
    • Added --max-execution-time for long running methods
    • Added ExecutionGrapher which gives a GraphViz compatible DOT file for an execution graph. Screen shots below.
    • Improved dead code detection
    • Mostly eliminated method re-execution during optimization
    • Many more tests and bug fixes

    Here's a small example method graph to show what ExecutionGrapher does. Each node in the graph is the execution of some instruction, along with all the relevant context at that point. This is before optimization: graph-before

    Graph after optimization: graph-after

    Source code(tar.gz)
    Source code(zip)
    simplify-0.9.0.jar(28.94 MB)
    smalivm-0.9.0.jar(28.06 MB)
  • v0.8.0(Sep 28, 2015)

Owner
Caleb Fenton
Cyberweaponsmith
Caleb Fenton
Deobfuscator for Android Application

This Tool is selected as BlackHat Arsenal USA 2020 What is Deoptfuscator Deoptfuscator is a tool for deobfuscating Android applications that have been

null 282 Dec 20, 2022
MiHawk 🦅👁️ is simple and secure 🔒 Android Library to store and retrieve pair of key-value data with encryption , internally it use jetpack DataStore Preferences 💽 to store data.

MiHawk MiHawk ?? ??️ is simple and secure ?? Android Library to store and retrieve pair of key-value data with encryption , internally it use jetpack

Nedal Hasan Ibrahem 5 Sep 3, 2022
BlackDex is an Android unpack tool, it supports Android 5.0~12 and need not rely to any environment. BlackDex can run on any Android mobile phones or emulators, you can unpack APK File in several seconds.

BlackDex is an Android unpack tool, it supports Android 5.0~12 and need not rely to any environment. BlackDex can run on any Android mobile phones or emulators, you can unpack APK File in several seconds.

null 4.3k Jan 2, 2023
Simple API to perform AES encryption on Android. This is the Android counterpart to the AESCrypt library Ruby and Obj-C (with the same weak security defaults :( ) created by Gurpartap Singh. https://github.com/Gurpartap/aescrypt

AESCrypt-Android Simple API to perform AES encryption on Android with no dependancies. This is the Android counterpart to the AESCrypt library Ruby an

Scott Alexander-Bown 636 Dec 18, 2022
Grab’n Run, a simple and effective Java Library for Android projects to secure dynamic code loading.

Grab’n Run, a simple and effective Java Library for Android projects to secure dynamic code loading.

Luca Falsina 418 Dec 29, 2022
A Java ePub reader and parser framework for Android.

FolioReader-Android is an EPUB reader written in Java and Kotlin. Features Custom Fonts Custom Text Size Themes / Day mode / Night mode Text Highlight

FolioReader 2.1k Jan 3, 2023
A program to flip every private, protected and package-private access flag to public in an Android dex file!

DexExposed A program to flip every private, protected and package-private access flag to public in an Android dex file! Building Simply run gradle mak

John Doe 2 Aug 29, 2021
A simple android app that parses its own signature and displays it

SigDisplayer Usage Download the release APK or clone the repository and compile yourself. Sign the APK with your preferred keystore. Install and open

Jonah 5 Oct 18, 2022
A program analysis tool to find cryptographic misuse in Java and Android.

A program analysis tool to find cryptographic misuse in Java and Android.

null 92 Dec 15, 2022
CRYLOGGER: Detecting Crypto Misuses for Android and Java Apps Dynamically

CRYLOGGER: Detecting Crypto Misuses for Android and Java Apps Dynamically

Luca Piccolboni 139 Dec 12, 2022
A tool translate a apk file to stantard android project include so hook api and il2cpp c++ scaffolding when apk is a unity il2cpp game. Write code on a apk file elegantly.

FakerAndroid (FakerAndroid.jar or FakerAndroid-AS) A tool translate a apk file to stantard android project include so hook api and il2cpp c++ scaffold

null 231 Dec 29, 2022
Writeup and exploit for installed app to system privilege escalation on Android 12 Beta through CVE-2021-0928, a `writeToParcel`/`createFromParcel` serialization mismatch in `OutputConfiguration`

Writeup and exploit for installed app to system privilege escalation on Android 12 Beta through CVE-2021-0928, a `writeToParcel`/`createFromParcel` serialization mismatch in `OutputConfiguration`

null 52 Dec 30, 2022
Easy to use cryptographic framework for data protection: secure messaging with forward secrecy and secure data storage. Has unified APIs across 14 platforms.

Themis provides strong, usable cryptography for busy people General purpose cryptographic library for storage and messaging for iOS (Swift, Obj-C), An

Cossack Labs 1.6k Dec 29, 2022
A simple and opinionated AES encrypt / decrypt Ruby gem that just works.

AESCrypt - Simple AES encryption / decryption for Ruby AESCrypt is a simple to use, opinionated AES encryption / decryption Ruby gem that just works.

Gurpartap Singh 158 Oct 18, 2022
Burp extension to create target specific and tailored wordlist from burp history.

Burp extension to create target specific and tailored wordlist from burp history.

Dexter0us 173 Jan 2, 2023
Secure your REST APIs with Spring Security, Resource and Authorization Server from zero to JWT

Secure REST APIs with Spring ./mvnw RTFM YouTube: Spring Security Patterns YouTube: Spring Security 5.5 From Taxi to Takeoff Official Apache Maven doc

Maksim Kostromin 1 Dec 5, 2021
Improve automated and semi-automated active scanning in Burp Pro

PentagridScanController Improve automated and semi-automated active scanning for BurpSuite Author: Tobias "floyd" Ospelt, @floyd_ch, http://www.floyd.

Pentagrid AG 48 Dec 13, 2022
UNIX-like reverse engineering framework and command-line toolset

Radare2: The Libre Unix-Like Reverse Engineering Framework See the Releases page for downloads. The current git master branch is 5.7.7, next will be 5

radare org 17.4k Jan 9, 2023