Overview
The Lua 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 Lua rule must follow this structure:check Function
Path to the directory containing analysis report JSON files
Detection verdict. Return “CLEAN” for benign files, or a malware family name (e.g., “Win32.EICAR.Dr”, “Dr.Semu!TEST”) for detections
Utils Module
Theutils module provides helper functions for accessing report data.
utils.get_first_process_json
Retrieves the dynamic analysis JSON for the starter process.Path to the report directory
Lua table containing dynamic analysis data with Windows API calls, or
nil if not available. Each element in the table represents a logged API call.- Reads
starter.jsonto get the starter process PID - Returns the dynamic JSON for that PID
- Returns
nilif starter.json is empty or missing required fields
utils.get_first_static
Retrieves the static analysis JSON for the starter executable.Path to the report directory
Lua table containing static analysis data (PE information, imports, etc.), or
nil if not available. Contains a generic field with properties like is_x86.- Reads
starter.jsonto get the SHA-256 hash - Returns the static analysis JSON for that hash
- Returns
nilif starter.json is empty
utils.get_json_pid
Retrieves the dynamic analysis JSON for a specific process ID.Path to the report directory
Process ID to retrieve
Lua table containing dynamic analysis data for the specified PID. Check the
empty field to verify if data is available.NtCreateUserProcess calls.
utils.get_json_from_path
Low-level function to read and parse any JSON file.Full path to a JSON file
Lua table containing the parsed JSON data
utils.read_content
Low-level function to read file contents as a string.Full path to a file
File contents as a string
Example Rule
This example detects execution ofwhoami.exe and malicious registry key creation:
API Call Structure
Each API call in the dynamic JSON follows this pattern:Common API Calls
NtCreateUserProcess - Process creationbefore.image_path: Path to the executableafter.proc_id: PID of the created process
before.key_path: Registry key pathsuccess: Whether the key was created successfully
Best Practices
- Always check for nil: Verify that
first_dynamicandfirst_staticare not nil before accessing them - Iterate all calls: Use
pairs()to enumerate all API calls in the dynamic JSON - Check success flags: Verify
success == truebefore processing call results - Track child processes: Use
get_json_pid()to analyze child process behavior - Return specific verdicts: Use descriptive malware family names instead of generic strings