### Start Local Development Server Source: https://github.com/clearbluejar/ghidriff/blob/main/www/README.md Starts a local development server that reflects changes live without requiring a restart. ```bash $ yarn start ``` -------------------------------- ### Install Dependencies Source: https://github.com/clearbluejar/ghidriff/blob/main/www/README.md Run this command to install all project dependencies using Yarn. ```bash $ yarn ``` -------------------------------- ### GhidraDiffEngine.__init__() Source: https://context7.com/clearbluejar/ghidriff/llms.txt Initializes the GhidraDiffEngine, starts the Ghidra JVM, configures memory, and sets up logging. Requires GHIDRA_INSTALL_DIR to be set. ```APIDOC ## GhidraDiffEngine.__init__() ### Description Instantiates the diff engine, starts the Ghidra JVM via `pyghidra`, configures JVM memory settings, sets up logging, and stores all configuration options. This is the constructor for both `VersionTrackingDiff`, `SimpleDiff`, and `StructualGraphDiff`. Requires `GHIDRA_INSTALL_DIR` to be set in the environment. ### Parameters - **args** (object) - Parsed command-line arguments including binary paths. - **verbose** (bool) - Enable verbose output. - **threaded** (bool) - Use multi-threading for analysis and diffing. - **max_ram_percent** (float) - Maximum percentage of host RAM the JVM can use. - **print_jvm_flags** (bool) - Print JVM flags. - **jvm_args** (list[str]) - Extra JVM arguments (e.g., `["-Xmx8G"]`). - **force_analysis** (bool) - Re-analyze even if already done. - **force_diff** (bool) - Bypass architecture/symbol mismatch checks. - **verbose_analysis** (bool) - Enable verbose analysis logging. - **no_symbols** (bool) - Disable PDB/symbol server lookups. - **engine_log_path** (Path) - Path to the engine's log file. - **engine_log_level** (str) - Logging level for the engine. - **engine_file_log_level** (str) - Logging level for the engine's file output. - **min_func_len** (int) - Minimum function length in bytes to consider. - **use_calling_counts** (bool) - Use calling counts for analysis. - **bsim** (bool) - Enable BSIM fuzzy matching correlator. - **bsim_full** (bool) - Enable full BSIM matching. - **gdts** (list[str]) - List of .gdt data type archive paths. - **base_address** (int | None) - Override image base address (e.g., 0x80000). - **program_options** (str | None) - Path to JSON file with custom analyzer settings. - **decompiler_timeout** (int) - Timeout in seconds for the decompiler. ### Request Example ```python import os from pathlib import Path from ghidriff import VersionTrackingDiff, get_parser from ghidriff import GhidraDiffEngine os.environ["GHIDRA_INSTALL_DIR"] = "/path/to/ghidra_12.0.4_PUBLIC" parser = get_parser() GhidraDiffEngine.add_ghidra_args_to_parser(parser) args = parser.parse_args(["old.bin", "new.bin"]) engine = VersionTrackingDiff( args=args, verbose=True, threaded=True, max_ram_percent=60.0, print_jvm_flags=False, jvm_args=[], force_analysis=False, force_diff=False, verbose_analysis=False, no_symbols=False, engine_log_path=Path("ghidriffs/ghidriff.log"), engine_log_level="INFO", engine_file_log_level="INFO", min_func_len=10, use_calling_counts=False, bsim=True, bsim_full=False, gdts=[], base_address=None, program_options=None, decompiler_timeout=60, ) ``` ``` -------------------------------- ### Setup Persistent Store for Contact Metadata Source: https://github.com/clearbluejar/ghidriff/blob/main/www/diffs/Samples/Mac/contacts-sample.md This Objective-C code snippet demonstrates the setup process for a persistent store manager, which is crucial for storing contact metadata. It involves creating a store directory if it doesn't exist and configuring options for adding the persistent store. ```objective-c ulong __CNContactMetadataPersistentStoreManager_setupIfNeeded__ (undefined8 param_1,undefined8 param_2,undefined8 *param_3) { uint uVar1; int iVar2; undefined8 uVar3; undefined8 uVar4; long lVar5; undefined8 uVar6; undefined8 uVar7; undefined8 uVar8; undefined8 extraout_x1; undefined8 extraout_x1_00; ulong uVar9; undefined auVar10 [16]; undefined8 local_98; undefined8 local_90; undefined8 local_88; undefined8 uStack_80; undefined *local_78; undefined *puStack_70; long local_68; local_68 = *(long *)__got::___stack_chk_guard; _objc_msgSend_persistentStoreCoordinator(); uVar3 = __auth_stubs::_objc_retainAutoreleasedReturnValue(); _objc_msgSend_persistentStores(); uVar4 = __auth_stubs::_objc_retainAutoreleasedReturnValue(); lVar5 = _objc_msgSend_count(); __auth_stubs::_objc_release(uVar4); __auth_stubs::_objc_release(uVar3); if (lVar5 == 0) { local_90 = 0; uVar1 = _objc_msgSend_createStoreDirectoryIfNeeded_(param_1,extraout_x1,&local_90); auVar10 = __auth_stubs::_objc_retain(local_90); uVar4 = auVar10._8_8_; uVar3 = auVar10._0_8_; if ((param_3 != (undefined8 *)0x0) && ((uVar1 & 1) == 0)) { auVar10 = __auth_stubs::_objc_retainAutorelease(uVar3); uVar4 = auVar10._8_8_; *param_3 = auVar10._0_8_; } if (uVar1 == 0) { uVar9 = 0; } else { _objc_msgSend_stringByAppendingString_( &cfstringStruct_1d93e3678,uVar4,&cfstringStruct_1d93e36b8); uVar4 = __auth_stubs::_objc_retainAutoreleasedReturnValue(); _objc_msgSend_storeLocation(param_1); auVar10 = __auth_stubs::_objc_retainAutoreleasedReturnValue(); _objc_msgSend_URLByAppendingPathComponent_(auVar10._0_8_,auVar10._8_8_,uVar4); uVar6 = __auth_stubs::_objc_retainAutoreleasedReturnValue(); __auth_stubs::_objc_release(auVar10._0_8_); local_88 = *(undefined8 *)__got::_NSMigratePersistentStoresAutomaticallyOption; uStack_80 = *(undefined8 *)__got::_NSInferMappingModelAutomaticallyOption; local_78 = __got::___kCFBooleanTrue; puStack_70 = __got::___kCFBooleanTrue; _objc_msgSend_dictionaryWithObjects_forKeys_count_( DAT_1d7e28060,extraout_x1_00,&local_78,&local_88,2); uVar7 = __auth_stubs::_objc_retainAutoreleasedReturnValue(); _objc_msgSend_persistentStoreCoordinator(param_1); auVar10 = __auth_stubs::_objc_retainAutoreleasedReturnValue(); local_98 = uVar3; _objc_msgSend_addPersistentStoreWithType_configuration_URL_options_error_( auVar10._0_8_,auVar10._8_8_,*(undefined8 *)__got::_NSSQLiteStoreType,0,uVar6,uVar7, &local_98); lVar5 = __auth_stubs::_objc_retainAutoreleasedReturnValue(); uVar8 = __auth_stubs::_objc_retain(local_98); __auth_stubs::_objc_release(uVar3); __auth_stubs::_objc_release(auVar10._0_8_); if (lVar5 == 0) { __auth_stubs::_objc_opt_class(param_1); _objc_msgSend_os_log(); uVar3 = __auth_stubs::_objc_retainAutoreleasedReturnValue(); ``` -------------------------------- ### Install Ghidriff using uv Source: https://github.com/clearbluejar/ghidriff/blob/main/README.md If using uv for environment management on Linux/Mac, set the GHIDRA_INSTALL_DIR environment variable and then install ghidriff using `uvx`. ```bash export GHIDRA_INSTALL_DIR "/path/to/ghidra/" uvx ghidriff ``` -------------------------------- ### `ghidriff` CLI Examples Source: https://context7.com/clearbluejar/ghidriff/llms.txt Illustrates various command-line invocations for `ghidriff`, covering basic diffs, custom output, firmware analysis, sequential diffs, and Docker usage. ```bash # Basic patch diff between two Windows kernel builds ghidriff ntoskrnl.exe.10.0.22621.1344 ntoskrnl.exe.10.0.22621.1413 ``` ```bash # Specify output directory and engine ghidriff --engine VersionTrackingDiff \ --output-path ./results \ afd.sys.x64.10.0.22621.1028 \ afd.sys.x64.10.0.22621.1415 ``` ```bash # Firmware diff with custom base address (no symbols) ghidriff --ba 0x80000 --no-symbols \ STM32F103C-firmware.bin \ STM32F103Ca-firmware.bin ``` ```bash # Diff multiple versions sequentially with a summary diff of first vs last ghidriff --summary \ clfs.sys.v1 clfs.sys.v2 clfs.sys.v3 ``` ```bash # Increase JVM memory, add side-by-side HTML, use custom GDT ghidriff --max-ram-percent 80 \ --sxs \ --gdt /path/to/windows_types.gdt \ --decompiler-timeout 120 \ tapisrv.dll.old tapisrv.dll.new ``` ```bash # Force re-analysis and ignore symbol count mismatch ghidriff --force-analysis --force-diff \ --log-level DEBUG \ lib.so.1.0 lib.so.1.1 ``` ```bash # Use Docker (no local Ghidra/Java required) docker pull ghcr.io/clearbluejar/ghidriff:latest mkdir -p ghidriffs docker run -it --rm \ -v $(pwd)/ghidriffs:/ghidriffs \ ghcr.io/clearbluejar/ghidriff:latest \ ghidriffs/clfs.sys.x64.10.0.22621.2506 \ ghidriffs/clfs.sys.x64.10.0.22621.2715 ``` -------------------------------- ### CNContactMetadataPersistentStoreManager Setup Cold Path Source: https://github.com/clearbluejar/ghidriff/blob/main/www/diffs/Samples/Mac/contacts-sample.md This snippet shows the cold path invocation for setting up the CNContactMetadataPersistentStoreManager. It includes Objective-C message sends and error handling for loading persistent stores. ```c void ___56__CNContactMetadataPersistentStoreManager_setupIfNeeded__block_invoke_cold_1 (undefined8 param_1,undefined8 param_2,undefined8 param_3) { undefined8 extraout_x1; long lVar1; lVar1 = *(long *)__got::___stack_chk_guard; _objc_msgSend_description(); __auth_stubs::_objc_retainAutoreleasedReturnValue(); _OUTLINED_FUNCTION_0(); _OUTLINED_FUNCTION_1 (&mach_header_194bd8000,extraout_x1,param_3,"Failed to load persistent stores: %@"); __auth_stubs::_objc_release(); if (*(long *)__got::___stack_chk_guard == lVar1) { return; } __auth_stubs::___stack_chk_fail(); return; } ``` -------------------------------- ### GhidraDiffEngine.setup_project() Source: https://context7.com/clearbluejar/ghidriff/llms.txt Creates or opens a Ghidra project, imports binaries, deduplicates them, and optionally sets a custom image base address and configures the symbol server. ```APIDOC ## GhidraDiffEngine.setup_project() ### Description Creates or opens a Ghidra project directory, imports the provided binary files into the project, deduplicates them by SHA-1, optionally sets a custom image base address, and configures the symbol server for PDB downloads. Must be called before `analyze_project()` and `diff_bins()`. ### Parameters - **binary_paths** (list[Path]) - A list of paths to the binary files to import. - **project_location** (Path) - The directory where the Ghidra project will be created or opened. - **project_name** (str) - The name of the Ghidra project. - **symbols_path** (Path) - Directory for local PDB cache. - **gzfs_path** (Path | None) - Optional path to save analyzed GZF snapshots. ### Request Example ```python from pathlib import Path binary_paths = [ Path("afd.sys.x64.10.0.22621.1028"), Path("afd.sys.x64.10.0.22621.1415"), ] project_name = f"ghidriff-{binary_paths[0].name}-{binary_paths[-1].name}" results = engine.setup_project( binary_paths=binary_paths, project_location=Path("ghidriffs/ghidra_projects"), project_name=project_name, symbols_path=Path("ghidriffs/symbols"), gzfs_path=Path("ghidriffs/gzfs"), ) for r in results: print(r) ``` ### Response #### Success Response (200) - **results** (list[list]) - A list where each inner list contains: `[program_name, imported, has_pdb, pdb_loaded, analyzed]` ``` -------------------------------- ### Ghidriff Console Output Example Source: https://github.com/clearbluejar/ghidriff/blob/main/www/docs/guides/Diffing the Windows Kernel.md This is an example of the console output generated by ghidriff during the kernel diffing process. It details the initialization, project setup, file importing, and symbol server configuration. ```console (.env) vscode ➜ /workspaces/ghidriff (main) $ ghidriff ntoskrnl.exe.10.0.22621.1344 ntoskrnl.exe.10.0.22621.1413 INFO | ghidriff | Init Ghidra Diff Engine... INFO | ghidriff | Engine Console Log: INFO INFO | ghidriff | Engine File Log: .ghidriffs/ghidriff.log INFO INFO | ghidriff | Starting Ghidra... INFO Using log config file: jar:file:/ghidra/Ghidra/Framework/Generic/lib/Generic.jar!/generic.log4j.xml (LoggingInitialization) INFO Using log file: /workspaces/ghidriff/.ghidriffs/ghidriff.log (LoggingInitialization) INFO Loading user preferences: /home/vscode/.ghidra/.ghidra_10.2.3_PUBLIC/preferences (Preferences) INFO Class search complete (716 ms) (ClassSearcher) INFO Initializing SSL Context (SSLContextInitializer) INFO Initializing Random Number Generator... (SecureRandomFactory) INFO Random Number Generator initialization complete: NativePRNGNonBlocking (SecureRandomFactory) INFO Trust manager disabled, cacerts have not been set (ApplicationTrustManagerFactory) INFO | ghidriff | GHIDRA_INSTALL_DIR: /ghidra INFO | ghidriff | GHIDRA 10.2.3 Build Date: 2023-Feb-08 1242 EST Release: PUBLIC INFO | ghidriff | Engine Args: INFO | ghidriff | old: ['ntoskrnl.exe.10.0.22621.1344'] INFO | ghidriff | new: [['ntoskrnl.exe.10.0.22621.1413']] INFO | ghidriff | engine: VersionTrackingDiff INFO | ghidriff | output_path: .ghidriffs INFO | ghidriff | summary: False INFO | ghidriff | project_location: .ghidra_projects INFO | ghidriff | project_name: ghidriff INFO | ghidriff | symbols_path: .symbols INFO | ghidriff | threaded: True INFO | ghidriff | force_analysis: False INFO | ghidriff | force_diff: False INFO | ghidriff | no_symbols: False INFO | ghidriff | log_level: INFO INFO | ghidriff | file_log_level: INFO INFO | ghidriff | log_path: ghidriff.log INFO | ghidriff | va: False INFO | ghidriff | max_ram_percent: 60.0 INFO | ghidriff | print_flags: False INFO | ghidriff | jvm_args: None INFO | ghidriff | side_by_side: False INFO | ghidriff | max_section_funcs: 200 INFO | ghidriff | md_title: None INFO | ghidriff | Setting Up Ghidra Project... INFO Creating project: /workspaces/ghidriff/.ghidra_projects/ghidriff-ntoskrnl.exe.10.0.22621.1344-ntoskrnl.exe.10.0.22621.1413/ghidriff-ntoskrnl.exe.10.0.22621.1344-ntoskrnl.exe.10.0.22621.1413 (DefaultProject) INFO | ghidriff | Created project: ghidriff-ntoskrnl.exe.10.0.22621.1344-ntoskrnl.exe.10.0.22621.1413 INFO | ghidriff | Project Location: /workspaces/ghidriff/.ghidra_projects/ghidriff-ntoskrnl.exe.10.0.22621.1344-ntoskrnl.exe.10.0.22621.1413 INFO | ghidriff | Importing ntoskrnl.exe.10.0.22621.1344 INFO Starting cache cleanup: /tmp/vscode-Ghidra/fscache2 (FileCacheMaintenanceDaemon) INFO Finished cache cleanup, estimated storage used: 0 (FileCacheMaintenanceDaemon) INFO Using Loader: Portable Executable (PE) (AutoImporter) INFO | ghidriff | Importing ntoskrnl.exe.10.0.22621.1413 INFO Using Loader: Portable Executable (PE) (AutoImporter) INFO | ghidriff | Setting up Symbol Server for symbols... INFO | ghidriff | path: .symbols level: 1 INFO | ghidriff | Symbol Server Configured path: SymbolServerService: symbolStore: LocalSymbolStore: [ rootDir: /workspaces/ghidriff/.symbols, storageLevel: -1], symbolServers: HttpSymbolServer: [ url: https://msdl.microsoft.com/download/symbols/, storageLevel: -1] HttpSymbolServer: [ url: https://chromium-browser-symsrv.commondatastorage.googleapis.com/, storageLevel: -1] HttpSymbolServer: [ url: https://symbols.mozilla.org/, storageLevel: -1] HttpSymbolServer: [ url: https://software.intel.com/sites/downloads/symbols/, storageLevel: -1] HttpSymbolServer: [ url: https://driver-symbols.nvidia.com/, storageLevel: -1] HttpSymbolServer: [ url: https://download.amd.com/dir/bin/, storageLevel: -1] INFO Connecting to https://msdl.microsoft.com/download/symbols/ (ConsoleTaskMonitor) INFO Success (ConsoleTaskMonitor) INFO Storing ntkrnlmp.pdb in local symbol store (12.66MB) (ConsoleTaskMonitor) INFO | ghidriff | Pdb stored at: /workspaces/ghidriff/.symbols/ntkrnlmp.pdb/FB0913AF0585F234BD64A64A87C62DB11/ntkrnlmp.pdb INFO Connecting to https://msdl.microsoft.com/download/symbols/ (ConsoleTaskMonitor) INFO Success (ConsoleTaskMonitor) INFO Storing ntkrnlmp.pdb in local symbol store (12.66MB) (ConsoleTaskMonitor) ``` -------------------------------- ### Setup Ghidra Project and Import Binaries Source: https://context7.com/clearbluejar/ghidriff/llms.txt Creates or opens a Ghidra project, imports binary files, deduplicates them, and optionally sets a custom image base address and symbol server. This must be called before analysis and diffing. ```python from pathlib import Path binary_paths = [ Path("afd.sys.x64.10.0.22621.1028"), Path("afd.sys.x64.10.0.22621.1415"), ] # project_name will appear as directory under project_location project_name = f"ghidriff-{binary_paths[0].name}-{binary_paths[-1].name}" results = engine.setup_project( binary_paths=binary_paths, project_location=Path("ghidriffs/ghidra_projects"), project_name=project_name, symbols_path=Path("ghidriffs/symbols"), # Local PDB cache directory gzfs_path=Path("ghidriffs/gzfs"), # Optional: save analyzed GZF snapshots ) # results is a list of [program_name, imported, has_pdb, pdb_loaded, analyzed] for r in results: print(r) # ['afd.sys.x64.10.0.22621.1028-a1b2c3', True, True, False, False] # ['afd.sys.x64.10.0.22621.1415-d4e5f6', True, True, False, False] ``` -------------------------------- ### Get Background Color from Contact Image Data Source: https://github.com/clearbluejar/ghidriff/blob/main/www/diffs/Samples/Mac/contacts-sample.md This Objective-C function retrieves the background color from image data associated with a contact. It handles object retention and release, and includes error handling. Ensure proper Objective-C runtime setup. ```objective-c void __CNAggregateContactStore_getBackgroundColorOnImageData_bitmapFormat_error__ (long param_1,undefined8 param_2,undefined8 param_3,undefined8 param_4, undefined8 *param_5) { code *UNRECOVERED_JUMPTABLE; undefined8 uVar1; undefined8 uVar2; long lVar3; undefined8 uVar4; undefined8 uVar5; undefined8 extraout_x1; undefined8 extraout_x1_00; undefined8 uVar6; undefined8 uVar7; long lVar8; long lVar9; ulong unaff_x30; undefined auVar10 [16]; undefined8 local_138; undefined8 local_130; long lStack_128; long *local_120; undefined8 uStack_118; undefined8 local_110; undefined8 uStack_108; undefined8 uStack_100; undefined8 uStack_f8; undefined auStack_f0 [128]; long local_70; local_70 = *(long *)__got::___stack_chk_guard; uVar1 = __auth_stubs::_objc_retain(param_3); uVar2 = __auth_stubs::_objc_retain(param_4); lStack_128 = 0; local_130 = 0; uStack_118 = 0; local_120 = (long *)0x0; uStack_108 = 0; local_110 = 0; uStack_f8 = 0; uStack_100 = 0; auVar10 = __auth_stubs::_objc_retain (*(undefined8 *) \ (param_1 + _OBJC_IVAR___CNAggregateContactStore__contactStores)); uVar4 = auVar10._0_8_; auVar10 = _objc_msgSend_countByEnumeratingWithState_objects_count_ (uVar4,auVar10._8_8_,&local_130,auStack_f0,0x10); if (auVar10._0_8_ == 0) { uVar6 = 0; } else { uVar6 = 0; lVar8 = *local_120; do { uVar5 = auVar10._8_8_; lVar9 = 0; uVar7 = uVar6; do { if (*local_120 != lVar8) { __auth_stubs::_objc_enumerationMutation(uVar4); uVar5 = extraout_x1; } local_138 = uVar7; _objc_msgSend_getBackgroundColorOnImageData_bitmapFormat_error_ (*(undefined8 *)(lStack_128 + lVar9 * 8),uVar5,uVar1,uVar2,&local_138); lVar3 = __auth_stubs::_objc_retainAutoreleasedReturnValue(); uVar6 = __auth_stubs::_objc_retain(local_138); __auth_stubs::_objc_release(uVar7); if (lVar3 != 0) goto LAB_194c21448; lVar9 = lVar9 + 1; uVar7 = uVar6; uVar5 = extraout_x1_00; } while (auVar10._0_8_ != lVar9); auVar10 = _objc_msgSend_countByEnumeratingWithState_objects_count_ (uVar4,extraout_x1_00,&local_130,auStack_f0,0x10); } while (auVar10._0_8_ != 0); } lVar3 = 0; LAB_194c21448: __auth_stubs::_objc_release(uVar4); lVar8 = __auth_stubs::_objc_retain(lVar3); if ((param_5 != (undefined8 *)0x0) && (lVar8 == 0)) { uVar4 = __auth_stubs::_objc_retainAutorelease(uVar6); *param_5 = uVar4; } __auth_stubs::_objc_release(uVar6); __auth_stubs::_objc_release(lVar8); __auth_stubs::_objc_release(uVar2); __auth_stubs::_objc_release(uVar1); if (*(long *)__got::___stack_chk_guard != local_70) { __auth_stubs::___stack_chk_fail(); return; } if (((unaff_x30 ^ unaff_x30 << 1) >> 0x3e & 1) == 0) { __auth_stubs::_objc_autoreleaseReturnValue(lVar8); return; } /* WARNING: Treating indirect jump as call */ UNRECOVERED_JUMPTABLE = (code *)SoftwareBreakpoint(0xc471,0x194c214d8); (*UNRECOVERED_JUMPTABLE)(); return; } ``` -------------------------------- ### Set GHIDRA_INSTALL_DIR and Install Ghidriff on Linux/Mac Source: https://github.com/clearbluejar/ghidriff/blob/main/README.md On Linux or macOS, set the GHIDRA_INSTALL_DIR environment variable using export and then install ghidriff using pip. For macOS, ensure a compatible JDK is installed and remove any quarantine attributes from the Ghidra archive if necessary. ```bash export GHIDRA_INSTALL_DIR "/path/to/ghidra/" pip install ghidriff ``` ```bash xattr -dr com.apple.quarantine /path/to/ghidra_12.0.4_PUBLIC export GHIDRA_INSTALL_DIR "/path/to/ghidra_12.0.4_PUBLIC" pip install ghidriff ``` -------------------------------- ### Detailed Diff for -[CNContactMetadataPersistentStoreManager_initWithStoreLocation:] Source: https://github.com/clearbluejar/ghidriff/blob/main/www/diffs/Samples/Mac/contacts-sample.md This snippet provides a detailed diff of the C code for the -[CNContactMetadataPersistentStoreManager_initWithStoreLocation:] method, highlighting changes in function calls, variable assignments, and block invocation. ```diff --- -[CNContactMetadataPersistentStoreManager_initWithStoreLocation:] +++ -[CNContactMetadataPersistentStoreManager_initWithStoreLocation:] @@ -1,31 +1,49 @@ long __CNContactMetadataPersistentStoreManager_initWithStoreLocation__ (undefined8 param_1,undefined8 param_2,undefined8 param_3) { undefined8 uVar1; long lVar2; - undefined8 uVar3; + long lVar3; undefined8 uVar4; + undefined8 uVar5; + undefined *local_70; + undefined8 local_68; + code *local_60; + undefined *puStack_58; + long local_50; + undefined8 local_48; undefined8 local_40; undefined8 uStack_38; uVar1 = __auth_stubs::_objc_retain(param_3); uStack_38 = DAT_0; local_40 = param_1; - lVar2 = __auth_stubs::_objc_msgSendSuper2(&local_40,0x1d021ccc3); + lVar2 = __auth_stubs::_objc_msgSendSuper2(&local_40,0x1cf0daf33); if (lVar2 != 0) { __auth_stubs::_objc_storeStrong(lVar2 + 8,param_3); - __auth_stubs::_objc_opt_class(lVar2); - _objc_msgSend_sharedPersistentContainer(); - uVar3 = __auth_stubs::_objc_retainAutoreleasedReturnValue(); - uVar4 = *(undefined8 *)(lVar2 + 0x10); - *(undefined8 *)(lVar2 + 0x10) = uVar3; - __auth_stubs::_objc_release(uVar4); - __auth_stubs::_objc_retain(lVar2); + local_70 = __got::__NSConcreteStackBlock; + local_68 = 0xc2000000; + local_60 = ___65__CNContactMetadataPersistentStoreManager_initWithStoreLocation___block_invoke; + puStack_58 = &___block_descriptor_48_e8_32s40s_e5_v8__0l; + lVar3 = __auth_stubs::_objc_retain(lVar2); + local_50 = lVar3; + local_48 = __auth_stubs::_objc_retain(uVar1); + if (_initWithStoreLocation__cn_once_token_4 != -1) { + __auth_stubs::_dispatch_once(&_initWithStoreLocation__cn_once_token_4,&local_70); + } + uVar4 = __auth_stubs::_objc_retain(_initWithStoreLocation__cn_once_object_4); + __auth_stubs::_objc_release(local_48); + __auth_stubs::_objc_release(local_50); + uVar5 = *(undefined8 *)(lVar3 + 0x10); + *(undefined8 *)(lVar3 + 0x10) = uVar4; + __auth_stubs::_objc_release(uVar5); + _objc_msgSend_setupIfNeeded(lVar3); + __auth_stubs::_objc_retain(lVar3); } __auth_stubs::_objc_release(uVar1); __auth_stubs::_objc_release(lVar2); return lVar2; } ``` -------------------------------- ### Objective-C Block Invocation for Contact Metadata Setup Source: https://github.com/clearbluejar/ghidriff/blob/main/www/diffs/Samples/Mac/contacts-sample.md This Objective-C code snippet represents a block invocation used within the CNContactMetadataPersistentStoreManager to handle the setup of persistent store data. It includes logic for retaining and releasing objects, logging, and error handling during the setup process. ```diff void ___56__CNContactMetadataPersistentStoreManager_setupIfNeeded__block_invoke (long param_1,undefined8 param_2,undefined8 param_3) { int iVar1; undefined8 uVar2; long lVar3; undefined8 uVar4; undefined8 uVar5; undefined auVar6 [16]; undefined4 local_50; undefined8 local_4c; long local_38; local_38 = *(long *)__got::___stack_chk_guard; uVar2 = __auth_stubs::_objc_retain(param_2); lVar3 = __auth_stubs::_objc_retain(param_3); auVar6 = __auth_stubs::_objc_loadWeakRetained(param_1 + 0x20); uVar4 = auVar6._0_8_; if (lVar3 == 0) { __auth_stubs::_objc_opt_class(); _objc_msgSend_os_log(); uVar5 = __auth_stubs::_objc_retainAutoreleasedReturnValue(); iVar1 = __auth_stubs::_os_log_type_enabled(uVar5,1); if (iVar1 != 0) { local_50 = 0x8400102; local_4c = uVar2; __auth_stubs::__os_log_impl (&mach_header_194bd8000,uVar5,1,"Loaded container with description: %@",&local_50, 0xc); } } else { _objc_msgSend_setLoadPersistentStoresError_(uVar4,auVar6._8_8_,lVar3); __auth_stubs::_objc_opt_class(uVar4); _objc_msgSend_os_log(); uVar5 = __auth_stubs::_objc_retainAutoreleasedReturnValue(); iVar1 = __auth_stubs::_os_log_type_enabled(uVar5,0x10); if (iVar1 != 0) { ___56__CNContactMetadataPersistentStoreManager_setupIfNeeded__block_invoke_cold_1(lVar3,uVar5) ; } } __auth_stubs::_objc_release(uVar5); __auth_stubs::_objc_release(uVar4); __auth_stubs::_objc_release(lVar3); __auth_stubs::_objc_release(uVar2); if (*(long *)__got::___stack_chk_guard == local_38) { return; } __auth_stubs::___stack_chk_fail(); return; } ``` -------------------------------- ### Set GHIDRA_INSTALL_DIR and Install ghidriff on Linux/Mac Source: https://github.com/clearbluejar/ghidriff/blob/main/www/docs/README/Quick Start Environment Setup.md Use these commands to set the GHIDRA_INSTALL_DIR environment variable and install ghidriff on Linux or macOS. ```bash export GHIDRA_INSTALL_DIR="/path/to/ghidra/" pip install ghidriff ``` -------------------------------- ### Set GHIDRA_INSTALL_DIR and Install ghidriff on Windows Source: https://github.com/clearbluejar/ghidriff/blob/main/www/docs/README/Quick Start Environment Setup.md Use this command to set the GHIDRA_INSTALL_DIR environment variable and install ghidriff on a Windows system. ```powershell PS C:\Users\user> [System.Environment]::SetEnvironmentVariable('GHIDRA_INSTALL_DIR','C:\ghidra_10.2.3_PUBLIC_20230208\ghidra_10.2.3_PUBLIC') PS C:\Users\user> pip install ghidriff ``` -------------------------------- ### Detailed Diff for -[CNWallpaper_initWithPosterArchiveData:metadata:] Source: https://github.com/clearbluejar/ghidriff/blob/main/www/diffs/Samples/Mac/contacts-sample.md Provides a detailed view of the code changes in the implementation of the CNWallpaper initializer, highlighting the addition of the 'contentIsSensitive' parameter and its usage. ```c --- -[CNWallpaper_initWithPosterArchiveData:metadata:] +++ -[CNWallpaper_initWithPosterArchiveData:metadata:contentIsSensitive:] @@ -1,50 +1,53 @@ undefined8 -__CNWallpaper_initWithPosterArchiveData_metadata__ - (undefined8 param_1,undefined8 param_2,undefined8 param_3,undefined8 param_4) +__CNWallpaper_initWithPosterArchiveData_metadata_contentIsSensitive__ + (undefined8 param_1,undefined8 param_2,undefined8 param_3,undefined8 param_4, + undefined8 param_5) { long lVar1; undefined8 uVar2; undefined8 uVar3; undefined8 uVar4; undefined8 uVar5; undefined8 uVar6; undefined8 uVar7; undefined auVar8 [16]; lVar1 = __auth_stubs::_objc_retain(param_4); auVar8 = __auth_stubs::_objc_retain(param_3); uVar7 = auVar8._0_8_; if (lVar1 == 0) { - uVar2 = _objc_msgSend_initWithPosterArchiveData_(param_1,auVar8._8_8_,uVar7); + uVar2 = _objc_msgSend_initWithPosterArchiveData_contentIsSensitive_ + (param_1,auVar8._8_8_,uVar7,param_5); __auth_stubs::_objc_release(uVar7); uVar7 = __auth_stubs::_objc_retain(uVar2); } else { _objc_msgSend_fontDescription(lVar1); uVar2 = __auth_stubs::_objc_retainAutoreleasedReturnValue(); _objc_msgSend_fontColorDescription(lVar1); uVar3 = __auth_stubs::_objc_retainAutoreleasedReturnValue(); _objc_msgSend_backgroundColorDescription(lVar1); uVar4 = __auth_stcs::_objc_retainAutoreleasedReturnValue(); _objc_msgSend_extensionBundleID(lVar1); uVar5 = __auth_stcs::_objc_retainAutoreleasedReturnValue(); uVar6 = _objc_msgSend_isVertical(lVar1); _objc_msgSend_visualFingerprintData(lVar1); auVar8 = __auth_stubs::_objc_retainAutoreleasedReturnValue(); - uVar6 = _objc_msgSend_initWithPosterArchiveData_fontDescription_fontColorDescription_backgroundColorDescription_extensionBundleID_vertical_visualFingerprintData_ - (param_1,auVar8._8_8_,uVar7,uVar2,uVar3,uVar4,uVar5,uVar6,auVar8._0_8_); + uVar6 = _objc_msgSend_initWithPosterArchiveData_fontDescription_fontColorDescription_backgroundColorDescription_extensionBundleID_vertical_visualFingerprintData_contentIsSensitive_ + (param_1,auVar8._8_8_,uVar7,uVar2,uVar3,uVar4,uVar5,uVar6,auVar8._0_8_, + (char)param_5); __auth_stubs::_objc_release(uVar7); uVar7 = __auth_stubs::_objc_retain(uVar6); __auth_stubs::_objc_release(auVar8._0_8_); __auth_stubs::_objc_release(uVar5); __auth_stubs::_objc_release(uVar4); __auth_stubs::_objc_release(uVar3); __auth_stubs::_objc_release(uVar2); } __auth_stubs::_objc_release(lVar1); __auth_stubs::_objc_release(uVar7); return uVar7; } ``` -------------------------------- ### Docker Command-Line Diffing Example Source: https://github.com/clearbluejar/ghidriff/blob/main/www/docs/README/Ghidriff in a Box.md Compares two binary files using Ghidriff within a Docker container. Binaries are downloaded and mapped into the container for comparison. The output includes a markdown diff, JSON diff, and Ghidra project files. ```bash mkdir -p ghidriffs wget https://msdl.microsoft.com/download/symbols/clfs.sys/9848245C6f000/clfs.sys -O ghidriffs/clfs.sys.x64.10.0.22621.2506 wget https://msdl.microsoft.com/download/symbols/clfs.sys/D929C6E56f000/clfs.sys -O ghidriffs/clfs.sys.x64.10.0.22621.2715 docker run -it --rm -v $(pwd)/ghidriffs:/ghidriffs ghcr.io/clearbluejar/ghidriff:latest ghidriffs/clfs.sys.x64.10.0.22621.2506 ghidriffs/clfs.sys.x64.10.0.22621.2715 ``` -------------------------------- ### Diff Output Example Source: https://github.com/clearbluejar/ghidriff/blob/main/www/diffs/Samples/Mac/contacts-sample.md This snippet displays a diff output indicating a change. ```diff --- -[CNAPITriageLogger_willExecuteFetchRequest:] called +++ -[CNAPITriageLogger_willExecuteFetchRequest:] called @@ -0,0 +1 @@ +__auth_stubs::_NSStringFromClass ``` -------------------------------- ### GhidraDiffEngine.setup_symbol_server() Source: https://context7.com/clearbluejar/ghidriff/llms.txt Configures Ghidra's PDB symbol server settings, including a local cache directory and remote symbol server URLs. ```APIDOC ## GhidraDiffEngine.setup_symbol_server() ### Description Configures Ghidra's PDB symbol server. This involves setting a local directory for caching symbols and registering remote HTTP symbol servers, such as Microsoft's public symbol server. The local store acts as a cache, downloading symbols on demand during analysis. Level 1 is used for Windows PE binaries and matches the standard `srv*` symbol path format. ### Method ```python engine.setup_symbol_server( symbols_path: str, level: int = 1, server_urls: list[str] = None ) ``` ### Parameters #### Path Parameters - **symbols_path** (str) - Required - The root directory for the local PDB cache. #### Optional Parameters - **level** (int) - Optional - The symbol store level. `1` for flat directory per PDB GUID (standard `srv*` format), `0` for user directory. Defaults to 1. - **server_urls** (list[str]) - Optional - A list of remote symbol server URLs to override or supplement well-known servers. ### Request Example ```python engine.setup_symbol_server( symbols_path="ghidriffs/symbols", level=1, server_urls=[ "https://msdl.microsoft.com/download/symbols/", "https://symbols.mozilla.org/", ], ) ``` ### Output Logs an INFO message indicating the symbol server configuration, including the local cache root and registered remote servers. ``` -------------------------------- ### Build Static Website Source: https://github.com/clearbluejar/ghidriff/blob/main/www/README.md Generates the static content for the website into the 'build' directory, ready for hosting. ```bash $ yarn build ```