blint is a binary analysis tool that examines executable files to extract a wide range of metadata. This document serves as a technical guide for security analysts and reverse engineers who want to understand the JSON output produced by blint.
The primary goal of blint's metadata generation is to act as a "Rosetta Stone" for binary formats. It parses different and often complex structures from ELF, PE, and Mach-O files and presents them in a single, standardized JSON format. This allows for consistent analysis, scripting, and threat hunting across different operating systems and architectures.
This guide details the attributes found in the metadata, their purpose, and the methods blint uses to obtain them, including notable strengths and limitations.
At the highest level, the JSON output contains attributes that identify the binary and provide universally applicable information.
| Attribute | Description | Use Case |
|---|---|---|
file_path |
The absolute path to the analyzed binary file on the filesystem. | Basic file identification and tracking. |
binary_type |
The format of the binary, such as ELF, PE, MachO, or WASM. This is the primary key for interpreting format-specific sections. |
Directing further analysis; knowing which format-specific tools to use next. |
hashes |
A collection of cryptographic hashes for the file, including MD5, SHA1, SHA256, and SHA512. | File identification, malware signature matching, and searching in threat intelligence platforms like VirusTotal. |
llvm_target_tuple |
A string constructed to represent the binary's target environment in a format recognized by LLVM. The format is arch-vendor-os-environment. For example: x86_64-pc-win32-msvc or mipsel-unknown-linux-muslsf. This is crucial for accurate disassembly. |
Configuring disassemblers and decompilers; understanding the intended operating system and ABI. |
callgraph |
Optional compact function-call graph derived from disassembled_functions when --disassemble is enabled. Includes nodes, internal edges (with call counts), and unresolved/ambiguous external targets. |
Control-flow triage, function reachability analysis, and quick hotspot detection without parsing full assembly text. |
strings |
A list of strings extracted from the binary that exhibit high entropy or match patterns for secrets (API keys, private keys, etc.). Non-secret strings are filtered out to reduce noise. Base64-encoded strings are automatically decoded. | Triage for hardcoded credentials, sensitive URLs, or cryptographic material. A primary step in vulnerability and malware analysis. |
informative_strings |
Optional list of selected non-secret strings that match stable operational or exploit-triage indicators (for example network stack hooks, raw socket constants, DNS redirection hints, or Windows local-elevation technique markers). Each item includes value and category. |
Capability clustering for behaviors that may be visible in constants or embedded paths rather than symbol tables alone. |
- Some parser fields can include raw bytes that are not valid UTF-8.
- blint serializes undecodable bytes as hex strings for compatibility with JSON reports.
- To avoid oversized report fields, hex output is capped by
BLINT_MAX_HEX_BYTES(default:4096). - If capped, the value is emitted as
<hex>...<truncated:N_bytes>whereNis the original byte length. - Set
BLINT_MAX_HEX_BYTES=0to disable truncation.
blint provides detailed information specific to each binary format, normalized where possible.
ELF (Executable and Linkable Format) files are the standard for Linux, BSD, and many embedded systems.
-
Header Information (
header): Contains fundamental properties of the ELF file.class:ELF32orELF64, indicating a 32-bit or 64-bit binary.endianness:LSB(Little-Endian) orMSB(Big-Endian). Crucial for MIPS and ARM analysis.identity_os_abi: The target OS Application Binary Interface (e.g.,LINUX,FREEBSD).machine_type: The target CPU architecture (e.g.,AARCH64,MIPS,X86_64).
-
Dynamic Entries (
dynamic_entries): Lists entries from the.dynamicsection, which are essential for the dynamic linker.NEEDED: Specifies a required shared library (e.g.,libc.so.6). This is the basis for dependency analysis.SONAME: The "shared object name" this binary provides if it's a library.RPATH/RUNPATH: Library search paths hardcoded into the binary. A common focus for security review, as they can be used for library hijacking.
-
Notes (
notes): Contains metadata from.notesections.GNU_BUILD_ID: A unique hash identifying the specific build, useful for matching the binary with its corresponding debug symbols.ANDROID_IDENT: If present, provides Android-specific information likesdk_versionandndk_version.dlopen_dependencies: Metadata extracted from the FDO ELF Note designed to declare dependencies loaded dynamically at runtime viadlopen().- Context: Standard binary analysis usually only detects libraries linked at build time (found in
NEEDEDentries). However, many modern applications load plugins, codecs, or optional modules programmatically during execution. - Content: This attribute parses the embedded JSON note to list these "hidden" dependencies, including the library name (
soname), its necessity (required,recommended, orsuggested), and the specific application feature it enables. - Use Case: Critical for discovering the full dependency tree of modular applications (like media players or system daemons) that would otherwise appear to have very few dependencies during static analysis.
- Context: Standard binary analysis usually only detects libraries linked at build time (found in
-
ABI Requirements (
abi_analysis): The runtime the binary requires and the ABI features that constrain where it can run. Seeabi_analysisbelow. -
Runtime Loading (
runtime_loading,recovered_dependencies): Libraries the binary opens at runtime rather than linking against, recovered from the image itself rather than from a declarative note. Seeruntime_loadingandrecovered_dependenciesbelow. -
Link Closure (
link_closure, optional): The result of resolving the dependency graph the way the dynamic loader would. Seelink_closurebelow.
PE (Portable Executable) files are the standard for Windows.
-
Headers (
dos_header,header,optional_header):machine_type: The target architecture (e.g.,AMD64,I386).subsystem: Indicates whether the application isWINDOWS_GUIorWINDOWS_CUI(console).dll_characteristics: A set of flags indicating security features likeDYNAMIC_BASE(ASLR) andCONTROL_FLOW_GUARD.
-
Load Configuration (
load_configuration): This structure is the bridge between the static binary and the OS Loader/Hypervisor security features.guard_flags: The raw integer flags indicating various security settings processed by the OS loader.guard_cf_flags: List of active Guard features, such asCF_INSTRUMENTED(Control Flow Guard) andRF_INSTRUMENTED(Return Flow Guard/PAC).code_integrity: Configuration for Hypervisor-Protected Code Integrity (HVCI).flags: Settings determining how the kernel verifies the digital signature of this binary at runtime.catalog: Indicates if the signature is stored in an external catalog file rather than embedded in the binary.
enclave_config: Metadata for running inside a Trusted Execution Environment (TEE), such as Intel SGX or Windows VBS (Virtualization-based Security) Enclaves.policy_flags: Security policies enforced by the enclave (e.g., debugging allowed).imports: Specific functions imported by the enclave code from the host process.
volatile_metadata: Information used by Virtual Secure Mode (VSM).- Defines memory ranges that are mutable vs. executable, allowing the Hypervisor to enforce W^X (Write XOR Execute) policies more granularly than standard page tables.
runtime_checks: A dictionary of specific function pointers present in the binary that correspond to hardware-backed security checks.guard_rf_verify_stackpointer: Indicates the binary expects the OS to verify the Stack Pointer using ARM64 PAC keys (Key B).guard_xfg_check: Indicates support for Extended Flow Guard (Type-based CFI).guard_eh_continuation: Indicates support for Intel CET (Shadow Stack) during exception handling.
-
Authenticode (
authenticode,signatures): Detailed information about the binary's digital signature.- Provides hashes (
authentihash_*) of the signed content. - Extracts information about the signer, including the issuer (
cert_signer) and serial number. This is vital for trust verification and threat intelligence.
- Provides hashes (
-
Resources (
resources): Metadata extracted from the.rsrcsection.version_metadata: Contains key-value pairs likeProductName,CompanyName, andFileVersion. Useful for identifying the software and its origin.manifest: The embedded XML application manifest, which controls privileges, dependencies, and UI settings.
-
data_directories, sections, and rich_header
- See the official LIEF documentation to learn about these attributes.
-
Imports and Exports (
imports,exports):imports: A list of all functions imported from external DLLs, grouped by library. Forms the basis of theimphash.exports: A list of all functions this binary provides to other executables.
-
Thread Local Storage (TLS) Callbacks:
tls_callbacks: List of the callbacks associated with the current TLS. These functions are called before any other functions.tls_address_index: The location to receive the TLS index assigned by the loader. This location should be located in a writable section like .data.tls_sizeof_zero_fill: Size in bytes of the zeros to be padded after the data specified by data_template.tls_data_template_len: Length of the initial content used to initialize TLS data.tls_characteristics: The four bits [23:20] describe alignment info. Possible values are those defined as LIEF.IMAGESCN_ALIGN*, which are also used to describe alignment of section in object files. The other 28 bits are reserved for future use.tls_section_name: Section associated with the TLS object (or absent if not linked)tls_directory_type: Name of the DataDirectory associated with the TLS object (or absent if not linked)
-
Exceptions (exceptions): For x86-64 and ARM64 PE binaries, this section provides detailed stack unwinding information extracted from the IMAGE_DIRECTORY_ENTRY_EXCEPTION.
- Attributes:
rva_startandrva_end: The memory boundaries of the function code.unwind_info: metadata including sizeof_prologue, frame_reg (frame pointer register), and flags.opcodes: The specific machine instructions (e.g., PUSH_NONVOL, ALLOC_SMALL) used to set up the stack frame.handler_rva: The address of the language-specific exception handler (e.g., __C_specific_handler).
- Use Cases:
- Function Discovery in Stripped Binaries: Even if the symbol table is removed, the Exception Directory must remain valid for the OS to handle crashes. This makes rva_start and rva_end the most reliable way to discover function boundaries in stripped malware or commercial software.
- Stack Frame Reconstruction: By analyzing the opcodes and prologue_size, analysts can reconstruct exactly how the stack is manipulated. This is vital for understanding where local variables are stored and identifying potential buffer overflow conditions.
- Anti-Analysis Detection: Malware sometimes employs custom exception handlers (handler_rva) to obscure control flow or detect debuggers. Identifying non-standard handlers is a key indicator of obfuscation.
- Attributes:
In the case of ARM64X, a single PE file encapsulates ARM64 and ARM64EC architectures. For ARM64EC nested PE binaries, an additional attribute nested_binary would contain the information such as exports, exceptions, functions, ctor_functions, and dotnet_dependencies.
Mach-O files are the standard for macOS, iOS, and other Apple operating systems.
-
Header (
header):cpu_type: The target architecture (e.g.,ARM64).file_type: Identifies the binary as anEXECUTABLE,DYLIB(shared library), etc.
-
Load Commands: Mach-O uses load commands instead of a dynamic section.
libraries: A list of required dylibs, equivalent toNEEDEDentries in ELF.uuid: A unique identifier for the binary, used by debuggers and crash report symbolication tools.rpath: A runtime search path for libraries.code_signature: Information about the binary's digital signature, crucial for Apple's security model.
-
Encryption (
is_encrypted,encryption_info): Derived fromLC_ENCRYPTION_INFO(_64).is_encryptedistruewhencrypt_idis non-zero (FairPlay-protected App Store binaries); developer, ad-hoc, and enterprise builds reportfalse.encryption_infocarriescrypt_id,crypt_offset, andcrypt_size. An encrypted__TEXTsegment cannot be meaningfully disassembled without on-device decryption. -
Objective-C metadata (
objc_metadata): Recovered by walking the raw__objc_*sections (LIEF's community build does not expose this). Internal pointers are resolved via relocation targets, with a chained-fixup fallback that decodes rawdyldchained pointers (validated against mapped section ranges) when no relocation map is present; external class pointers are resolved via the dyld binding table. Present only when the binary contains 64-bit Objective-C metadata (32-bit armv7/i386 layouts are skipped).class_count,protocol_count,selector_count: summary counters.classes: each entry hasname,superclass(internal class name or external framework class),method_count,methods(selector names), and optionalprotocols.protocols: declared protocols with theirnameandmethods.selectors: distinct selectors referenced at message-send sites (__objc_selrefs).external_classes: framework/runtime classes the binary links against (e.g.CLLocationManager,CTTelephonyNetworkInfo). Selectors and external classes feed the capability review, surfacing iOS privacy capabilities.method_imps: recovered method implementations as{name, address}, wherenameis the readable-[Class selector]form andaddressis the implementation's virtual address. These seed and label thefunctionslist (see below) so message handlers are disassembled and named even in stripped binaries.
-
Function recovery (
functions): For stripped release builds (the common case for shipped iOS/macOS apps) the symbol table exposes little beyond__mh_execute_header. blint augments the function list from theLC_FUNCTION_STARTStable — every entry point is recovered, reusing a surviving symbol name when one exists and synthesising asub_<address>name otherwise. Recovered Objective-C implementations then upgrade matchingsub_<address>entries to their-[Class selector]names. This is what allows disassembly and callgraph construction to work on stripped apps. -
Skipped disassembly (
disassembly_skipped): When--disassembleis requested for a FairPlay-encrypted binary (is_encryptedistrue), disassembly is skipped and this field is set tofairplay_encryptedrather than producing meaningless instructions from the encrypted__TEXT.
Swift symbols are demangled automatically (e.g.
Foundation.URL.appendingPathComponent(...)), including the Mach-O underscore-prefixed manglings (_$s…/_$S…/_T0…) which the bundled demangler recognises directly. When--disassembleis enabled, Mach-O imported calls made through__stubsand the GOT are resolved to their demangled symbol names, so call sites reference real Foundation/libswiftCore/libc APIs rather than anonymous stubs.
An .ipa is a zip archive containing a Payload/<App>.app/ bundle. blint unpacks it and analyzes every Mach-O it contains — the main executable, embedded frameworks and dylibs (Frameworks/), and app extensions (PlugIns/*.appex) — each producing its own *-metadata.json. The application context from the bundle's Info.plist is attached to each binary's metadata.
| Attribute | Description |
|---|---|
ios_bundle |
Bundle context: bundle_identifier, bundle_name, bundle_version, bundle_build, minimum_os_version, platform_name, application_category, role (main/framework/dylib/plugin), bundle_path, and the optional app_transport_security, url_schemes, and privacy keys described below. |
bundle_identifier |
Convenience top-level copy of the app's CFBundleIdentifier. |
bundle_version |
Convenience top-level copy of CFBundleShortVersionString. |
minimum_os_version |
Minimum supported OS version from the bundle. |
The bundle context can also carry two security-relevant keys parsed from the Info.plist:
app_transport_security: present only when the App Transport Security policy weakens the secure default. Carriesallows_arbitrary_loads,allows_arbitrary_loads_media,allows_arbitrary_loads_web, and aninsecure_exception_domainslist. For the main executable these are also projected intoinformative_stringsasATS_*tokens so the rule engine can flag a weakened transport posture (ruleIOS_INSECURE_TRANSPORT_ATS).url_schemes: the custom URL schemes the app registers (CFBundleURLTypes), useful as deep-link / inter-app entry points.
The bundle context also carries the app's privacy posture, parsed from the Info.plist and the PrivacyInfo.xcprivacy privacy manifest(s):
privacy_usage_descriptions: theNS...UsageDescriptionconsent-string keys the app declares (e.g.NSCameraUsageDescription), indicating the sensitive resources it is provisioned to access.query_schemes: theLSApplicationQueriesSchemesthe app can probe viacanOpenURLto detect other installed apps.bonjour_services: theNSBonjourServicesthe app browses for on the local network.privacy_manifest: present when any component ships aPrivacyInfo.xcprivacy. Aggregated across the app, embedded frameworks and extensions, it carriespresent,manifest_count,tracking,tracking_domains,collected_data_types, andaccessed_api_categories(the declared "required reason" API categories).
For the main executable these are projected into informative_strings as PRIV_* tokens (mirroring the ATS_* tokens above) so the rule engine can flag the privacy surface — for example PRIV_NSCameraUsageDescription, PRIV_LSApplicationQueriesSchemes, PRIV_NSPrivacyTracking, PRIV_PrivacyManifestMissing, and PRIV_UNDECLARED_<category> for a required-reason API referenced by the binary without a matching manifest declaration.
Embedded framework and app-extension binaries are additionally enriched with their own Info.plist identity (bundle_identifier, bundle_version) so the SBOM can report the real product version of a bundled dependency rather than inheriting the host app's version.
WASM (WebAssembly) binaries are parsed via wasm_tools and then normalized into blint's common metadata model.
- Detection: blint treats a file as WASM when the extension is
.wasmor the magic bytes are00 61 73 6d. - Normalization: blint preserves common cross-format keys (
imports,dynamic_entries,functions,symtab_symbols,dynamic_symbols) so dependency and review workflows continue to work. - Raw passthrough export: the complete parser output is written as a separate report artifact (
*-wasm-report.json) in the reports directory.
| Attribute | Description | Notes |
|---|---|---|
binary_type |
Set to WASM. |
Distinguishes the format in downstream logic. |
exe_type |
Set to wasmbinary. |
Format hint used by review logic. |
machine_type |
WASM architecture class: WASM32 or WASM64. |
Derived from memory limits (memories[].limits.is_64). |
module_version |
WebAssembly module version from header. | Usually 1 for core wasm modules. |
section_count |
Number of parsed sections. | Mirrors parser report. |
sections |
Parsed section records (id, name, size, offset, etc.). |
Format-specific detail for structural analysis. |
wasm_imports |
Detailed WASM imports with module, name, kind, type_index. |
Use this for function-level import analysis. |
imports |
Compatibility dependency list. | For WASM this is normalized to module-level {name, tag:"NEEDED"} entries. |
dynamic_entries |
Same dependency-style list as imports. |
Keeps dependency processing consistent with ELF/PE/Mach-O. |
exports |
WASM exports with name, kind, ref_index. |
Export-level capability and surface analysis. |
functions |
Parsed functions mapped to blint shape (index, name, address, size, instruction_count). |
address reflects instruction/body offset in wasm bytes. |
dynamic_symbols |
Synthetic imported symbol list used by dependency graph logic. | Built from WASM imports; includes is_imported markers. |
symtab_symbols |
Synthetic exported symbol list used by review logic. | Built from WASM exports; includes is_exported markers. |
wasm_analysis |
Structured analysis from wasm_tools (detections, capabilities, profiles, findings). |
Preserved as provided by parser API. |
wasm_errors |
Parser-reported errors, if any. | Non-fatal parse warnings/errors can appear here. |
errors |
blint-level error list for WASM parsing. | Set when parser reports issues or parse operation fails. |
WASM binaries also receive common derived fields like hashes, import_dependencies, llvm_target_tuple (for example wasm32-unknown-unknown), security_properties, and binary_composition.
blint writes the raw parser payload to a companion file named *-wasm-report.json alongside *-metadata.json.
Representative WASM fixtures used by tests are available under tests/data/*.wasm.
This collection of attributes describes the functions and data within the binary, providing insight into its structure and capabilities.
Symbols are names for locations in memory, typically corresponding to functions or global variables. BLint extracts symbols from two primary sources, which serve different purposes.
+------------------------------------+
| Your Executable File |
| |
| +-----------------+ (for static |
| | .symtab | linking & |
| | (symtab_symbols)| debugging) |
| +-----------------+ |
| ^ |
| | (often stripped) |
| |
| +-----------------+ (for dynamic |
| | .dynsym | linking at |
| |(dynamic_symbols)| runtime) |
| +-----------------+ |
| |
+------------------------------------+
-
symtab_symbols: This is the full symbol table (.symtabin ELF), containing names for all functions and global variables, including internal, non-exported ones.- Purpose: Provides a comprehensive map of the binary's internal structure.
- Use Case: Invaluable for reverse engineering, as it gives names to internal functions.
- Limitation: This table is often stripped from production binaries to reduce size and hinder reverse engineering. Its absence is a key indicator (
"stripped": trueinsecurity_properties).
-
dynamic_symbols: This is the smaller symbol table (.dynsymin ELF) used by the dynamic linker at runtime. It only contains symbols that are imported from or exported to other shared libraries.- Purpose: To resolve dependencies between shared libraries.
- Use Case: Understanding the binary's public API (what it exports) and its direct dependencies on functions from other libraries (what it imports).
- Strength: This table is almost never stripped from dynamically linked executables, as it is essential for the program to run.
Each symbol entry contains details like its name, type (FUNC or OBJECT), binding (GLOBAL, LOCAL, WEAK), and whether it is is_imported or is_exported.
nameis the demangled form where one exists, which is what a reader wants to see.raw_nameis the linkage name, present only when demangling changed it. This is the name that appears in another object's export table, so it is the only key that matches a C++ or Rust symbol across binaries. It is what symbol attribution and version-aware database lookups match on.versionis the symbol version node the symbol binds to, such asGLIBC_2.28. Seeabi_analysis.
While symbol tables provide the names, these lists represent a curated set of functions that LIEF identifies as code entry points.
-
functions: A list of general functions identified by the parser, often corresponding to exported symbols or entries in specific sections. -
ctor_functions: A list of constructors. These are special functions that are executed before the program's main entry point (mainorWinMain).- Purpose: To initialize the program's state or set up runtime environments.
- Use Case for Analysts: Malware and legitimate programs alike use constructors for early initialization. Examining these functions can reveal anti-debugging checks, environment setup, or other critical startup logic that occurs before the main code path.
-
dtor_functions: A list of destructors. These are special functions that are executed when the program exits cleanly.- Purpose: To perform cleanup tasks like flushing files or releasing resources.
- Use Case for Analysts: Malware may use destructors to cover its tracks, delete files, or send a final beacon upon exit. These are important to check for cleanup or anti-forensic activities.
These attributes provide insight into the toolchain, programming language, and third-party libraries used to create the binary. This is critical for Supply Chain Security and vulnerability analysis.
This object summarizes key information about the toolchain and primary language used to compile the binary.
| Property | Description | Use Case |
|---|---|---|
language |
The primary programming language detected (e.g., Go, Rust, .NET). This is inferred from language-specific sections or symbols. |
Guides the reverse engineering process by setting expectations for runtime behavior, calling conventions, and data structures. |
go_version |
If the language is Go, this specifies the exact version of the Go compiler toolchain used (e.g., go1.18.3). |
Allows for checking against known vulnerabilities in specific versions of the Go compiler or standard library. |
linker_version |
The version of the linker program (e.g., from ld or link.exe) that produced the final executable, if this information is present in the binary. |
Can help fingerprint the build environment (e.g., a specific Linux distribution or version of Visual Studio). |
compiler_version |
The compiler identification string, often extracted from the .comment section in ELF files (e.g., GCC: (Ubuntu 11.2.0-19ubuntu1) 11.2.0). |
Precisely identifies the compiler and its version, which is useful for tracking toolchain vulnerabilities. |
These attributes provide detailed lists of third-party libraries and packages compiled into the binary.
| Attribute | Description | Use Case |
|---|---|---|
go_dependencies |
A list of Go packages used to build the binary, extracted from the embedded .go.buildinfo section. Includes package names, exact versions, and checksums (h1: hashes). |
Gold Standard for SCA. Allows for precise identification of Go libraries and their versions, enabling direct mapping to known vulnerabilities (CVEs) in those packages. |
rust_dependencies |
A list of Rust crates used to build the binary, extracted from the .dep-v0 section created by the cargo-auditable feature. Includes crate name, version, and kind. |
Similar to Go, this enables precise SCA for Rust applications, mapping crates to known CVEs. Limitation: This section is only present if the developer explicitly enables the cargo-auditable feature during compilation. |
dotnet_dependencies |
A structured list of NuGet packages and their versions, extracted from the deps.json file embedded in the PE overlay of self-contained .NET applications. |
Provides precise SCA for .NET applications, allowing for vulnerability mapping. Limitation: This is only available for .NET Core/5+ applications published in "self-contained" mode and is not present in framework-dependent deployments. |
import_dependencies |
A structured graph detailing which shared libraries (.dll, .so, .dylib) are imported by the main binary and which specific symbols are used from each library. See Symbol attribution for what the attribution is based on per format. |
Provides a clear, high-level view of runtime dependencies. Helps identify the use of sensitive APIs (e.g., crypto, networking) and from which library they originate. This is a foundational element for behavior analysis. |
This is where blint provides the most value, by interpreting low-level data and presenting high-level security and compositional insights.
When disassembly output is available, blint derives a deterministic top-level callgraph:
version: Schema version for downstream compatibility.node_count/edge_count: Number of internal nodes and internal edges.nodes: Stable list of functions with{id, key, name, address, aliases}wherealiasesincludes other names sharing the same entry address.edges: Internal call edges as{src, dst, count, kind, confidence}wherekindis one ofdirect,tailcall,indirect_hint.external: Unresolved or ambiguous call targets as{src, target, count, reason, confidence}, pluslibrarywhen the target can be attributed to the library that supplies it.external_attribution_sources/attributed_external_count: What the library attribution was based on, and how many external edges carry one.
Notes:
- The graph includes direct edges, tail-call approximations, and register-tracked indirect hints.
confidenceindicates edge trust level (high,medium,low) for analyst triage.- Duplicate call instructions are preserved via edge
count. - Address/name collisions and misses are surfaced in
externalwith reason buckets such asambiguous_address,ambiguous_name, andaddress_space_miss. - An external edge carries a
libraryonly when the resolver recovered a symbol name for the target and that name is a known import. Edges whose target is a register-indirect operand cannot be attributed, solibraryis absent on most of them. Where it is present,confidenceis raised fromlowtomedium: the target is still unresolved as an internal edge, but the library it reaches is evidence rather than a guess. - Same-address symbol aliases are collapsed into a canonical node to reduce false ambiguity while preserving alias visibility.
ELF only. Describes the runtime the binary requires and the ABI features that constrain where it can be deployed. Every value is derived from the imported symbols, not from the version definition table, because a version node appearing in .gnu.version_r does not mean any symbol binds to it.
| Property | Description |
|---|---|
libc |
The C library the binary is linked against: glibc, musl, bionic, or empty when it cannot be determined. Inferred from the interpreter first, then from the version providers and DT_NEEDED. |
min_glibc_version |
The minimum glibc the binary can run on, as a dotted version. Empty when no glibc version node is bound. |
requirements |
One entry per version provider. See the table below. |
features |
Symbol-level ABI features: ifunc_symbols, imported_ifunc_symbols, tls_symbols, unique_symbols, and implementation_specific_imports. Each is a capped list of symbol names. |
uses_symbol_versioning |
True when any imported symbol carries a version node. |
uses_ifunc |
True when the binary defines or imports an indirect function, which requires a loader that runs IFUNC resolvers. |
uses_tls |
True when thread-local storage symbols are present. |
uses_unique_symbols |
True when the binary defines STB_GNU_UNIQUE symbols, which prevent the object from being unloaded. |
uses_private_symbol_versions |
True when a symbol binds to a private version node such as GLIBC_PRIVATE. These are internal interfaces with no stability promise. |
private_version_providers |
The private providers bound, e.g. ["GLIBC_PRIVATE"]. |
uses_implementation_specific_interfaces |
True when the binary imports C library internals that have no portable equivalent (loader introspection, allocator internals, backtrace support, non-portable pthread extensions). |
is_statically_linked |
True when there is no interpreter and no DT_NEEDED entry. |
portability_notes |
Human-readable sentences summarizing the above, suitable for direct display. |
Each entry in requirements describes one version provider:
| Property | Description |
|---|---|
provider |
The version node provider, e.g. GLIBC, GLIBCXX, LIBPAM_EXTENSION, GLIBC_PRIVATE. |
min_version |
The highest version node any imported symbol binds to — that is, the minimum the runtime must supply. Empty for providers whose nodes carry no version. |
determining_symbols |
The imported symbols that set min_version. Use these to trace an unexpectedly high floor back to the single import responsible. |
symbol_count |
How many imported symbols bind to this provider. |
versions |
Every distinct version bound for this provider, sorted numerically. |
package_name / package_group |
Package coordinates for the provider where known, e.g. libc / gnu for GLIBC. Used to build the SBOM component. |
Libraries opened through dlopen never appear in DT_NEEDED, so a dependency list built from the dynamic table alone omits them. dlopen_dependencies covers the case where the project embeds a declarative note; these two attributes cover everything else by recovering the information from the image.
runtime_loading describes the behaviour:
| Property | Description |
|---|---|
entry_points |
The runtime-loading functions the binary imports (dlopen, dlmopen, android_dlopen_ext, LoadLibraryW, dlsym, …). |
loads_libraries |
True when at least one entry point actually opens a library. dlsym alone operates on a handle the caller already has and does not count. |
call_sites |
Maps each entry point to the functions that call it. Populated only with --disassemble. |
call_site_count |
Total number of call sites across all entry points. |
recovered_dependencies lists the libraries themselves. Names already present in DT_NEEDED, libraries, or dlopen_dependencies are excluded, since those are not gaps.
| Property | Description |
|---|---|
name |
The soname as it appears in the binary, e.g. libgpm.so.2. |
confidence |
high when the name is a literal in a read-only data section and looks like a library, medium for weaker placement, low otherwise. |
evidence |
Why the candidate was accepted: which loading entry point is imported, which section the literal is in, and any absolute path found. |
paths |
Absolute paths found for the library, when the binary hardcodes one. |
sections |
The sections the name was found in. |
Format templates such as %s/libfoo.so are excluded: they are assembled at runtime and are not themselves names. This keeps the pass conservative — it under-reports rather than inventing dependencies.
Opt-in. Resolving the closure reads the filesystem the scan runs on, which is only meaningful when that filesystem is the binary's intended runtime. Enable it with:
| Environment variable | Description |
|---|---|
BLINT_RESOLVE_LINK_CLOSURE |
Set to 1, true, or yes to run the resolution. |
BLINT_LINK_ROOT |
Filesystem root to resolve against. Point this at an unpacked image or sysroot rather than the scanning host. |
BLINT_LINK_SEARCH_PATH |
Extra directories treated as if they were in LD_LIBRARY_PATH, separated by the platform path separator. |
Resolution follows the loader's documented search order: DT_RPATH (ignored when DT_RUNPATH is present), then LD_LIBRARY_PATH, then DT_RUNPATH, then the default directories for the machine type plus anything configured in /etc/ld.so.conf. The $ORIGIN, $LIB and $PLATFORM tokens are expanded as the loader expands them.
| Property | Description |
|---|---|
resolved |
Each object that would be mapped, with path, found_via (which kind of search path answered), needed_by, relation (direct or transitive), and export_count. |
missing |
Sonames nothing on the search path supplies. Each is a load-time failure and usually indicates an undeclared packaging dependency. |
unresolved_symbols |
Imported symbols no object in the closure defines, capped at 64 entries. Weak imports are excluded, since going unresolved is their intended behaviour. |
unresolved_symbol_count |
The full count, before the cap. |
symbol_providers |
Maps each resolved symbol name to the soname that supplies it. This is the edge-level dependency data dynamic_entries cannot give you. |
risky_search_paths |
DT_RPATH / DT_RUNPATH entries that are relative, empty (which the loader reads as the working directory), or under a world-writable directory. Each carries path, kind, and issue. |
complete |
True only when nothing is missing and no symbol is unresolved. |
root |
The filesystem root the result describes. |
The closure is capped at 256 objects so a pathological dependency graph cannot stall a run.
import_dependencies maps each imported symbol to the library that supplies it. How much evidence exists for that depends entirely on the format:
| Format | Evidence | Available |
|---|---|---|
| PE | The import table is organised by DLL, so every import names its library. | Always |
| Mach-O | Each symbol is bound to a dylib, recorded as library::symbol. |
Always |
| ELF | The dynamic symbol table and the DT_NEEDED list are unrelated flat lists. The connection only exists once the dependency closure is resolved and each library's exports are read. |
Only with link_closure enabled |
Two fields record what the result rests on:
| Property | Description |
|---|---|
attribution_sources |
Which evidence was used: import_table, load_commands, link_closure. Empty means none was available. |
unattributed_symbol_count |
How many imported symbols could not be tied to a library. These are collected under a synthetic unattributed entry in libraries. |
An ELF binary analysed without closure resolution attributes nothing. That is deliberate. Assigning a symbol to an arbitrary declared library produces a dependency edge that is indistinguishable downstream from a correct one, and a wrong edge is worse than an honest gap.
C++ and Rust symbols are matched on their linkage name, which blint records as raw_name on the symbol whenever demangling changed it. A provider's export table holds mangled names, so the demangled name alone never matches.
Note that :: is a library separator only in Mach-O, and only when the prefix looks like a library. Everywhere else it separates namespace components, and APT::PackageContainer::begin is one symbol rather than a dependency on APT.
Reports declared dependencies that are never used and used libraries that are never declared. Requires symbol attribution, so for ELF it needs closure resolution; the whole block is absent when nothing could be attributed, because with no evidence every dependency looks unused.
| Property | Description |
|---|---|
unused_dependencies |
Declared libraries from which no symbol is imported, each with a name and a reason. Linking with --as-needed removes them. |
undeclared_dependencies |
Libraries supplying symbols without being declared, with symbol_count and a sample of symbols. These work only for as long as some other dependency keeps them mapped. |
attribution_sources |
The evidence the result is based on, as above. |
unattributed_symbol_count |
Imports not tied to any library. A high count means the findings are based on partial evidence. |
declared_count |
How many direct dependencies were declared. |
unused_dependencies answers a similar question to ldd -u, but not an identical one. ldd -u relocates the whole closure and counts a library as used if anything in it binds to the library, so a library this binary never calls still counts as used when some other dependency calls it. blint reports direct use, which is what --as-needed acts on. Everything ldd -u reports unused will also be reported here; the reverse does not hold.
Over-linking is largely a property of the distribution rather than the project: builds that pass --as-needed are almost free of it, while those that do not accumulate it as link lines are inherited between libraries.
This object provides a quick, at-a-glance summary of the most important security mitigations compiled into the binary.
| Property | Description | Security Implication |
|---|---|---|
nx |
Non-eXecutable. True if data regions (stack/heap) are not executable. | Mitigates code injection attacks. |
pie / aslr |
Address Space Layout Randomization. | Makes memory corruption exploits harder by randomizing locations. |
canary |
Stack Cookie. Confirmed via Load Config or symbols. | Mitigates stack-based buffer overflows. |
control_flow_guard |
CFG (Forward-Edge). Validates indirect call targets. | Mitigates function pointer corruption (e.g., vtable hijacking). |
xfg |
Extended Flow Guard. A stricter version of CFG that validates function signatures (types) at indirect call sites. | significantly reduces the number of valid targets for an attacker compared to standard CFG. |
cfg_export_suppression |
CFG Export Suppression. Prevents valid exported functions from being called indirectly unless explicitly permitted. | Reduces the attack surface by limiting available gadgets in exported APIs. |
pac |
Pointer Authentication (ARM64). Signs return addresses. | Hardware-enforced protection against ROP. |
pac_strict |
Strict PAC. Fails to load if hardware support is missing. | Enforces a fail-closed security policy for PAC. |
cet_shadow_stack |
Intel CET / Shadow Stack. Indicated by EH Continuation Tables. | Hardware-enforced protection against ROP by maintaining a secondary, immutable stack for return addresses. |
retpoline |
Retpoline. Use of return trampolines. | Mitigates Spectre Variant 2 (Branch Target Injection) side-channel attacks. |
cast_guard |
CastGuard. Validates virtual function calls. | Mitigates C++ type confusion and vtable hijacking attacks. |
safe_seh |
Safe SEH. (x86) Registers exception handlers at compile time. | Prevents attackers from overwriting SEH chains on the stack to gain execution. |
safe_delay_load |
Protected Delay-Load IAT. Marks delay-load tables read-only after initialization. | Prevents hooking of APIs that are loaded lazily during execution. |
enclave |
Enclave Support. Binary contains configuration for SGX/VBS. | Indicates the application uses TEE (Trusted Execution Environment) features for high-security operations. |