A collection of ML-based Android malware detectors. Currently including:
- DrebinSVM (https://www.ndss-symposium.org/wp-content/uploads/2017/09/11_3_1.pdf)
- DeepDrebin (https://link.springer.com/chapter/10.1007/978-3-319-66399-9_4)
- RAMDA (https://dl.acm.org/doi/10.1145/3442381.3450044)
- MalScan (https://ieeexplore.ieee.org/document/8952382)
- HCC (https://www.usenix.org/conference/usenixsecurity23/presentation/chen-yizheng)
Note that all code has been reimplemented based on the description of the frameworks in the original papers.
This library was released as part of the artifacts of the work Beyond the TESSERACT: Trustworthy Dataset Curation for Sound Evaluations of Android Malware Classifiers (IEEE SaTML 2026) and implements the temporal evaluation constraints originally introduced in TESSERACT: Eliminating Experimental Bias in Malware Classification across Space and Time (USENIX Security 2019). When using it, please cite the work introducing the specific malware detector you will be using as well as TESSERACT and Beyond the TESSERACT.
@inproceedings{chow2025breaking,
title = {{Beyond the TESSERACT: Trustworthy Dataset Curation for Sound Evaluations of Android Malware Classifiers}},
author = {Chow, Theo and D'Onghia, Mario and Linhardt, Lorenz and Kan, Zeliang and Arp, Daniel and Cavallaro, Lorenzo and Pierazzi, Fabio},
year = {2026},
booktitle = {{IEEE} Conference on Secure and Trustworthy Machine Learning ({SaTML})},
}@inproceedings{pendlebury2019tesseract,
title = {TESSERACT: Eliminating experimental bias in malware classification across space and time},
author = {Pendlebury, Feargus and Pierazzi, Fabio and Jordaney, Roberto and Kinder, Johannes and Cavallaro, Lorenzo},
booktitle = {Proc. of {USENIX} Security Symposium},
year = {2019},
}Apart from cloning the repository and using it directly, you can easily add the library to your Python project by adding
the following line to your requirements file:
git+ssh://git@github.com/s2labres/android_malware_detectors.git@main#egg=android_malware_detectors
This will install the library as a pip module. You can do it also manually. To install it system-wise or in a venv, just run
pip install git+ssh://git@github.com/s2labres/android_malware_detectors.git@main#egg=android_malware_detectorsPlease notice that the library is based on tensorflow and that, at the time of writing, tensorflow only supports Python [3.8-3.12]. If you're using a bleeding-edge linux distro (e.g., Fedora or Arch Linux) you may have a newer version of Python, which is unfortunately not supported. Hence, you'll need to install an older one (Python3.12 is recommended).
Training a model consists of instantiating the relative class and calling the method train. The latter takes in
a dataset, the labels, and optionally a list of samples' hashes.
The list of hashes is used in case the dataset contains more samples than needed.
The dataset can be either a path to a directory containing the features for each individual APK, a path to a json/pickle
file containing a dictionary {hash: features}, or directly a python dict having the same structure.
The labels should be either a np.ndarray with shape (num_samples,) or a dict {hash: label}. They can again be either
a path to a npy/npz/pickle file or the actual python object.
The library provides a set of functions to easily construct dataset and labels objects as well as samples' hashes lists.
import numpy as np
from android_malware_detectors.detectors.drebin.svm_detector import DrebinSVM
save_directory = "path/to/save/dir"
drebin_dataset_path = "path/to/drebin/features/files"
labels = np.load("path/to/labels/npy")
training_shas = ["sha_1", "sha_2", "...", "sha_n"]
drebin_svm = DrebinSVM(save_directory)
drebin_svm.train(drebin_dataset_path, labels, training_shas)
drebin_svm.save()In testing mode, the library offers 3 different methods: predict, evaluate, evaluate_time_aware.
predictreturns the list of predictions by the model.
from android_malware_detectors.detectors.drebin.svm_detector import DrebinSVM
save_directory = "path/to/save/dir"
drebin_svm = DrebinSVM(save_directory)
drebin_svm.load()
drebin_dataset_path = "path/to/drebin/features/files"
test_shas = ["sha_1", "sha_2", "...", "sha_n"]
predictions = drebin_svm.predict(drebin_dataset_path, test_shas)
# predictions are in the order specified by test_shas. If training_shas is None/empty then it defaults to
# alphabetical order.evaluatereturns the f1 score. The true labels passed to the method follow the same rules as for thetrainmethod.
from android_malware_detectors.detectors.drebin.svm_detector import DrebinSVM
save_directory = "path/to/save/dir"
drebin_svm = DrebinSVM(save_directory)
drebin_svm.load()
drebin_dataset_path = "path/to/drebin/features/files"
test_shas = ["sha_1", "sha_2", "...", "sha_n"]
labels = {"sha_1": 0, "sha_2": 0, "sha_n": 1}
scores_dict = drebin_svm.evaluate(drebin_dataset_path, labels, test_shas)
# scores_dict = {"f1": value, "recall": value, "precision": value}evaluate_time_awarereturns the f1 score per time frame. For instance, if the test set is divided by months, then the method returns an f1 score per each month in the test set. Here, thesamples_hashes_by_dateis a required field, and it has to be a dictionary{datetime.date(...): hashes}. The library provides some functions for easily generating such data structures.
import datetime
from android_malware_detectors.detectors.drebin.svm_detector import DrebinSVM
save_directory = "path/to/save/dir"
drebin_svm = DrebinSVM(save_directory)
drebin_svm.load()
drebin_dataset_path = "path/to/drebin/features/files"
samples_hashes_by_date = {datetime.date(2015, 1, 1): ["sha_1", "sha_2", "...", "sha_n"]}
labels = {"sha_1": 0, "sha_2": 0, "sha_n": 1}
scores_by_month = drebin_svm.evaluate(drebin_dataset_path, labels, samples_hashes_by_date)
# scores_by_month = {datetime.date(year, month, 1): {"f1": value, "recall": value, "precision": value}}All the functions and methods that you should use contain a docstring with instructions on how to use them.
Moreover, the directory examples contains full examples for each of the implemented detectors.
Please refer to them, especially to understand how to construct or obtain the correct data structures.
Notice that to run the examples you'll need to install the library and that the data required by the examples
comes compressed, so you'll need to decompress it first. The examples run on a randomly downsampled version of
the Trascendent dataset, so don't be surprised if the reported performance are low.
If you feel that the library should include other detectors, please get in touch. If you want to add it yourself, you are more than welcome!
Please, pull the latest version of the library, branch out from main, add your changes, write unit tests, and open a pull request!
$ git pull --rebase
$ git checkout -b the_new_methods_name
$ git push --set-upstream origin the_new_methods_namePlease refer to the various *_tests.py files in the library to understand how to write unit tests.
They should follow the AAA pattern (https://medium.com/@sandy619g/aaa-pattern-testing-5681c5c668f4).
Always make sure that ALL tests (new and old) pass before pushing any local change.
$ python -m unittest discover -s ./ -p '*_tests.py'If you identify anything wrong with the library please get in touch or open an issue. If you think you can fix it yourself, please give it a shot. Do follow however the guidance provided above for extending the library.