Overview
The Python Rule API provides utilities for writing custom detection rules. Rules must implement acheck() function that analyzes malware reports and returns a detection verdict.
Rule Structure
Every Python rule must follow this structure:check Function
Path to the directory containing analysis report JSON files (as bytes)
Detection verdict as bytes. Return
b"CLEAN" for benign files, or a malware family name (e.g., b"Win32.EICAR.Dr") for detectionsdr_semu_utils Module
Thedr_semu_utils module provides helper functions for accessing report data.
Don’t forget to add module names to the
py_imports.config file when using additional Python modules.dr_semu_utils.get_starter_details
Retrieves basic information about the starter process fromstarter.json.
Path to the report directory as bytes
Path to the executable that was analyzed
Process ID of the starter process
SHA-256 hash of the analyzed executable
(image_path, pid, sha_256). All values are None if starter.json is missing or cannot be read.
Implementation Details:
- Reads
starter.jsonfrom the report directory - Returns
(None, None, None)if the file doesn’t exist - Extracts
image_path,starter_pid, andsha_256fields from the JSON
dr_semu_utils.get_json_from_file
Reads and parses a JSON file.Full path to a JSON file as bytes
Python dictionary containing the parsed JSON data, or
None if the file doesn’t exist- Loading static analysis data:
report_directory + b"\\" + sha_256.encode() + b".json" - Loading dynamic analysis data:
report_directory + b"\\" + str(pid).encode() + b".json"
Example Rule
This example detects the EICAR test file by checking for execution ofdrsemu_eicar.exe:
Working with Report Files
Path Construction
All paths use bytes and Windows-style backslashes:Loading Analysis Data
Dynamic Analysis Structure
The dynamic analysis JSON is a list of API call dictionaries. Each call follows this structure:Iterating API Calls
Common API Calls
NtCreateUserProcess - Process creationbefore["image_path"]: Path to the executableafter["proc_id"]: PID of the created processsuccess: Whether the process was created successfully
before["key_path"]: Registry key pathsuccess: Whether the key was created successfully
Static Analysis Structure
The static analysis JSON contains PE file information:Best Practices
- Use bytes for paths: All file paths must be bytes objects with the
bprefix - Check for None: Always verify that
get_starter_details()andget_json_from_file()return valid data - Encode strings: Convert strings to bytes using
.encode()when building paths - Iterate all calls: Loop through the entire dynamic_info list to check all API calls
- Return bytes verdicts: Always return bytes (e.g.,
b"CLEAN",b"Win32.Malware.Dr") - Check success flags: Verify the
successfield before processing API call results - Update py_imports.config: Add any additional Python modules to the configuration file
Differences from Lua API
- Python uses bytes for paths and verdicts, Lua uses strings
- Python uses dictionaries and lists, Lua uses tables
- Python has separate functions for getting starter details vs loading JSON files
- Python uses
inoperator for key checking, Lua checks for nil - Python uses
True/False, Lua usestrue/false