summaryrefslogtreecommitdiff
path: root/rust/examples
diff options
context:
space:
mode:
authorJosh Ferrell <josh@vector35.com>2024-06-06 15:41:48 -0400
committerJosh Ferrell <josh@vector35.com>2024-06-06 15:41:48 -0400
commit783a3cb0f4c2f2943653293937010b3de1aaf900 (patch)
treefb9090dd138d4058b24b3e286d3647a95a651b13 /rust/examples
parent7dd6f311b81460478b2ffc2726bfd3cb0e62c9ed (diff)
Support for local debug directories
Diffstat (limited to 'rust/examples')
-rw-r--r--rust/examples/dwarf/dwarf_import/src/helpers.rs65
-rw-r--r--rust/examples/dwarf/dwarf_import/src/lib.rs42
-rw-r--r--rust/examples/dwarf/shared/src/lib.rs10
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
}