Skip to content

Commit 44a1415

Browse files
committed
More rust cleanup
- Hopefully fixed the rust.yml CI - Added TypePrinter API (this is still WIP and will crash) - Added TypeParser API - Added TypeContainer API - More work around QualifiedName apis
1 parent 9131cb5 commit 44a1415

File tree

16 files changed

+2098
-1762
lines changed

16 files changed

+2098
-1762
lines changed

.github/workflows/rust.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@ jobs:
1717
runs-on: ubuntu-latest
1818
steps:
1919
- uses: actions/checkout@v4
20-
# Ensure rustfmt is installed and setup problem matcher
20+
# Ensure rustfmt is installed
2121
- uses: actions-rust-lang/setup-rust-toolchain@v1
2222
with:
2323
components: rustfmt
2424
- name: Rustfmt Check
25-
working-directory: ./rust
2625
uses: actions-rust-lang/rustfmt@v1
26+
with:
27+
manifest-path: ./rust

plugins/pdb-ng/src/type_parser.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,7 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> {
769769
ClassKind::Interface => NamedTypeReferenceClass::StructNamedTypeClass,
770770
};
771771
return Ok(Some(Box::new(ParsedType::Bare(Type::named_type(
772-
&*NamedTypeReference::new(ntr_class, QualifiedName::from(class_name)),
772+
&*NamedTypeReference::new(ntr_class, class_name),
773773
)))));
774774
}
775775

@@ -1083,7 +1083,7 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> {
10831083
NamedTypeReferenceClass::StructNamedTypeClass
10841084
};
10851085
vt_bases.push(BaseStructure::new(
1086-
NamedTypeReference::new(ntr_class, vt_base_name.into()),
1086+
NamedTypeReference::new(ntr_class, vt_base_name),
10871087
0,
10881088
vt_base_type.width(),
10891089
));
@@ -1638,7 +1638,7 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> {
16381638

16391639
let ntr_class = NamedTypeReferenceClass::EnumNamedTypeClass;
16401640
return Ok(Some(Box::new(ParsedType::Bare(Type::named_type(
1641-
&*NamedTypeReference::new(ntr_class, QualifiedName::from(enum_name)),
1641+
&*NamedTypeReference::new(ntr_class, enum_name),
16421642
)))));
16431643
}
16441644

@@ -1766,7 +1766,7 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> {
17661766

17671767
let ntr_class = NamedTypeReferenceClass::UnionNamedTypeClass;
17681768
return Ok(Some(Box::new(ParsedType::Bare(Type::named_type(
1769-
&*NamedTypeReference::new(ntr_class, QualifiedName::from(union_name)),
1769+
&*NamedTypeReference::new(ntr_class, union_name),
17701770
)))));
17711771
}
17721772

plugins/warp/src/convert.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -434,11 +434,11 @@ pub fn to_bn_type<A: BNArchitecture>(arch: &A, ty: &Type) -> BNRef<BNType> {
434434
Some(guid) => BNNamedTypeReference::new_with_id(
435435
NamedTypeReferenceClass::UnknownNamedTypeClass,
436436
guid.to_string(),
437-
base_struct_ntr_name.into(),
437+
base_struct_ntr_name,
438438
),
439439
None => BNNamedTypeReference::new(
440440
NamedTypeReferenceClass::UnknownNamedTypeClass,
441-
base_struct_ntr_name.into(),
441+
base_struct_ntr_name,
442442
),
443443
};
444444
base_structs.push(BNBaseStructure::new(
@@ -548,19 +548,19 @@ pub fn to_bn_type<A: BNArchitecture>(arch: &A, ty: &Type) -> BNRef<BNType> {
548548
NamedTypeReference::new_with_id(
549549
NamedTypeReferenceClass::UnknownNamedTypeClass,
550550
guid_str,
551-
ntr_name.into(),
551+
ntr_name,
552552
)
553553
}
554554
None => match c.name.as_ref() {
555555
Some(ntr_name) => NamedTypeReference::new(
556556
NamedTypeReferenceClass::UnknownNamedTypeClass,
557-
ntr_name.into(),
557+
ntr_name,
558558
),
559559
None => {
560560
log::error!("Referrer with no reference! {:?}", c);
561561
NamedTypeReference::new(
562562
NamedTypeReferenceClass::UnknownNamedTypeClass,
563-
"AHHHHHH".into(),
563+
"AHHHHHH",
564564
)
565565
}
566566
},

rust/src/binaryview.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ use std::{ops, result, slice};
5959
use crate::rc::*;
6060
use crate::references::{CodeReference, DataReference};
6161
use crate::string::*;
62+
use crate::typecontainer::TypeContainer;
6263
use crate::variable::DataVariable;
6364
// TODO : general reorg of modules related to bv
6465

@@ -1474,6 +1475,34 @@ pub trait BinaryViewExt: BinaryViewBase {
14741475
unsafe { Array::new(result, count, ()) }
14751476
}
14761477

1478+
/// Type container for all types (user and auto) in the Binary View.
1479+
///
1480+
/// NOTE: Modifying an auto type will promote it to a user type.
1481+
fn type_container(&self) -> TypeContainer {
1482+
let type_container_ptr =
1483+
NonNull::new(unsafe { BNGetAnalysisTypeContainer(self.as_ref().handle) });
1484+
// NOTE: I have no idea how this isn't a UAF, see the note in `TypeContainer::from_raw`
1485+
unsafe { TypeContainer::from_raw(type_container_ptr.unwrap()) }
1486+
}
1487+
1488+
/// Type container for user types in the Binary View.
1489+
fn user_type_container(&self) -> TypeContainer {
1490+
let type_container_ptr =
1491+
NonNull::new(unsafe { BNGetAnalysisUserTypeContainer(self.as_ref().handle) });
1492+
// NOTE: I have no idea how this isn't a UAF, see the note in `TypeContainer::from_raw`
1493+
unsafe { TypeContainer::from_raw(type_container_ptr.unwrap()) }
1494+
}
1495+
1496+
/// Type container for auto types in the Binary View.
1497+
///
1498+
/// NOTE: Unlike [`Self::type_container`] modification of auto types will **NOT** promote it to a user type.
1499+
fn auto_type_container(&self) -> TypeContainer {
1500+
let type_container_ptr =
1501+
NonNull::new(unsafe { BNGetAnalysisAutoTypeContainer(self.as_ref().handle) });
1502+
// NOTE: I have no idea how this isn't a UAF, see the note in `TypeContainer::from_raw`
1503+
unsafe { TypeContainer::from_raw(type_container_ptr.unwrap()) }
1504+
}
1505+
14771506
/// Make the contents of a type library available for type/import resolution
14781507
fn add_type_library(&self, library: &TypeLibrary) {
14791508
unsafe { BNAddBinaryViewTypeLibrary(self.as_ref().handle, library.as_raw()) }

rust/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ pub mod fileaccessor;
148148
pub mod filemetadata;
149149
pub mod flowgraph;
150150
pub mod function;
151-
pub mod typeparser;
152151
pub mod functionrecognizer;
153152
pub mod headless;
154153
pub mod hlil;
@@ -172,7 +171,10 @@ pub mod symbol;
172171
pub mod tags;
173172
pub mod templatesimplifier;
174173
pub mod typearchive;
174+
pub mod typecontainer;
175175
pub mod typelibrary;
176+
pub mod typeparser;
177+
pub mod typeprinter;
176178
pub mod types;
177179
pub mod update;
178180
pub mod variable;

rust/src/platform.rs

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,20 @@
1414

1515
//! Contains all information related to the execution environment of the binary, mainly the calling conventions used
1616
17-
use std::{borrow::Borrow, ffi, ptr};
18-
1917
use binaryninjacore_sys::*;
18+
use std::ptr::NonNull;
19+
use std::{borrow::Borrow, ffi, ptr};
2020

21+
use crate::typecontainer::TypeContainer;
22+
use crate::typeparser::{TypeParserError, TypeParserErrorSeverity, TypeParserResult};
2123
use crate::{
2224
architecture::{Architecture, CoreArchitecture},
2325
callingconvention::CallingConvention,
2426
rc::*,
2527
string::*,
2628
typelibrary::TypeLibrary,
27-
types::{QualifiedName, QualifiedNameAndType, Type},
29+
types::QualifiedNameAndType,
2830
};
29-
use crate::typeparser::{TypeParserError, TypeParserErrorSeverity, TypeParserResult};
3031

3132
#[derive(PartialEq, Eq, Hash)]
3233
pub struct Platform {
@@ -169,6 +170,14 @@ impl Platform {
169170
unsafe { CoreArchitecture::from_raw(BNGetPlatformArchitecture(self.handle)) }
170171
}
171172

173+
pub fn type_container(&self) -> TypeContainer {
174+
let type_container_ptr = NonNull::new(unsafe { BNGetPlatformTypeContainer(self.handle) });
175+
// NOTE: I have no idea how this isn't a UAF, see the note in `TypeContainer::from_raw`
176+
// TODO: We are cloning here for platforms but we dont need to do this for [BinaryViewExt::type_container]
177+
// TODO: Why does this require that we, construct a TypeContainer, duplicate the type container, then drop the original.
178+
unsafe { TypeContainer::from_raw(type_container_ptr.unwrap()).clone() }
179+
}
180+
172181
pub fn get_type_libraries_by_name<T: BnStrCompatible>(&self, name: T) -> Array<TypeLibrary> {
173182
let mut count = 0;
174183
let name = name.into_bytes_with_nul();
@@ -262,6 +271,7 @@ impl Platform {
262271
}
263272
}
264273

274+
// TODO: Documentation, specifically how this differs from the TypeParser impl
265275
pub fn preprocess_source(
266276
&self,
267277
source: &str,
@@ -283,21 +293,23 @@ impl Platform {
283293
include_dirs.len(),
284294
)
285295
};
286-
296+
287297
if success {
288298
assert!(!result.is_null());
289299
Ok(unsafe { BnString::from_raw(result) })
290300
} else {
291301
assert!(!error_string.is_null());
292302
Err(TypeParserError::new(
293303
TypeParserErrorSeverity::FatalSeverity,
294-
unsafe { BnString::from_raw(error_string) },
295-
file_name,
304+
unsafe { BnString::from_raw(error_string) }.to_string(),
305+
file_name.to_string(),
296306
0,
297307
0,
298308
))
299309
}
300310
}
311+
312+
// TODO: Documentation, specifically how this differs from the TypeParser impl
301313
pub fn parse_types_from_source(
302314
&self,
303315
src: &str,
@@ -309,14 +321,14 @@ impl Platform {
309321
let file_name_cstr = BnString::new(filename);
310322
let auto_type_source = BnString::new(auto_type_source);
311323

312-
let mut result = BNTypeParserResult::default();
324+
let mut raw_result = BNTypeParserResult::default();
313325
let mut error_string = ptr::null_mut();
314326
let success = unsafe {
315327
BNParseTypesFromSource(
316328
self.handle,
317329
source_cstr.as_ptr(),
318330
file_name_cstr.as_ptr(),
319-
&mut result,
331+
&mut raw_result,
320332
&mut error_string,
321333
include_dirs.as_ptr() as *mut *const ffi::c_char,
322334
include_dirs.len(),
@@ -325,19 +337,20 @@ impl Platform {
325337
};
326338

327339
if success {
328-
Ok(unsafe { TypeParserResult::from_raw(result) })
340+
Ok(raw_result.into())
329341
} else {
330342
assert!(!error_string.is_null());
331343
Err(TypeParserError::new(
332344
TypeParserErrorSeverity::FatalSeverity,
333-
unsafe { BnString::from_raw(error_string) },
334-
filename,
345+
unsafe { BnString::from_raw(error_string) }.to_string(),
346+
filename.to_string(),
335347
0,
336348
0,
337349
))
338350
}
339351
}
340352

353+
// TODO: Documentation, specifically how this differs from the TypeParser impl
341354
pub fn parse_types_from_source_file(
342355
&self,
343356
filename: &str,
@@ -362,13 +375,13 @@ impl Platform {
362375
};
363376

364377
if success {
365-
Ok(unsafe { TypeParserResult::from_raw(result) })
378+
Ok(result.into())
366379
} else {
367380
assert!(!error_string.is_null());
368381
Err(TypeParserError::new(
369382
TypeParserErrorSeverity::FatalSeverity,
370-
unsafe { BnString::from_raw(error_string) },
371-
filename,
383+
unsafe { BnString::from_raw(error_string) }.to_string(),
384+
filename.to_string(),
372385
0,
373386
0,
374387
))

rust/src/rc.rs

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -203,26 +203,14 @@ pub(crate) unsafe trait CoreArrayProviderInner: CoreArrayProvider {
203203
unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a>;
204204
}
205205

206+
// TODO: I would really like if we impld Debug for this, but lifetimes are hard!
206207
#[allow(private_bounds)]
207208
pub struct Array<P: CoreArrayProviderInner> {
208209
contents: *mut P::Raw,
209210
count: usize,
210211
context: P::Context,
211212
}
212213

213-
unsafe impl<P> Sync for Array<P>
214-
where
215-
P: CoreArrayProviderInner,
216-
P::Context: Sync,
217-
{
218-
}
219-
unsafe impl<P> Send for Array<P>
220-
where
221-
P: CoreArrayProviderInner,
222-
P::Context: Send,
223-
{
224-
}
225-
226214
#[allow(private_bounds)]
227215
impl<P: CoreArrayProviderInner> Array<P> {
228216
pub(crate) unsafe fn new(raw: *mut P::Raw, count: usize, context: P::Context) -> Self {
@@ -242,10 +230,13 @@ impl<P: CoreArrayProviderInner> Array<P> {
242230
pub fn is_empty(&self) -> bool {
243231
self.count == 0
244232
}
245-
}
246233

247-
#[allow(private_bounds)]
248-
impl<P: CoreArrayProviderInner> Array<P> {
234+
pub fn to_vec(&self) -> Vec<P::Wrapped<'_>> {
235+
let mut res = Vec::with_capacity(self.count);
236+
res.extend(self.iter());
237+
res
238+
}
239+
249240
#[inline]
250241
pub fn get(&self, index: usize) -> P::Wrapped<'_> {
251242
unsafe {
@@ -262,6 +253,19 @@ impl<P: CoreArrayProviderInner> Array<P> {
262253
}
263254
}
264255

256+
unsafe impl<P> Sync for Array<P>
257+
where
258+
P: CoreArrayProviderInner,
259+
P::Context: Sync,
260+
{
261+
}
262+
unsafe impl<P> Send for Array<P>
263+
where
264+
P: CoreArrayProviderInner,
265+
P::Context: Send,
266+
{
267+
}
268+
265269
impl<'a, P: CoreArrayProviderInner> IntoIterator for &'a Array<P> {
266270
type Item = P::Wrapped<'a>;
267271
type IntoIter = ArrayIter<'a, P>;

rust/src/string.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ unsafe impl BnStrCompatible for &Path {
277277
type Result = Vec<u8>;
278278

279279
fn into_bytes_with_nul(self) -> Self::Result {
280-
self.to_string_lossy().into_bytes_with_nul()
280+
self.as_os_str().as_encoded_bytes().to_vec()
281281
}
282282
}
283283

0 commit comments

Comments
 (0)