Repository navigation
Implement Import/Export Symbol Classification Pipeline #20
Description
Summary
Implement the classification pipeline that converts parsed import/export symbol metadata and section names from ContainerInfo into tagged, scored FoundString objects. This is the missing bridge between the container parsers and the string ranking/output layers.
Current State
The following components are already implemented and ready to build on:
| Component | Status | Location |
|---|---|---|
| ELF/PE/Mach-O container parsers | ✅ Done | src/container/ |
ImportInfo / ExportInfo types |
✅ Done | src/types/mod.rs |
Tag::Import / Tag::Export variants |
✅ Done | src/types/mod.rs |
StringSource::ImportName / ExportName |
✅ Done | src/types/mod.rs |
SymbolDemangler (Rust + C++) |
✅ Done | src/classification/symbols.rs |
RankingEngine with Import/Export boosts (+60) |
✅ Done | src/classification/ranking.rs |
SemanticClassifier (URLs, IPs, paths, etc.) |
✅ Done | src/classification/mod.rs |
What is missing: Nothing currently converts the Vec<ImportInfo> and Vec<ExportInfo> stored in ContainerInfo into FoundString objects. The Tag::Import and Tag::Export ranking boosts are defined but never applied because no code path creates strings with those tags from binary metadata.
Required Work
1. New ImportClassifier in src/classification/imports.rs
Create a struct that consumes ContainerInfo metadata and emits Vec<FoundString>:
pub struct ImportClassifier {
demangler: SymbolDemangler,
crypto_apis: HashSet<&'static str>,
network_apis: HashSet<&'static str>,
file_apis: HashSet<&'static str>,
entry_points: HashSet<&'static str>,
}
impl ImportClassifier {
/// Convert all imports in ContainerInfo to tagged FoundStrings
pub fn process_imports(&self, info: &ContainerInfo) -> Vec<FoundString>;
/// Convert all exports in ContainerInfo to tagged FoundStrings
pub fn process_exports(&self, info: &ContainerInfo) -> Vec<FoundString>;
/// Extract section names as high-value FoundStrings
pub fn process_section_names(&self, info: &ContainerInfo) -> Vec<FoundString>;
}
/// Main entry point for the pipeline
pub fn extract_symbol_strings(info: &ContainerInfo) -> Vec<FoundString>;Import processing rules:
source: StringSource::ImportNametags: always includeTag::Import; add semantic tags (Tag::Crypto,Tag::Network,Tag::FileIO) based on symbol namesection: uselibraryfield fromImportInfoif present, otherwise".idata"(PE) or".dynsym"(ELF)rva: fromImportInfo::addressif availableconfidence: 1.0(import names are high-confidence by nature)
Export processing rules:
source: StringSource::ExportNametags: always includeTag::Export; applySymbolDemanglerand addTag::DemangledSymbolif demangled; addTag::EntryPointfor known entry symbolsrva: fromExportInfo::address- Entry point symbols to detect:
main,_start,DllMain,WinMain,wWinMain
Section name processing:
source: StringSource::SectionDataconfidence: 1.0- Useful for downstream context when ranking strings by section
2. New Tag Variants in src/types/mod.rs
Add the following variants to the Tag enum and update FromStr, Display, and any exhaustive match sites:
#[serde(rename = "crypto")]
Crypto, // Cryptographic API (CryptEncrypt, EVP_*, AES_*)
#[serde(rename = "network")]
Network, // Network API (socket, connect, WSA*, curl_*)
#[serde(rename = "fileio")]
FileIO, // File I/O API (CreateFileW, fopen, ReadFile)
#[serde(rename = "entry-point")]
EntryPoint, // Binary entry point (main, _start, DllMain)3. Update RankingConfig in src/classification/ranking.rs
Add tag boosts for the four new tags:
| Tag | Suggested Boost |
|---|---|
Tag::Crypto |
+50 |
Tag::Network |
+45 |
Tag::FileIO |
+35 |
Tag::EntryPoint |
+40 |
4. Export from src/classification/mod.rs
pub mod imports;
pub use imports::{ImportClassifier, extract_symbol_strings};5. API Pattern Sets
Use std::sync::LazyLock (already used in this codebase—do not use once_cell) for static API sets:
Crypto APIs: CryptEncrypt, CryptDecrypt, CryptHashData, EVP_EncryptInit, EVP_DecryptInit, AES_encrypt, AES_decrypt, BCryptEncrypt, BCryptDecrypt, crypto_secretbox, crypto_box
Network APIs: socket, connect, bind, listen, accept, send, recv, sendto, recvfrom, WSAStartup, WSASocket, WSAConnect, curl_easy_init, curl_easy_perform, getaddrinfo, gethostbyname
File I/O APIs: CreateFileW, CreateFileA, ReadFile, WriteFile, open, fopen, fread, fwrite, NtCreateFile, ZwCreateFile
Test Requirements
Create tests/classification_symbols.rs covering:
- Import classification:
Tag::Importalways set; crypto/network/file I/O tags applied correctly; library name preserved insectionfield - Export classification:
Tag::Exportalways set; demangled symbols getTag::DemangledSymbol; entry points getTag::EntryPoint - API pattern detection: Each API category hits at least 3 representative symbols; non-matching symbols do not receive semantic tags
- Section name extraction: Section names produce
FoundStringwithsource: StringSource::SectionData - Integration tests: Use existing fixtures from
tests/fixtures/(ELF, PE, Mach-O) to verify end-to-endextract_symbol_stringsoutput
Documentation Fix
docs/src/classification.md currently references once_cell::sync::Lazy but the codebase uses std::sync::LazyLock. Update the pattern matching engine example to reflect the actual implementation.
Success Criteria
-
ImportClassifierimplemented insrc/classification/imports.rs -
extract_symbol_strings(&ContainerInfo) -> Vec<FoundString>public API - All imports tagged with
Tag::Import+ applicable semantic tags - All exports tagged with
Tag::Export; demangled where applicable -
Tag::Crypto,Tag::Network,Tag::FileIO,Tag::EntryPointadded to type system - New tags wired into
RankingConfigwith appropriate boosts -
tests/classification_symbols.rswith unit + integration tests -
docs/src/classification.mdupdated (fixonce_cell→std::sync::LazyLock)
References
src/classification/symbols.rs—SymbolDemangler(already implemented, reuse directly)src/classification/ranking.rs—RankingConfigtag boosts to extendsrc/types/mod.rs—Tagenum,ImportInfo,ExportInfo,ContainerInfosrc/container/elf/mod.rs,pe/mod.rs,macho/mod.rs— how ImportInfo/ExportInfo are populated
Activity
unclesp1d3r commentedon Nov 10, 2025
@coderabbitai Enhance this issue body with additional context and a proposed solution. Improve the issue title and assign the proper labels and other metadata.
[-]Import/Export Classification[/-][+]Implement Symbol Classification and Import/Export Tagging[/+]traycerai commentedon Nov 10, 2025
Plan
Observations
The codebase has a complete foundation with container parsers (ELF, PE, Mach-O) that extract imports/exports into
ContainerInfo. TheSymbolDemangleris already implemented insrc/classification/symbols.rswith full Rust and C++ demangling support. TheRankingEnginewith tag boosts is complete but currently only applies boosts toTag::ImportandTag::Export(both +60). The missing piece is the bridge: code that convertsImportInfo/ExportInfofromContainerInfointoFoundStringobjects with appropriate tags and semantic classification.Approach
Create a new
ImportClassifierstruct insrc/classification/imports.rsthat consumesContainerInfoand emitsVec<FoundString>. Implement three processing methods:process_imports(),process_exports(), andprocess_section_names(). Add four newTagvariants (Crypto,Network,FileIO,EntryPoint) to the type system. UpdateRankingConfigwith boosts for the new tags. Usestd::sync::LazyLockfor static API pattern sets (crypto, network, file I/O). Reuse the existingSymbolDemanglerfor export symbol demangling. Create comprehensive tests covering all three binary formats.Mermaid Diagram
sequenceDiagram participant CP as ContainerParser participant CI as ContainerInfo participant IC as ImportClassifier participant SD as SymbolDemangler participant FS as Vec<FoundString> Note over CP,CI: Container Parsing Phase (Already Complete) CP->>CI: parse() returns ContainerInfo Note over CI: Contains imports, exports, sections Note over IC,FS: Symbol Classification Phase (New Implementation) CI->>IC: extract_symbol_strings(&container_info) IC->>IC: process_imports(&imports) loop For each ImportInfo IC->>IC: Check against crypto_apis, network_apis, file_apis Note over IC: Apply semantic tags (Crypto, Network, FileIO) IC->>FS: Create FoundString with Tag::Import + semantic tags Note over FS: source: ImportName, confidence: 1.0 end IC->>IC: process_exports(&exports) loop For each ExportInfo IC->>SD: demangle(symbol_name) alt Demangled successfully SD-->>IC: demangled_name + Tag::DemangledSymbol else Not mangled SD-->>IC: original_name end IC->>IC: Check for entry points (main, _start, DllMain, etc.) IC->>FS: Create FoundString with Tag::Export + optional EntryPoint Note over FS: source: ExportName, confidence: 1.0 end IC->>IC: process_section_names(§ions) loop For each SectionInfo IC->>FS: Create FoundString from section name Note over FS: source: SectionData, confidence: 1.0 end IC-->>CI: Return Vec<FoundString> Note over FS: Ready for ranking and outputImplementation Tasks
1. Add New Tag Variants to
file:src/types/mod.rsAdd four new semantic tag variants to the
Tagenum (after line 58, before the closing brace):Update the
FromStrimplementation (lines 60-89) to handle the new tags:"crypto" => Ok(Tag::Crypto)"network" => Ok(Tag::Network)"fileio" => Ok(Tag::FileIO)"entry-point" => Ok(Tag::EntryPoint)2. Create
file:src/classification/imports.rs(New File)Implement the
ImportClassifierstruct with the following structure:Static API Pattern Sets (using
std::sync::LazyLock):CRYPTO_APIS: CryptEncrypt, CryptDecrypt, CryptHashData, EVP_EncryptInit, EVP_DecryptInit, AES_encrypt, AES_decrypt, BCryptEncrypt, BCryptDecrypt, crypto_secretbox, crypto_boxNETWORK_APIS: socket, connect, bind, listen, accept, send, recv, sendto, recvfrom, WSAStartup, WSASocket, WSAConnect, curl_easy_init, curl_easy_perform, getaddrinfo, gethostbynameFILE_APIS: CreateFileW, CreateFileA, ReadFile, WriteFile, open, fopen, fread, fwrite, NtCreateFile, ZwCreateFileENTRY_POINTS: main, _start, DllMain, WinMain, wWinMainImportClassifier struct:
Methods:
pub fn new() -> Self- Constructor that initializes SymbolDemanglerpub fn process_imports(&self, info: &ContainerInfo) -> Vec<FoundString>- Convert all imports to FoundString with Tag::Import + semantic tagspub fn process_exports(&self, info: &ContainerInfo) -> Vec<FoundString>- Convert all exports to FoundString with Tag::Export, apply demangling, detect entry pointspub fn process_section_names(&self, info: &ContainerInfo) -> Vec<FoundString>- Extract section names as FoundString with StringSource::SectionDatafn classify_symbol(&self, name: &str) -> Vec<Tag>- Return semantic tags (Crypto, Network, FileIO) based on API pattern matchingfn is_entry_point(&self, name: &str) -> bool- Check if symbol is in ENTRY_POINTS setMain entry point:
Implementation details:
classify_symbol(), setsource: StringSource::ImportName,confidence: 1.0, use library name as section if availablesource: StringSource::ExportName,confidence: 1.0source: StringSource::SectionData,confidence: 1.03. Update
file:src/classification/mod.rsAdd module declaration and re-exports (after line 47):
4. Update
file:src/classification/ranking.rsAdd tag boosts to the
RankingConfig::default()method (in thetag_boostsHashMap, around line 121-142):tag_boosts.insert(Tag::Crypto, 50);tag_boosts.insert(Tag::Network, 45);tag_boosts.insert(Tag::FileIO, 35);tag_boosts.insert(Tag::EntryPoint, 40);Also update the test
test_default_config_values()(around line 304-350) to verify the new tag boosts are present.5. Create
file:tests/classification_symbols.rs(New File)Comprehensive test suite covering:
Import classification tests:
test_import_crypto_api_detection- Verify crypto APIs get Tag::Cryptotest_import_network_api_detection- Verify network APIs get Tag::Networktest_import_file_api_detection- Verify file APIs get Tag::FileIOtest_import_always_tagged- Verify all imports get Tag::Importtest_import_library_preserved- Verify library name is in section fieldtest_import_source_and_confidence- Verify source is ImportName and confidence is 1.0Export classification tests:
test_export_always_tagged- Verify all exports get Tag::Exporttest_export_entry_point_detection- Verify main, _start, DllMain, WinMain get Tag::EntryPointtest_export_demangling- Verify mangled symbols are demangled and get Tag::DemangledSymboltest_export_source_and_confidence- Verify source is ExportName and confidence is 1.0Section name tests:
test_section_names_extracted- Verify section names become FoundString objectstest_section_names_source- Verify source is SectionDatatest_section_names_confidence- Verify confidence is 1.0Integration tests (using fixtures from
tests/fixtures/):test_extract_symbol_strings_elf- Full pipeline with ELF fixturetest_extract_symbol_strings_pe- Full pipeline with PE fixture (if available)test_extract_symbol_strings_macho- Full pipeline with Mach-O fixture (if available)test_empty_container_info- Graceful handling of empty imports/exports/sectionsUse the fixture loading pattern from
tests/integration_elf.rs(lines 5-10).6. Update
file:docs/src/classification.mdFix the documentation reference from
once_cell::sync::Lazytostd::sync::LazyLockin the pattern matching engine example. Add a new section documenting theImportClassifier:extract_symbol_strings()7. Update
file:README.mdAdd a section describing the symbol classification feature:
Ensure the feature list reflects that symbol classification is now implemented.
Import In IDE
🤖 Prompt for AI Agents
Execution Information
Branch: main
Commit: cde9ad3
💡 Tips
Supported Commands (Inside Comments)
@traycerai generateto iterate on the previous version of the implementation plan.Supported Commands (Inside Description)
@traycerai ignoreanywhere in the ticket description to prevent this ticket from being processed.@traycerai branch:<branch-name>anywhere in the ticket description to specify the target branch for the implementation plan.Community
coderabbitai commentedon Nov 10, 2025
Tip
For best results, initiate chat on the files or code changes.
🧩 Analysis chain
🏁 Script executed:
Length of output: 2925
🏁 Script executed:
Length of output: 32796
🏁 Script executed:
Length of output: 9971
🏁 Script executed:
Length of output: 11778
🏁 Script executed:
Length of output: 199
🏁 Script executed:
Length of output: 1565
🏁 Script executed:
Length of output: 858
@unclesp1d3r I've successfully enhanced issue #20 with comprehensive details! Here's what was updated:
✅ Changes Made
Title
Before: Import/Export Classification
After: Implement Symbol Classification and Import/Export Tagging
Enhanced Body Content
Added detailed sections covering:
Current State Analysis
Requirements Breakdown (4.2, 4.3, 4.4)
Proposed Solution
SymbolClassifierAPI designsrc/classification/symbols.rsTest Requirements
Success Criteria
Technical Notes
References
Metadata Updates
priority:mediumlabelThe issue now provides complete implementation guidance with clear technical direction, test requirements, and success criteria. The proposed solution leverages the already-implemented container parsers and focuses on the classification layer that converts raw symbol data into tagged, scored
FoundStringobjects.View the enhanced issue: #20
unclesp1d3r commentedon Mar 16, 2026
@coderabbitai Enhance this issue body with additional context and a proposed solution. Improve the issue title and assign the proper labels and other metadata.
[-]Implement Symbol Classification and Import/Export Tagging[/-][+]Implement Import/Export Symbol Classification Pipeline[/+]coderabbitai commentedon Mar 16, 2026
🧩 Analysis chain
🏁 Script executed:
Length of output: 11625
🏁 Script executed:
Length of output: 55452
🏁 Script executed:
Length of output: 11694
🏁 Script executed:
Length of output: 2773
🏁 Script executed:
Length of output: 319
@unclesp1d3rIssue#20has been updated with accurate context and a concrete proposed solution. Here's a summary of what changed and why:Title
Before:
Import/Export ClassificationAfter:
Implement Import/Export Symbol Classification PipelineBody — Key Corrections
The previous body contained several inaccuracies that I corrected by analyzing the actual codebase:
SemanticClassifier,SymbolDemangler, andRankingEngineare all fully implementedrustc-demangleto Cargo.toml"rustc-demangle = "0.1.27"+cpp_demangle = "0.5.1"SymbolClassifier"SymbolDemangleralready exists insrc/classification/symbols.rswith full Rust + C++ demanglingActual Gap Identified
Tag::Import(+60) andTag::Export(+60) scoring boosts are configured inRankingConfigbut nothing ever createsFoundStringobjects with those tags — theVec<ImportInfo>andVec<ExportInfo>inContainerInfogo unprocessed. The proposed solution targets this precisely:src/classification/imports.rs—ImportClassifierstruct convertingContainerInfoimports/exports/sections →Vec<FoundString>Tagvariants insrc/types/mod.rs:Crypto,Network,FileIO,EntryPointwith serde renames and ranking boostsstd::sync::LazyLock(matching the existing codebase pattern — the docs incorrectly referenceonce_cell, which is also flagged as a doc fix)tests/classification_symbols.rsusing the existing fixture infrastructureMetadata
MVPlabel (this is core v0.1 functionality)area:analyzer,type:enhancement,status:backlog,lang:rust,needs:tests,priority:medium,story-points:8traycerai commentedon Mar 16, 2026
I have updated the Implementation Plan to reflect the recent changes in the ticket.
feat: Import/Export symbol classification pipeline (#174)