12.3 Static Malware Triage: Strings, PE Headers, Import Tables, Hashes & YARA Rule Matching

Key Takeaways

  • Static malware triage evaluates suspicious binary characteristics without executing the specimen, providing initial IoC discovery and threat classification within an isolated environment.
  • Cryptographic hashes (SHA-256) provide exact binary identity, while SSDEEP computes Context Triggered Piecewise Hashes (CTPH) to evaluate code similarity, and ImpHash calculates MD5 hashes of ordered import tables to identify malware family lineages.
  • Shannon entropy values exceeding 7.2 bits per byte across PE sections, combined with high discrepancies between Virtual Size and Size of Raw Data, indicate payload packing, obfuscation, or encryption.
  • The Import Address Table (IAT) reveals fundamental binary capabilities; high concentrations of Win32 APIs like VirtualAllocEx, WriteProcessMemory, and CreateRemoteThread indicate process injection routines.
  • YARA rules automate signature matching through modular rule definitions combining metadata, string definitions (text, hex with wildcards, regex), and boolean logic conditions.
Last updated: September 2026

12.3 Static Malware Triage: Strings, PE Headers, Import Tables, Hashes & YARA Rule Matching

Quick Answer: Static malware triage inspects a binary's structure, code headers, strings, and metadata without executing the code. Triage begins with calculating cryptographic hashes (SHA-256 for exact identification, SSDEEP fuzzy hashing for code similarity, and ImpHash for import table clustering). Examiners inspect the Portable Executable (PE) structure, evaluating Shannon entropy across sections: an entropy value > 7.2 (out of 8.0) or a large discrepancy between SizeOfRawData and VirtualSize signifies packing or encryption. Reviewing the Import Address Table (IAT) reveals suspicious Win32 APIs (e.g., VirtualAllocEx, WriteProcessMemory, CreateRemoteThread). Finally, examiners engineer YARA rules composed of meta, strings (text, hex, regex), and condition blocks to automate malware detection across endpoints.


Static Triage Methodology & Safe Handling Protocols

Static malware analysis represents the initial phase of reverse engineering. Because static triage evaluates binaries without runtime execution, it eliminates the risk of sandbox evasion, accidental network infection, or environmental contamination.

Malware Lab Safety Standards

  • Air-Gapped Isolation: Malware analysis must take place on dedicated workstations physically separated from enterprise production networks.
  • Read-Only Evidence Locks: Specimen archives should be stored with restricted read-only permissions and password-protected (e.g., .zip protected with standard password infected or malware) to prevent inadvertent double-click execution.
  • Extension Neutralization: Renaming suspicious executables (e.g., changing invoice.exe to invoice.exe.bin or invoice.malware) prevents the host operating system shell from associating the file with executable launch handlers.

Cryptographic & Similarity Hashing

Cryptographic hashing provides a deterministic mathematical fingerprint of an evidentiary file. In malware triage, analysts utilize three distinct classes of hashes:

+-------------------------------------------------------------------------+
|                    MALWARE HASHING TAXONOMY                             |
+-------------------------------------------------------------------------+
| Hash Type           | Algorithm / Metric     | Forensic Objective       |
|---------------------|------------------------|--------------------------|
| **Cryptographic**   | MD5 (128-bit)          | Exact file identity;     |
| **Hashes**          | SHA-256 (256-bit)      | Threat Intel lookups on  |
|                     |                        | VirusTotal / AlienVault  |
|---------------------|------------------------|--------------------------|
| **Fuzzy Similarity**| SSDEEP (Context        | Identifies code reuse and|
| **Hashing (CTPH)**  | Triggered Piecewise    | modified variants;       |
|                     | Hashing)               | Similarity score (0–100) |
|---------------------|------------------------|--------------------------|
| **Import Table**    | ImpHash (MD5 of parsed | Clusters malware families|
| **Hashing**         | & ordered Win32 IAT    | sharing identical library|
|                     | library functions)     | loading mechanics        |
+-------------------------------------------------------------------------+

1. Cryptographic Hashes: MD5 & SHA-256

Standard cryptographic hashes are subject to the avalanche effect: altering a single bit in a 10 MB compiled binary completely changes the resulting SHA-256 digest. While excellent for querying threat intelligence repositories (such as VirusTotal), cryptographic hashes cannot determine if two slightly different files belong to the same malware family.

2. SSDEEP (Context Triggered Piecewise Hashing - CTPH)

To overcome the avalanche effect, Dr. Jesse Kornblum developed SSDEEP, an implementation of Context Triggered Piecewise Hashing (CTPH):

  • Mechanism: SSDEEP divides a binary into variable-sized chunks using a rolling hash function. When the rolling hash matches a specific mathematical trigger, a boundary is set, and a traditional hash is computed for that block. The final SSDEEP output consists of: blocksize:hash1:hash2.
  • Similarity Scoring: Comparing two SSDEEP hashes yields a match score between 0 (no similarity) and 100 (identical). If an adversary updates a malware variant by modifying hardcoded C2 strings or changing compile-time flags, standard SHA-256 changes completely, but SSDEEP often returns a similarity score > 85, proving shared code lineage.
# Generate SSDEEP hash of specimen
ssdeep -b sample_v1.exe > hashes.txt

# Compare new suspect specimen against baseline hash
ssdeep -b -m hashes.txt sample_v2.exe
# Output: sample_v2.exe matches hashes.txt:sample_v1.exe (92%)

3. ImpHash (Import Hash)

Developed by Mandiant, ImpHash calculates an MD5 digest of the binary's Import Address Table (IAT):

  • Mechanism: ImpHash parses all imported dynamic link libraries (DLLs) and their specific imported function names. It converts the library names and APIs to lowercase, orders them according to the binary's import sequence, joins them with commas, and computes an MD5 hash.
  • Forensic Power: Threat actors frequently rebuild, recompile, or repack malware to evade antivirus signatures, but they rarely alter the underlying sequence of Win32 APIs required to execute their malicious payloads. Binaries with identical ImpHash values almost certainly share identical source code frameworks, builders, or development toolkits.
# Calculating ImpHash using Python pefile library
import pefile
pe = pefile.PE('malware_sample.exe')
print(f"ImpHash: {pe.get_imphash()}")

String Extraction & Decoding Techniques

Extracting printable character sequences from an unexecuted binary provides rapid insights into developer intent, infrastructure dependencies, and embedded capabilities.

# Extract ASCII strings of length 8 or greater with file offsets
strings -a -o -n 8 sample.exe > strings_ascii.txt

# Extract 16-bit Little-Endian Unicode strings (standard for Windows binaries)
strings -a -o -e l -n 8 sample.exe > strings_unicode.txt

High-Value String Artifacts

  • Network Endpoints: Hardcoded IPv4/IPv6 addresses, Command and Control (C2) domains, IRC channels, user-agent strings (e.g., Mozilla/5.0...), and URL paths (/gate.php, /submit.aspx).
  • Operating System Artifacts: Windows Registry persistence paths (SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run), security service names (WinDefend, wuauserv), and system directory targets.
  • Cryptographic & Obfuscation Clues: Base64 padding indicators (==), RSA public key headers (-----BEGIN PUBLIC KEY-----), and decryption routine labels.
  • PDB Debugging Paths: Compilation artifact strings embedded by compilers (D:\\Projects\\Backdoor\\Release\\payload.pdb). PDB strings expose the developer's local username, project names, and internal directory structures.

Advanced Deobfuscation with FLOSS

Modern malware obfuscates critical strings in memory arrays or decrypts them dynamically during runtime, rendering standard strings output useless.

  • FLOSS (FireEye Labs Obfuscated String Solver): An advanced static utility that uses automated symbolic execution and emulation to identify deobfuscation routines, extract stack-allocated strings, and recover dynamically decoded text without running the malware on a live OS.
# Extract obfuscated and stack strings using FLOSS
floss --no-static-strings sample.exe

Portable Executable (PE) Format Architecture

The Portable Executable (PE) format is the file format for 32-bit and 64-bit executables, object code, and DLLs in Windows operating systems. The PE architecture contains nested structural headers that provide deep forensic telemetry.

+-------------------------------------------------------------+
|               PORTABLE EXECUTABLE (PE) FORMAT               |
+-------------------------------------------------------------+
| DOS Header (MZ Signature: 0x5A4D)                           |
| DOS Stub ("This program cannot be run in DOS mode")         |
| e_lfanew (Offset pointing to PE Header)                     |
+-------------------------------------------------------------+
| PE Header / IMAGE_NT_HEADERS                                |
| • Signature: 0x00004550 ("PE\0\0")                         |
| • File Header (Machine architecture, NumberOfSections)      |
| • Optional Header (AddressOfEntryPoint, ImageBase)          |
+-------------------------------------------------------------+
| Section Headers (IMAGE_SECTION_HEADER Table)                |
| • .text   (Code segment; executable)                        |
| • .data   (Initialized global/static read-write data)       |
| • .rdata  (Read-only data: imports, exports, string literals|
| • .rsrc   (Resources: icons, manifests, embedded binaries)  |
| • .reloc  (Relocation table for ASLR)                       |
+-------------------------------------------------------------+
| Section Data Bodies                                         |
+-------------------------------------------------------------+

1. DOS Header & DOS Stub

Every valid Windows PE binary begins with a 64-byte DOS Header (IMAGE_DOS_HEADER):

  • e_magic: The first two bytes must contain the magic characters MZ (0x4D 0x5A in hex), representing Mark Zbikowski, an early architect of MS-DOS.
  • e_lfanew: Located at offset 0x3C, this 4-byte DWORD specifies the exact file offset where the modern PE File Header (IMAGE_NT_HEADERS) begins.
  • DOS Stub: A minimal MS-DOS program inserted for backwards compatibility. If executed in DOS, it prints: This program cannot be run in DOS mode.

2. PE Header (IMAGE_NT_HEADERS)

  • Signature: 4-byte signature 0x00004550 (representing characters P, E, and two terminating null bytes).
  • File Header (IMAGE_FILE_HEADER): Specifies target architecture (e.g., 0x014C for x86 32-bit; 0x8664 for x64 64-bit), NumberOfSections, and the TimeDateStamp. (Note: Attackers frequently modify TimeDateStamp using anti-forensic timestomping tools).
  • Optional Header (IMAGE_OPTIONAL_HEADER): Contains the AddressOfEntryPoint (Relative Virtual Address [RVA] where execution begins), the preferred ImageBase (typically 0x00400000 for 32-bit executables), the required Windows subsystem (GUI vs. Console), and the Data Directory array (which locates the Import Directory and Export Directory).

3. Standard PE Sections & Operational Roles

  • .text: Contains the primary executable machine code instructions. Characteristics are typically marked IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ.
  • .data: Stores initialized global and static variables. Marked IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE.
  • .rdata: Stores read-only data, string constants, and the Import Address Table. Marked IMAGE_SCN_MEM_READ.
  • .rsrc: Contains user interface resources including icons, menu structures, version information, and dialog boxes. Threat actors frequently conceal secondary malicious payloads (e.g., encrypted .dll or .exe files) inside .rsrc sections.
  • .reloc: Contains base relocations, required when Address Space Layout Randomization (ASLR) moves the binary's base address in memory.

Detecting Packing, Obfuscation & Section Anomalies

Malware authors routinely run compiled binaries through packers (such as UPX, ASPack, or Themida) or custom crypters to compress, encrypt, and obfuscate executable code, rendering static signatures ineffective.

Unpacked Executable Section Layout:
+----------------------+----------------------+----------------------+
| .text (Entropy: 6.2) | .rdata (Entropy: 5.1)| .data (Entropy: 3.4) |
+----------------------+----------------------+----------------------+

Packed / Encrypted Executable Section Layout:
+---------------------------------------------+----------------------+
| UPX0 (VirtualSize: 120KB, RawSize: 0KB)     | UPX1 (Entropy: 7.89) |
| [Allocated Memory Space for Decompression]   | [Compressed Payload] |
+---------------------------------------------+----------------------+

1. Shannon Entropy Analysis

Entropy measures the degree of randomness or unpredictability in a dataset, calculated on a mathematical scale from 0.0 to 8.0 bits per byte:

  • 0.0–3.0: Highly repetitive data (e.g., large blocks of 0x00 null bytes).
  • 3.0–5.5: Standard human language text, source code, and configuration scripts.
  • 5.5–6.8: Normal compiled, uncompressed machine instructions (.text sections).
  • 7.2–8.0: Packed, compressed, or encrypted data. If a PE section exhibits entropy exceeding 7.2, it almost certainly contains encrypted payloads or compressed shellcode.

2. Discrepancies Between Virtual Size & Size of Raw Data

In the Section Header table:

  • SizeOfRawData: The size of the section as stored on the physical disk.
  • VirtualSize: The size of the section once loaded and allocated into virtual memory.
  • The Packing Anomaly: In a standard unpacked binary, SizeOfRawData and VirtualSize are approximately equal (differing only due to sector alignment padding). In a packed binary, the packer reserves a large virtual memory space (VirtualSize is large) but stores very little data on disk (SizeOfRawData is tiny or 0). At runtime, an unpacking stub executes, decompresses the payload, and writes the unpacked instructions into the pre-allocated virtual memory space.

3. Suspicious Section Names

Standard compilers (MSVC, GCC) generate standard section names (.text, .data, .rdata, .rsrc). Packers often leave signature section names:

  • UPX: .upx0, .upx1, .upx2
  • ASPack: .aspack, .adata
  • Themida / VMProtect: .themida, .vmp0, .vmp1
  • Custom Crypters: Non-standard ASCII strings, random alphanumeric strings, or blank/null section names.

Import Address Table (IAT) Analysis: Suspicious Win32 APIs

The Import Address Table (IAT) lists the functions dynamically imported from external operating system libraries (e.g., kernel32.dll, user32.dll, advapi32.dll). Reviewing imported APIs reveals the specimen's core capabilities.

Functional CategorySuspicious Win32 APIsMalicious Intent / Forensic Indicator
Process InjectionVirtualAllocEx, WriteProcessMemory, CreateRemoteThread, QueueUserAPC, NtQueueApcThreadAllocates memory in a remote process, writes foreign shellcode, and executes a remote thread (Process Injection / DLL Injection).
Process HollowingCreateProcessA (with CREATE_SUSPENDED), ZwUnmapViewOfSection, SetThreadContext, ResumeThreadLaunches a legitimate process in suspended mode, unmaps the genuine code, replaces it with malware, and resumes execution.
Keylogging & SpywareSetWindowsHookExA, GetAsyncKeyState, GetKeyState, RegisterHotKeyIntercepts keyboard input, captures passwords, and monitors keystrokes across all system windows.
Dynamic API ResolutionLoadLibraryA, GetProcAddress, LdrLoadDllBypasses IAT inspection by loading libraries and resolving API addresses dynamically at runtime. (Sparse IAT indicator).
Persistence & ServiceRegCreateKeyExA, RegSetValueExA, CreateServiceA, OpenSCManagerAModifies Run/RunOnce registry keys or installs unauthorized Windows background services.
Anti-DebuggingIsDebuggerPresent, CheckRemoteDebuggerPresent, OutputDebugStringAQueries Process Environment Block (BeingDebugged flag) to detect active analysis and terminate execution.
Network & ExfiltrationInternetOpenA, HttpSendRequestA, URLDownloadToFileA, WSAStartup, connectEstablishes C2 network connections, retrieves secondary stage payloads, and exfiltrates captured telemetry.

[!TIP] If an executable has an Import Address Table that imports only two functions—specifically LoadLibraryA and GetProcAddress—this is a classic indicator that the executable is packed. The packer uses these two fundamental APIs to manually locate and resolve all other required functions after decompressing the payload in memory.


YARA Rule Engineering & Signature Matching

YARA is the industry standard for pattern matching and malware identification. YARA rules categorize and identify malware families by matching text patterns, hexadecimal sequences, and structural conditions within files or memory dumps.

+-------------------------------------------------------------+
|                  YARA RULE LOGICAL STRUCTURE                |
+-------------------------------------------------------------+
| rule Rule_Name {                                            |
|     meta:                                                   |
|         // Non-matching descriptive metadata                |
|     strings:                                                |
|         // Text strings, Hex sequences, Regex definitions   |
|     condition:                                              |
|         // Boolean logic determining if rule fires          |
| }                                                           |
+-------------------------------------------------------------+

Anatomy of a Production-Grade YARA Rule

rule APT_CobaltStrike_Beacon_Loader {
    meta:
        description = "Detects unpacked Cobalt Strike loader variants based on unique API sequence and config strings"
        author = "Lead Forensic Examiner"
        date = "2026-09-22"
        reference = "CHFI-Case-2026-12"
        hash = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
        threat_level = "Critical"

    strings:
        // 1. Text Strings: Case-insensitive and Unicode Little-Endian matching
        $str_c2_path = "/submit.php?id=" ascii nocase
        $str_pipe    = "msagent_" ascii wide
        $str_useragent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" ascii

        // 2. Hexadecimal Strings: Matching opcodes with wildcards (??) and byte jumps [2-4]
        // Decryption loop stub: xor eax, 0x5a; rol eax, 4; call [relative]
        $hex_decrypt = { 35 5A 00 00 00 C1 C0 04 [2-4] E8 ?? ?? ?? ?? }

        // 3. Regular Expression: Matching suspicious C2 IP and port combination
        $regex_c2 = /https?:\/\/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}:8443\/[a-z]{4,8}/ nocase

    condition:
        // Verify target is a valid Windows PE binary (MZ header at offset 0 and PE signature)
        uint16(0) == 0x5A4D and
        uint32(uint32(0x3C)) == 0x00004550 and

        // File size guardrails (prevent scanning giant ISO or VMDK archives)
        filesize < 5MB and

        // Match logic: Requires hex decryption stub AND at least two text strings, OR the regex pattern
        ($hex_decrypt and 2 of ($str*)) or $regex_c2
}

Executing YARA Rules

Examiners run YARA against suspect directory trees, raw disk images, or volatile memory dumps:

# Scan a directory of seized suspect binaries recursively
yara -r /rules/apt_rules.yar /evidence/seized_binaries/

# Scan a live process memory space by PID using YARA
yara /rules/cobalt_strike.yar 4128

Practical Forensic Case Scenario: Triaging an Obfuscated Dropper

The Incident

A corporate employee opens a malicious email attachment named Invoice_Q3.pdf.exe. Endpoint protection alerts on suspicious process creation before isolating the machine.

Static Analysis Steps

  1. Hash Generation: The analyst computes the SHA-256 hash. A VirusTotal query reveals zero matches, indicating a freshly compiled zero-day dropper or custom crypter. However, generating the SSDEEP hash reveals an 89% similarity match to a known variant of the Emotet banking trojan.
  2. PE Header Inspection: The analyst inspects section headers using pecheck. The binary contains two sections: .text and .upx1. The .text section exhibits a SizeOfRawData of 512 bytes but a VirtualSize of 180 KB. The Shannon entropy of .upx1 is calculated at 7.84, confirming packing via UPX.
  3. IAT Examination: Reviewing the Import Address Table reveals exactly two APIs: LoadLibraryA and GetProcAddress. This corroborates the presence of an unpacking stub.
  4. Unpacking & String Recovery: The analyst executes upx -d -o unpacked_dropper.exe Invoice_Q3.pdf.exe. Inspecting the unpacked binary's IAT reveals VirtualAllocEx, WriteProcessMemory, and CreateRemoteThread. Running strings on the unpacked file extracts cleartext C2 URLs (hxxps://corporate-portal-login[.]com/gate.php) and a base64 encoded PowerShell command line.
Loading diagram...
Static Malware Triage & PE Analysis Workflow
Test Your Knowledge

A digital forensics investigator compares two separate compiled malware samples recovered from different compromised endpoints across an enterprise network. Both binaries have completely different SHA-256 cryptographic hashes. However, when the investigator computes the ImpHash for both files, the returned MD5 values are completely identical. What does an identical ImpHash value indicate to the investigator?

A
B
C
D
Test Your Knowledge

During static triage of an executable named update_patch.exe, an examiner evaluates the binary's sections using a PE inspection tool. The .text section displays a Size of Raw Data of 1,024 bytes and a Virtual Size of 262,144 bytes, while the Shannon entropy of the succeeding section is calculated at 7.91 bits per byte. Furthermore, the Import Address Table lists only LoadLibraryA and GetProcAddress. What forensic conclusion is directly supported by these metrics?

A
B
C
D
Test Your Knowledge

An incident responder writes a YARA rule to detect an in-memory reflective loader. Which of the following condition blocks correctly validates that the target file is a Windows Portable Executable (PE) binary before applying signature string logic?

A
B
C
D