Dexcalibur v0.7.9 releases: Android reverse engineering platform
Dexcalibur is an Android reverse engineering platform focus on instrumentation automation. Its particularity is to use dynamic analysis to improve static analysis heuristics. It aims to automate boring tasks related to dynamic instrumentation, such as :
- Decompile/disass intercepted bytecode at runtime
- Write hook code and Manage a lot of hook message
- Search interesting pattern/things to hook
- Process data gathered by hook (dex file, invoked method, class loader, …)
- and so … But not only that, because Dexcalibur has its own static analysis engine and it is able to execute a partial piece of smali.
Features and limitations
Actually, the biggest limitation is Dexcalibur is not able to generate source code of hook targeting native function (into JNI library). However, you can declare manually a Frida’s Interceptor by editing a hook.
Assuming Dexcalibur does not provide (for the moment) features to analyze native parts such as the JNI library or JNA, only features and limitations related to the Java part have been detailed.
Analysis accuracy depends on the completeness of the Android API image used during the early steps of the analysis. That means, if you use a DEX file generated from the Android.jar file from Android SDK, some references to internal methods, fields, or classes from Android java API could be missing. Better results are obtained when the analysis starts from a “boot.oat” file extracted directly from a real device running the expected Android version.
D.1.A Static analyzer
TODO : write text
D.1.B Hook manager
TODO : write text
D.1.C Dexcalibur’s smali VM
Static analyzer involved in “Run smali (VM)” action is able to discover and accept but track the following behaviors :
- Out-of-bound destination register (register out of v0 – v255)
- Out-of-bound source register (register out of v0 – v65535)
- Detect invalid instruction throwing implicitly an internal exception
- Detect some piece of valid bytecode non-compliant with Android specification
- Compute the length of an undefined array
- Fill undefined array
- and more …
Actually, handlers/listeners for such invalid instruction are not supported but events are tracked and rendered.
The VM produces a custom and simplified Intermediate Representation (IR) which is displayed only to help analysts to perform its analysis.
Depending on the value of the callstack depth and configuration, IR can include or not instruction executed into the called function. If the execution enters into a try block and continues to return, but never executes the catch, then the catch block will not be rendered. In fact, the purpose of Dexcalibur IR is to render only “what is executed” or “what could be executed depending on some symbol’s value” into VM context.
Dexcalibur IR helps to read a cleaned version of bytecode by removing useless goto and opaque predicate. Dexcalibur IR can be generated by the VM with 2 simplifying levels :
1st level IR could be used if you don’t trust 2nd level IR :
- no CFG simplifying: conditions and incondtionnal jumps are rendered.
- every move into a register are rendered
2nd level :
- Hide assign if the register is not modified with an unknown value before its use.
- Always TRUE/FALSE predicate are removed
- Inconditional jump such goto are removed under certain conditions: single predecessor of a targeted basic block, etc …
- Resolve & replace Method.inoke() call by called method if possible.
- Instructions into a Try block are not rendered if an exception is thrown before
Fixed issues :
- Goto label inserted into array statement are ignored
- Addditionnal characters after string delimiter are ignored
Copyright 2019 Georges-Bastien MICHEL