Skip to main content

Assembly-level malware detection using fine-tuned CodeBERT

Project description

asmdetect

Compiler-Aware Assembly-Level Malware Detection using Fine-Tuned Language Models

Model Python

A Python library for static malware detection using x86 assembly opcode sequences. Fine-tunes microsoft/codebert-base on disassembled binaries to classify files as malware or benign — no execution required.

Built for SOC teams who need fast, explainable triage of suspicious binaries before deeper sandbox analysis.


Model

HuggingFace: Swarnadharshini/codebert-malware-detector

Property Value
Base model microsoft/codebert-base
Task Binary sequence classification
Input x86 opcode sequences (max 512 tokens)
Output malware / benign + confidence score
Parameters ~125M (8 frozen layers + 4 fine-tuned + classifier)
Training data 1,458 samples (with augmentation)
Dataset Arun152k — objdump-disassembled PE binaries
Decision threshold 0.62 (calibrated on test set)

Dataset

Processed opcode sequences available on Kaggle: https://www.kaggle.com/datasets/swarnadharshini/malware-opcodes

Original source: Arun152k/Malware-Detection-using-N-Gram-Frequency

Test set results

Metric Value
Accuracy 86.0%
F1 Score 0.857
Precision 86.8%
Recall 84.6%
AUC-ROC 0.910
False Negatives 12
False Positives 10

Installation

pip install -r requirements.txt
pip install -e .

Quick start

from asmdetect import MalwareDetector

# Load model from HuggingFace Hub (downloads once, cached locally)
detector = MalwareDetector.from_pretrained()

# Predict from a .csv assembly file (IDA Pro / objdump format)
result = detector.predict_file("suspicious_binary.csv")
print(result)
# DetectionResult(
#   source      = suspicious_binary.csv
#   prediction  = MALWARE  [HIGH] HIGH
#   confidence  = 99.60%
#   malware_p   = 99.60%
#   benign_p    = 0.40%
#   tokens      = 312  (truncated=False)
#   threshold   = 0.62
# )

# Predict from a raw opcode string
result = detector.predict_text("push mov xor xor call ret add nop")

# Batch triage a folder — sorted by malware probability (highest first)
results = detector.predict_batch("/soc/incoming/suspicious/")
for r in results[:5]:
    print(f"{r.malware_probability*100:.1f}%  {r.risk_level}  {r.source}")

CLI

# Single file
asmdetect --file suspicious.csv

# Raw opcode string
asmdetect --text "push mov xor call ret"

# Batch triage a folder
asmdetect --batch /soc/incoming/

# Custom threshold
asmdetect --file suspicious.csv --threshold 0.70

# JSON output (for SIEM/SOAR integration)
asmdetect --file suspicious.csv --json

Scripts

# Run demo predictions from HuggingFace
python scripts/predict_from_hf.py

# Predict a specific file
python scripts/predict_from_hf.py --file path/to/sample.csv

# Predict raw opcodes
python scripts/predict_from_hf.py --text "push mov xor call ret"

# SOC batch triage with JSON report
python scripts/batch_triage.py --folder /soc/incoming/ --report report.json

API reference

MalwareDetector

MalwareDetector.from_pretrained(
    model_id  = "Swarnadharshini/codebert-malware-detector",  # or local path
    threshold = 0.62,   # decision threshold — lower = more sensitive
    device    = "auto", # 'cuda', 'cpu', or 'auto'
)
Method Description
predict_file(filepath) Classify a .csv assembly file
predict_text(text) Classify a raw opcode string
predict_batch(folder) Classify all CSVs in a folder, sorted by risk
set_threshold(value) Update threshold at runtime
benchmark(text, n=10) Measure inference latency

DetectionResult

Field Type Description
prediction str 'malware' or 'benign'
label int 1 = malware, 0 = benign
confidence float Probability of predicted class
malware_probability float Raw P(malware)
benign_probability float Raw P(benign)
risk_level str 'HIGH' ≥80% | 'MEDIUM' ≥55% | 'LOW'
input_tokens int Token count before truncation
truncated bool True if input exceeded 512 tokens
is_malware bool Convenience property
is_benign bool Convenience property
to_dict() dict Serialise to dictionary
to_json() str Serialise to JSON string

Threshold tuning

# High-security: catch more malware (more false alarms)
detector.set_threshold(0.45)

# Low-noise: fewer false alarms (may miss borderline cases)
detector.set_threshold(0.75)

# Reset to calibrated default
detector.set_threshold(0.62)

Input format

CSV files — from IDA Pro or objdump -d:

Address,Hex_Opcode,Opcode,Operand 1,Operand 2
402000:,30 7d 07,xor,%bh,
402003:,00 00,add,%al,

Raw opcode strings:

detector.predict_text("push mov sub lea call add pop ret")

Project structure

asmdetect/
├── asmdetect/
│   ├── __init__.py        ← public API
│   ├── detector.py        ← MalwareDetector class
│   ├── preprocessing.py   ← opcode extraction utilities
│   ├── result.py          ← DetectionResult dataclass
│   ├── cli.py             ← asmdetect CLI
│   └── version.py
├── tests/
│   └── test_asmdetect.py  ← 26 unit tests
├── scripts/
│   ├── predict_from_hf.py ← standalone HF demo script
│   └── batch_triage.py    ← SOC batch triage with report
├── examples/
│   └── basic_usage.py     ← usage examples
├── notebooks/
│   └── malware-detect.ipynb ← Kaggle training notebook
├── pyproject.toml
├── requirements.txt
└── README.md

Training

The model was trained on Kaggle (Tesla P100 GPU) using the pipeline in notebooks/malware-detect.ipynb.

Training iterations:

Run Key changes Accuracy F1 AUC-ROC
Baseline Default cross-entropy loss 78.9% 0.802 0.890
Run 2 Frozen layers + weighted loss (2.0) 76.4% 0.800 0.854
Run 3 weight=1.5 + threshold calibration + augmentation 86.0% 0.857 0.910

Limitations

  • Trained on 1,042 samples — a larger dataset will improve generalisation
  • Input truncated to 256 opcodes; signatures in binary tails may be missed
  • Obfuscated/packed malware that alters opcode distribution may evade detection
  • Designed for x86 Windows PE binaries; accuracy on ARM or ELF is untested
  • Static analysis only — does not detect runtime/memory-resident malware

AsmDetect

Assembly-level malware detection using CodeBERT.

Install

pip install asmdetect

Usage

from asmdetect import MalwareDetector

detector = MalwareDetector.from_pretrained()
detector.predict_text("push mov xor call")

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

asmdetect-1.0.0.tar.gz (23.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

asmdetect-1.0.0-py3-none-any.whl (24.7 kB view details)

Uploaded Python 3

File details

Details for the file asmdetect-1.0.0.tar.gz.

File metadata

  • Download URL: asmdetect-1.0.0.tar.gz
  • Upload date:
  • Size: 23.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for asmdetect-1.0.0.tar.gz
Algorithm Hash digest
SHA256 7aac31020ce55e85547e1a8bd1bd75fdc5cef3428e484770f2297a6d83a3bd25
MD5 d4f6d339245ff1562fc22d03499650c3
BLAKE2b-256 51b7c055addf16c52805490106d8858e9e6c875249c5e27a2d84c7f6e0e61959

See more details on using hashes here.

File details

Details for the file asmdetect-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: asmdetect-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 24.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for asmdetect-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1da1549979a3244a15e24b26421689feadb7c67d2bbc4889dfef675c7c0f7286
MD5 d5f9158fb67ab3417d812b40d9113038
BLAKE2b-256 ea42c3e04f0f435032eeb05eeedcf10cc3ae0b7b81cbf6f38af76fbabdfe492b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page