summaryrefslogtreecommitdiff
path: root/rust/src
diff options
context:
space:
mode:
authorFabian Freyer <fabian.freyer@physik.tu-berlin.de>2022-02-10 23:09:38 +0100
committerKyle Martin <krm504@nyu.edu>2022-02-14 15:28:25 -0500
commit692088fac1a880263491b105ceb4b242402a6d6b (patch)
treef43f71cc11b24d6a86d4be536e0bdf86ec52bfe0 /rust/src
parentee4ac3bb46f83f80b7f9b5b38dca0e2a49dc07e2 (diff)
rust: Add BinaryReader and BinaryWriter
Diffstat (limited to 'rust/src')
-rw-r--r--rust/src/binaryreader.rs85
-rw-r--r--rust/src/binarywriter.rs83
-rw-r--r--rust/src/lib.rs2
3 files changed, 170 insertions, 0 deletions
diff --git a/rust/src/binaryreader.rs b/rust/src/binaryreader.rs
new file mode 100644
index 00000000..c92b9e50
--- /dev/null
+++ b/rust/src/binaryreader.rs
@@ -0,0 +1,85 @@
+use binaryninjacore_sys::*;
+
+use crate::binaryview::BinaryView;
+use crate::Endianness;
+
+use std::io::{Read, Seek, SeekFrom};
+
+pub struct BinaryReader {
+ handle: *mut BNBinaryReader,
+}
+
+impl BinaryReader {
+ pub fn new(view: &BinaryView, endian: Endianness) -> Self {
+ let handle = unsafe { BNCreateBinaryReader(view.handle) };
+ unsafe {
+ BNSetBinaryReaderEndianness(handle, endian);
+ }
+ Self { handle }
+ }
+
+ pub fn endian(&self) -> Endianness {
+ unsafe { BNGetBinaryReaderEndianness(self.handle) }
+ }
+
+ pub fn set_endian(&self, endian: Endianness) {
+ unsafe { BNSetBinaryReaderEndianness(self.handle, endian) }
+ }
+
+ pub fn offset(&self) -> u64 {
+ unsafe { BNGetReaderPosition(self.handle) }
+ }
+
+ pub fn eof(&self) -> bool {
+ unsafe { BNIsEndOfFile(self.handle) }
+ }
+}
+
+impl Seek for BinaryReader {
+ /// Seek to the specified position.
+ ///
+ /// # Errors
+ /// Seeking relative to [SeekFrom::End] is unsupported and will return an error.
+ fn seek(&mut self, pos: SeekFrom) -> std::io::Result<u64> {
+ unsafe {
+ match pos {
+ SeekFrom::Current(offset) => BNSeekBinaryReaderRelative(self.handle, offset),
+ SeekFrom::Start(offset) => BNSeekBinaryReader(self.handle, offset),
+ _ => {
+ return Err(std::io::Error::new(
+ std::io::ErrorKind::Unsupported,
+ "Cannot seek end of BinaryReader",
+ ))
+ }
+ };
+ }
+
+ Ok(self.offset())
+ }
+}
+
+impl Read for BinaryReader {
+ fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
+ let len = buf.len();
+
+ let result = unsafe { BNReadData(self.handle, buf.as_mut_ptr() as *mut _, len) };
+
+ if !result {
+ Err(std::io::Error::new(
+ std::io::ErrorKind::Other,
+ "Read out of bounds",
+ ))
+ } else {
+ Ok(len)
+ }
+ }
+}
+
+impl Drop for BinaryReader {
+ fn drop(&mut self) {
+ unsafe { BNFreeBinaryReader(self.handle) }
+ }
+}
+
+unsafe impl Sync for BinaryReader {}
+unsafe impl Send for BinaryReader {}
diff --git a/rust/src/binarywriter.rs b/rust/src/binarywriter.rs
new file mode 100644
index 00000000..c137af93
--- /dev/null
+++ b/rust/src/binarywriter.rs
@@ -0,0 +1,83 @@
+use binaryninjacore_sys::*;
+
+use crate::binaryview::BinaryView;
+use crate::Endianness;
+
+use std::io::{Seek, SeekFrom, Write};
+
+pub struct BinaryWriter {
+ handle: *mut BNBinaryWriter,
+}
+
+impl BinaryWriter {
+ pub fn new(view: &BinaryView, endian: Endianness) -> Self {
+ let handle = unsafe { BNCreateBinaryWriter(view.handle) };
+ unsafe {
+ BNSetBinaryWriterEndianness(handle, endian);
+ }
+ Self { handle }
+ }
+
+ pub fn endian(&self) -> Endianness {
+ unsafe { BNGetBinaryWriterEndianness(self.handle) }
+ }
+
+ pub fn set_endian(&self, endian: Endianness) {
+ unsafe { BNSetBinaryWriterEndianness(self.handle, endian) }
+ }
+
+ pub fn offset(&self) -> u64 {
+ unsafe { BNGetWriterPosition(self.handle) }
+ }
+}
+
+impl Seek for BinaryWriter {
+ /// Seek to the specified position.
+ ///
+ /// # Errors
+ /// Seeking relative to [SeekFrom::End] is unsupported and will return an error.
+ fn seek(&mut self, pos: SeekFrom) -> std::io::Result<u64> {
+ unsafe {
+ match pos {
+ SeekFrom::Current(offset) => BNSeekBinaryWriterRelative(self.handle, offset),
+ SeekFrom::Start(offset) => BNSeekBinaryWriter(self.handle, offset),
+ _ => {
+ return Err(std::io::Error::new(
+ std::io::ErrorKind::Unsupported,
+ "Cannot seek end of BinaryWriter",
+ ))
+ }
+ };
+ }
+
+ Ok(self.offset())
+ }
+}
+
+impl Write for BinaryWriter {
+ fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
+ let len = buf.len();
+ let result = unsafe { BNWriteData(self.handle, buf.as_ptr() as *mut _, len) };
+ if !result {
+ Err(std::io::Error::new(
+ std::io::ErrorKind::Other,
+ "write out of bounds",
+ ))
+ } else {
+ Ok(len)
+ }
+ }
+
+ fn flush(&mut self) -> std::io::Result<()> {
+ Ok(())
+ }
+}
+
+impl Drop for BinaryWriter {
+ fn drop(&mut self) {
+ unsafe { BNFreeBinaryWriter(self.handle) }
+ }
+}
+
+unsafe impl Sync for BinaryWriter {}
+unsafe impl Send for BinaryWriter {}
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 6555e947..f1fd51f4 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -39,7 +39,9 @@ mod ffi;
pub mod architecture;
pub mod backgroundtask;
pub mod basicblock;
+pub mod binaryreader;
pub mod binaryview;
+pub mod binarywriter;
pub mod callingconvention;
pub mod command;
pub mod custombinaryview;