Skip to content

Commit 432da6c

Browse files
committed
update idb_import idb-rs to 0.1.13
1 parent 9124b7b commit 432da6c

File tree

3 files changed

+98
-89
lines changed

3 files changed

+98
-89
lines changed

plugins/idb_import/src/addr_info.rs

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,54 @@
1-
use std::borrow::Cow;
21
use std::collections::HashMap;
32

43
use anyhow::Result;
54

65
use idb_rs::addr_info::all_address_info;
7-
use idb_rs::id0::{ID0Section, Netdelta};
6+
use idb_rs::id0::{ID0Section, RootInfo};
87
use idb_rs::id1::ID1Section;
98
use idb_rs::id2::ID2Section;
10-
use idb_rs::{til, Address, IDAKind};
9+
use idb_rs::{til, Address, IDAKind, IDBString};
1110

1211
#[derive(Default)]
13-
pub struct AddrInfo<'a> {
12+
pub struct AddrInfo {
1413
// TODO does binja differentiate comments types on the API?
15-
pub comments: Vec<Vec<u8>>,
16-
pub label: Option<Cow<'a, [u8]>>,
14+
pub comments: Vec<IDBString>,
15+
pub label: Option<IDBString>,
1716
// TODO make this a ref
1817
pub ty: Option<til::Type>,
1918
}
2019

21-
pub fn get_info<'a, K: IDAKind>(
22-
id0: &'a ID0Section<K>,
23-
id1: &ID1Section,
20+
pub fn get_info<K: IDAKind>(
21+
id0: &ID0Section<K>,
22+
id1: &ID1Section<K>,
2423
id2: Option<&ID2Section<K>>,
25-
netdelta: Netdelta<K>,
26-
) -> Result<HashMap<Address<K>, AddrInfo<'a>>> {
24+
root_info: &RootInfo<K>,
25+
) -> Result<HashMap<Address<K>, AddrInfo>> {
2726
let mut addr_info: HashMap<Address<K>, AddrInfo> = HashMap::new();
2827

2928
// comments defined on the address information
29+
let netdelta = root_info.netdelta();
3030
for (info, _info_size) in all_address_info(id0, id1, id2, netdelta) {
3131
let entry = addr_info.entry(info.address()).or_default();
3232
if let Some(comment) = info.comment() {
33-
entry.comments.push(comment.to_vec());
33+
entry.comments.push(comment.to_idb_string());
3434
}
3535
if let Some(comment) = info.comment_repeatable() {
36-
entry.comments.push(comment.to_vec());
36+
entry.comments.push(comment.to_idb_string());
3737
}
3838
if let Some(comment) = info.comment_pre() {
39-
entry.comments.extend(comment.map(|line| line.to_vec()));
39+
entry
40+
.comments
41+
.extend(comment.map(|line| line.to_idb_string()));
4042
}
4143
if let Some(comment) = info.comment_post() {
42-
entry.comments.extend(comment.map(|line| line.to_vec()));
44+
entry
45+
.comments
46+
.extend(comment.map(|line| line.to_idb_string()));
4347
}
4448
if let Some(label) = info.label()? {
4549
entry.label = Some(label);
4650
}
47-
if let Some(ty) = info.tinfo()? {
51+
if let Some(ty) = info.tinfo(root_info)? {
4852
entry.ty = Some(ty);
4953
}
5054
}

plugins/idb_import/src/lib.rs

Lines changed: 39 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use std::borrow::Cow;
33
use std::io::{BufRead, Cursor, Seek};
44

55
use idb_rs::id1::ID1Section;
6-
use idb_rs::id2::{ID2Section, ID2SectionVariants};
7-
use idb_rs::{IDAKind, IDAUsize, IDBFormat};
6+
use idb_rs::id2::ID2Section;
7+
use idb_rs::{IDAKind, IDAUsize, IDAVariants, IDBFormat, IDBString};
88
use types::*;
99
mod addr_info;
1010
use addr_info::*;
@@ -14,7 +14,7 @@ use binaryninja::debuginfo::{
1414
CustomDebugInfoParser, DebugFunctionInfo, DebugInfo, DebugInfoParser,
1515
};
1616

17-
use idb_rs::id0::{ID0Section, ID0SectionVariants};
17+
use idb_rs::id0::ID0Section;
1818
use idb_rs::til::section::TILSection;
1919
use idb_rs::til::TypeVariant as TILTypeVariant;
2020

@@ -135,8 +135,11 @@ fn parse_idb_info(
135135
let mut file = std::io::BufReader::new(file);
136136
let idb_kind = idb_rs::identify_idb_file(&mut file)?;
137137
match idb_kind {
138-
idb_rs::IDBFormats::Separated(sep) => {
139-
parse_idb_info_format(debug_info, bv, debug_file, sep, file, progress)
138+
idb_rs::IDBFormats::Separated(IDAVariants::IDA32(sep32)) => {
139+
parse_idb_info_format(debug_info, bv, debug_file, sep32, file, progress)
140+
}
141+
idb_rs::IDBFormats::Separated(IDAVariants::IDA64(sep64)) => {
142+
parse_idb_info_format(debug_info, bv, debug_file, sep64, file, progress)
140143
}
141144
idb_rs::IDBFormats::InlineUncompressed(inline) => {
142145
parse_idb_info_format(debug_info, bv, debug_file, inline, file, progress)
@@ -156,11 +159,11 @@ fn parse_idb_info(
156159
}
157160
}
158161

159-
fn parse_idb_info_format(
162+
fn parse_idb_info_format<K: IDAKind>(
160163
debug_info: &mut DebugInfo,
161164
bv: &BinaryView,
162165
debug_file: &BinaryView,
163-
format: impl IDBFormat,
166+
format: impl IDBFormat<K>,
164167
mut idb_data: impl BufRead + Seek,
165168
progress: Box<dyn Fn(usize, usize) -> Result<(), ()>>,
166169
) -> Result<()> {
@@ -185,21 +188,7 @@ fn parse_idb_info_format(
185188
.map(|id2_idx| format.read_id2(&mut idb_data, id2_idx))
186189
.transpose()?;
187190

188-
match (id0, id2) {
189-
(ID0SectionVariants::IDA32(id0), Some(ID2SectionVariants::IDA32(id2))) => {
190-
parse_id0_section_info(debug_info, bv, debug_file, &id0, &id1, Some(&id2))?
191-
}
192-
(ID0SectionVariants::IDA32(id0), None) => {
193-
parse_id0_section_info(debug_info, bv, debug_file, &id0, &id1, None)?
194-
}
195-
(ID0SectionVariants::IDA64(id0), Some(ID2SectionVariants::IDA64(id2))) => {
196-
parse_id0_section_info(debug_info, bv, debug_file, &id0, &id1, Some(&id2))?
197-
}
198-
(ID0SectionVariants::IDA64(id0), None) => {
199-
parse_id0_section_info(debug_info, bv, debug_file, &id0, &id1, None)?
200-
}
201-
_ => unreachable!(),
202-
}
191+
parse_id0_section_info(debug_info, bv, debug_file, &id0, &id1, id2.as_ref())?;
203192

204193
Ok(())
205194
}
@@ -291,19 +280,18 @@ fn parse_id0_section_info<K: IDAKind>(
291280
bv: &BinaryView,
292281
debug_file: &BinaryView,
293282
id0: &ID0Section<K>,
294-
id1: &ID1Section,
283+
id1: &ID1Section<K>,
295284
id2: Option<&ID2Section<K>>,
296285
) -> Result<()> {
297286
let ida_info_idx = id0.root_node()?;
298287
let ida_info = id0.ida_info(ida_info_idx)?;
299288
let idb_baseaddr = ida_info.addresses.loading_base.into_u64();
300289
let bv_baseaddr = bv.start();
301-
let netdelta = ida_info.netdelta();
302290
// just addr this value to the address to translate from ida to bn
303291
// NOTE this delta could wrap here and while using translating
304292
let addr_delta = bv_baseaddr.wrapping_sub(idb_baseaddr);
305293

306-
for (idb_addr, info) in get_info(id0, id1, id2, netdelta)? {
294+
for (idb_addr, info) in get_info(id0, id1, id2, &ida_info)? {
307295
let addr = addr_delta.wrapping_add(idb_addr.into_raw().into_u64());
308296
// just in case we change this struct in the future, this line will for us to review this code
309297
// TODO merge this data with folder locations
@@ -314,30 +302,35 @@ fn parse_id0_section_info<K: IDAKind>(
314302
} = info;
315303
// TODO set comments to address here
316304
for function in &bv.functions_containing(addr) {
317-
function.set_comment_at(addr, &String::from_utf8_lossy(&comments.join(&b"\n"[..])));
305+
let comments: Vec<String> = comments
306+
.iter()
307+
.map(idb_rs::IDBString::as_utf8_lossy)
308+
.map(Cow::into_owned)
309+
.collect();
310+
function.set_comment_at(addr, &comments.join("\n"));
318311
}
319312

320-
let bnty = ty
321-
.as_ref()
322-
.and_then(|ty| match translate_ephemeral_type(debug_file, ty) {
323-
TranslateTypeResult::Translated(result) => Some(result),
324-
TranslateTypeResult::PartiallyTranslated(result, None) => {
325-
warn!("Unable to fully translate the type at {addr:#x}");
326-
Some(result)
327-
}
328-
TranslateTypeResult::NotYet => {
329-
error!("Unable to translate the type at {addr:#x}");
330-
None
331-
}
332-
TranslateTypeResult::PartiallyTranslated(_, Some(bn_type_error))
333-
| TranslateTypeResult::Error(bn_type_error) => {
334-
error!("Unable to translate the type at {addr:#x}: {bn_type_error}",);
335-
None
336-
}
337-
});
313+
let bnty =
314+
ty.as_ref().and_then(
315+
|ty| match translate_ephemeral_type(debug_file, &ida_info, ty) {
316+
TranslateTypeResult::Translated(result) => Some(result),
317+
TranslateTypeResult::PartiallyTranslated(result, None) => {
318+
warn!("Unable to fully translate the type at {addr:#x}");
319+
Some(result)
320+
}
321+
TranslateTypeResult::NotYet => {
322+
error!("Unable to translate the type at {addr:#x}");
323+
None
324+
}
325+
TranslateTypeResult::PartiallyTranslated(_, Some(bn_type_error))
326+
| TranslateTypeResult::Error(bn_type_error) => {
327+
error!("Unable to translate the type at {addr:#x}: {bn_type_error}",);
328+
None
329+
}
330+
},
331+
);
338332

339-
let label: Option<Cow<'_, str>> =
340-
label.as_ref().map(Cow::as_ref).map(String::from_utf8_lossy);
333+
let label: Option<Cow<'_, str>> = label.as_ref().map(IDBString::as_utf8_lossy);
341334
match (label, &ty, bnty) {
342335
(label, Some(ty), bnty) if matches!(&ty.type_variant, TILTypeVariant::Function(_)) => {
343336
if bnty.is_none() {

plugins/idb_import/src/types.rs

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@ use binaryninja::types::{
1111
EnumerationBuilder, FunctionParameter, MemberAccess, MemberScope, StructureBuilder,
1212
StructureType, Type,
1313
};
14+
use idb_rs::id0::RootInfo;
1415
use idb_rs::til::function::CallingConvention as TILCallingConvention;
1516
use idb_rs::til::pointer::Pointer as TILPointer;
1617
use idb_rs::til::r#enum::EnumMembers;
1718
use idb_rs::til::{
1819
array::Array as TILArray, function::Function as TILFunction, r#enum::Enum as TILEnum,
19-
r#struct::Struct as TILStruct, r#struct::StructMember as TILStructMember,
20-
r#union::Union as TILUnion, section::TILSection, TILTypeInfo, Type as TILType,
21-
TypeVariant as TILTypeVariant,
20+
section::TILSection, udt::UDTMember as TILUDTMember, udt::UDT as TILUDT, TILTypeInfo,
21+
Type as TILType, TypeVariant as TILTypeVariant,
2222
};
23-
use idb_rs::IDBString;
23+
use idb_rs::{IDAKind, IDBString};
2424

2525
#[derive(Debug, Clone)]
2626
pub enum BnTypeError {
@@ -306,7 +306,7 @@ impl<F: Fn(usize, usize) -> Result<(), ()>> TranslateIDBTypes<'_, F> {
306306
fn condensate_bitfields_from_struct(
307307
&self,
308308
offset: usize,
309-
members_slice: &[TILStructMember],
309+
members_slice: &[TILUDTMember],
310310
struct_builder: &mut StructureBuilder,
311311
) {
312312
if members_slice.is_empty() {
@@ -326,7 +326,7 @@ impl<F: Fn(usize, usize) -> Result<(), ()>> TranslateIDBTypes<'_, F> {
326326

327327
let mut create_field = |start_idx, i, bytes| {
328328
let name = if start_idx == i - 1 {
329-
let member: &TILStructMember = &members_slice[i - 1];
329+
let member: &TILUDTMember = &members_slice[i - 1];
330330
member
331331
.name
332332
.as_ref()
@@ -366,7 +366,7 @@ impl<F: Fn(usize, usize) -> Result<(), ()>> TranslateIDBTypes<'_, F> {
366366
}
367367
}
368368

369-
fn translate_struct(&self, ty_struct: &TILStruct) -> TranslateTypeResult {
369+
fn translate_struct(&self, ty_struct: &TILUDT) -> TranslateTypeResult {
370370
if ty_struct.members.is_empty() {
371371
// binary ninja crashes if you create an empty struct, because it divide by 0
372372
return TranslateTypeResult::Translated(Type::void());
@@ -376,7 +376,7 @@ impl<F: Fn(usize, usize) -> Result<(), ()>> TranslateIDBTypes<'_, F> {
376376
if let Some(align) = ty_struct.alignment {
377377
structure.alignment(align.get().into());
378378
}
379-
structure.packed(ty_struct.is_unaligned && ty_struct.is_uknown_8);
379+
structure.packed(ty_struct.is_unaligned && ty_struct.is_unknown_8);
380380

381381
let mut errors = vec![];
382382
let mut first_bitfield_seq = None;
@@ -440,16 +440,16 @@ impl<F: Fn(usize, usize) -> Result<(), ()>> TranslateIDBTypes<'_, F> {
440440
}
441441
}
442442

443-
fn translate_union(&self, ty_union: &TILUnion) -> TranslateTypeResult {
443+
fn translate_union(&self, ty_union: &TILUDT) -> TranslateTypeResult {
444444
let mut is_partial = false;
445445
let mut structure = StructureBuilder::new();
446446
structure.structure_type(StructureType::UnionStructureType);
447447
let mut errors = vec![];
448448
for (i, member) in ty_union.members.iter().enumerate() {
449449
// bitfields can be translated into complete fields
450-
let mem = match &member.ty.type_variant {
450+
let mem = match &member.member_type.type_variant {
451451
TILTypeVariant::Bitfield(field) => field_from_bytes(field.nbytes.get().into()),
452-
_ => match self.translate_type(&member.ty) {
452+
_ => match self.translate_type(&member.member_type) {
453453
TranslateTypeResult::Translated(ty) => ty,
454454
TranslateTypeResult::Error(error) => {
455455
errors.push((i, error));
@@ -580,21 +580,28 @@ impl<F: Fn(usize, usize) -> Result<(), ()>> TranslateIDBTypes<'_, F> {
580580
TILTypeVariant::Enum(ty_enum) => {
581581
TranslateTypeResult::Translated(self.translate_enum(ty_enum))
582582
}
583-
TILTypeVariant::Typeref(typeref) => match &typeref.typeref_value {
584-
idb_rs::til::TyperefValue::Ref(idx) => self.find_typedef(&self.types[*idx]),
585-
idb_rs::til::TyperefValue::UnsolvedName(name) => self
586-
.find_typedef_by_name(name.as_ref().map(|x| x.as_bytes()).unwrap_or(&[]))
587-
.unwrap_or_else(|| {
588-
TranslateTypeResult::Error(BnTypeError::NameNotFound(
583+
TILTypeVariant::Typeref(typeref) => {
584+
match self.til.get_ref_value_idx(&typeref.typeref_value) {
585+
Some(idx) => self.find_typedef(&self.types[idx]),
586+
None => match &typeref.typeref_value {
587+
idb_rs::til::TyperefValue::Name(name) => {
588+
// search the default non-defined names
589589
name.as_ref()
590-
.map(|x| x.as_utf8_lossy().to_string())
591-
.unwrap_or(String::new()),
592-
))
593-
}),
594-
idb_rs::til::TyperefValue::UnsolvedOrd(ord) => {
595-
TranslateTypeResult::Error(BnTypeError::OrdinalNotFound(*ord))
590+
.and_then(|name| self.find_typedef_by_name(name.as_bytes()))
591+
.unwrap_or_else(|| {
592+
TranslateTypeResult::Error(BnTypeError::NameNotFound(
593+
name.as_ref()
594+
.map(|x| x.as_utf8_lossy().to_string())
595+
.unwrap_or(String::new()),
596+
))
597+
})
598+
}
599+
idb_rs::til::TyperefValue::Ordinal(ord) => {
600+
TranslateTypeResult::Error(BnTypeError::OrdinalNotFound(*ord))
601+
}
602+
},
596603
}
597-
},
604+
}
598605

599606
TILTypeVariant::Pointer(ty) => self.translate_pointer(ty),
600607
TILTypeVariant::Function(fun) => self.translate_function(fun),
@@ -607,10 +614,15 @@ impl<F: Fn(usize, usize) -> Result<(), ()>> TranslateIDBTypes<'_, F> {
607614
}
608615
}
609616

610-
pub fn translate_ephemeral_type(debug_file: &BinaryView, ty: &TILType) -> TranslateTypeResult {
617+
pub fn translate_ephemeral_type<K: IDAKind>(
618+
debug_file: &BinaryView,
619+
root_info: &RootInfo<K>,
620+
ty: &TILType,
621+
) -> TranslateTypeResult {
611622
// in case we need to translate types
612-
let header = idb_rs::til::ephemeral_til_header();
623+
let header = root_info.til_header();
613624
let translator = TranslateIDBTypes {
625+
// TODO find the correct processor using the segment registers
614626
arch: debug_file.default_arch().unwrap(/* TODO */),
615627
progress: |_, _| Ok(()),
616628
// TODO it's unclear what to do here
@@ -630,7 +642,7 @@ pub fn translate_til_types(
630642
arch: CoreArchitecture,
631643
til: &TILSection,
632644
progress: impl Fn(usize, usize) -> Result<(), ()>,
633-
) -> Result<Vec<TranslatesIDBType>> {
645+
) -> Result<Vec<TranslatesIDBType<'_>>> {
634646
let total = til.symbols.len() + til.types.len();
635647
let mut types = Vec::with_capacity(total);
636648
let mut types_by_ord = HashMap::with_capacity(total);

0 commit comments

Comments
 (0)