├── README.md ├── RustDependencyStrings.py └── img ├── bundle_manager.png ├── ghidra_bundle_directory_menu.png ├── ghidra_script_directory_menu.png ├── ghidra_script_manager_context.png ├── ghidra_splash.png ├── script_list_refresh.png ├── script_manager.png ├── select_bundles.png └── usage_example.png /README.md: -------------------------------------------------------------------------------- 1 | # Rust Crate String Extractor - Ghidra 2 | 3 | Extracts string references to Rust crates in compiled Rust programs. 4 | 5 | ## Example 6 | ![usage_example.png](https://github.com/BinaryDefense/GhidraRustDependenciesExtractor/blob/main/img/usage_example.png) 7 | 8 | ## Installation Guide 9 | Download the `RustDependencyStrings.py` file and place it into the `~/ghidra_scripts` directory. 10 | 11 | ```bash 12 | mkdir ~/ghidra_scripts 13 | curl -L "https://raw.githubusercontent.com/BinaryDefense/GhidraRustDependenciesExtractor/main/RustDependencyStrings.py" -o ~/ghidra_scripts/RustDependencyStrings.py 14 | ``` 15 | 16 | Run Ghidra and click on the green dragon CodeBrowser icon in the Tool Chest. 17 | 18 | ![ghidra_splash.png](https://github.com/BinaryDefense/GhidraRustDependenciesExtractor/blob/main/img/ghidra_splash.png) 19 | 20 | Open the Script Manager window by selecting `Window -> Script Manager` in the application menu. 21 | 22 | ![ghidra_script_manager_context.png](https://github.com/BinaryDefense/GhidraRustDependenciesExtractor/blob/main/img/ghidra_script_manager_context.png) 23 | 24 | Select the `Manage Script Directories` button in the top right corner of the script manager window. 25 | 26 | ![ghidra_script_directory.png](https://github.com/BinaryDefense/GhidraRustDependenciesExtractor/blob/main/img/ghidra_script_directory_menu.png) 27 | 28 | Add the `~/ghidra_scripts` directory as a bundle. 29 | 30 | ![ghidra_bundle_directory_menu.png](https://github.com/BinaryDefense/GhidraRustDependenciesExtractor/blob/main/img/ghidra_bundle_directory_menu.png) 31 | 32 | ![select_bundles.png](https://github.com/BinaryDefense/GhidraRustDependenciesExtractor/blob/main/img/select_bundles.png) 33 | 34 | Click `Ok` and the `~/ghidra_scripts` directory should be added as a script search directory for Ghidra indicated by a green path location and check mark. 35 | 36 | ![bungle_manager.png](https://github.com/BinaryDefense/GhidraRustDependenciesExtractor/blob/main/img/bundle_manager.png) 37 | 38 | Exit out of the bundle manager and refresh the script list. 39 | 40 | ![script_list_refresh.png](https://github.com/BinaryDefense/GhidraRustDependenciesExtractor/blob/main/img/script_list_refresh.png) 41 | 42 | Ensure the script `RustDependencyStrings.py` is available in the list. 43 | 44 | ![script_manager.png](https://github.com/BinaryDefense/GhidraRustDependenciesExtractor/blob/main/img/script_manager.png) 45 | 46 | The script is now loaded and can be ran by opening a Rust binary, navigating to the `Script Manager` window, and double-clicking on the `RustDependencyStrings.py` script. -------------------------------------------------------------------------------- /RustDependencyStrings.py: -------------------------------------------------------------------------------- 1 | # Extracts Rust crate dependency strings from a compiled Rust binary. 2 | # @author Matt Ehrnschwender 3 | # @category Search 4 | 5 | import re 6 | import string 7 | import struct 8 | 9 | from ghidra.program.database import * 10 | 11 | unsigned_convert = lambda x: struct.unpack("B", struct.pack("b", x))[0] 12 | 13 | regex_string = ( 14 | r".cargo(/|\\)registry(/|\\)src(/|\\).*?-[a-f0-9]{16}(/|\\)(.*?\d+.\d+.\d+)" 15 | ) 16 | 17 | initialized_sections = filter( 18 | lambda x: x.isInitialized(), currentProgram.getMemory().getBlocks() 19 | ) 20 | 21 | rw_sections = filter(lambda x: x.getPermissions() & 1 == 0, initialized_sections) 22 | 23 | string_data = "" 24 | for section in rw_sections: 25 | raw_bytes = [unsigned_convert(x) for x in section.getData().readAllBytes()] 26 | printable_bytes = [chr(x) for x in raw_bytes if chr(x) in string.printable] 27 | string_data += "".join(printable_bytes) 28 | 29 | matches = sorted(set(re.findall(regex_string, string_data))) 30 | 31 | if len(matches) > 0: 32 | for match in matches: 33 | print(match[-1]) 34 | else: 35 | print("No Rust crate dependency strings found.") 36 | -------------------------------------------------------------------------------- /img/bundle_manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BinaryDefense/GhidraRustDependenciesExtractor/855a72c6c9e7fec2f602647eaf349dcb787598cc/img/bundle_manager.png -------------------------------------------------------------------------------- /img/ghidra_bundle_directory_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BinaryDefense/GhidraRustDependenciesExtractor/855a72c6c9e7fec2f602647eaf349dcb787598cc/img/ghidra_bundle_directory_menu.png -------------------------------------------------------------------------------- /img/ghidra_script_directory_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BinaryDefense/GhidraRustDependenciesExtractor/855a72c6c9e7fec2f602647eaf349dcb787598cc/img/ghidra_script_directory_menu.png -------------------------------------------------------------------------------- /img/ghidra_script_manager_context.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BinaryDefense/GhidraRustDependenciesExtractor/855a72c6c9e7fec2f602647eaf349dcb787598cc/img/ghidra_script_manager_context.png -------------------------------------------------------------------------------- /img/ghidra_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BinaryDefense/GhidraRustDependenciesExtractor/855a72c6c9e7fec2f602647eaf349dcb787598cc/img/ghidra_splash.png -------------------------------------------------------------------------------- /img/script_list_refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BinaryDefense/GhidraRustDependenciesExtractor/855a72c6c9e7fec2f602647eaf349dcb787598cc/img/script_list_refresh.png -------------------------------------------------------------------------------- /img/script_manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BinaryDefense/GhidraRustDependenciesExtractor/855a72c6c9e7fec2f602647eaf349dcb787598cc/img/script_manager.png -------------------------------------------------------------------------------- /img/select_bundles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BinaryDefense/GhidraRustDependenciesExtractor/855a72c6c9e7fec2f602647eaf349dcb787598cc/img/select_bundles.png -------------------------------------------------------------------------------- /img/usage_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BinaryDefense/GhidraRustDependenciesExtractor/855a72c6c9e7fec2f602647eaf349dcb787598cc/img/usage_example.png --------------------------------------------------------------------------------