JSON Output¶
ppee-cli --json writes one JSON document to stdout. The MCP tools return the same document, so this reference applies to both.
Conventions¶
| Convention | Example | Notes |
|---|---|---|
Values read from the file are uppercase hex strings without 0x | "FileHeader.Machine": "8664" | Convert with tonumber in a language, or ("0x"+.) style helpers in jq, see recipes |
| Counts, indexes, sizes and ordinals are JSON numbers | "numberOfFunctions": 12 | |
| Measurements are JSON numbers | "entropy": 6.231031 | |
Optional directories carry "present": true/false | "exports": {"present": false, ...} | The object is still emitted, so check present first |
| List-type directories are arrays, empty when absent | "boundImports": [] | |
| Text is UTF-8 | Non-printable bytes are escaped |
Top level¶
{
"path": "/abs/path/sample.dll", // absolute path of the analyzed file
"size": 650752, // file size in bytes
"is64Bit": true, // PE32+ (true) or PE32 (false)
"headers": { ... }, // --headers
"dataDirectories": { ... }, // --dirs
"sections": { ... }, // --sections
"fileInfo": { ... }, // --hashes / --similarity
"similarity": { ... }, // --similarity
"imports": [ ... ], // --imports
"exports": { ... }, // --exports
"baseRelocations": [ ... ], // --basereloc
"tls": { ... }, // --tls
"debug": [ ... ], // --debug
"boundImports": [ ... ], // --bound-imports
"delayImports": [ ... ], // --delay-imports
"resources": { ... }, // --resources
"exception": { ... }, // --exception
"security": { ... }, // --security
"loadConfig": { ... }, // --loadconfig
"net": { ... }, // --net
"richHeader": { ... }, // --richheader
"appManifest": { ... }, // --appmanifest
"analysis": { ... }, // --analysis / --analysis-deep
"strings": { ... }, // --strings
"disasm": { ... }, // --disasm
"xrefs": { ... }, // --xrefs
"functions": { ... } // --functions
}
Only the sections you select are present. Keys always appear in this order.
Sections¶
headers, dataDirectories, sections¶
Flat objects that map a field name to a hex string. The names are the ones --set accepts.
"headers": {
"DosHeader.e_magic": "5A4D",
"FileHeader.Machine": "8664",
"FileHeader.TimeDateStamp": "F8929A64",
"OptionalHeader.DllCharacteristics": "4160"
},
"dataDirectories": { "DataDirectory[1].VirtualAddress": "425638", "DataDirectory[1].Size": "AB4" },
"sections": { "Section[0].Name": ".text", "Section[0].Characteristics": "60000020" }
A section whose name is a COFF long name (/29) also has Section[i].LongName, the name it stands for (.debug_info).
fileInfo¶
"fileInfo": {
"crc32": "B1A68BA9", "entropy": 6.231031,
"md5": "706FCA0D…", "sha1": "E56F1366…", "sha256": "5027E704…",
"ssdeep": "12288:LplT1X0l8…", "tlsh": "T11DD45B2E…",
"impHash": "6501FFF7…", "authentihash": "4D6CFACB…"
}
See Hashes & Entropy.
similarity¶
"similarity": {
"available": true, // false if the database could not be opened (read-only location)
"dbRecordCount": 2,
"matches": [ { "peerPath": "/samples/explorer.exe", "kind": "SHA256 identical" } ]
}
imports, delayImports, boundImports¶
"imports": [
{ "name": "msvcrt.dll", "originalFirstThunk": "94A90", "timeDateStamp": "0",
"forwarderChain": "0", "firstThunk": "72540",
"functions": [ { "hint": 1280, "name": "wcscat_s" }, { "ordinal": 12 } ] }
],
"delayImports": [
{ "name": "Bcp47Langs.dll", "attributes": "1", "timeDateStamp": "0",
"functions": [ { "hint": 42, "name": "GetSerializedUserLanguageProfile" } ] }
]
A function imported by ordinal has ordinal instead of hint/name.
exports¶
"exports": {
"present": true, "name": "AEPIC.dll", "characteristics": "0", "timeDateStamp": "F8929A64",
"majorVersion": 0, "minorVersion": 0, "base": 1,
"numberOfFunctions": 12, "numberOfNames": 12,
"functions": [ { "ordinal": 1, "name": "GetAppInventoryCore", "rva": "29CB0" },
{ "ordinal": 12, "name": "ADsSetLastError", "forwarder": "ADSLDPC.ADsSetLastError" } ]
}
A forwarded export has forwarder instead of rva.
baseRelocations¶
"baseRelocations": [ { "pageRVA": "70000", "sizeOfBlock": 868,
"entries": [ { "offset": "0", "type": 10 } ] } ]
type 10 is IMAGE_REL_BASED_DIR64, 3 is HIGHLOW, 0 is padding (ABSOLUTE).
tls¶
"tls": { "present": true, "startAddressOfRawData": "1403F4A48", "endAddressOfRawData": "1403F4A50",
"addressOfIndex": "140433518", "addressOfCallBacks": "1403A0478",
"sizeOfZeroFill": "0", "characteristics": "300000", "callbacks": [] }
debug¶
"debug": [ { "type": 2, "timeDateStamp": "F8929A64", "sizeOfData": 34, "pointerToRawData": "82908",
"codeView": { "format": "RSDS", "pdbPath": "aepic.pdb", "age": 1,
"guid": "D269A603-CE82-ED0C-3EBD-B5FB71DA278C" } } ]
type: 2 = CodeView, 12 = VC feature, 13 = POGO, 16 = repro, 20 = extended DLL characteristics.
resources¶
"resources": {
"present": true, "numberOfNamedEntries": 0, "numberOfIdEntries": 1,
"types": [ { "id": 16, "typeName": "RT_VERSION",
"names": [ { "id": 1,
"languages": [ { "id": 1033, "offsetToData": "507580", "size": 120, "codePage": 0,
"entropy": 5.66, "md5": "927E8608…",
"firstBytesHex": "89 50 4E 47 …", "firstBytesAscii": ".PNG…",
"typeDetected": "PNG" } ] } ] } ]
}
Named entries have name instead of id. offsetToData is an RVA (as in the PE format).
exception¶
"exception": { "present": true, "machine": "AMD64",
"entries": [ { "beginAddress": "1008", "endAddress": "10B0", "unwindInfoAddress": "89FFC",
"unwindInfo": { "version": 1, "flags": 3, "sizeOfProlog": 38, "countOfCodes": 9 } } ] }
security¶
"security": {
"present": true,
"certificates": [ { "fileOffset": "8600", "length": 9336, "revision": "200",
"certificateType": "2", "sha256": "95E27476…" } ],
"validity": { "available": false, "result": "Not available on this platform",
"comment": "Signature validity is checked by the Windows version of ppee" },
"signatures": [ {
"certificateIndex": 0, "nested": false, "parsed": true,
"programName": "Microsoft Windows", "publisherLink": "http://www.microsoft.com/windows",
"digestAlgorithm": "SHA256", "signatureAlgorithm": "RSA",
"embeddedDigestAlgorithm": "SHA256", "embeddedDigest": "7C1A1478…", "authentihash": "7C1A1478…",
"signerCertificate": { "serialNumber": "…", "issuerName": "…", "issuer": "C=US, …",
"subjectName": "Microsoft Windows", "subject": "C=US, …",
"validFrom": "2019/03/27 19:21:43", "validTo": "2020/03/27 19:21:43",
"signatureAlgorithm": "SHA256 RSA", "publicKey": "RSA 2048-bit",
"enhancedKeyUsage": "…, Code Signing" },
"timestamp": { "kind": "RFC3161 token", "date": "2019/12/07 04:35:20", "certificate": { … } } } ]
}
embeddedDigest == authentihashmeans the file hasn't been modified since it was signed.validity.availableistrueonly on Windows builds, whereresultcarries the WinVerifyTrust verdict.
loadConfig¶
"loadConfig": { "present": true, "isPe64": true,
"header": { "size": "118", "securityCookie": "140431C68", "guardFlags": "417500",
"guardCFFunctionTable": "1403A097C", "guardCFFunctionCount": "F71", … },
"safeSeh": { "present": false, "entries": [] },
"guardCFFunction": { "present": true, "entries": [ { "rva": "4F10" } ] },
"guardAddressTakenIat": { "present": true, "entries": [ … ] },
"guardLongJumpTarget": { "present": false, "entries": [] },
"guardEHContinuation": { "present": true, "entries": [ … ] } }
net¶
"net": { "present": true,
"header": { "cb": "48", "majorRuntimeVersion": 2, "minorRuntimeVersion": 5, "flags": "18",
"entryPointToken": "26314", "metaDataRva": "8DA0", "metaDataSize": "13504", … },
"metadataRoot": { "present": true, "signature": "424A5342", "versionString": "v2.0.50727",
"numberOfStreams": 5,
"streams": [ { "name": "#~", "offset": "6C", "size": "66F4" } ] },
"vTableFixups": [ … ] }
richHeader, appManifest¶
Row lists that mirror the GUI's Member / Value / Comment columns:
"richHeader": { "present": true, "rows": [ { "member": "Product ID", "value": "0104", "comment": "C object, VS2015" } ] },
"appManifest": { "present": true, "rows": [ { "member": "Level", "value": "asInvoker", "comment": "No additional permissions" } ] }
analysis¶
Derived views for the runtimes PPEE detected, kept under one key so a consumer can never mistake them for data read from the file. runtimes is empty when nothing was detected.
"analysis": { "runtimes": [ {
"key": "go", "name": "Go", // key: net | go | rust | aot
"evidence": "Go build info at offset 0x5B0220; Go 1.20+ pclntab at offset 0x8C61E0",
"views": [
{ "key": "analysis.go.summary", "title": "Summary",
"source": "the Go build info, build ID and pclntab, and the file layout",
"tone": "warning", // normal | warning | error | muted
"blocks": [ // rich views (Summary)
{ "kind": "heading", "spans": [ { "text": "Identity" } ] },
{ "kind": "fact", "label": "Go version",
"spans": [ { "text": "go1.24.2", "link": 0 } ] }, // link: index into this view's "links"
{ "kind": "note", "tone": "warning", "spans": [ { "text": "Overlay (appended data): 1177.6 KB" } ] } ],
"links": [ { "offset": "5B0220", "length": "20", "where": "offset 0x5B0220" } ] },
{ "key": "analysis.go.packages", "title": "Packages", "source": "the pclntab (the runtime's function table)",
"tone": "normal",
"table": { "columns": [ "Package", "Functions", "Source files" ], // table views
"rows": [ { "cells": [ "main", "4", "1" ],
"tone": "warning", // only when not normal
"link": 0, // optional link index
"detail": { "columns": [ … ], "rows": [ … ] } } ] }, // optional nested table
"links": [ … ] } ] } ] }
| Object | Fields |
|---|---|
| runtime | key, name, evidence, views[] |
| view | key, title, source, tone, and either blocks[] (rich) or table (rows), plus links[] |
| block | kind (heading, fact, note, paragraph), label (facts), tone (notes), spans[] (text, optional link) |
| table row | cells[], optional link, tone, detail (a nested table) |
| link | {va, where} (code, opens the Code window) or one of {node, where}, {node, row, where} (a tree node or table row), {offset, length, where} (a file range, hex strings) or {action: "deep", where} (a hint that the deep pass would add more) |
View keys: analysis.net.{summary,imports,nativeimports,exports,resources}, analysis.go.{summary,packages,modules,build}, analysis.rust.{summary,sources}, analysis.aot.summary, analysis.code.{summary,calls,patterns,functions}.
The Code runtime (key: "code") adds two things: a block of kind: "code" holding instruction evidence as lines[] (va, text), and code links {va, where} that point at an address in code rather than a file range. Go and NativeAOT function rows also link with va. Tables that would be empty are omitted. See Runtime Analysis.
strings¶
"strings": {
"ascii": [ { "offset": "4D", "sectionName": "Inside header area", "text": "!This program cannot be run in DOS mode." } ],
"unicode": [ … ],
"url": [ { "offset": "76600", "sectionName": ".rdata [R] (#2 section)", "type": "ASCII", "text": "…" } ],
"registry": [ … ],
"suspicious": [ … ]
}
offset is a file offset. Tagged hits (url, registry, suspicious) add type (ASCII / UNICODE). The MCP get_strings tool adds omittedByLimit with per-group counts.
disasm, xrefs, functions¶
Present only with --disasm, --xrefs and --functions; see that page for the shapes and examples.
Validating output in scripts¶
ppee-cli --json --hashes "$f" | jq -e '.fileInfo.sha256 | length == 64' > /dev/null \
|| echo "unexpected output for $f"
Related: jq recipes · CI policy gates · MCP tools
References¶
- jq manual: the filter language used in the JSON examples on this page.