Skip to content

Implement Capstone Disassembly Pass to Identify Code-Referenced Strings #61

Description

@unclesp1d3r

Background

StringyMcStringFace aims to extract meaningful strings from binaries by being data-structure aware and prioritizing high-value strings over arbitrary byte sequences. A critical enhancement to string relevance scoring is identifying which strings are actually referenced by executable code versus those that are dead data, padding, or artifacts.

By performing disassembly of executable sections using the Capstone framework, we can:

  • Distinguish active strings from dead data by identifying instruction-level references
  • Improve ranking accuracy by boosting strings that are demonstrably used in the code
  • Provide context about how strings are accessed (direct reference, computed offset, etc.)
  • Enhance analysis value for malware analysis, reverse engineering, and YARA rule generation

Objective

Implement a Capstone disassembly pass that performs linear sweep disassembly of executable sections (.text, __TEXT,__text, etc.) to identify and flag strings that are directly referenced by machine code instructions.

Technical Approach

1. Disassembly Engine Integration

  • Add capstone-rs dependency to Cargo.toml for multi-architecture disassembly support
  • Support architectures: x86, x86-64, ARM, ARM64, as indicated by binary format headers
  • Perform linear sweep disassembly of executable sections identified by container parsers

2. Instruction Analysis

Target instruction patterns that commonly reference string data:

  • x86/x64: lea rax, [rip+offset], mov rax, offset, push offset
  • ARM/ARM64: adr, adrp, ldr with PC-relative addressing, immediate loads
  • Extract effective addresses from operands (handle RIP-relative, absolute, register-indirect)

3. Cross-Referencing

  • Maintain a map of extracted string offsets/RVAs from string extraction passes
  • For each instruction with a data reference:
    • Resolve the target address (accounting for relocations, base addresses, RIP-relative calculations)
    • Check if the target address overlaps with any extracted string offset
    • If match found, tag the string with CodeReferenced or increment reference count

4. Scoring Integration

  • Strings flagged as code-referenced receive a significant scoring boost in the ranking algorithm
  • Potentially add metadata to FoundString: referenced_by: Vec<u64> to track instruction addresses
  • Consider tracking reference frequency (multiple instructions referencing the same string)

Implementation Steps

  1. Add Capstone dependency

    • Add capstone = "0.12" to Cargo.toml
    • Create src/analysis/disasm.rs module
  2. Implement DisassemblyAnalyzer

    • Trait or struct to encapsulate disassembly logic
    • Method: analyze_code_sections(&self, container_info: &ContainerInfo, sections: &[SectionInfo]) -> Result<Vec<CodeReference>>
    • Detect architecture from container format (ELF e_machine, PE Machine, Mach-O cputype)
    • Initialize Capstone engine with appropriate architecture and mode
  3. Linear Sweep Disassembly

    • Iterate through executable sections (identified by container parser)
    • Disassemble instruction stream from section start to end
    • Handle disassembly errors gracefully (skip bad instructions, continue)
  4. Reference Extraction

    • For each instruction, analyze operands for data references:
      • Immediate values that could be addresses
      • Memory operands with displacement/offset
      • PC-relative references (x86-64 RIP-relative, ARM PC-relative)
    • Resolve addresses accounting for section RVA/virtual address
    • Emit CodeReference { instruction_addr: u64, target_addr: u64, ref_type: ReferenceType }
  5. Integration with String Extraction

    • After string extraction phase, run disassembly analysis
    • Cross-reference CodeReference.target_addr with FoundString.offset/rva
    • Tag matching strings or update scoring metadata
  6. Testing

    • Create test binaries (ELF, PE, Mach-O) with known string references
    • Verify strings referenced by lea, mov, adr instructions are correctly flagged
    • Benchmark performance impact on large binaries
    • Add integration tests in tests/integration_disasm.rs

Dependencies

  • capstone-rs (v0.12+): Rust bindings for the Capstone disassembly framework
    • Supports x86, x64, ARM, ARM64, and other architectures
    • Provides instruction-level analysis and operand information
  • Existing: goblin for binary format parsing and section identification

Success Criteria

  • Capstone-rs integrated and architecture detection working for ELF, PE, Mach-O
  • Linear sweep disassembly successfully processes .text sections in test binaries
  • Data reference instructions (lea, mov, adr, etc.) correctly extract target addresses
  • Cross-referencing identifies strings referenced by code with high accuracy
  • FoundString metadata enhanced with code reference information
  • Integration tests verify correct flagging on test binaries with known references
  • Documentation explains disassembly analysis and its impact on scoring

Related Issues

Notes

  • This is a linear sweep approach (disassemble sequentially), not recursive traversal
  • False positives possible (immediate values that happen to match string offsets but aren't references)
  • Consider making disassembly pass optional via CLI flag (--disassemble) due to performance cost
  • For obfuscated or packed binaries, disassembly may be unreliable (acceptable limitation)
  • Future enhancement: combine with relocation table analysis (Add relocation-based string ranking to identify code-referenced addresses #60) for higher confidence

Activity

  1. added theissue type on Nov 10, 2025
  2. changed the issue type fromtoon Nov 10, 2025
  3. traycerai commented on Nov 10, 2025

    @traycerai

    Plan

    Observations

    The codebase provides complete container parsing for ELF, PE, and Mach-O formats via goblin, with robust type definitions in types.rs including ContainerInfo, SectionInfo, and FoundString. The extraction module is currently a stub, ready for implementation. No disassembly functionality exists, and Capstone is not a dependency. Architecture detection needs to be added to parsers. The project structure supports modular addition of an analysis module for disassembly.

    Approach

    Introduce a new analysis module with Capstone integration for linear sweep disassembly of executable sections. Detect architecture from binary headers, initialize Capstone accordingly, extract data references from instructions (e.g., LEA, MOV, ADR), resolve addresses to file offsets, and cross-reference with extracted strings to flag code-referenced ones. Extend FoundString with reference metadata and integrate into the extraction pipeline for scoring boost. Add optional CLI flag for performance.

    Reasoning

    I examined the project root and source directory structure, reviewed the Cargo.toml for dependencies, analyzed the types.rs for core data structures like FoundString and ContainerInfo, inspected the lib.rs for module organization, checked the extraction module which is currently a stub, and reviewed container parser files to understand section identification and parsing logic.

    Proposed File Changes

    📄 Cargo.toml (MODIFY) 🔗

    Add the capstone crate as a dependency with version "0.12" or the latest stable version. This enables multi-architecture disassembly capabilities essential for analyzing code references across x86, x86-64, ARM, and ARM64 binaries. Ensure it is added under the [dependencies] section.

    📄 src/types.rs (MODIFY) 🔗

    Introduce an Architecture enum with variants for X86, X86_64, ARM, ARM64, and Unknown to represent detected CPU architectures. Add an optional architecture: Option<Architecture> field to the ContainerInfo struct for storing the parsed architecture. Extend the FoundString struct with a new field code_references: Vec<u64> to track instruction addresses referencing the string, and a is_code_referenced: bool derived field for quick scoring checks. Update serialization derives if necessary to include these fields.

    📄 src/container/elf.rs (MODIFY) 🔗

    References

    In the parse function, detect the architecture by inspecting elf.header.e_machine and mapping values like EM_386 (3) to X86, EM_X86_64 (62) to X86_64, EM_ARM (40) to ARM, EM_AARCH64 (183) to ARM64 using goblin constants. Set container_info.architecture = Some(detected_arch) before returning. Ensure this integrates seamlessly with existing section and import/export parsing.

    📄 src/container/pe.rs (MODIFY) 🔗

    References

    In the parse function, detect architecture from pe.header.coff_header.machine, mapping COFF_MACHINE_I386 (0x14c) to X86, COFF_MACHINE_AMD64 (0x8664) to X86_64, COFF_MACHINE_ARM (0x1c0) to ARM, COFF_MACHINE_ARM64 (0xaa64) to ARM64. Assign to container_info.architecture and return the updated struct. This enhances the existing PE section classification without altering current logic.

    📄 src/container/macho.rs (MODIFY) 🔗

    References

    In parse_single_macho, detect architecture via macho.header.cputype(), mapping CPU_TYPE_I386 (7) to X86, CPU_TYPE_X86_64 (CPU_TYPE_I386 | CPU_ARCH_ABI64) to X86_64, CPU_TYPE_ARM (12) to ARM, CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64) to ARM64. Set in container_info.architecture. Also, refine is_executable_section to include __TEXT,__stubs and __TEXT,__stub_helper alongside __TEXT,__text for comprehensive code section coverage.

    📄 src/lib.rs (MODIFY) 🔗

    Add pub mod analysis; to declare the new analysis module. Re-export key types and functions from the analysis module, such as pub use analysis::{DisassemblyAnalyzer, CodeReference}; to make them accessible via the library crate root. This maintains the modular public API structure.

    📄 src/analysis/mod.rs (NEW) 🔗

    References

    Define the DisassemblyAnalyzer struct to hold Capstone engine and address resolution state. Implement new(architecture: Architecture) -> Result<Self> to initialize Capstone with appropriate mode (e.g., x86 mode 32/64, arm/arm64). Provide analyze(&self, data: &[u8], container: &ContainerInfo) -> Result<Vec<CodeReference>> for linear sweep over executable sections, extracting references. Include error handling for unsupported arches.

    📄 src/analysis/reference_extractor.rs (NEW) 🔗

    References

    Create a module for instruction operand analysis. Implement extract_references(instr: &Instruction) -> Vec<u64> to parse immediates and displacements for target instructions: x86 LEA/MOV/PUSH with offsets, RIP-relative; ARM ADR/ADRP/LDR PC-relative. Resolve effective addresses using instruction address and operand details. Define ReferenceType enum (Direct, Relative, Immediate) for metadata. Focus on patterns likely referencing strings.

    📄 src/analysis/address_resolver.rs (NEW) 🔗

    References

    Implement AddressResolver struct built from ContainerInfo sections, mapping RVAs to offsets and vice versa. Methods: rva_to_offset(&self, rva: u64) -> Option<u64>, offset_to_rva(&self, offset: u64) -> Option<u64>, resolve_target(&self, instr_addr: u64, operand: &Operand) -> Option<u64> for RIP/PC-relative calculations. Handle relocations minimally for now, assuming flat address space.

    📄 src/analysis/linear_sweep.rs (NEW) 🔗

    References

    Provide perform_sweep(data: &[u8], section: &SectionInfo, analyzer: &DisassemblyAnalyzer) -> Result<Vec<CodeReference>>. Iterate bytes in section, disassemble sequentially with Capstone, call reference extraction on each valid instruction, resolve addresses, and collect references with instruction RVA. Skip invalid instructions, log errors. This realizes the linear sweep without control flow analysis.

    📄 src/extraction/mod.rs (MODIFY) 🔗

    References

    Implement basic string extraction framework: extract_strings(data: &[u8], container: &ContainerInfo) -> Result<Vec<FoundString>>. Scan sections by weight, detect ASCII/UTF8/UTF16 strings (min length 4), assign sources, sections, offsets/RVAs. After extraction, if container.architecture.is_some(), instantiate DisassemblyAnalyzer, run analysis, cross-reference targets with string offsets/RVAs (tolerance ±8 bytes), update FoundString.code_references and is_code_referenced. Boost score by 50 for referenced strings.

    📄 src/main.rs (MODIFY) 🔗

    References

    Add CLI flag --disassemble or -d to Clap for optional disassembly. In the main logic, after parsing container, if flag set and architecture detected, proceed with disassembly-integrated extraction; else, use basic extraction without analysis. Update help text to explain the flag enables code reference detection at performance cost.

    📄 tests/integration_disasm.rs (NEW) 🔗

    References

    Add integration tests using sample binaries (create or use fixtures) for ELF/PE/Mach-O with known code-string references (e.g., LEA to string literal). Verify architecture detection, disassembly coverage, reference extraction accuracy, and flagging in FoundString. Test unsupported arch fallback, error handling, and score boosting. Use insta snapshots for output validation.

    📄 README.md (MODIFY) 🔗

    References

    Update the features section to highlight the new Capstone disassembly pass for identifying code-referenced strings, improving relevance scoring. Add usage example with --disassemble flag. Mention supported architectures and performance note. Expand the architecture overview to include the analysis module.

    📄 docs/src/architecture.md (MODIFY) 🔗

    References

    If the docs exist, add a section on the Analysis Module describing Capstone integration, linear sweep process, reference extraction, and integration with extraction/scoring. Update data flow diagram to show disassembly pass post-container parsing, pre-output. Include architecture detection details and reference types.

    Diagram

    sequenceDiagram
        participant B as Binary Data
        participant C as Container Parser
        participant E as Extraction Module
        participant A as Analysis Module
        participant S as Strings
    
        B->>C: Parse format & sections
        C->>C: Detect architecture
        C-->>E: ContainerInfo (w/ arch)
    
        E->>E: Extract raw strings from sections
        E-->>S: Vec<FoundString>
    
        alt Disassembly enabled
            E->>A: Initialize DisassemblyAnalyzer(arch)
            A->>A: Linear sweep executable sections
            A->>A: Extract & resolve references
            A-->>E: Vec<CodeReference>
            E->>E: Cross-ref & flag strings
            E->>E: Boost scores for referenced
        end
    
        E-->>User: Ranked FoundStrings w/ metadata
    
    Loading

    Import In IDE

    VSCode Icon Cursor Icon Windsurf Icon

    🤖 Prompt for AI Agents
    I have created the following plan after thorough exploration and analysis of the codebase. Follow the below plan verbatim. Trust the files and references. Do not re-verify what's written in the plan. Explore only when absolutely necessary. First implement all the proposed file changes and then I'll review all the changes together at the end.
    
    ### Observations
    
    The codebase provides complete container parsing for ELF, PE, and Mach-O formats via goblin, with robust type definitions in `types.rs` including `ContainerInfo`, `SectionInfo`, and `FoundString`. The `extraction` module is currently a stub, ready for implementation. No disassembly functionality exists, and Capstone is not a dependency. Architecture detection needs to be added to parsers. The project structure supports modular addition of an analysis module for disassembly.
    
    ### Approach
    
    Introduce a new `analysis` module with Capstone integration for linear sweep disassembly of executable sections. Detect architecture from binary headers, initialize Capstone accordingly, extract data references from instructions (e.g., LEA, MOV, ADR), resolve addresses to file offsets, and cross-reference with extracted strings to flag code-referenced ones. Extend `FoundString` with reference metadata and integrate into the extraction pipeline for scoring boost. Add optional CLI flag for performance.
    
    ### Reasoning
    
    I examined the project root and source directory structure, reviewed the Cargo.toml for dependencies, analyzed the types.rs for core data structures like FoundString and ContainerInfo, inspected the lib.rs for module organization, checked the extraction module which is currently a stub, and reviewed container parser files to understand section identification and parsing logic.
    
    ## Mermaid Diagram
    
    sequenceDiagram
        participant B as Binary Data
        participant C as Container Parser
        participant E as Extraction Module
        participant A as Analysis Module
        participant S as Strings
    
        B->>C: Parse format & sections
        C->>C: Detect architecture
        C-->>E: ContainerInfo (w/ arch)
    
        E->>E: Extract raw strings from sections
        E-->>S: Vec<FoundString>
    
        alt Disassembly enabled
            E->>A: Initialize DisassemblyAnalyzer(arch)
            A->>A: Linear sweep executable sections
            A->>A: Extract & resolve references
            A-->>E: Vec<CodeReference>
            E->>E: Cross-ref & flag strings
            E->>E: Boost scores for referenced
        end
    
        E-->>User: Ranked FoundStrings w/ metadata
    
    ## Proposed File Changes
    
    ### Cargo.toml(MODIFY)
    
    Add the `capstone` crate as a dependency with version "0.12" or the latest stable version. This enables multi-architecture disassembly capabilities essential for analyzing code references across x86, x86-64, ARM, and ARM64 binaries. Ensure it is added under the `[dependencies]` section.
    
    ### src/types.rs(MODIFY)
    
    Introduce an `Architecture` enum with variants for X86, X86_64, ARM, ARM64, and Unknown to represent detected CPU architectures. Add an optional `architecture: Option<Architecture>` field to the `ContainerInfo` struct for storing the parsed architecture. Extend the `FoundString` struct with a new field `code_references: Vec<u64>` to track instruction addresses referencing the string, and a `is_code_referenced: bool` derived field for quick scoring checks. Update serialization derives if necessary to include these fields.
    
    ### src/container/elf.rs(MODIFY)
    
    References: 
    
    - src/types.rs(MODIFY)
    
    In the `parse` function, detect the architecture by inspecting `elf.header.e_machine` and mapping values like EM_386 (3) to X86, EM_X86_64 (62) to X86_64, EM_ARM (40) to ARM, EM_AARCH64 (183) to ARM64 using goblin constants. Set `container_info.architecture = Some(detected_arch)` before returning. Ensure this integrates seamlessly with existing section and import/export parsing.
    
    ### src/container/pe.rs(MODIFY)
    
    References: 
    
    - src/types.rs(MODIFY)
    
    In the `parse` function, detect architecture from `pe.header.coff_header.machine`, mapping COFF_MACHINE_I386 (0x14c) to X86, COFF_MACHINE_AMD64 (0x8664) to X86_64, COFF_MACHINE_ARM (0x1c0) to ARM, COFF_MACHINE_ARM64 (0xaa64) to ARM64. Assign to `container_info.architecture` and return the updated struct. This enhances the existing PE section classification without altering current logic.
    
    ### src/container/macho.rs(MODIFY)
    
    References: 
    
    - src/types.rs(MODIFY)
    
    In `parse_single_macho`, detect architecture via `macho.header.cputype()`, mapping CPU_TYPE_I386 (7) to X86, CPU_TYPE_X86_64 (CPU_TYPE_I386 | CPU_ARCH_ABI64) to X86_64, CPU_TYPE_ARM (12) to ARM, CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64) to ARM64. Set in `container_info.architecture`. Also, refine `is_executable_section` to include `__TEXT,__stubs` and `__TEXT,__stub_helper` alongside `__TEXT,__text` for comprehensive code section coverage.
    
    ### src/lib.rs(MODIFY)
    
    Add `pub mod analysis;` to declare the new analysis module. Re-export key types and functions from the analysis module, such as `pub use analysis::{DisassemblyAnalyzer, CodeReference};` to make them accessible via the library crate root. This maintains the modular public API structure.
    
    ### src/analysis/mod.rs(NEW)
    
    References: 
    
    - src/types.rs(MODIFY)
    
    Define the `DisassemblyAnalyzer` struct to hold Capstone engine and address resolution state. Implement `new(architecture: Architecture) -> Result<Self>` to initialize Capstone with appropriate mode (e.g., x86 mode 32/64, arm/arm64). Provide `analyze(&self, data: &[u8], container: &ContainerInfo) -> Result<Vec<CodeReference>>` for linear sweep over executable sections, extracting references. Include error handling for unsupported arches.
    
    ### src/analysis/reference_extractor.rs(NEW)
    
    References: 
    
    - src/types.rs(MODIFY)
    
    Create a module for instruction operand analysis. Implement `extract_references(instr: &Instruction) -> Vec<u64>` to parse immediates and displacements for target instructions: x86 LEA/MOV/PUSH with offsets, RIP-relative; ARM ADR/ADRP/LDR PC-relative. Resolve effective addresses using instruction address and operand details. Define `ReferenceType` enum (Direct, Relative, Immediate) for metadata. Focus on patterns likely referencing strings.
    
    ### src/analysis/address_resolver.rs(NEW)
    
    References: 
    
    - src/types.rs(MODIFY)
    
    Implement `AddressResolver` struct built from `ContainerInfo` sections, mapping RVAs to offsets and vice versa. Methods: `rva_to_offset(&self, rva: u64) -> Option<u64>`, `offset_to_rva(&self, offset: u64) -> Option<u64>`, `resolve_target(&self, instr_addr: u64, operand: &Operand) -> Option<u64>` for RIP/PC-relative calculations. Handle relocations minimally for now, assuming flat address space.
    
    ### src/analysis/linear_sweep.rs(NEW)
    
    References: 
    
    - src/types.rs(MODIFY)
    - src/analysis/reference_extractor.rs(NEW)
    - src/analysis/address_resolver.rs(NEW)
    
    Provide `perform_sweep(data: &[u8], section: &SectionInfo, analyzer: &DisassemblyAnalyzer) -> Result<Vec<CodeReference>>`. Iterate bytes in section, disassemble sequentially with Capstone, call reference extraction on each valid instruction, resolve addresses, and collect references with instruction RVA. Skip invalid instructions, log errors. This realizes the linear sweep without control flow analysis.
    
    ### src/extraction/mod.rs(MODIFY)
    
    References: 
    
    - src/types.rs(MODIFY)
    - src/analysis/mod.rs(NEW)
    
    Implement basic string extraction framework: `extract_strings(data: &[u8], container: &ContainerInfo) -> Result<Vec<FoundString>>`. Scan sections by weight, detect ASCII/UTF8/UTF16 strings (min length 4), assign sources, sections, offsets/RVAs. After extraction, if `container.architecture.is_some()`, instantiate `DisassemblyAnalyzer`, run analysis, cross-reference targets with string offsets/RVAs (tolerance ±8 bytes), update `FoundString.code_references` and `is_code_referenced`. Boost score by 50 for referenced strings.
    
    ### src/main.rs(MODIFY)
    
    References: 
    
    - src/extraction/mod.rs(MODIFY)
    
    Add CLI flag `--disassemble` or `-d` to Clap for optional disassembly. In the main logic, after parsing container, if flag set and architecture detected, proceed with disassembly-integrated extraction; else, use basic extraction without analysis. Update help text to explain the flag enables code reference detection at performance cost.
    
    ### tests/integration_disasm.rs(NEW)
    
    References: 
    
    - src/extraction/mod.rs(MODIFY)
    - src/analysis/mod.rs(NEW)
    - src/types.rs(MODIFY)
    
    Add integration tests using sample binaries (create or use fixtures) for ELF/PE/Mach-O with known code-string references (e.g., LEA to string literal). Verify architecture detection, disassembly coverage, reference extraction accuracy, and flagging in `FoundString`. Test unsupported arch fallback, error handling, and score boosting. Use insta snapshots for output validation.
    
    ### README.md(MODIFY)
    
    References: 
    
    - src/main.rs(MODIFY)
    
    Update the features section to highlight the new Capstone disassembly pass for identifying code-referenced strings, improving relevance scoring. Add usage example with `--disassemble` flag. Mention supported architectures and performance note. Expand the architecture overview to include the analysis module.
    
    ### docs/src/architecture.md(MODIFY)
    
    References: 
    
    - src/analysis/mod.rs(NEW)
    
    If the docs exist, add a section on the Analysis Module describing Capstone integration, linear sweep process, reference extraction, and integration with extraction/scoring. Update data flow diagram to show disassembly pass post-container parsing, pre-output. Include architecture detection details and reference types.

    Developer Humor

    🛠️ Stringy's New Trick 🛠️\n>\n> Why did the disassembler go to therapy?\n> It had too many relative issues with RIP!\n> But with Capstone, it finally found its address.\n>\n> 🎉 Now strings are truly referenced! 🎉


    Execution Information

    Branch: main
    Commit: 37cfc7c


    💡 Tips

    Supported Commands (Inside Comments)

    • Use @traycerai generate to iterate on the previous version of the implementation plan.

    Supported Commands (Inside Description)

    • Add @traycerai ignore anywhere in the ticket description to prevent this ticket from being processed.
    • Add @traycerai branch:<branch-name> anywhere in the ticket description to specify the target branch for the implementation plan.

    Community

    • Join our Discord Community to get help, request features, and share feedback.
    • Follow us on X/Twitter for updates and announcements.
  4. unclesp1d3r commented on Nov 10, 2025

    @unclesp1d3r
    MemberAuthor

    @coderabbitai Enhance this issue body with additional context and a proposed solution. Improve the issue title and assign the proper labels and other metadata.

  5. changed the title [-]Capstone Disassembly Pass[/-] [+]Implement Capstone Disassembly Pass to Identify Code-Referenced Strings[/+] on Nov 10, 2025
  6. coderabbitai commented on Nov 10, 2025

    @coderabbitai
    Contributor

    Tip

    For best results, initiate chat on the files or code changes.

    🧩 Analysis chain

    🏁 Script executed:

    #!/bin/bash
    # Fetch the current issue details
    gh issue view 61 --repo EvilBit-Labs/StringyMcStringFace --json title,body,labels,assignees,milestone,state
    
    # Get repository README for context
    cat README.md 2>/dev/null || echo "README not found"
    
    # Look for relevant files related to disassembly or capstone
    fd -t f -e py -e rs -e cpp -e h | head -20
    
    # Check for any existing disassembly or capstone related code
    rg -l "capstone|disassem" --type py --type rust --type cpp 2>/dev/null | head -10
    

    Length of output: 8022


    🏁 Script executed:

    #!/bin/bash
    # Check if Capstone is already in dependencies
    cat Cargo.toml | grep -i capstone || echo "Capstone not found in Cargo.toml"
    
    # Look for any related issues
    gh issue list --repo EvilBit-Labs/StringyMcStringFace --json number,title,labels --limit 30
    
    # Check for any task tracking or implementation plan
    cat .kiro/specs/stringy-binary-analyzer/tasks.md 2>/dev/null | head -100 || echo "Task file not found"
    
    # Look for existing disassembly or code analysis components
    fd -t f . src/ | head -20
    

    Length of output: 22751


    🏁 Script executed:

    #!/bin/bash
    # Update issue #61 with enhanced content
    gh issue edit 61 --repo EvilBit-Labs/StringyMcStringFace \
      --title "Implement Capstone Disassembly Pass to Identify Code-Referenced Strings" \
      --body "## Background
    
    StringyMcStringFace aims to extract meaningful strings from binaries by being data-structure aware and prioritizing high-value strings over arbitrary byte sequences. A critical enhancement to string relevance scoring is identifying which strings are actually **referenced by executable code** versus those that are dead data, padding, or artifacts.
    
    By performing disassembly of executable sections using the Capstone framework, we can:
    - **Distinguish active strings** from dead data by identifying instruction-level references
    - **Improve ranking accuracy** by boosting strings that are demonstrably used in the code
    - **Provide context** about how strings are accessed (direct reference, computed offset, etc.)
    - **Enhance analysis value** for malware analysis, reverse engineering, and YARA rule generation
    
    ## Objective
    
    Implement a **Capstone disassembly pass** that performs linear sweep disassembly of executable sections (.text, __TEXT,__text, etc.) to identify and flag strings that are directly referenced by machine code instructions.
    
    ## Technical Approach
    
    ### 1. Disassembly Engine Integration
    - Add **capstone-rs** dependency to Cargo.toml for multi-architecture disassembly support
    - Support architectures: x86, x86-64, ARM, ARM64, as indicated by binary format headers
    - Perform linear sweep disassembly of executable sections identified by container parsers
    
    ### 2. Instruction Analysis
    Target instruction patterns that commonly reference string data:
    - **x86/x64**: \`lea rax, [rip+offset]\`, \`mov rax, offset\`, \`push offset\`
    - **ARM/ARM64**: \`adr\`, \`adrp\`, \`ldr\` with PC-relative addressing, immediate loads
    - Extract effective addresses from operands (handle RIP-relative, absolute, register-indirect)
    
    ### 3. Cross-Referencing
    - Maintain a map of extracted string offsets/RVAs from string extraction passes
    - For each instruction with a data reference:
      - Resolve the target address (accounting for relocations, base addresses, RIP-relative calculations)
      - Check if the target address overlaps with any extracted string offset
      - If match found, tag the string with \`CodeReferenced\` or increment reference count
    
    ### 4. Scoring Integration
    - Strings flagged as code-referenced receive a **significant scoring boost** in the ranking algorithm
    - Potentially add metadata to \`FoundString\`: \`referenced_by: Vec<u64>\` to track instruction addresses
    - Consider tracking reference frequency (multiple instructions referencing the same string)
    
    ## Implementation Steps
    
    1. **Add Capstone dependency**
       - Add \`capstone = \"0.12\"\` to Cargo.toml
       - Create \`src/analysis/disasm.rs\` module
    
    2. **Implement DisassemblyAnalyzer**
       - Trait or struct to encapsulate disassembly logic
       - Method: \`analyze_code_sections(&self, container_info: &ContainerInfo, sections: &[SectionInfo]) -> Result<Vec<CodeReference>>\`
       - Detect architecture from container format (ELF e_machine, PE Machine, Mach-O cputype)
       - Initialize Capstone engine with appropriate architecture and mode
    
    3. **Linear Sweep Disassembly**
       - Iterate through executable sections (identified by container parser)
       - Disassemble instruction stream from section start to end
       - Handle disassembly errors gracefully (skip bad instructions, continue)
    
    4. **Reference Extraction**
       - For each instruction, analyze operands for data references:
         - Immediate values that could be addresses
         - Memory operands with displacement/offset
         - PC-relative references (x86-64 RIP-relative, ARM PC-relative)
       - Resolve addresses accounting for section RVA/virtual address
       - Emit \`CodeReference { instruction_addr: u64, target_addr: u64, ref_type: ReferenceType }\`
    
    5. **Integration with String Extraction**
       - After string extraction phase, run disassembly analysis
       - Cross-reference \`CodeReference.target_addr\` with \`FoundString.offset/rva\`
       - Tag matching strings or update scoring metadata
    
    6. **Testing**
       - Create test binaries (ELF, PE, Mach-O) with known string references
       - Verify strings referenced by \`lea\`, \`mov\`, \`adr\` instructions are correctly flagged
       - Benchmark performance impact on large binaries
       - Add integration tests in \`tests/integration_disasm.rs\`
    
    ## Dependencies
    
    - **capstone-rs** (v0.12+): Rust bindings for the Capstone disassembly framework
      - Supports x86, x64, ARM, ARM64, and other architectures
      - Provides instruction-level analysis and operand information
    - Existing: **goblin** for binary format parsing and section identification
    
    ## Success Criteria
    
    - [ ] Capstone-rs integrated and architecture detection working for ELF, PE, Mach-O
    - [ ] Linear sweep disassembly successfully processes .text sections in test binaries
    - [ ] Data reference instructions (lea, mov, adr, etc.) correctly extract target addresses
    - [ ] Cross-referencing identifies strings referenced by code with high accuracy
    - [ ] \`FoundString\` metadata enhanced with code reference information
    - [ ] Integration tests verify correct flagging on test binaries with known references
    - [ ] Documentation explains disassembly analysis and its impact on scoring
    
    ## Related Issues
    
    - #41 - Epic: Add relocation-hinted string reference detection with Capstone disassembly (broader scope)
    - #60 - Relocation-Based Hinting (complementary approach using relocation tables)
    
    ## Notes
    
    - This is a **linear sweep** approach (disassemble sequentially), not recursive traversal
    - False positives possible (immediate values that happen to match string offsets but aren't references)
    - Consider making disassembly pass **optional** via CLI flag (\`--disassemble\`) due to performance cost
    - For obfuscated or packed binaries, disassembly may be unreliable (acceptable limitation)
    - Future enhancement: combine with relocation table analysis (#60) for higher confidence"
    
    # Add labels
    gh issue edit 61 --repo EvilBit-Labs/StringyMcStringFace \
      --add-label enhancement,dependencies,lang:rust,needs:tests
    
    # Assign to unclesp1d3r
    gh issue edit 61 --repo EvilBit-Labs/StringyMcStringFace \
      --add-assignee unclesp1d3r
    

    Length of output: 185


    @unclesp1d3r I've successfully enhanced issue #61! Here's what was updated:

    📝 Changes Made

    Title

    Before: "Capstone Disassembly Pass"
    After: "Implement Capstone Disassembly Pass to Identify Code-Referenced Strings"

    Issue Body

    Added comprehensive sections including:

    • Background - Explains why identifying code-referenced strings is critical for StringyMcStringFace's goals
    • Objective - Clear statement of what the Capstone disassembly pass should accomplish
    • Technical Approach - Detailed breakdown covering:
      • Disassembly engine integration (capstone-rs, multi-architecture support)
      • Instruction analysis patterns for x86/x64 and ARM/ARM64
      • Cross-referencing methodology with extracted strings
      • Scoring integration strategy
    • Implementation Steps - 6-step actionable plan with specific deliverables
    • Dependencies - Identifies capstone-rs v0.12+ requirement
    • Success Criteria - Checklist of completion requirements
    • Related Issues - Links to Add relocation-hinted string reference detection with Capstone disassembly #41 (broader epic) and Add relocation-based string ranking to identify code-referenced addresses #60 (complementary relocation-based approach)
    • Notes - Important considerations about linear sweep approach, false positives, performance, and future enhancements

    Metadata

    • Labels Added: enhancement, dependencies, lang:rust, needs:tests (retains existing area:analyzer)
    • Assigned To: unclesp1d3r

    The issue is now ready for implementation with clear technical guidance and success criteria! 🎯

  7. traycerai commented on Nov 10, 2025

    @traycerai

    I have updated the Implementation Plan to reflect the recent changes in the ticket.

    Previous Plan

    Observations

    The codebase has a well-defined architecture with complete container parsing for ELF, PE, and Mach-O formats. The extraction module is currently a stub, and there's no existing disassembly code. The task requires adding Capstone-based disassembly to identify code references to strings. Architecture detection is available via goblin's format-specific headers.

    Approach

    Add a new disassembly module that performs linear sweep of executable sections using Capstone, identifies data references in instructions (lea, mov with immediates), cross-references these addresses with extracted string offsets, and flags strings that are referenced by code. Extend FoundString to track code references and integrate the disassembly pass into the extraction pipeline.

    Reasoning

    I explored the codebase structure, examined all container parsers (ELF, PE, Mach-O), reviewed the type system and data structures, checked the main entry point, searched for existing Capstone references, researched goblin's architecture detection capabilities, and reviewed the design documentation to understand the intended pipeline flow.

    Proposed File Changes

    📄 Cargo.toml (MODIFY) 🔗

    Add capstone dependency (version 0.12 or latest) to enable disassembly functionality. This crate provides Rust bindings to the Capstone disassembly framework and supports multiple architectures (x86, x86_64, ARM, ARM64, etc.).

    📄 src/types.rs (MODIFY) 🔗

    Extend the FoundString struct to include a new field referenced_by_code: bool (default false) to track whether the string is referenced by executable code. Optionally, add a code_references: Vec<u64> field to store the specific instruction addresses that reference this string, which can be useful for deeper analysis and debugging.
    Add a new Architecture enum to represent CPU architectures detected from binaries. Include variants for X86, X86_64, ARM, ARM64, and Unknown. This will be used to select the appropriate Capstone disassembly mode. Add a field architecture: Option<Architecture> to the ContainerInfo struct to store the detected architecture.

    📄 src/container/elf.rs (MODIFY) 🔗

    References

    Add architecture detection in the parse method by examining elf.header.e_machine. Map common values to the Architecture enum: EM_386 (3) → X86, EM_X86_64 (62) → X86_64, EM_ARM (40) → ARM, EM_AARCH64 (183) → ARM64. Set the architecture field in the returned ContainerInfo. Use goblin::elf::header::EM_* constants for matching.

    📄 src/container/pe.rs (MODIFY) 🔗

    References

    Add architecture detection in the parse method by examining pe.header.coff_header.machine. Map COFF machine types to the Architecture enum: COFF_MACHINE_X86 (0x14c) → X86, COFF_MACHINE_X86_64 (0x8664) → X86_64, COFF_MACHINE_ARM (0x1c0) / COFF_MACHINE_ARMNT (0x1c4) → ARM, COFF_MACHINE_ARM64 (0xaa64) → ARM64. Set the architecture field in the returned ContainerInfo. Use goblin::pe::header::COFF_MACHINE_* constants.

    📄 src/container/macho.rs (MODIFY) 🔗

    References

    Add architecture detection in the parse_single_macho method by examining macho.header.cputype(). Map Mach-O CPU types to the Architecture enum: CPU_TYPE_X86 (7) → X86, CPU_TYPE_X86_64 (0x01000007) → X86_64, CPU_TYPE_ARM (12) → ARM, CPU_TYPE_ARM64 (0x0100000c) → ARM64. Set the architecture field in the returned ContainerInfo. Use goblin::mach::constants::cputype::* constants for matching.
    Fix the is_executable_section method to properly identify all executable sections. Currently it only recognizes __TEXT,__text, but should also include __TEXT,__stubs and __TEXT,__stub_helper which contain executable code (trampolines and helper functions). Update the logic to check if segment is __TEXT and section is one of __text, __stubs, or __stub_helper.

    📁 src/disassembly (NEW) 🔗

    Create a new directory for the disassembly module.

    📄 src/disassembly/mod.rs (NEW) 🔗

    References

    Create the main disassembly module file. Define a DisassemblyAnalyzer struct that holds a reference to the binary data and container info. Implement a public function analyze_code_references that takes &[u8] (binary data), &ContainerInfo, and &[FoundString] as parameters, performs linear sweep disassembly on executable sections, and returns a HashMap<u64, Vec<u64>> mapping string offsets to instruction addresses that reference them. Include error handling for unsupported architectures and disassembly failures. Re-export the main analysis function for easy access.

    📄 src/disassembly/capstone_wrapper.rs (NEW) 🔗

    References

    Create a wrapper module for Capstone initialization and configuration. Implement a function create_disassembler that takes an Architecture enum and returns a configured Capstone instance with the appropriate architecture and mode settings. Map Architecture::X86 → Capstone::new().x86().mode(arch::x86::ArchMode::Mode32), Architecture::X86_64 → mode(arch::x86::ArchMode::Mode64), Architecture::ARM → Capstone::new().arm(), Architecture::ARM64 → Capstone::new().arm64(). Include error handling for unsupported architectures and Capstone initialization failures. Set detail mode to true to access operand information.

    📄 src/disassembly/reference_detector.rs (NEW) 🔗

    References

    Create a module for detecting data references in disassembled instructions. Implement a function extract_data_references that takes a disassembled instruction and returns a Vec<u64> of potential data addresses. For x86/x86_64, look for: (1) immediate operands in LEA instructions, (2) immediate operands in MOV instructions, (3) RIP-relative addressing (x86_64), (4) memory operands with displacement. For ARM/ARM64, look for: (1) LDR with PC-relative addressing, (2) ADRP/ADD pairs for address calculation, (3) immediate values in MOV/MOVZ/MOVK sequences. Handle address resolution by converting RIP-relative offsets to absolute addresses using the instruction address. Include helper functions to determine if an address falls within a valid data section range.

    📄 src/disassembly/address_resolver.rs (NEW) 🔗

    References

    Create a module for address resolution and mapping between file offsets and virtual addresses (RVAs). Implement a AddressMapper struct that builds a mapping from ContainerInfo sections, storing offset→RVA and RVA→offset mappings. Provide methods: rva_to_offset(rva: u64) → Option<u64> to convert virtual addresses to file offsets, offset_to_rva(offset: u64) → Option<u64> for the reverse, and is_valid_data_address(addr: u64) → bool to check if an address falls within a data section. Handle cases where sections may not have RVA information (return None). This is critical for matching instruction operands (which use RVAs) with string offsets (which are file offsets).

    📄 src/disassembly/linear_sweep.rs (NEW) 🔗

    References

    Create a module for performing linear sweep disassembly. Implement a function perform_linear_sweep that takes binary data, a section (from SectionInfo), and a Capstone disassembler, then disassembles all instructions in that section sequentially. For each instruction, extract potential data references using the reference_detector module. Return a Vec<(u64, Vec<u64>)> where each tuple contains the instruction address and the data addresses it references. Handle disassembly errors gracefully by skipping invalid instructions and continuing. Include logic to stop at section boundaries. This implements the "linear sweep" approach mentioned in the issue (as opposed to recursive traversal or CFG-based disassembly).

    📄 src/disassembly/cross_reference.rs (NEW) 🔗

    References

    Create a module for cross-referencing disassembled data references with extracted strings. Implement a function build_string_reference_map that takes the results from linear sweep (instruction addresses and their data references), an AddressMapper, and a slice of FoundString objects. For each data reference, convert it to a file offset using the address mapper, then check if it matches any string's offset or falls within the range [offset, offset+length]. Build and return a HashMap<u64, Vec<u64>> mapping string offsets to the instruction addresses that reference them. Include tolerance for slight address mismatches (±4 bytes) to handle alignment and pointer arithmetic. This is the core cross-referencing logic mentioned in the issue.

    📄 src/lib.rs (MODIFY) 🔗

    References

    Add the new disassembly module to the library's public API by adding pub mod disassembly; after the existing module declarations. This makes the disassembly functionality available to both the CLI and library users. Re-export key types and functions from the disassembly module if needed for convenience, such as pub use disassembly::analyze_code_references;.

    📄 src/extraction/mod.rs (MODIFY) 🔗

    References

    Add a public function flag_referenced_strings that takes a mutable slice of FoundString objects and a reference map (from the disassembly module), then updates each string's referenced_by_code field to true if it appears in the reference map. Optionally populate the code_references field with the instruction addresses. This function serves as the integration point between string extraction and disassembly analysis. It should be called after strings are extracted but before they're returned to the caller.

    📄 tests/integration_disassembly.rs (NEW) 🔗

    References

    Create integration tests for the disassembly functionality. Test with the existing test_binary_elf fixture to verify: (1) architecture detection works correctly, (2) executable sections are identified, (3) linear sweep disassembly completes without errors, (4) at least some data references are detected in typical binaries, (5) the cross-referencing logic correctly identifies strings referenced by code. Include tests for error handling with unsupported architectures and corrupted binaries. Use the existing test fixture infrastructure from integration_elf.rs as a reference for structure and helper functions.

    📄 docs/src/architecture.md (MODIFY) 🔗

    References

    Update the architecture documentation to include the new disassembly module. Add a new section "6. Disassembly Module (src/disassembly/)" describing the Capstone-based linear sweep analysis, architecture detection, data reference extraction, and cross-referencing with strings. Update the data flow diagram to show the disassembly pass occurring after string extraction. Update the module dependencies diagram to include the disassembly module and its sub-modules. Add Capstone to the list of external dependencies with a note about its purpose (multi-architecture disassembly).

    📄 README.md (MODIFY) 🔗

    Update the README to mention the new code reference detection feature. Add a bullet point under features describing how Stringy can identify strings that are referenced by executable code using disassembly analysis. This helps users understand that the tool goes beyond simple string extraction to provide context about which strings are actually used by the program. Keep the description concise and user-focused.

    Diagram

    sequenceDiagram
        participant User
        participant Container Parser
        participant Disassembly Module
        participant String Extractor
        participant Output
    
        User->>Container Parser: Parse binary
        Container Parser->>Container Parser: Detect architecture
        Container Parser->>Container Parser: Identify executable sections
        Container Parser-->>User: ContainerInfo (with architecture)
        
        User->>String Extractor: Extract strings
        String Extractor-->>User: Vec<FoundString>
        
        User->>Disassembly Module: analyze_code_references(data, container_info, strings)
        
        Disassembly Module->>Disassembly Module: Create Capstone disassembler for architecture
        
        loop For each executable section
            Disassembly Module->>Disassembly Module: Linear sweep disassembly
            Disassembly Module->>Disassembly Module: Extract data references (LEA, MOV, etc.)
            Disassembly Module->>Disassembly Module: Convert RVA to file offset
        end
        
        Disassembly Module->>Disassembly Module: Cross-reference with string offsets
        Disassembly Module-->>User: Reference map (string offset → instruction addresses)
        
        User->>String Extractor: flag_referenced_strings(strings, reference_map)
        String Extractor->>String Extractor: Update referenced_by_code field
        String Extractor-->>User: Updated strings
        
        User->>Output: Format and display results
    
    Loading

    Import In IDE

    VSCode Icon Cursor Icon Windsurf Icon

    🤖 Prompt for AI Agents
    I have created the following plan after thorough exploration and analysis of the codebase. Follow the below plan verbatim. Trust the files and references. Do not re-verify what's written in the plan. Explore only when absolutely necessary. First implement all the proposed file changes and then I'll review all the changes together at the end.
    
    ### Observations
    
    The codebase has a well-defined architecture with complete container parsing for ELF, PE, and Mach-O formats. The extraction module is currently a stub, and there's no existing disassembly code. The task requires adding Capstone-based disassembly to identify code references to strings. Architecture detection is available via goblin's format-specific headers.
    
    ### Approach
    
    Add a new disassembly module that performs linear sweep of executable sections using Capstone, identifies data references in instructions (lea, mov with immediates), cross-references these addresses with extracted string offsets, and flags strings that are referenced by code. Extend `FoundString` to track code references and integrate the disassembly pass into the extraction pipeline.
    
    ### Reasoning
    
    I explored the codebase structure, examined all container parsers (ELF, PE, Mach-O), reviewed the type system and data structures, checked the main entry point, searched for existing Capstone references, researched goblin's architecture detection capabilities, and reviewed the design documentation to understand the intended pipeline flow.
    
    ## Mermaid Diagram
    
    sequenceDiagram
        participant User
        participant Container Parser
        participant Disassembly Module
        participant String Extractor
        participant Output
    
        User->>Container Parser: Parse binary
        Container Parser->>Container Parser: Detect architecture
        Container Parser->>Container Parser: Identify executable sections
        Container Parser-->>User: ContainerInfo (with architecture)
        
        User->>String Extractor: Extract strings
        String Extractor-->>User: Vec<FoundString>
        
        User->>Disassembly Module: analyze_code_references(data, container_info, strings)
        
        Disassembly Module->>Disassembly Module: Create Capstone disassembler for architecture
        
        loop For each executable section
            Disassembly Module->>Disassembly Module: Linear sweep disassembly
            Disassembly Module->>Disassembly Module: Extract data references (LEA, MOV, etc.)
            Disassembly Module->>Disassembly Module: Convert RVA to file offset
        end
        
        Disassembly Module->>Disassembly Module: Cross-reference with string offsets
        Disassembly Module-->>User: Reference map (string offset → instruction addresses)
        
        User->>String Extractor: flag_referenced_strings(strings, reference_map)
        String Extractor->>String Extractor: Update referenced_by_code field
        String Extractor-->>User: Updated strings
        
        User->>Output: Format and display results
    
    ## Proposed File Changes
    
    ### Cargo.toml(MODIFY)
    
    Add `capstone` dependency (version 0.12 or latest) to enable disassembly functionality. This crate provides Rust bindings to the Capstone disassembly framework and supports multiple architectures (x86, x86_64, ARM, ARM64, etc.).
    
    ### src/types.rs(MODIFY)
    
    Extend the `FoundString` struct to include a new field `referenced_by_code: bool` (default false) to track whether the string is referenced by executable code. Optionally, add a `code_references: Vec<u64>` field to store the specific instruction addresses that reference this string, which can be useful for deeper analysis and debugging.
    Add a new `Architecture` enum to represent CPU architectures detected from binaries. Include variants for X86, X86_64, ARM, ARM64, and Unknown. This will be used to select the appropriate Capstone disassembly mode. Add a field `architecture: Option<Architecture>` to the `ContainerInfo` struct to store the detected architecture.
    
    ### src/container/elf.rs(MODIFY)
    
    References: 
    
    - src/types.rs(MODIFY)
    
    Add architecture detection in the `parse` method by examining `elf.header.e_machine`. Map common values to the `Architecture` enum: EM_386 (3) → X86, EM_X86_64 (62) → X86_64, EM_ARM (40) → ARM, EM_AARCH64 (183) → ARM64. Set the `architecture` field in the returned `ContainerInfo`. Use `goblin::elf::header::EM_*` constants for matching.
    
    ### src/container/pe.rs(MODIFY)
    
    References: 
    
    - src/types.rs(MODIFY)
    
    Add architecture detection in the `parse` method by examining `pe.header.coff_header.machine`. Map COFF machine types to the `Architecture` enum: COFF_MACHINE_X86 (0x14c) → X86, COFF_MACHINE_X86_64 (0x8664) → X86_64, COFF_MACHINE_ARM (0x1c0) / COFF_MACHINE_ARMNT (0x1c4) → ARM, COFF_MACHINE_ARM64 (0xaa64) → ARM64. Set the `architecture` field in the returned `ContainerInfo`. Use `goblin::pe::header::COFF_MACHINE_*` constants.
    
    ### src/container/macho.rs(MODIFY)
    
    References: 
    
    - src/types.rs(MODIFY)
    
    Add architecture detection in the `parse_single_macho` method by examining `macho.header.cputype()`. Map Mach-O CPU types to the `Architecture` enum: CPU_TYPE_X86 (7) → X86, CPU_TYPE_X86_64 (0x01000007) → X86_64, CPU_TYPE_ARM (12) → ARM, CPU_TYPE_ARM64 (0x0100000c) → ARM64. Set the `architecture` field in the returned `ContainerInfo`. Use `goblin::mach::constants::cputype::*` constants for matching.
    Fix the `is_executable_section` method to properly identify all executable sections. Currently it only recognizes `__TEXT,__text`, but should also include `__TEXT,__stubs` and `__TEXT,__stub_helper` which contain executable code (trampolines and helper functions). Update the logic to check if segment is `__TEXT` and section is one of `__text`, `__stubs`, or `__stub_helper`.
    
    ### src/disassembly(NEW)
    
    Create a new directory for the disassembly module.
    
    ### src/disassembly/mod.rs(NEW)
    
    References: 
    
    - src/types.rs(MODIFY)
    
    Create the main disassembly module file. Define a `DisassemblyAnalyzer` struct that holds a reference to the binary data and container info. Implement a public function `analyze_code_references` that takes `&[u8]` (binary data), `&ContainerInfo`, and `&[FoundString]` as parameters, performs linear sweep disassembly on executable sections, and returns a `HashMap<u64, Vec<u64>>` mapping string offsets to instruction addresses that reference them. Include error handling for unsupported architectures and disassembly failures. Re-export the main analysis function for easy access.
    
    ### src/disassembly/capstone_wrapper.rs(NEW)
    
    References: 
    
    - src/types.rs(MODIFY)
    
    Create a wrapper module for Capstone initialization and configuration. Implement a function `create_disassembler` that takes an `Architecture` enum and returns a configured `Capstone` instance with the appropriate architecture and mode settings. Map Architecture::X86 → Capstone::new().x86().mode(arch::x86::ArchMode::Mode32), Architecture::X86_64 → mode(arch::x86::ArchMode::Mode64), Architecture::ARM → Capstone::new().arm(), Architecture::ARM64 → Capstone::new().arm64(). Include error handling for unsupported architectures and Capstone initialization failures. Set detail mode to true to access operand information.
    
    ### src/disassembly/reference_detector.rs(NEW)
    
    References: 
    
    - src/types.rs(MODIFY)
    
    Create a module for detecting data references in disassembled instructions. Implement a function `extract_data_references` that takes a disassembled instruction and returns a `Vec<u64>` of potential data addresses. For x86/x86_64, look for: (1) immediate operands in LEA instructions, (2) immediate operands in MOV instructions, (3) RIP-relative addressing (x86_64), (4) memory operands with displacement. For ARM/ARM64, look for: (1) LDR with PC-relative addressing, (2) ADRP/ADD pairs for address calculation, (3) immediate values in MOV/MOVZ/MOVK sequences. Handle address resolution by converting RIP-relative offsets to absolute addresses using the instruction address. Include helper functions to determine if an address falls within a valid data section range.
    
    ### src/disassembly/address_resolver.rs(NEW)
    
    References: 
    
    - src/types.rs(MODIFY)
    
    Create a module for address resolution and mapping between file offsets and virtual addresses (RVAs). Implement a `AddressMapper` struct that builds a mapping from `ContainerInfo` sections, storing offset→RVA and RVA→offset mappings. Provide methods: `rva_to_offset(rva: u64) → Option<u64>` to convert virtual addresses to file offsets, `offset_to_rva(offset: u64) → Option<u64>` for the reverse, and `is_valid_data_address(addr: u64) → bool` to check if an address falls within a data section. Handle cases where sections may not have RVA information (return None). This is critical for matching instruction operands (which use RVAs) with string offsets (which are file offsets).
    
    ### src/disassembly/linear_sweep.rs(NEW)
    
    References: 
    
    - src/types.rs(MODIFY)
    - src/disassembly/reference_detector.rs(NEW)
    
    Create a module for performing linear sweep disassembly. Implement a function `perform_linear_sweep` that takes binary data, a section (from `SectionInfo`), and a Capstone disassembler, then disassembles all instructions in that section sequentially. For each instruction, extract potential data references using the `reference_detector` module. Return a `Vec<(u64, Vec<u64>)>` where each tuple contains the instruction address and the data addresses it references. Handle disassembly errors gracefully by skipping invalid instructions and continuing. Include logic to stop at section boundaries. This implements the "linear sweep" approach mentioned in the issue (as opposed to recursive traversal or CFG-based disassembly).
    
    ### src/disassembly/cross_reference.rs(NEW)
    
    References: 
    
    - src/types.rs(MODIFY)
    - src/disassembly/address_resolver.rs(NEW)
    
    Create a module for cross-referencing disassembled data references with extracted strings. Implement a function `build_string_reference_map` that takes the results from linear sweep (instruction addresses and their data references), an `AddressMapper`, and a slice of `FoundString` objects. For each data reference, convert it to a file offset using the address mapper, then check if it matches any string's offset or falls within the range [offset, offset+length]. Build and return a `HashMap<u64, Vec<u64>>` mapping string offsets to the instruction addresses that reference them. Include tolerance for slight address mismatches (±4 bytes) to handle alignment and pointer arithmetic. This is the core cross-referencing logic mentioned in the issue.
    
    ### src/lib.rs(MODIFY)
    
    References: 
    
    - src/disassembly/mod.rs(NEW)
    
    Add the new `disassembly` module to the library's public API by adding `pub mod disassembly;` after the existing module declarations. This makes the disassembly functionality available to both the CLI and library users. Re-export key types and functions from the disassembly module if needed for convenience, such as `pub use disassembly::analyze_code_references;`.
    
    ### src/extraction/mod.rs(MODIFY)
    
    References: 
    
    - src/types.rs(MODIFY)
    - src/disassembly/mod.rs(NEW)
    
    Add a public function `flag_referenced_strings` that takes a mutable slice of `FoundString` objects and a reference map (from the disassembly module), then updates each string's `referenced_by_code` field to true if it appears in the reference map. Optionally populate the `code_references` field with the instruction addresses. This function serves as the integration point between string extraction and disassembly analysis. It should be called after strings are extracted but before they're returned to the caller.
    
    ### tests/integration_disassembly.rs(NEW)
    
    References: 
    
    - tests/integration_elf.rs
    - src/disassembly/mod.rs(NEW)
    - src/types.rs(MODIFY)
    
    Create integration tests for the disassembly functionality. Test with the existing `test_binary_elf` fixture to verify: (1) architecture detection works correctly, (2) executable sections are identified, (3) linear sweep disassembly completes without errors, (4) at least some data references are detected in typical binaries, (5) the cross-referencing logic correctly identifies strings referenced by code. Include tests for error handling with unsupported architectures and corrupted binaries. Use the existing test fixture infrastructure from `integration_elf.rs` as a reference for structure and helper functions.
    
    ### docs/src/architecture.md(MODIFY)
    
    References: 
    
    - src/disassembly/mod.rs(NEW)
    
    Update the architecture documentation to include the new disassembly module. Add a new section "6. Disassembly Module (`src/disassembly/`)" describing the Capstone-based linear sweep analysis, architecture detection, data reference extraction, and cross-referencing with strings. Update the data flow diagram to show the disassembly pass occurring after string extraction. Update the module dependencies diagram to include the disassembly module and its sub-modules. Add Capstone to the list of external dependencies with a note about its purpose (multi-architecture disassembly).
    
    ### README.md(MODIFY)
    
    Update the README to mention the new code reference detection feature. Add a bullet point under features describing how Stringy can identify strings that are referenced by executable code using disassembly analysis. This helps users understand that the tool goes beyond simple string extraction to provide context about which strings are actually used by the program. Keep the description concise and user-focused.

    Developer Humor

    🔍 Disassembly Detective at Work 🔍\n>\n> Linear sweep through the code,\n> Finding strings in their abode,\n> LEA and MOV reveal the way,\n> Which strings the program will display!\n>\n> 🎯 *\No string left unreferenced!* 🎯


    Execution Information

    Branch: main
    Commit: bdd6206

    New Plan

    Observations

    The codebase provides complete container parsing for ELF, PE, and Mach-O formats via goblin, with robust type definitions in types.rs including ContainerInfo, SectionInfo, and FoundString. The extraction module is currently a stub, ready for implementation. No disassembly functionality exists, and Capstone is not a dependency. Architecture detection needs to be added to parsers. The project structure supports modular addition of an analysis module for disassembly.

    Approach

    Introduce a new analysis module with Capstone integration for linear sweep disassembly of executable sections. Detect architecture from binary headers, initialize Capstone accordingly, extract data references from instructions (e.g., LEA, MOV, ADR), resolve addresses to file offsets, and cross-reference with extracted strings to flag code-referenced ones. Extend FoundString with reference metadata and integrate into the extraction pipeline for scoring boost. Add optional CLI flag for performance.

    Reasoning

    I examined the project root and source directory structure, reviewed the Cargo.toml for dependencies, analyzed the types.rs for core data structures like FoundString and ContainerInfo, inspected the lib.rs for module organization, checked the extraction module which is currently a stub, and reviewed container parser files to understand section identification and parsing logic.

    Proposed File Changes

    📄 Cargo.toml (MODIFY) 🔗

    Add the capstone crate as a dependency with version "0.12" or the latest stable version. This enables multi-architecture disassembly capabilities essential for analyzing code references across x86, x86-64, ARM, and ARM64 binaries. Ensure it is added under the [dependencies] section.

    📄 src/types.rs (MODIFY) 🔗

    Introduce an Architecture enum with variants for X86, X86_64, ARM, ARM64, and Unknown to represent detected CPU architectures. Add an optional architecture: Option<Architecture> field to the ContainerInfo struct for storing the parsed architecture. Extend the FoundString struct with a new field code_references: Vec<u64> to track instruction addresses referencing the string, and a is_code_referenced: bool derived field for quick scoring checks. Update serialization derives if necessary to include these fields.

    📄 src/container/elf.rs (MODIFY) 🔗

    References

    In the parse function, detect the architecture by inspecting elf.header.e_machine and mapping values like EM_386 (3) to X86, EM_X86_64 (62) to X86_64, EM_ARM (40) to ARM, EM_AARCH64 (183) to ARM64 using goblin constants. Set container_info.architecture = Some(detected_arch) before returning. Ensure this integrates seamlessly with existing section and import/export parsing.

    📄 src/container/pe.rs (MODIFY) 🔗

    References

    In the parse function, detect architecture from pe.header.coff_header.machine, mapping COFF_MACHINE_I386 (0x14c) to X86, COFF_MACHINE_AMD64 (0x8664) to X86_64, COFF_MACHINE_ARM (0x1c0) to ARM, COFF_MACHINE_ARM64 (0xaa64) to ARM64. Assign to container_info.architecture and return the updated struct. This enhances the existing PE section classification without altering current logic.

    📄 src/container/macho.rs (MODIFY) 🔗

    References

    In parse_single_macho, detect architecture via macho.header.cputype(), mapping CPU_TYPE_I386 (7) to X86, CPU_TYPE_X86_64 (CPU_TYPE_I386 | CPU_ARCH_ABI64) to X86_64, CPU_TYPE_ARM (12) to ARM, CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64) to ARM64. Set in container_info.architecture. Also, refine is_executable_section to include __TEXT,__stubs and __TEXT,__stub_helper alongside __TEXT,__text for comprehensive code section coverage.

    📄 src/lib.rs (MODIFY) 🔗

    Add pub mod analysis; to declare the new analysis module. Re-export key types and functions from the analysis module, such as pub use analysis::{DisassemblyAnalyzer, CodeReference}; to make them accessible via the library crate root. This maintains the modular public API structure.

    📄 src/analysis/mod.rs (NEW) 🔗

    References

    Define the DisassemblyAnalyzer struct to hold Capstone engine and address resolution state. Implement new(architecture: Architecture) -> Result<Self> to initialize Capstone with appropriate mode (e.g., x86 mode 32/64, arm/arm64). Provide analyze(&self, data: &[u8], container: &ContainerInfo) -> Result<Vec<CodeReference>> for linear sweep over executable sections, extracting references. Include error handling for unsupported arches.

    📄 src/analysis/reference_extractor.rs (NEW) 🔗

    References

    Create a module for instruction operand analysis. Implement extract_references(instr: &Instruction) -> Vec<u64> to parse immediates and displacements for target instructions: x86 LEA/MOV/PUSH with offsets, RIP-relative; ARM ADR/ADRP/LDR PC-relative. Resolve effective addresses using instruction address and operand details. Define ReferenceType enum (Direct, Relative, Immediate) for metadata. Focus on patterns likely referencing strings.

    📄 src/analysis/address_resolver.rs (NEW) 🔗

    References

    Implement AddressResolver struct built from ContainerInfo sections, mapping RVAs to offsets and vice versa. Methods: rva_to_offset(&self, rva: u64) -> Option<u64>, offset_to_rva(&self, offset: u64) -> Option<u64>, resolve_target(&self, instr_addr: u64, operand: &Operand) -> Option<u64> for RIP/PC-relative calculations. Handle relocations minimally for now, assuming flat address space.

    📄 src/analysis/linear_sweep.rs (NEW) 🔗

    References

    Provide perform_sweep(data: &[u8], section: &SectionInfo, analyzer: &DisassemblyAnalyzer) -> Result<Vec<CodeReference>>. Iterate bytes in section, disassemble sequentially with Capstone, call reference extraction on each valid instruction, resolve addresses, and collect references with instruction RVA. Skip invalid instructions, log errors. This realizes the linear sweep without control flow analysis.

    📄 src/extraction/mod.rs (MODIFY) 🔗

    References

    Implement basic string extraction framework: extract_strings(data: &[u8], container: &ContainerInfo) -> Result<Vec<FoundString>>. Scan sections by weight, detect ASCII/UTF8/UTF16 strings (min length 4), assign sources, sections, offsets/RVAs. After extraction, if container.architecture.is_some(), instantiate DisassemblyAnalyzer, run analysis, cross-reference targets with string offsets/RVAs (tolerance ±8 bytes), update FoundString.code_references and is_code_referenced. Boost score by 50 for referenced strings.

    📄 src/main.rs (MODIFY) 🔗

    References

    Add CLI flag --disassemble or -d to Clap for optional disassembly. In the main logic, after parsing container, if flag set and architecture detected, proceed with disassembly-integrated extraction; else, use basic extraction without analysis. Update help text to explain the flag enables code reference detection at performance cost.

    📄 tests/integration_disasm.rs (NEW) 🔗

    References

    Add integration tests using sample binaries (create or use fixtures) for ELF/PE/Mach-O with known code-string references (e.g., LEA to string literal). Verify architecture detection, disassembly coverage, reference extraction accuracy, and flagging in FoundString. Test unsupported arch fallback, error handling, and score boosting. Use insta snapshots for output validation.

    📄 README.md (MODIFY) 🔗

    References

    Update the features section to highlight the new Capstone disassembly pass for identifying code-referenced strings, improving relevance scoring. Add usage example with --disassemble flag. Mention supported architectures and performance note. Expand the architecture overview to include the analysis module.

    📄 docs/src/architecture.md (MODIFY) 🔗

    References

    If the docs exist, add a section on the Analysis Module describing Capstone integration, linear sweep process, reference extraction, and integration with extraction/scoring. Update data flow diagram to show disassembly pass post-container parsing, pre-output. Include architecture detection details and reference types.

    Diagram

    sequenceDiagram
        participant B as Binary Data
        participant C as Container Parser
        participant E as Extraction Module
        participant A as Analysis Module
        participant S as Strings
    
        B->>C: Parse format & sections
        C->>C: Detect architecture
        C-->>E: ContainerInfo (w/ arch)
    
        E->>E: Extract raw strings from sections
        E-->>S: Vec<FoundString>
    
        alt Disassembly enabled
            E->>A: Initialize DisassemblyAnalyzer(arch)
            A->>A: Linear sweep executable sections
            A->>A: Extract & resolve references
            A-->>E: Vec<CodeReference>
            E->>E: Cross-ref & flag strings
            E->>E: Boost scores for referenced
        end
    
        E-->>User: Ranked FoundStrings w/ metadata
    
    Loading

    Import In IDE

    VSCode Icon Cursor Icon Windsurf Icon

    🤖 Prompt for AI Agents
    I have created the following plan after thorough exploration and analysis of the codebase. Follow the below plan verbatim. Trust the files and references. Do not re-verify what's written in the plan. Explore only when absolutely necessary. First implement all the proposed file changes and then I'll review all the changes together at the end.
    
    ### Observations
    
    The codebase provides complete container parsing for ELF, PE, and Mach-O formats via goblin, with robust type definitions in `types.rs` including `ContainerInfo`, `SectionInfo`, and `FoundString`. The `extraction` module is currently a stub, ready for implementation. No disassembly functionality exists, and Capstone is not a dependency. Architecture detection needs to be added to parsers. The project structure supports modular addition of an analysis module for disassembly.
    
    ### Approach
    
    Introduce a new `analysis` module with Capstone integration for linear sweep disassembly of executable sections. Detect architecture from binary headers, initialize Capstone accordingly, extract data references from instructions (e.g., LEA, MOV, ADR), resolve addresses to file offsets, and cross-reference with extracted strings to flag code-referenced ones. Extend `FoundString` with reference metadata and integrate into the extraction pipeline for scoring boost. Add optional CLI flag for performance.
    
    ### Reasoning
    
    I examined the project root and source directory structure, reviewed the Cargo.toml for dependencies, analyzed the types.rs for core data structures like FoundString and ContainerInfo, inspected the lib.rs for module organization, checked the extraction module which is currently a stub, and reviewed container parser files to understand section identification and parsing logic.
    
    ## Mermaid Diagram
    
    sequenceDiagram
        participant B as Binary Data
        participant C as Container Parser
        participant E as Extraction Module
        participant A as Analysis Module
        participant S as Strings
    
        B->>C: Parse format & sections
        C->>C: Detect architecture
        C-->>E: ContainerInfo (w/ arch)
    
        E->>E: Extract raw strings from sections
        E-->>S: Vec<FoundString>
    
        alt Disassembly enabled
            E->>A: Initialize DisassemblyAnalyzer(arch)
            A->>A: Linear sweep executable sections
            A->>A: Extract & resolve references
            A-->>E: Vec<CodeReference>
            E->>E: Cross-ref & flag strings
            E->>E: Boost scores for referenced
        end
    
        E-->>User: Ranked FoundStrings w/ metadata
    
    ## Proposed File Changes
    
    ### Cargo.toml(MODIFY)
    
    Add the `capstone` crate as a dependency with version "0.12" or the latest stable version. This enables multi-architecture disassembly capabilities essential for analyzing code references across x86, x86-64, ARM, and ARM64 binaries. Ensure it is added under the `[dependencies]` section.
    
    ### src/types.rs(MODIFY)
    
    Introduce an `Architecture` enum with variants for X86, X86_64, ARM, ARM64, and Unknown to represent detected CPU architectures. Add an optional `architecture: Option<Architecture>` field to the `ContainerInfo` struct for storing the parsed architecture. Extend the `FoundString` struct with a new field `code_references: Vec<u64>` to track instruction addresses referencing the string, and a `is_code_referenced: bool` derived field for quick scoring checks. Update serialization derives if necessary to include these fields.
    
    ### src/container/elf.rs(MODIFY)
    
    References: 
    
    - src/types.rs(MODIFY)
    
    In the `parse` function, detect the architecture by inspecting `elf.header.e_machine` and mapping values like EM_386 (3) to X86, EM_X86_64 (62) to X86_64, EM_ARM (40) to ARM, EM_AARCH64 (183) to ARM64 using goblin constants. Set `container_info.architecture = Some(detected_arch)` before returning. Ensure this integrates seamlessly with existing section and import/export parsing.
    
    ### src/container/pe.rs(MODIFY)
    
    References: 
    
    - src/types.rs(MODIFY)
    
    In the `parse` function, detect architecture from `pe.header.coff_header.machine`, mapping COFF_MACHINE_I386 (0x14c) to X86, COFF_MACHINE_AMD64 (0x8664) to X86_64, COFF_MACHINE_ARM (0x1c0) to ARM, COFF_MACHINE_ARM64 (0xaa64) to ARM64. Assign to `container_info.architecture` and return the updated struct. This enhances the existing PE section classification without altering current logic.
    
    ### src/container/macho.rs(MODIFY)
    
    References: 
    
    - src/types.rs(MODIFY)
    
    In `parse_single_macho`, detect architecture via `macho.header.cputype()`, mapping CPU_TYPE_I386 (7) to X86, CPU_TYPE_X86_64 (CPU_TYPE_I386 | CPU_ARCH_ABI64) to X86_64, CPU_TYPE_ARM (12) to ARM, CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64) to ARM64. Set in `container_info.architecture`. Also, refine `is_executable_section` to include `__TEXT,__stubs` and `__TEXT,__stub_helper` alongside `__TEXT,__text` for comprehensive code section coverage.
    
    ### src/lib.rs(MODIFY)
    
    Add `pub mod analysis;` to declare the new analysis module. Re-export key types and functions from the analysis module, such as `pub use analysis::{DisassemblyAnalyzer, CodeReference};` to make them accessible via the library crate root. This maintains the modular public API structure.
    
    ### src/analysis/mod.rs(NEW)
    
    References: 
    
    - src/types.rs(MODIFY)
    
    Define the `DisassemblyAnalyzer` struct to hold Capstone engine and address resolution state. Implement `new(architecture: Architecture) -> Result<Self>` to initialize Capstone with appropriate mode (e.g., x86 mode 32/64, arm/arm64). Provide `analyze(&self, data: &[u8], container: &ContainerInfo) -> Result<Vec<CodeReference>>` for linear sweep over executable sections, extracting references. Include error handling for unsupported arches.
    
    ### src/analysis/reference_extractor.rs(NEW)
    
    References: 
    
    - src/types.rs(MODIFY)
    
    Create a module for instruction operand analysis. Implement `extract_references(instr: &Instruction) -> Vec<u64>` to parse immediates and displacements for target instructions: x86 LEA/MOV/PUSH with offsets, RIP-relative; ARM ADR/ADRP/LDR PC-relative. Resolve effective addresses using instruction address and operand details. Define `ReferenceType` enum (Direct, Relative, Immediate) for metadata. Focus on patterns likely referencing strings.
    
    ### src/analysis/address_resolver.rs(NEW)
    
    References: 
    
    - src/types.rs(MODIFY)
    
    Implement `AddressResolver` struct built from `ContainerInfo` sections, mapping RVAs to offsets and vice versa. Methods: `rva_to_offset(&self, rva: u64) -> Option<u64>`, `offset_to_rva(&self, offset: u64) -> Option<u64>`, `resolve_target(&self, instr_addr: u64, operand: &Operand) -> Option<u64>` for RIP/PC-relative calculations. Handle relocations minimally for now, assuming flat address space.
    
    ### src/analysis/linear_sweep.rs(NEW)
    
    References: 
    
    - src/types.rs(MODIFY)
    - src/analysis/reference_extractor.rs(NEW)
    - src/analysis/address_resolver.rs(NEW)
    
    Provide `perform_sweep(data: &[u8], section: &SectionInfo, analyzer: &DisassemblyAnalyzer) -> Result<Vec<CodeReference>>`. Iterate bytes in section, disassemble sequentially with Capstone, call reference extraction on each valid instruction, resolve addresses, and collect references with instruction RVA. Skip invalid instructions, log errors. This realizes the linear sweep without control flow analysis.
    
    ### src/extraction/mod.rs(MODIFY)
    
    References: 
    
    - src/types.rs(MODIFY)
    - src/analysis/mod.rs(NEW)
    
    Implement basic string extraction framework: `extract_strings(data: &[u8], container: &ContainerInfo) -> Result<Vec<FoundString>>`. Scan sections by weight, detect ASCII/UTF8/UTF16 strings (min length 4), assign sources, sections, offsets/RVAs. After extraction, if `container.architecture.is_some()`, instantiate `DisassemblyAnalyzer`, run analysis, cross-reference targets with string offsets/RVAs (tolerance ±8 bytes), update `FoundString.code_references` and `is_code_referenced`. Boost score by 50 for referenced strings.
    
    ### src/main.rs(MODIFY)
    
    References: 
    
    - src/extraction/mod.rs(MODIFY)
    
    Add CLI flag `--disassemble` or `-d` to Clap for optional disassembly. In the main logic, after parsing container, if flag set and architecture detected, proceed with disassembly-integrated extraction; else, use basic extraction without analysis. Update help text to explain the flag enables code reference detection at performance cost.
    
    ### tests/integration_disasm.rs(NEW)
    
    References: 
    
    - src/extraction/mod.rs(MODIFY)
    - src/analysis/mod.rs(NEW)
    - src/types.rs(MODIFY)
    
    Add integration tests using sample binaries (create or use fixtures) for ELF/PE/Mach-O with known code-string references (e.g., LEA to string literal). Verify architecture detection, disassembly coverage, reference extraction accuracy, and flagging in `FoundString`. Test unsupported arch fallback, error handling, and score boosting. Use insta snapshots for output validation.
    
    ### README.md(MODIFY)
    
    References: 
    
    - src/main.rs(MODIFY)
    
    Update the features section to highlight the new Capstone disassembly pass for identifying code-referenced strings, improving relevance scoring. Add usage example with `--disassemble` flag. Mention supported architectures and performance note. Expand the architecture overview to include the analysis module.
    
    ### docs/src/architecture.md(MODIFY)
    
    References: 
    
    - src/analysis/mod.rs(NEW)
    
    If the docs exist, add a section on the Analysis Module describing Capstone integration, linear sweep process, reference extraction, and integration with extraction/scoring. Update data flow diagram to show disassembly pass post-container parsing, pre-output. Include architecture detection details and reference types.

    Developer Humor

    🛠️ Stringy's New Trick 🛠️\n>\n> Why did the disassembler go to therapy?\n> It had too many relative issues with RIP!\n> But with Capstone, it finally found its address.\n>\n> 🎉 Now strings are truly referenced! 🎉


    Execution Information

    Branch: main
    Commit: 37cfc7c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions