### Sample Configuration Example Source: https://github.com/joxeankoret/diaphora/blob/master/tester/README.md Example of a sample configuration file (ls.cfg). It defines test case parameters, expected export values, and diffing settings. ```ini ################################################################################ # Test-case for some Linux ELF x64 'ls' program ################################################################################ [Testcase] filename=ls export=ls.sqlite ida-binary=idat64 decompiler=1 script= [Export] total basic blocks=3635 total bblocks instructions=86208 total bblocks relations=15831 total call graph items=1004 total constants=358 total functions bblocks=8562 total functions=318 total instructions=16225 total program items=1 total program data items=43 call graph primes=9.983313005596550880312916944E+365 compilation units=11 named compilation units=2 total microcode basic blocks=4875 total microcode instructions=69983 [Diff] against=ls-old.sqlite output=ls-vs-ls-old.db best=132 partial=101 unreliable=0 multimatches=3 ``` -------------------------------- ### Tester Configuration Example Source: https://github.com/joxeankoret/diaphora/blob/master/tester/README.md This is an example of the tester.cfg file. Configure paths to your samples, Diaphora script, IDA, and Python. Adjust the number of CPUs for parallel processing. ```ini [General] samples-directory=/shared/samples/ diaphora-script=/shared/diaphora/diaphora.py cpus=1 [IDA] path=/shared/ida/ida83/ [Python] path=/usr/bin/python3.10 ``` -------------------------------- ### Ratio-Based Heuristic with Minimum Threshold Example Source: https://github.com/joxeankoret/diaphora/blob/master/HACKING.md This example demonstrates a heuristic that uses a ratio-based comparison with a minimum threshold for accepting partial matches. It considers constant values and node counts. ```python NAME = "Same rare constant and node count" HEURISTICS.append({ "name":NAME, "category":"Partial", "ratio":HEUR_TYPE_RATIO_MAX, "sql": மாதிரி"select " + get_query_fields(NAME) + "\n from main.constants mc,\n diff.constants dc,\n main.functions f,\n diff.functions df\n where mc.constant = dc.constant\n and f.id = mc.func_id\n and df.id = dc.func_id\n and f.nodes = df.nodes\n and f.nodes >= 5\n %POSTFIX%\n order by f.source_file = df.source_file", "min":0.5, "flags":[] }) ``` -------------------------------- ### CBinDiff Initialization Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/README.md Illustrates the initialization steps of the CBinDiff class, including database operations, heuristic loading, thread pool setup, and configuration loading. ```text CBinDiff.__init__() ├─ Open/create SQLite database ├─ Load heuristics ├─ Initialize thread pool └─ Load configuration ``` -------------------------------- ### Install Diaphora using Hex-Rays Plugin Manager Source: https://github.com/joxeankoret/diaphora/blob/master/README.md Use this command to install Diaphora directly using the Hex-Rays plugin manager. Ensure you have the manager installed. ```bash hcli plugin install https://github.com/joxeankoret/diaphora/archive/refs/tags/3.4.1.zip ``` -------------------------------- ### Minimal No-False-Positives Heuristic Example Source: https://github.com/joxeankoret/diaphora/blob/master/HACKING.md An example of a simple heuristic that uses exact byte hash and node count for matching. It's categorized as 'Best' and includes a flag for same CPU architecture. ```python NAME = "Same bytes hash and node count" HEURISTICS.append({ "name":NAME, "category":"Best", "ratio":HEUR_TYPE_NO_FPS, "sql": மாதிரி"select distinct " + get_query_fields(NAME) + "\n from functions f,\n diff.functions df\n where f.bytes_hash = df.bytes_hash\n and f.nodes = df.nodes\n and f.nodes >= 3\n %POSTFIX%", "flags":[HEUR_FLAG_SAME_CPU] }) ``` -------------------------------- ### Comprehensive Analysis Configuration Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/configuration.md Example configuration for comprehensive analysis. Enable unreliable, experimental, and slow heuristics, and increase row limits. ```python DIFFING_ENABLE_UNRELIABLE = True DIFFING_ENABLE_EXPERIMENTAL = True DIFFING_ENABLE_SLOW_HEURISTICS = True SQL_TIMEOUT_LIMIT = 600 SQL_MAX_PROCESSED_ROWS = 5000000 ML_USE_TRAINED_MODEL = True ``` -------------------------------- ### Implement Diaphora Diff Start Hook Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/scripting-and-hooks.md The `on_diff_start` hook is executed at the beginning of the diffing process. It's used here to initialize custom statistics and enable experimental features. ```python # ============================================================================ # HOOKS # ============================================================================ def on_diff_start(bindiff): """Initialize for firmware patching analysis.""" print("[Firmware] Starting patch analysis...") # Use relaxed ratio for feature detection bindiff.relaxed_ratio = False bindiff.experimental = True # Store stats bindiff.custom_stats = { "matches_by_heur": {}, "security_matches": [] } ``` -------------------------------- ### Configuration-Based Script Loading Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/scripting-and-hooks.md This example shows how to configure script loading using a `diaphora_config.py` file. It demonstrates setting the `PROJECT_SCRIPT` variable at the top level of the configuration file and then loading it within the Diaphora instance. ```python # At top level (not in default settings) import os PROJECT_SCRIPT = os.path.join( os.path.dirname(__file__), "project_hooks.py" ) ``` ```python bindiff.project_script = PROJECT_SCRIPT bindiff.load_hooks() ``` -------------------------------- ### Fast Patch Diffing Configuration Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/configuration.md Example configuration for fast patch diffing. Set unreliable, experimental, and slow heuristics to False. ```python DIFFING_ENABLE_UNRELIABLE = False DIFFING_ENABLE_EXPERIMENTAL = False DIFFING_ENABLE_SLOW_HEURISTICS = False SQL_TIMEOUT_LIMIT = 60 SQL_MAX_PROCESSED_ROWS = 100000 ``` -------------------------------- ### Patch Diffing with Symbols Configuration Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/configuration.md Example configuration for patch diffing with symbols. Enable relaxed ratio and set a minimum percentage for symbol diffing speedup. ```python DIFFING_ENABLE_RELAXED_RATIO = True IGNORE_ALL_NAMES = False SPEEDUP_PATCH_DIFF_SYMBOLS_MIN_PERCENT = 90.0 ``` -------------------------------- ### Initialize CBinDiff Instance Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-cbindiff.md Instantiate CBinDiff to start a new binary diffing session. Use ':memory:' for temporary in-memory databases or a file path for persistent storage. ```python from diaphora import CBinDiff # Create in-memory database (for command-line diffing) bindiff = CBinDiff(":memory:") # Create file-based database bindiff = CBinDiff("mydiff.db") ``` -------------------------------- ### IDA Project Script Hooks Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-ida-integration.md Define custom hooks for Diaphora's IDA integration within your project's script. This example shows how to set up handlers for the start and end of a diff, and when a match is found. ```python # Example project_script.py HOOKS = { "DiaphoraHooks": { "on_diff_start": lambda bindiff: None, "on_diff_end": lambda bindiff: None, "on_match_found": lambda bindiff, main_row, diff_row, ratio: None, } } ``` -------------------------------- ### Performing Database Queries in Hooks Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/scripting-and-hooks.md This example shows how to execute custom SQL queries on the diff database from within a hook function. It demonstrates fetching the top 20 most complex functions based on their block count and closing the database cursor. ```python def on_diff_end(bindiff): """List all matched functions with details.""" cur = bindiff.db_cursor() try: sql = """ SELECT f.name, f.address, f.nodes, f.instructions FROM functions f ORDER BY f.nodes DESC LIMIT 20 """ cur.execute(sql) print("Top 20 functions by complexity:") for name, addr, nodes, insns in cur.fetchall(): print(f" {name} @ {addr}: {nodes} blocks, {insns} insns") finally: cur.close() ``` -------------------------------- ### Example Heuristic Definition Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/types.md An example of how to define a heuristic for Diaphora, specifically for comparing byte hashes of functions. This heuristic uses the HEUR_TYPE_NO_FPS ratio and includes the HEUR_FLAG_SAME_CPU flag. ```python HEURISTICS.append({ "name": "Bytes Hash", "category": "Best", "ratio": HEUR_TYPE_NO_FPS, "sql": """SELECT {fields} FROM functions f, diff.functions df WHERE f.bytes_hash = df.bytes_hash AND f.nodes >= 3 %POSTFIX%""", "flags": [HEUR_FLAG_SAME_CPU] }) ``` -------------------------------- ### Python f-string Formatting Source: https://github.com/joxeankoret/diaphora/blob/master/HACKING.md Prefer f-strings for new code for string formatting. This example shows formatting an address and a hexadecimal value. ```python log(f"Processing function {name} at 0x{ea:08x}") ``` -------------------------------- ### IDA Pro Integration with CIDABinDiff Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/README.md Integrate Diaphora with IDA Pro using the CIDABinDiff class. This example covers exporting the current IDA database and performing diffing. ```python from diaphora_ida import CIDABinDiff # Within IDA ida_diff = CIDABinDiff("myanalysis.db") # Export current IDA database ida_diff.do_export() # Perform diffing ida_diff.diff("patch.db") # Display results (automatic) ida_diff.show_choosers() ``` -------------------------------- ### Match Result Tuple Example Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/types.md Demonstrates how to access specific elements from a match result tuple using the defined indices. This is useful for extracting primary function addresses or similarity ratios. ```python match = ("0x401000", "main", "0x5001000", "main", 1.0, "Same RVA and hash") primary_ea = match[0] ratio = match[4] ``` -------------------------------- ### Get Control Flow Graph Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-cbindiff.md Builds a control flow graph for a given function address. Supports loading from primary or diff databases and different assembly types. ```python def get_graph(self, ea1, primary=False, asm_type="native") ``` -------------------------------- ### Transaction Management: commit_and_start_transaction Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-ida-integration.md Commits the current transaction to the database and starts a new one, managing SQLite pragmas according to the Diaphora configuration. ```APIDOC ## commit_and_start_transaction() ### Description Commit current transaction and start a new one. ### Parameters None ### Returns None ### Notes Handles SQLite pragma configuration based on `diaphora_config.py` settings: - `SQLITE_JOURNAL_MODE`: WAL, DELETE, TRUNCATE, etc. - `SQLITE_PRAGMA_SYNCHRONOUS`: Synchronization level ``` -------------------------------- ### Querying Diaphora Database Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/README.md Execute custom SQL queries against the Diaphora analysis database. This example demonstrates fetching function names, addresses, and instruction counts. ```python bindiff = CBinDiff("mydb.db") cur = bindiff.db_cursor() try: cur.execute(""" SELECT name, address, nodes, instructions FROM functions WHERE instructions > 100 ORDER BY nodes DESC LIMIT 10 """) for name, addr, nodes, insns in cur.fetchall(): print(f"{name} @ {addr}: {nodes} blocks, {insns} instructions") finally: cur.close() ``` -------------------------------- ### Querying Function Data Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/types.md Demonstrates how to query the Diaphora database for function rows and access their data. The example shows fetching functions by name and accessing fields like 'name', 'nodes', and 'assembly'. ```python cur = bindiff.db_cursor() cur.execute("SELECT * FROM functions WHERE name LIKE ?", ("%main%",)) for row in cur.fetchall(): # row is dict-like name = row["name"] nodes = row["nodes"] assembly = row["assembly"] ``` -------------------------------- ### Get SQL Query Fields for Heuristics Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-utilities.md Generates a SQL SELECT field list for heuristic queries. Use this function to dynamically create SQL queries that include heuristic descriptions. ```python def get_query_fields(heur, quote=True) ``` ```python from diaphora_heuristics import get_query_fields fields = get_query_fields("My Heuristic") sql = f"SELECT {fields} FROM functions f, diff.functions df WHERE ..." ``` -------------------------------- ### CREATE TABLE bb_instructions Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/database-schema.md Maps individual instructions to their respective basic blocks. Contains row ID, basic block ID, and instruction ID. ```sql CREATE TABLE bb_instructions ( id INTEGER PRIMARY KEY, basic_block_id INTEGER REFERENCES basic_blocks(id), instruction_id INTEGER REFERENCES instructions(id) ) ``` -------------------------------- ### Commit and Start SQLite Transaction Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-ida-integration.md Commits the current SQLite transaction and starts a new one. It configures SQLite pragmas based on settings in `diaphora_config.py` for journal mode and synchronization. ```python def commit_and_start_transaction(self) ``` -------------------------------- ### Implement on_diff_start Hook Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/scripting-and-hooks.md This hook is called when diffing begins. Use it to initialize state or load data. ```python def on_diff_start(bindiff): print("Diffing started") bindiff.slow_heuristics = False # Fast mode ``` -------------------------------- ### Running the Testing Suite Source: https://github.com/joxeankoret/diaphora/blob/master/tester/README.md Execute the tester.py script to run the testing suite. By default, it exports and then diffs all samples. Use arguments like -el for export only or -dl for diff only. ```bash $ ./tester.py ``` ```bash $ ./tester.py -el ``` ```bash $ ./tester.py -dl ``` ```bash $ ./tester.py ls.cfg ``` -------------------------------- ### Get Prime Factorization as Dictionary Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-utilities.md Returns the prime factorization of a number as a dictionary where keys are prime factors and values are their corresponding exponents. ```python factorization(72) # {2: 3, 3: 2} # 2^3 * 3^2 ``` -------------------------------- ### Get CFG for Function Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/database-schema.md Retrieve the basic block IDs and their addresses for a given function ID to reconstruct its Control Flow Graph. ```sql SELECT fb.basic_block_id, bb.address FROM function_bblocks fb JOIN basic_blocks bb ON fb.basic_block_id = bb.id WHERE fb.function_id = 42; ``` -------------------------------- ### Run Diaphora for Batch Diffing (using command-line arguments) Source: https://github.com/joxeankoret/diaphora/wiki/How-can-I-automate-the-diffing-process? Alternatively, run Diaphora for batch diffing by providing database paths and output file directly as command-line arguments. ```bash python /path/to/diaphora/diaphora.py first.db second.db -o output.db ``` -------------------------------- ### CREATE TABLE instructions Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/database-schema.md Stores details for individual instructions, including function ID, address, disassembly, mnemonic, comments, operand information, and assembly type. ```sql CREATE TABLE instructions ( id INTEGER PRIMARY KEY, func_id INTEGER NOT NULL, address TEXT, disasm TEXT, mnemonic TEXT, comment1 TEXT, comment2 TEXT, operand_names TEXT, name TEXT, type TEXT, pseudocomment TEXT, pseudoitp INTEGER, asm_type TEXT ) ``` -------------------------------- ### Customize Exported Function Data with Hooks Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/scripting-and-hooks.md The `on_function_export` hook allows modification of function data before it is exported. This example annotates security-critical functions with a comment. ```python # ============================================================================ # EXPORT HOOK (IDA-specific) # ============================================================================ def on_function_export(bindiff, func_ea, func_data): """Customize exported function data.""" # Annotate security-critical functions func_name = func_data.get("name", "") if "check" in func_name or "verify" in func_name: if "comment" not in func_data: func_data["comment"] = "[SECURITY] Potential security check" return func_data ``` -------------------------------- ### CREATE TABLE program Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/database-schema.md Defines the table for storing binary-level metadata, including callgraph information, processor type, and MD5 hash. ```sql CREATE TABLE program ( id INTEGER PRIMARY KEY, callgraph_primes TEXT, callgraph_all_primes TEXT, processor TEXT, md5sum TEXT ) ``` -------------------------------- ### Implement on_heuristic_start Hook Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/scripting-and-hooks.md Called before executing each heuristic. Use to log progress or skip specific heuristics. ```python def on_heuristic_start(bindiff, heur_name): pass ``` -------------------------------- ### ML Support Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-utilities.md Provides optional machine learning capabilities for match prediction. This includes functions to extract ML features and a flag to check ML dependency installation. ```APIDOC ## ML Support (Optional) ### ml.basic_engine **Location:** `ml/basic_engine.py` Machine learning classification for match prediction (optional feature). | Function | |----------| | `get_model_comparison_data()` | Extract ML features from function pair | | `ML_AVAILABLE` | Boolean flag if ML dependencies installed | ``` -------------------------------- ### Define Custom Heuristics in Python Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/heuristics.md Define project-specific heuristics in a Python script. This example shows how to create a custom heuristic named 'My Custom Heuristic' and register it. ```python # project_heuristics.py from diaphora_heuristics import ( HEUR_TYPE_RATIO, HEUR_FLAG_SLOW, get_query_fields ) CUSTOM_HEURISTICS = [ { "name": "My Custom Heuristic", "category": "Best", "ratio": HEUR_TYPE_RATIO, "sql": "SELECT {fields} FROM functions f, diff.functions df WHERE %POSTFIX%".format(fields=get_query_fields("My Custom Heuristic")), "flags": [HEUR_FLAG_SLOW], } ] # Register in project script hooks Hooks = { "DiaphoraHooks": { "heuristics": CUSTOM_HEURISTICS, } } ``` -------------------------------- ### Initialize CIDABinDiff Instance Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-ida-integration.md Initializes an IDA-integrated binary diffing instance. Specify the path to the SQLite database or use ':memory:' for an in-memory database. ```python from diaphora_ida import CIDABinDiff ida_diff = CIDABinDiff("myanalysis.db") ida_diff.diff("patch.db") ida_diff.show_choosers() ``` -------------------------------- ### CBinDiff Constructor Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-cbindiff.md Initializes a new binary diffing instance with a specified database name and an optional chooser class. ```APIDOC ## `__init__(db_name, chooser=CChooser)` ### Description Initialize a new binary diffing instance. ### Parameters #### Path Parameters - **db_name** (str) - Required - Path to SQLite database file (use `:memory:` for in-memory) - **chooser** (type) - Optional - Chooser class for displaying results UI. Defaults to `CChooser`. ### Returns None ### Notes The constructor initializes database connections, loads configuration, and prepares heuristics. It automatically creates the database schema and loads saved settings if available. ### Example ```python from diaphora import CBinDiff # Create in-memory database (for command-line diffing) bindiff = CBinDiff(":memory:") # Create file-based database bindiff = CBinDiff("mydiff.db") ``` ``` -------------------------------- ### Configure Project Script via Python Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/scripting-and-hooks.md Set the project script path in a Python configuration file or override it at runtime. ```python # diaphora_config.py or database override project_script = "/path/to/my_project_hooks.py" ``` ```python from diaphora import CBinDiff bindiff = CBinDiff("mydb.db") bindiff.project_script = "/path/to/hooks.py" bindiff.load_hooks() # Manual loading ``` -------------------------------- ### SQL Query Requirements and Placeholders Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/scripting-and-hooks.md Illustrates the requirements for heuristic SQL queries, including the use of `get_query_fields` for standard fields and the `%POSTFIX%` placeholder for size filtering. ```python from diaphora_heuristics import get_query_fields fields = get_query_fields("My Heuristic Name") sql = f""" SELECT {fields} FROM functions f, diff.functions df WHERE %POSTFIX% """ ``` ```sql and f.instructions > 5 and df.instructions > 5 ``` -------------------------------- ### Get Function Row by Name Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-cbindiff.md Retrieves a function's data row from the main or diff database using its name. Useful for looking up function details by identifier. ```python def get_function_row(self, name, db_name="main") ``` -------------------------------- ### Load and Import All Results Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-ida-integration.md Loads diffing results from a specified file and applies all matches to the IDA database. Exits IDA after import. Requires paths to the results file and both databases. ```python def load_and_import_all_results(filename, main_db, diff_db) ``` -------------------------------- ### show_summary() Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-cbindiff.md Displays a summary of the diffing process results, including statistics on matched functions and similarity. ```APIDOC ## show_summary() ### Description Display summary of diffing results. ### Parameters None ### Returns None ### Notes Logs statistics about matched functions, similarity percentages, etc. ``` -------------------------------- ### Enable Import Warnings Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/configuration.md Set to True to display warnings for missing optional libraries, such as cdifflib. ```python SHOW_IMPORT_WARNINGS = True ``` -------------------------------- ### Complete Export and Diff Workflow with CIDABinDiff Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-ida-integration.md Instantiate `CIDABinDiff` to create a diffing instance, load a second database, and perform the diffing operation. Results are automatically displayed in IDA. Access programmatic results via the `all_matches` attribute. ```python from diaphora_ida import CIDABinDiff # Create diffing instance ida_diff = CIDABinDiff("myanalysis.db") # Load second database and perform diffing success = ida_diff.diff("patch.db") # Results displayed automatically in IDA if success: # Access results programmatically best_matches = ida_diff.all_matches["best"] for match in best_matches[:5]: print(f"Match: {match}") ``` -------------------------------- ### Individual Heuristic Steps Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/README.md Outlines the typical workflow for a single heuristic, including query generation, result processing, similarity calculation, and filtering. ```text Each heuristic: 1. Generates SQL query with standard field set 2. Returns function pairs 3. Calculates similarity ratio 4. Applies match filters 5. Adds to appropriate category ``` -------------------------------- ### Get Function Row by Address Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-cbindiff.md Retrieves a function's data row from the main or diff database using its effective address (EA). Useful for looking up function details by memory location. ```python def get_function_row_by_ea(self, ea, db_name="main") ``` -------------------------------- ### Comprehensive Analysis Configuration Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/README.md Presents Python configuration settings for comprehensive analysis, enabling unreliable, experimental, and slow heuristics, along with machine learning model usage. ```python DIFFING_ENABLE_UNRELIABLE = True DIFFING_ENABLE_EXPERIMENTAL = True DIFFING_ENABLE_SLOW_HEURISTICS = True ML_USE_TRAINED_MODEL = True ``` -------------------------------- ### Basic Block Record Schema Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/types.md Defines the structure of a basic block record as stored in the database. This schema includes the block's ID, number within the function, start address, and assembly type. ```python { "id": int, # Database primary key "num": int, # Basic block number in function "address": str, # BB start address (hex string) "asm_type": str, # "native" or "microcode" } ``` -------------------------------- ### Execute Complete Database Diff Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-cbindiff.md Initiates the full diffing process between two databases. Ensure databases are exported from IDA first. ```python def diff(self, db) ``` ```python # Export from IDA first to create primary.db and patch.db bindiff = CBinDiff("results.db") success = bindiff.diff("patch.db") if success: bindiff.show_choosers(False) ``` -------------------------------- ### CREATE TABLE function_bblocks Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/database-schema.md Maps functions to their corresponding basic blocks. Includes function ID, basic block ID, and assembly type. ```sql CREATE TABLE function_bblocks ( id INTEGER PRIMARY KEY, function_id INTEGER NOT NULL REFERENCES functions(id), basic_block_id INTEGER NOT NULL REFERENCES basic_blocks(id), asm_type TEXT ) ``` -------------------------------- ### Define Thread Pool Function Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-utilities.md Applies a function to a list of items in parallel using a thread pool. Exceptions are logged, and results are returned in the original order. Each thread gets an independent database connection. ```python def threads_apply(function, items, max_threads=None) ``` ```python from jkutils.threads import threads_apply def process_heuristic(heur): # Each heuristic runs in its own thread return execute_sql_query(heur['sql']) results = threads_apply(process_heuristic, HEURISTICS, max_threads=4) ``` -------------------------------- ### Get Prime Factorization of a Number Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-utilities.md Computes the prime factors of a given integer. It employs trial division for smaller primes and Pollard's rho algorithm for larger factors. The result can be sorted if requested. ```python primefactors(60) # [2, 2, 3, 5] primefactors(100) # [2, 2, 5, 5] ``` -------------------------------- ### CREATE TABLE program_data Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/database-schema.md Defines the table for a key-value store used for per-database configuration options. ```sql CREATE TABLE program_data ( id INTEGER PRIMARY KEY, name VARCHAR(255), type VARCHAR(255), value TEXT ) ``` -------------------------------- ### Load Runtime Overrides Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/configuration.md Load configuration values from the database using CBinDiff.get_value_for(). These values persist across sessions if saved. ```python bindiff = CBinDiff("myanalysis.db") # These are loaded from the database if saved previously unreliable_enabled = bindiff.unreliable slow_heuristics = bindiff.slow_heuristics export_microcode = bindiff.export_microcode ``` -------------------------------- ### Access and Modify Configuration Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-utilities.md Demonstrates how to read and modify configuration settings for CBinDiff. Configuration changes are session-specific and persist in the database. ```python from diaphora import CBinDiff bindiff = CBinDiff("mydb.db") # Read configuration cpu_count = bindiff.cpu_count use_microcode = bindiff.export_microcode # Modify for this session bindiff.ignore_small_functions = True bindiff.cpu_count = 2 ``` -------------------------------- ### Accessing CBinDiff Instance in Hooks Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/scripting-and-hooks.md This snippet demonstrates how to access and utilize the `bindiff` object within a hook function. It shows examples of performing database operations, configuring diffing parameters, accessing matching results, retrieving function information, and storing custom data. ```python def my_hook(bindiff): # Database operations cur = bindiff.db_cursor() bindiff.open_db() bindiff.attach_database("other.db") # Configuration bindiff.export_microcode = False bindiff.cpu_count = 4 # Results best = bindiff.all_matches["best"] partial = bindiff.all_matches["partial"] # Matching functions row = bindiff.get_function_row("main") row2 = bindiff.get_function_row_by_ea(0x401000) # Custom state bindiff.custom_data = {} # Store arbitrary data ``` -------------------------------- ### SQL Query Optimization Patterns Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/database-schema.md Illustrates common SQL patterns for optimizing queries in Diaphora, such as avoiding Cartesian products and using indexed columns effectively. It also shows how to limit results for performance. ```sql -- Avoid cartesian product SELECT DISTINCT f.id FROM functions f, diff.functions df WHERE f.address = df.address -- Filter early -- Use indexed columns first WHERE f.bytes_hash = '...' AND f.instructions > 5 -- Limit results LIMIT 1000 ``` -------------------------------- ### Run IDA in Batch Mode for Export (IDA 7.0+) Source: https://github.com/joxeankoret/diaphora/wiki/How-can-I-automate-the-diffing-process? Execute IDA in batch mode with the Diaphora script for exporting. Ensure IDA version is 6.8 or higher. ```bash ida -A -B -S/path/to/diaphora.py your_binary ``` ```bash ida64 -A -B -S/path/to/diaphora.py your_binary ``` -------------------------------- ### ast_ratio Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-cbindiff.md Compares abstract syntax trees (ASTs) derived from pseudocode to calculate their similarity. ```APIDOC ## ast_ratio(ast1, ast2) ### Description Compare abstract syntax trees (pseudocode ASTs). ### Method Python (method signature) ### Parameters #### Path Parameters - **ast1** (object) - Required - AST from primary function - **ast2** (object) - Required - AST from diff function ### Response #### Success Response - **Returns:** `float` — Similarity ratio ``` -------------------------------- ### Run IDA in Batch Mode for Export (IDA <= 6.95) Source: https://github.com/joxeankoret/diaphora/wiki/How-can-I-automate-the-diffing-process? Execute IDA in batch mode with the Diaphora script for exporting. Ensure IDA version is 6.8 or higher. ```bash idaq -A -B -S/path/to/diaphora.py your_binary ``` ```bash idaq64 -A -B -S/path/to/diaphora.py your_binary ``` -------------------------------- ### Run Diaphora for Batch Diffing (using environment variables) Source: https://github.com/joxeankoret/diaphora/wiki/How-can-I-automate-the-diffing-process? Execute the main Diaphora script to perform diffing using the previously set environment variables. ```bash python /path/to/diaphora/diaphora.py ``` -------------------------------- ### Optimize Hook Performance by Caching Results Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/scripting-and-hooks.md Compares a suboptimal approach of querying the database for each match with an optimized version that caches a computed value in on_diff_start and reuses it in on_match_found. ```python # BAD: Query database for each match def on_match_found(bindiff, heur, ratio, main_row, diff_row): sql = "SELECT COUNT(*) FROM functions WHERE nodes > ?" cur = bindiff.db_cursor() cur.execute(sql, (10,)) count = cur.fetchone()[0] cur.close() return count > 0 ``` ```python # GOOD: Cache the result def on_diff_start(bindiff): cur = bindiff.db_cursor() cur.execute("SELECT COUNT(*) FROM functions WHERE nodes > ?", (10,)) bindiff.complex_funcs_count = cur.fetchone()[0] cur.close() def on_match_found(bindiff, heur, ratio, main_row, diff_row): return bindiff.complex_funcs_count > 0 ``` -------------------------------- ### Basic Binary Diffing with CBinDiff Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/README.md Perform binary diffing using the CBinDiff class. This snippet shows how to initialize the class, perform the diff, and access/save the results. ```python from diaphora import CBinDiff # Create diffing instance bindiff = CBinDiff("results.db") # Perform diffing success = bindiff.diff("patch.db") if success: # Access results best_matches = bindiff.all_matches["best"] print(f"Found {len(best_matches)} best matches") # Save results bindiff.save_results("analysis.diaphora") ``` -------------------------------- ### Fast Patch Diffing Configuration Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/README.md Provides Python configuration settings optimized for fast patch diffing, disabling unreliable and experimental features, and setting a moderate SQL timeout. ```python DIFFING_ENABLE_UNRELIABLE = False DIFFING_ENABLE_EXPERIMENTAL = False DIFFING_ENABLE_SLOW_HEURISTICS = False SQL_TIMEOUT_LIMIT = 60 ``` -------------------------------- ### CREATE TABLE version Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/database-schema.md Defines the table for storing the schema version information. This value must match between databases being compared. ```sql CREATE TABLE version ( value TEXT ) ``` -------------------------------- ### Check Schema Version Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/database-schema.md Use this SQL query to verify the current schema version of the database. The value must match the expected version for compatibility. ```sql SELECT value FROM version; -- Should be "3.4" ``` -------------------------------- ### Display Diffing Summary Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-cbindiff.md Logs statistics about matched functions and similarity percentages. Call this after performing a diff to review the results. ```python def show_summary(self) ``` -------------------------------- ### load_and_import_all_results(filename, main_db, diff_db) Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-ida-integration.md Loads diffing results from a specified file and applies all matches to the IDA database. This function exits IDA after the import process. ```APIDOC ## load_and_import_all_results(filename, main_db, diff_db) ### Description Load results and apply all matches to IDA database. ### Method ```python def load_and_import_all_results(filename, main_db, diff_db) ``` ### Parameters #### Path Parameters - **filename** (str) - Required - Path to .diaphora results file - **main_db** (str) - Required - Path to primary exported database - **diff_db** (str) - Required - Path to secondary exported database ### Returns None ### Notes Exits IDA after import. ``` -------------------------------- ### CIDABinDiff Constructor Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-ida-integration.md Initializes an IDA-integrated binary diffing instance. It extends CBinDiff with IDA-specific functionality for GUI integration, function export, and IDA-native features. ```APIDOC ## __init__(db_name) ### Description Initialize IDA-integrated binary diffing instance. ### Parameters #### Path Parameters - **db_name** (str) - Required - Path to SQLite database (use ":memory:" for in-memory) ### Returns None ### IDA Features Enabled - Automatic name resolution using IDA's Names() - Memory range detection (min_ea, max_ea) - Microcode instruction extraction - Decompiler integration ### Example ```python from diaphora_ida import CIDABinDiff ida_diff = CIDABinDiff("myanalysis.db") ida_diff.diff("patch.db") ida_diff.show_choosers() ``` ``` -------------------------------- ### Python Class Initialization Source: https://github.com/joxeankoret/diaphora/blob/master/HACKING.md Initialize all attributes in the __init__ method for explicit inheritance. Do not rely on implicit object base class. ```python class CMyClass(CBaseClass): def __init__(self): self.some_attr = None self.items = [] ``` -------------------------------- ### Compare Abstract Syntax Trees Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-cbindiff.md Compares abstract syntax trees (ASTs) derived from pseudocode. This method is useful for comparing the structural representation of code logic. ```python def ast_ratio(self, ast1, ast2) ``` -------------------------------- ### Find Functions by Hash Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/database-schema.md Use this query to locate functions within the database based on their byte hash. ```sql SELECT id, name, address FROM functions WHERE bytes_hash = 'abc123...'; ``` -------------------------------- ### Import Diff Results in Batch Mode with IDA Source: https://github.com/joxeankoret/diaphora/wiki/How-can-I-automate-the-diffing-process? Use this command to load and import diffing results into an IDA session in batch mode. ```bash ida64 -A -S"/path/to/diaphora_load_and_import.py output.db first.db second.db" your_binary.i64 ``` -------------------------------- ### Compare Control Flow Graphs Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-cbindiff.md Compares two control flow graphs using sequence matching. This method is suitable for comparing the structural similarity of functions. ```python def compare_graphs(self, g1, g2) ``` -------------------------------- ### Large Database Configuration Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/README.md Offers Python configuration settings suitable for large databases (over 100K functions), prioritizing function summaries, disabling microcode export, and increasing the SQL timeout limit. ```python EXPORTING_FUNCTION_SUMMARIES_ONLY = True EXPORTING_USE_MICROCODE = False MIN_FUNCTIONS_TO_DISABLE_SLOW = 50000 SQL_TIMEOUT_LIMIT = 600 ``` -------------------------------- ### Configure SQLite Pragmas Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/configuration.md Set SQLite journal mode and synchronous level for performance and data integrity. `SQLITE_JOURNAL_MODE` can be set to "WAL" for better concurrency, or "OFF" for maximum speed at the risk of data loss. `SQLITE_PRAGMA_SYNCHRONOUS` controls the sync level, with "1" being a common balance. ```python SQLITE_JOURNAL_MODE = "WAL" SQLITE_PRAGMA_SYNCHRONOUS = "1" ``` -------------------------------- ### ML Model Configuration Options Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/configuration.md Configuration settings for the machine learning model used in Diaphora. These options control whether to use a trained model, its path, match score thresholds, and debugging output. ```python ML_USE_TRAINED_MODEL = False ML_TRAINED_MODEL = os.path.join(CONFIGURATION_DIRECTORY, "ml/diaphora-amalgamation-model.pkl") ML_TRAINED_MODEL_MATCH_SCORE = 0.15 ML_DEBUG_SHOW_MATCHES = True ``` -------------------------------- ### Manual Script Loading Programmatically Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/scripting-and-hooks.md This snippet illustrates how to load a Diaphora script manually by instantiating `CBinDiff` and setting the `project_script` attribute. It includes error handling for the `load_hooks` method. ```python from diaphora import CBinDiff bindiff = CBinDiff("mydb.db") bindiff.project_script = "/path/to/hooks.py" if not bindiff.load_hooks(): print("Error loading hooks!") exit(1) # Proceed with diffing bindiff.diff("patch.db") ``` -------------------------------- ### Graph Comparison Parameters Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/configuration.md Configuration for graph-based comparison heuristics. These constants define the minimum number of basic blocks and the maximum allowed percentage difference in basic blocks for diffing-based matches. ```python DIFFING_MATCHES_MIN_BBLOCKS = 3 DIFFING_MATCHES_MAX_DIFFERENT_BBLOCKS_PERCENT = 25 ``` -------------------------------- ### Enable IDA Workaround Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/configuration.md Enable this workaround for a known IDA bug related to large tinfo_t structures. ```python DIAPHORA_WORKAROUND_MAX_TINFO_T = False ``` -------------------------------- ### diff Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-ida-integration.md Executes the diffing process and displays the results within IDA Pro. ```APIDOC ## diff(db) ### Description Execute diffing and display results in IDA. This function shows a wait box during the process and automatically displays choosers if matches are found. ### Method ```python def diff(self, db) ``` ### Parameters #### Path Parameters - **db** (str) - Required - Path to second database to compare ### Request Example ```python success = ida_diff.diff("patch.db") if success: # Matches displayed automatically pass ``` ### Response #### Success Response (bool or None) - **True** on success - **False** on error - **None** if cancelled ``` -------------------------------- ### Configure Decompiler and Microcode Export Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/configuration.md Enable these boolean options to include Hex-Rays pseudo-code and microcode in the export. This provides more detailed information but increases export time and size. ```python EXPORTING_USE_DECOMPILER = True EXPORTING_USE_MICROCODE = True ``` -------------------------------- ### Patch Diffing Optimization Settings Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/configuration.md Configuration for optimizing patch diffing. These constants define the percentage of matched functions required to enable speedups for stripped binaries and patch diffing with symbols, as well as the minimum ratio for matching renamed functions. ```python SPEEDUP_STRIPPED_BINARIES_MIN_PERCENT = 99.0 SPEEDUP_PATCH_DIFF_SYMBOLS_MIN_PERCENT = 90.0 SPEEDUP_PATCH_DIFF_RENAMED_FUNCTION_MIN_RATIO = 0.6 ``` -------------------------------- ### compare_graphs Source: https://github.com/joxeankoret/diaphora/blob/master/_autodocs/api-reference-cbindiff.md Compares two control flow graphs (CFGs) using sequence matching to determine their similarity. ```APIDOC ## compare_graphs(g1, g2) ### Description Compare control flow graphs using sequence matching. ### Method Python (method signature) ### Parameters #### Path Parameters - **g1** (list) - Required - Control flow graph from primary function - **g2** (list) - Required - Control flow graph from diff function ### Response #### Success Response - **Returns:** `float` — Graph similarity ratio ```