Documentation
¶
Overview ¶
Package dranzer parses the plain-text report produced by the CERT/CC dranzer tool (https://github.com/CERTCC/dranzer), which fuzz-tests ActiveX/COM controls. Dranzer has no machine-readable output mode and its format is undocumented, so the parser is intentionally tolerant: it extracts the structure it recognizes (the run summary, per-object metadata and error findings) and always preserves the full original text in Raw so a policy can fall back to string matching.
Real dranzer reports are emitted in the system's ANSI code page rather than UTF-8, so the parser sanitizes invalid byte sequences instead of rejecting them.
Index ¶
Constants ¶
const ToolName = "dranzer"
ToolName is the canonical tool name recorded for dranzer materials.
Variables ¶
var ErrNoReports = errors.New("no dranzer report found")
ErrNoReports is returned when a dranzer material holds no recognizable report: a single file that is not dranzer output, or an archive with no report entry.
Functions ¶
This section is empty.
Types ¶
type Bundle ¶ added in v1.105.0
Bundle is the policy projection of a CERTCC_DRANZER material, which may hold a single report or an archive of the per-mode reports produced by one dranzer run (its -b, -p, -s and -t modes).
Report is embedded so the aggregate is promoted to the top level of the JSON: a policy reading input.summary / input.findings / input.tool behaves the same whether the material was one report or a bundle of them. Reports carries the per-mode breakdown for policies that need to be precise about which mode reported what.
func ParseBundle ¶ added in v1.105.0
ParseBundle projects one dranzer material to JSON-ready form. A value that is not an archive is treated as a bundle of one; an archive is expanded and every entry that is a recognizable report contributes to the aggregate.
A single non-archive value is never rejected, so projecting an already-recorded material cannot start failing — validating the input is Inspect's job, at craft time. An archive, by contrast, must yield at least one report: selecting entries is only meaningful if something was selected.
type Entry ¶ added in v1.105.0
type Entry struct {
Source string `json:"source,omitempty"`
Tool Tool `json:"tool"`
Summary Summary `json:"summary"`
}
Entry is one report's contribution to a Bundle: which archive entry it came from and the counters it reported. Its objects and findings are not repeated here — they are in the Bundle's aggregate, each stamped with the same Source — so the policy input carries them once.
type Finding ¶
type Finding struct {
Source string `json:"source,omitempty"`
CLSID string `json:"clsid,omitempty"`
ClassName string `json:"class_name,omitempty"`
Method string `json:"method,omitempty"`
ErrorCode string `json:"error_code,omitempty"`
ErrorMessage string `json:"error_message,omitempty"`
Address string `json:"address,omitempty"`
AccessType string `json:"access_type,omitempty"`
}
Finding is a single error reported against a COM object during the run. The header failure blocks populate CLSID/ClassName/ErrorCode/ErrorMessage; the inline access-violation and exception blocks additionally populate Method, Address and AccessType. Source names the archive entry the finding came from when the material is a bundle of reports, and is empty otherwise.
type Inspection ¶ added in v1.105.0
Inspection is what reading a dranzer material tells us about it, without retaining its content: how many reports it holds and which tool version produced them.
func Inspect ¶ added in v1.105.0
func Inspect(p string) (Inspection, error)
Inspect validates a dranzer material on disk and summarizes it, accepting either a single report or an archive of them. Archives are streamed rather than held in memory.
It shares both of its predicates with ParseBundle — what counts as an archive (archiveio.DetectFile, which reads content just as the projection's DetectBytes does, rather than trusting the filename) and what counts as a report (parseReportEntry) — so a material this accepts is necessarily one the projection can aggregate. Were the two to disagree, a material would be attested at craft time and then silently skip policy evaluation, which on a compliance gate reads as a clean run.
ErrNoReports means the material is not dranzer evidence at all.
type Object ¶
type Object struct {
Source string `json:"source,omitempty"`
CLSID string `json:"clsid,omitempty"`
Description string `json:"description,omitempty"`
Metadata map[string]string `json:"metadata,omitempty"`
}
Object is a single COM/ActiveX control described in the report, with its version/identity metadata. Only the per-object test modes (e.g. -t) emit these blocks; summary-only modes (-b/-p/-s) leave Objects empty. Source names the archive entry it came from when the material is a bundle of reports, and is empty otherwise.
type Report ¶
type Report struct {
Source string `json:"source,omitempty"`
Tool Tool `json:"tool"`
Objects []Object `json:"objects"`
Findings []Finding `json:"findings"`
Summary Summary `json:"summary"`
Raw string `json:"raw"`
}
Report is the structured projection of a dranzer run. Source names the archive entry it was read from when the material is a bundle of reports, and is empty for a single-file material.
Raw is always emitted, even when empty, so a policy reading input.raw for a string-matching fallback finds a string rather than an undefined key.
func Parse ¶
Parse converts a dranzer text report into a Report. Real reports are emitted in the system ANSI code page, so invalid UTF-8 byte sequences are sanitized rather than rejected; parsing therefore never fails on well-formed reports. Unrecognized content is preserved in the top-level Raw field.
func (*Report) LooksLikeDranzer ¶
LooksLikeDranzer reports whether the parsed report resembles genuine dranzer output. It is lenient about structure — a test-engine version banner, a parsed object, a parsed finding, or any parsed run counter is enough, and every mode emits the banner — but it judges only what the parser actually extracted, never the presence of a phrase in the raw text.
That distinction matters because dranzer bundles ship a CSV companion beside the reports which quotes both the per-object banner and an error line inside its columns. A raw substring match accepts such a file even though it yields no version, objects, findings or counters; it would then be recorded as dranzer evidence and *skip* policy evaluation, which on a compliance gate is indistinguishable from a clean run. Genuine reports put the banner and the counters on their own lines, where the line-anchored patterns match them, so nothing real is lost.
A parsed counter counts even when its value is zero, so a legitimate run that found no COM objects is still recognized.
type Summary ¶
type Summary struct {
ObjectCount int `json:"object_count"`
KillBit int `json:"kill_bit_count"`
Passed int `json:"passed_count"`
Failed int `json:"failed_count"`
Hung int `json:"hung_count"`
Counters map[string]int `json:"counters,omitempty"`
}
Summary holds the run-level counters dranzer prints in every report. The well-known counters are exposed as explicit fields for convenient policy access; every "Number of ..." line is also recorded verbatim (normalized to a snake_case key) in Counters so mode-specific counters are not lost.