diff options
| author | Josh Ferrell <josh@vector35.com> | 2024-06-06 15:41:48 -0400 |
|---|---|---|
| committer | Josh Ferrell <josh@vector35.com> | 2024-06-06 15:41:48 -0400 |
| commit | 783a3cb0f4c2f2943653293937010b3de1aaf900 (patch) | |
| tree | fb9090dd138d4058b24b3e286d3647a95a651b13 /rust/examples | |
| parent | 7dd6f311b81460478b2ffc2726bfd3cb0e62c9ed (diff) | |
Support for local debug directories
Diffstat (limited to 'rust/examples')
| -rw-r--r-- | rust/examples/dwarf/dwarf_import/src/helpers.rs | 65 | ||||
| -rw-r--r-- | rust/examples/dwarf/dwarf_import/src/lib.rs | 42 | ||||
| -rw-r--r-- | rust/examples/dwarf/shared/src/lib.rs | 10 |
3 files changed, 102 insertions, 15 deletions
diff --git a/rust/examples/dwarf/dwarf_import/src/helpers.rs b/rust/examples/dwarf/dwarf_import/src/helpers.rs index ae338a4b..8c19f4ad 100644 --- a/rust/examples/dwarf/dwarf_import/src/helpers.rs +++ b/rust/examples/dwarf/dwarf_import/src/helpers.rs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::path::PathBuf; use std::{ collections::HashMap, ops::Deref, @@ -303,9 +304,7 @@ pub(crate) fn get_expr_value<R: Reader<Offset = usize>>( } -pub(crate) fn download_debug_info(view: &BinaryView) -> Result<Ref<BinaryView>, String> { - let settings = Settings::new(""); - +pub(crate) fn get_build_id(view: &BinaryView) -> Result<String, String> { let mut build_id: Option<String> = None; if let Ok(raw_view) = view.raw_view() { @@ -351,14 +350,24 @@ pub(crate) fn download_debug_info(view: &BinaryView) -> Result<Ref<BinaryView>, } } - if build_id.is_none() { - return Err("Failed to get build id".to_string()); + if let Some(x) = build_id { + Ok(x) } + else { + Err("Failed to get build id".to_string()) + } +} + + +pub(crate) fn download_debug_info(view: &BinaryView) -> Result<Ref<BinaryView>, String> { + let settings = Settings::new(""); + + let build_id = get_build_id(view)?; let debug_server_urls = settings.get_string_list("network.debuginfodServers", Some(view), None); for debug_server_url in debug_server_urls.iter() { - let artifact_url = format!("{}/buildid/{}/debuginfo", debug_server_url, build_id.as_ref().unwrap()); + let artifact_url = format!("{}/buildid/{}/debuginfo", debug_server_url, build_id); // Download from remote let (tx, rx) = mpsc::channel(); @@ -421,3 +430,47 @@ pub(crate) fn download_debug_info(view: &BinaryView) -> Result<Ref<BinaryView>, } return Err("Could not find a server with debug info for this file".to_string()); } + + +pub(crate) fn load_debug_info_for_build_id(view: &BinaryView) -> Result<Option<Ref<BinaryView>>, String> { + let settings = Settings::new(""); + let debug_info_paths = settings.get_string_list("analysis.debugInfo.debugDirectories", Some(view), None); + if debug_info_paths.is_empty() { + return Ok(None) + } + + for debug_info_path in debug_info_paths.into_iter() { + if let Ok(path) = PathBuf::from_str(&debug_info_path.to_string()) + { + let build_id = get_build_id(view)?; + let elf_path = path + .join(&build_id[..2]) + .join(&build_id[2..]) + .join("elf"); + + let debug_ext_path = path + .join(&build_id[..2]) + .join(format!("{}.debug", &build_id[2..])); + + let options = "{\"analysis.debugInfo.internal\": false}"; + let final_path = if debug_ext_path.exists() { + debug_ext_path + } + else if elf_path.exists() { + elf_path + } + else { + // No paths exist + return Ok(None) + }; + return Ok( + binaryninja::load_with_options( + final_path.to_string_lossy().to_string(), + false, + Some(options) + ) + ); + } + } + Ok(None) +} diff --git a/rust/examples/dwarf/dwarf_import/src/lib.rs b/rust/examples/dwarf/dwarf_import/src/lib.rs index c8b48792..1f4fce4d 100644 --- a/rust/examples/dwarf/dwarf_import/src/lib.rs +++ b/rust/examples/dwarf/dwarf_import/src/lib.rs @@ -270,7 +270,9 @@ struct DWARFParser; impl CustomDebugInfoParser for DWARFParser { fn is_valid(&self, view: &BinaryView) -> bool { - dwarfreader::is_valid(view) || dwarfreader::can_use_debuginfod(view) + dwarfreader::is_valid(view) || + dwarfreader::can_use_build_id(view) || + dwarfreader::can_use_debuginfod(view) } fn parse_info( @@ -280,13 +282,29 @@ impl CustomDebugInfoParser for DWARFParser { debug_file: &BinaryView, progress: Box<dyn Fn(usize, usize) -> Result<(), ()>>, ) -> bool { - let external_file = if !dwarfreader::is_valid(bv) && dwarfreader::can_use_debuginfod(bv) { - if let Ok(debug_view) = helpers::download_debug_info(bv) { - Some(debug_view) - } else { + let external_file = if !dwarfreader::is_valid(bv) { + if dwarfreader::can_use_build_id(bv) { + if let Ok(Some(debug_view)) = helpers::load_debug_info_for_build_id(bv) { + Some(debug_view) + } + else { + if dwarfreader::can_use_debuginfod(bv) { + if let Ok(debug_view) = helpers::download_debug_info(bv) { + Some(debug_view) + } else { + None + } + } + else { + None + } + } + } + else { None } - } else { + } + else { None }; @@ -333,6 +351,18 @@ pub extern "C" fn CorePluginInit() -> bool { }"#, ); + settings.register_setting_json( + "analysis.debugInfo.debugDirectories", + r#"{ + "title" : "Debug File Directories", + "type" : "array", + "elementType" : "string", + "default" : [], + "description" : "Paths to folder containing debug info stored by build id.", + "ignore" : [] + }"#, + ); + DebugInfoParser::register("DWARF", DWARFParser {}); true } diff --git a/rust/examples/dwarf/shared/src/lib.rs b/rust/examples/dwarf/shared/src/lib.rs index 76c903e4..e3d1315d 100644 --- a/rust/examples/dwarf/shared/src/lib.rs +++ b/rust/examples/dwarf/shared/src/lib.rs @@ -54,10 +54,14 @@ pub fn is_raw_dwo_dwarf(view: &BinaryView) -> bool { } pub fn can_use_debuginfod(view: &BinaryView) -> bool { + can_use_build_id(view) && + Settings::new("") + .get_bool("network.enableDebuginfod", Some(view), None) +} + +pub fn can_use_build_id(view: &BinaryView) -> bool { if let Ok(raw_view) = view.raw_view() { - if raw_view.section_by_name(".note.gnu.build-id").is_ok() { - return Settings::new("").get_bool("network.enableDebuginfod", Some(view), None); - } + return raw_view.section_by_name(".note.gnu.build-id").is_ok() } false } |
