Metadata-Version: 2.1
Name: kavanoz
Version: 0.0.3
Summary: Unpacking framework for common android malware
Author: Ahmet Bilal Can
Author-email: eybisii@gmail.com
Maintainer-email: Ahmet Bilal Can <eybisii@gmail.com>
License: MIT License
Keywords: android,malware,unpacking,packer
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: androguard==4.0.1
Requires-Dist: apkInspector>=1.2.1
Requires-Dist: androidemu==0.0.2
Requires-Dist: arc4==0.3.0
Requires-Dist: androguard
Requires-Dist: halo==0.0.31
Requires-Dist: lief==0.12.3
Requires-Dist: loguru==0.6.0
Requires-Dist: pycryptodome==3.16.0

# 🫙 kavanoz 🫙
![](https://img.shields.io/github/license/eybisi/kavanoz)
![](https://img.shields.io/github/stars/eybisi/kavanoz)
![](https://img.shields.io/github/issues-closed/eybisi/kavanoz.svg)
![](https://img.shields.io/github/issues-pr-closed/eybisi/kavanoz.svg)

Statically unpacking common android banker malware.
Ever wanted to get payload from packed malware without running android emulator ? Me neither.

![](assets/unpack.gif)

### :eyes: Installation

```
pip install kavanoz
```

### :zap: Usage

from cmdline
```bash
kavanoz /tmp/filepath
```

from python library
```py
from kavanoz.core import Kavanoz
from kavanoz import utils

utils.set_log("DEBUG")
k = Kavanoz(apk_path="tests/test_apk/coper.apk")
for plugin_result in k.get_plugin_results():
    if plugin_result["status"] == "success":
        print("Unpacked")
        print(plugin_result)
        break
```

### :snake: Scripts:

- [rc4.py](src/kavanoz/loader/rc4.py) Generic rc4 encrypted asset file. Script covers multiple versions.
- [old_rc4.py](src/kavanoz/loader/old_rc4.py) Another Generic rc4 encrypted asset file.
- [subapp.py](src/kavanozloader/subapp.py) Decryption of file with key derived from Manifest file ProtectKey variable
- [multidex.py](src/kavanoz/loader/multidex.py) Multidex like loader with inflated packed file. (zlib compression)
- [coper.py](src/kavanoz/loader/coper.py) Extract rc4 key from native lib with emulation (AndroidNativeEmu)
- [moqhao.py](src/kavanozloader/moqhao.py) Emulation for moqhau unpacking.
- [sesdex.py](src/kavanoz/loader/sesdex.py)
- [simple_aes.py](src/kavanoz/loader/simple_aes.py)
- [simple_xor.py](src/kavanoz/loader/simple_xor.py)
- [simple_xor2.py](src/kavanoz/loader/simple_xor2.py)
- [simple_xor_zlib.py](src/kavanoz/loader/simple_xor_zlib.py)
- [subapp.py](src/kavanoz/loader/subapp.py) Decrypt asset with package name


### :gear: Development

To add new plugins just create new file in loader folder. Extend Unpacker class from unpack_plugin.py file. Define start_decrypt function with your implementation. 
```py
def start_decrypt(self, apk_object: APK, dexes: "list[DEX]"):
```

Add following function to make early exit from plugin. 
```py
def lazy_check(self,apk_object:APK, dexes: "list[DEX]"):
```

If extraction is succesful assign self.decrypted_payload_path with extracted file path.
You can use helper functions from unpacker class:
- get_array_data
- get_smali
- find_method(class_name,method_name,descriptor="")
- check_and_write_file(file_data) : checks file has dex, zip and zlib headers and writes unpacked dex with name : "external-{m[:8]}.dex"

### :book: Tips

- self.dexes hold dex objects. You can get class with `dex.get_class(smali_annotation_of_class)`.
- You can use get_smali function and give target method obj to get smali represantation of target method. Then apply some regex to get data from smali. There are lots of defined regexs in [smali_regexes.py](smali_regexes.py) file to lookup. 
- Most of the time packers use file from asset folder. You can get files with `self.apk_object.get_files()` 
- Most of the time packers use Application class to start unpacking sequence. Use `application = self.apk_object.get_attribute_value("application", "name")` to get application class defined in manifest file. 

### Thanks:
[apkdetect.com](https://apkdetect.com) for unique samples to work with. 

