First-pass malware triage should answer a bounded question: what is this artifact, what evidence suggests relevant behavior, and what analysis should happen next? It should not turn a list of suspicious strings into a confident family attribution. Static analysis can identify useful leads without executing the sample, but every result still needs provenance and a clear distinction between observed content and inferred behavior.
This guide assumes you are authorized to handle the artifact and have an isolated analysis workspace. Unknown binaries should not be launched on a normal workstation. Analysis tools themselves parse complex untrusted files, so keep the environment updated and separate it from sensitive accounts and data. Begin with a harmless sample you compiled yourself when learning the workflow.
Preserve identity and handling context
Record the acquisition source, collection time, original filename, size, and SHA-256 hash. Preserve an untouched original and create a working copy. Avoid putting confidential customer names or incident identifiers in a filename that may later appear in a screenshot or external query.
For a local Windows working copy, PowerShell can calculate the hash without launching the file:
$sample = Get-Item -LiteralPath .\sample.bin$sample | Select-Object Name, LengthGet-FileHash -Algorithm SHA256 -LiteralPath $sample.FullNameA matching hash is evidence of identical bytes for practical artifact tracking; a filename match is not. A hash alone does not establish whether the file is malicious or whether two different samples belong to the same campaign. Keep identity, behavior, and attribution as separate fields in your notes.
Identify the container before the code
Check the file format rather than trusting its extension. Determine whether you are looking at a native executable, a managed assembly, an archive, a script, or a raw data object. If it is an archive, inventory its members in the isolated environment before deciding which component deserves deeper analysis.
For Windows PE files, inspect the machine type, sections, entry point, imports, exports, and resources as relevant. Microsoft’s PE/COFF format documentation defines these structures. Section names and timestamps are contextual evidence, not reliable identity or intent claims. A section called .text can be misleading, and a timestamp may be absent or manipulated.
Use the loader’s interpretation as a starting point and record errors. If the file is malformed, do not force an ordinary import merely to obtain a decompiler window. The malformed structure may itself be important to the investigation or may require a different parser.
Inventory strings and imports as leads
Collect strings with their addresses or file offsets and encoding. A domain-like string, a command fragment, or a registry path can direct navigation. Its presence does not prove it is used, reachable, or malicious. Dead code, embedded resources, library routines, and deliberate decoys all complicate interpretation.
Likewise, an imported networking function indicates a possible capability rather than a confirmed connection. A program may resolve APIs dynamically or use a runtime library that obscures direct imports. Record both the lead and the limitation instead of treating a missing import as proof that a behavior cannot occur.
Use a lead table with provenance:
| Lead | Location | Immediate reference | Status |
|---|---|---|---|
| URL-like string | recorded address | function references data | not yet traced |
| File creation import | import entry | caller found | argument analysis pending |
| Encoded data block | recorded range | loop accesses bytes | purpose unknown |
This table prevents a report writer from accidentally promoting “found in strings” into “contacts this server.” It also gives the next analyst a direct place to continue.
Trace a small number of relevant behaviors
Pick one or two leads that answer the incident question. If the concern is persistence, trace configuration or startup-related operations. If the question is data access, inspect the file selection and read paths. Do not spend the entire first pass reconstructing unrelated runtime initialization.
For each path, identify callers, controlling conditions, and arguments. Keep the Listing beside the Decompiler when checking an important comparison or indirect call. Rename functions only after you can describe their operations. A loop over bytes is not automatically a decryptor, and a function named by an earlier analyst is not independent evidence.
Describe behavior with conditions: “This function constructs a path from the supplied base directory and a fixed filename before calling the file operation.” That statement is more precise than “drops malware” when you have not established the contents, execution, or external trigger.
Recognize when static triage has reached its limit
Packing, runtime-generated code, unresolved indirect calls, and environment checks may prevent a useful static conclusion. Record the obstruction and the evidence behind it. High entropy can motivate investigation, but it does not uniquely identify packing or encryption; compressed benign resources can also have high entropy.
Do not repeatedly rerun automatic analysis with arbitrary settings until the output looks plausible. Keep the original import assumptions and explain each change. If you need dynamic analysis, create a separate plan for an appropriately isolated environment, with snapshot and network controls suited to the case. A static triage report can legitimately end with a request for that next stage.
Write a report with explicit evidence levels
Use separate labels for directly observed facts, supported interpretations, and open questions. CISA’s public malware analysis reports provide examples of artifact-centered reporting with technical detail. Your first-pass report can be much smaller while preserving that emphasis on identifiable evidence.
Artifact: filename, size, SHA-256Scope: static triage only; sample not executedEnvironment: analysis tool and versionObserved: file structure, imports, strings, referenced codeInterpreted: behavior with supporting addresses and conditionsUnknown: unresolved targets, encoded content, runtime dependenciesNext action: deeper static work or approved isolated dynamic analysisInclude time limits and coverage. “Reviewed two functions reachable from the file-writing call” conveys far more than “analyzed the binary.” A report that clearly defines what was not examined is easier to trust and extend.
Keep sensitive material local by default
Do not upload a sample, strings export, decompilation, or report to a public scanner or cloud model without explicit authorization. A strings list can contain tokens, internal paths, or proprietary identifiers even when the binary itself stays local. Record any approved external submission and its scope.
Opcodex’s planned automated triage reports should follow the same evidence model; no generated summary should imply observed runtime behavior from static strings alone. See the report feature status and the AI/MCP guide for integration boundaries. When the input is a benign training target, the beginner workflow is a good way to practice before handling incident material.
Opcodex is under development. These field notes describe analysis techniques and clearly labeled plans, not a claim that Pro features are available.