病毒分析
点击放大


![Build Status]() ![Co Status]() ![Co Scan Build Status]()
Simplify executes an app to understand its behavior and then tries to optimize the code so that it beha 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.
The code on the left is a decompilation of an obfuscated app, and the code on the right has been deobfuscated.
<section>
<p align="center">
<img src=" alt="Lots of method calls, no clear meaning" height="380px" align="center" />
<img src=" alt="Wow, such literal, much meaning" height="380px" align="center" />
</p>
</section>
There are three parts to the project: smali, and the demo app.
1. smalivm: Provides a machine sandbox for executing Dal. After executing a method, it returns a graph containing all possible register and class for every execution path. It works even if some 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, remo, 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.
Building requires the Ja Kit 8 (JDK) to be installed.
Because this project contains submodules for Android frameworks, either clone with --recursive:
Or update submodules at any time with:
Then, to build a single jar which contains all dependencies:
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):
To understand what's getting deobfuscated, check out Obfuscated App's README.
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 exceeded, try using higher --max-address-, --max-call-depth, and --max-method-.
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 JA en to your JDK path, and make sure to close and re-open the command prompt you use to build.
Don't be shy. I think 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.
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).
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:
In this example, an encrypted string is decrypted and placed into v0. Since strings are "constantizable", the mo v0 can be replaced with a const-string:
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 , or perform any IO. This is a difficult to determine in static analysis. Luckily, smali't have to be clever. It just stupidly executes e it can and assumes there are side effects if it can't be sure. Consider the example from Constant Propagation:
In this code, the in 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.
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.
Huzzah!
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 in such as:
It can know the of v0, v1, and v2. If it's sure what the are, it can replace the call to Method.invoke() with an actual non-reflected method in. The same applies for reflected field and class lookups.
For e 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.
All this does is v0 = 1.
The mo 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 for every possible execution path at intValue()I. Other types of that can be turned into constants:
* numbers - const/4, const/16, etc.
* strings - const-string
* classes - const-class
Because the code above const/4 v0, 0x1 does not affect state outside of the method (no side-effects), it can be remo changing behavior. If there was a method call that wrote something to the file system or network, it couldn't be remo 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(); }
This tool is a 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 a in the LICENSE.COMMERCIAL and LICENSE.GPL files.
* Dal Execution with SmaliVM
* Guillot, Yoann, and Alexandre Gazet. "Automatic Binary Deobfuscation." Journal in Computer 6.3 (2010): 261-76
* Unicorn - The ultimate CPU emulator
* Babak Yadegari, Saumya Debray. "Symbolic Execution of Obfuscated Code"
* Success stories:
* Android Dynamic Class Loading with "AES/CFB/NoPadding" encryption. Take a peek before & after. Tool used: #simplify. #Android #obfuscation #classencryption #dex
* Decrypting Malware String Encryption
开发语言:Java
Star 数:4668
该项目属于病毒分析方向的开源资源,代码结构清晰,适合安全研究人员学习参考。项目围绕Android virtual machine and deobfuscator展开,提供了可运行的实现,对理解相关安全机制、工具原理与攻防技术具有较高的研究价值。
从技术实现角度看,此类项目的核心在于对底层原理的深入理解与工程化落地。开发者在研究过程中可以结合官方文档与社区讨论,梳理项目的初始化流程、核心模块职责与数据流转,逐步掌握其中的技术细节与设计思路。
1. 下载源码压缩包,解压到本地环境。
2. 根据项目类型准备对应的运行环境与依赖。
3. 按照 README 中的步骤完成配置与部署。
4. 在隔离的测试环境中运行验证,避免影响生产系统。
本资源来源于开源社区,仅供安全研究、技术学习与合法授权范围内的攻防演练使用,请勿用于任何非法或侵害他人权益的用途。使用本项目产生的一切后果由使用者自行承担。
| 资源标题 | simplify - Android virtual machine and deobfuscator |
| 所属分类 | 病毒分析 |
| 发布作者 | admin |
| 发布时间 | 2026-10-05 23:11:19 |
| 下载权限 | 免费下载 |
| 附件数量 | 2 个下载链接 |
| 浏览次数 | 447 |
| 讨论数量 | 0 |
| 主题状态 | 正常讨论中 |