Skip to content

Commit 7d6c475

Browse files
committed
checkpoint
1 parent 16b7e70 commit 7d6c475

14 files changed

+343
-241
lines changed

src/cpu/arm.rs

+10-11
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ impl cpu::Cpu for Arm {
99

1010
fn ptrsize(&self) -> usize {
1111
4
12-
// TODO: thumb
1312
}
1413

1514
fn ret_insns(&self) -> Vec<(Vec<u8>, Vec<u8>)> {
@@ -43,11 +42,11 @@ impl cpu::Cpu for Arm {
4342
}
4443
}
4544

46-
impl std::fmt::Debug for Arm {
47-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48-
f.debug_struct("Arm").finish()
49-
}
50-
}
45+
// impl std::fmt::Debug for Arm {
46+
// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47+
// f.debug_struct("Arm").finish()
48+
// }
49+
// }
5150

5251
pub struct Arm64;
5352

@@ -108,8 +107,8 @@ impl cpu::Cpu for Arm64 {
108107
}
109108
}
110109

111-
impl std::fmt::Debug for Arm64 {
112-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
113-
f.debug_struct("Arm64").finish()
114-
}
115-
}
110+
// impl std::fmt::Debug for Arm64 {
111+
// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
112+
// f.debug_struct("Arm64").finish()
113+
// }
114+
// }

src/cpu/mod.rs

+33-21
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@ pub enum CpuType {
1313
ARM64,
1414
}
1515

16-
pub trait Cpu: Send + Sync + std::fmt::Debug {
16+
pub trait Cpu: Send + Sync {
1717
fn cpu_type(&self) -> CpuType;
1818
fn ptrsize(&self) -> usize;
1919
fn insn_step(&self) -> usize;
2020

2121
//
2222
// for each instruction type, the format is Vector<opcode, mask>
23+
// TODO: replace with &[u8], &[u8]
2324
//
2425

2526
fn ret_insns(&self) -> Vec<(Vec<u8>, Vec<u8>)>;
@@ -31,17 +32,28 @@ pub trait Cpu: Send + Sync + std::fmt::Debug {
3132
}
3233
}
3334

35+
impl std::fmt::Debug for dyn Cpu {
36+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37+
f.debug_struct("Cpu")
38+
.field("cpu_type", &self.cpu_type())
39+
.field("name", &self.name())
40+
.field("ptrsize", &self.ptrsize())
41+
.field("insn_step", &self.insn_step())
42+
.finish()
43+
}
44+
}
45+
3446
impl std::fmt::Display for CpuType {
3547
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36-
let val = match self {
37-
CpuType::X86 => "x86-32",
38-
CpuType::X64 => "x86-64",
39-
CpuType::ARM => "ARM",
40-
CpuType::ARM64 => "ARM64",
41-
CpuType::Unknown => "Unknown",
42-
};
48+
// let val = match self {
49+
// CpuType::X86 => "x86-32",
50+
// CpuType::X64 => "x86-64",
51+
// CpuType::ARM => "ARM",
52+
// CpuType::ARM64 => "ARM64",
53+
// CpuType::Unknown => "Unknown",
54+
// };
4355

44-
write!(f, "Arch={}", val)
56+
write!(f, "{:?}", self)
4557
}
4658
}
4759

@@ -69,15 +81,15 @@ impl From<&goblin::mach::header::Header> for CpuType {
6981
}
7082
}
7183

72-
impl From<&goblin::pe::header::CoffHeader> for CpuType {
73-
fn from(obj: &goblin::pe::header::CoffHeader) -> Self {
74-
match obj.machine {
75-
goblin::pe::header::COFF_MACHINE_X86 => CpuType::X86,
76-
goblin::pe::header::COFF_MACHINE_X86_64 => CpuType::X64,
77-
goblin::pe::header::COFF_MACHINE_ARM => CpuType::ARM,
78-
goblin::pe::header::COFF_MACHINE_ARMNT => CpuType::ARM,
79-
goblin::pe::header::COFF_MACHINE_ARM64 => CpuType::ARM64,
80-
_ => panic!("Unsupported format"),
81-
}
82-
}
83-
}
84+
// impl From<&goblin::pe::header::CoffHeader> for CpuType {
85+
// fn from(obj: &goblin::pe::header::CoffHeader) -> Self {
86+
// match obj.machine {
87+
// goblin::pe::header::COFF_MACHINE_X86 => CpuType::X86,
88+
// goblin::pe::header::COFF_MACHINE_X86_64 => CpuType::X64,
89+
// goblin::pe::header::COFF_MACHINE_ARM => CpuType::ARM,
90+
// goblin::pe::header::COFF_MACHINE_ARMNT => CpuType::ARM,
91+
// goblin::pe::header::COFF_MACHINE_ARM64 => CpuType::ARM64,
92+
// _ => panic!("Unsupported format"),
93+
// }
94+
// }
95+
// }

src/cpu/x86.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,11 @@ impl cpu::Cpu for X86 {
4646
}
4747
}
4848

49-
impl std::fmt::Debug for X86 {
50-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51-
f.debug_struct("X86").finish()
52-
}
53-
}
49+
// impl std::fmt::Debug for X86 {
50+
// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51+
// f.debug_struct("X86").finish()
52+
// }
53+
// }
5454

5555
pub struct X64;
5656

@@ -104,8 +104,8 @@ impl cpu::Cpu for X64 {
104104
}
105105
}
106106

107-
impl std::fmt::Debug for X64 {
108-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
109-
f.debug_struct("X64").finish()
110-
}
111-
}
107+
// impl std::fmt::Debug for X64 {
108+
// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
109+
// f.debug_struct("X64").finish()
110+
// }
111+
// }

src/engine.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ impl Disassembler for CapstoneDisassembler {
7878
}
7979

8080
fn name(&self) -> String {
81-
// todo: add version strings
8281
let (major, minor) = Capstone::lib_version();
8382
format!("Capstone-Engine({}.{})", major, minor)
8483
}
@@ -90,7 +89,7 @@ impl Disassembler for CapstoneDisassembler {
9089

9190
impl std::fmt::Display for CapstoneDisassembler {
9291
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93-
write!(f, "Disassembler({})", self.name())
92+
write!(f, "{}", self.name())
9493
}
9594
}
9695

src/format/elf.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl ExecutableFileFormat for Elf {
107107
FileFormat::Elf
108108
}
109109

110-
fn sections(&self) -> &Vec<Section> {
110+
fn executable_sections(&self) -> &Vec<Section> {
111111
&self.sections
112112
}
113113

src/format/mach.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ impl ExecutableFileFormat for Mach {
9999
FileFormat::MachO
100100
}
101101

102-
fn sections(&self) -> &Vec<Section> {
102+
fn executable_sections(&self) -> &Vec<Section> {
103103
&self.sections
104104
}
105105

src/format/mod.rs

+26-10
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ pub enum FileFormat {
2121

2222
impl std::fmt::Display for FileFormat {
2323
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24-
let val = match self {
25-
FileFormat::Pe => "PE",
26-
FileFormat::Elf => "ELF",
27-
FileFormat::MachO => "MachO",
28-
// _ => panic!("Invalid FileFormat"),
29-
};
30-
31-
write!(f, "BinaryFormat={}", val)
24+
// let val = match self {
25+
// FileFormat::Pe => "PE",
26+
// FileFormat::Elf => "ELF",
27+
// FileFormat::MachO => "MachO",
28+
// // _ => panic!("Invalid FileFormat"),
29+
// };
30+
31+
write!(f, "{:?}", &self)
3232
}
3333
}
3434

@@ -38,7 +38,7 @@ pub trait ExecutableFileFormat: Send + Sync {
3838

3939
fn format(&self) -> FileFormat;
4040

41-
fn sections(&self) -> &Vec<Section>;
41+
fn executable_sections(&self) -> &Vec<Section>;
4242

4343
// fn cpu(&self) -> &dyn cpu::Cpu;
4444

@@ -47,6 +47,23 @@ pub trait ExecutableFileFormat: Send + Sync {
4747
fn entry_point(&self) -> u64;
4848
}
4949

50+
impl std::fmt::Display for dyn ExecutableFileFormat {
51+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52+
write!(f, "{:?}", &self)
53+
}
54+
}
55+
56+
impl std::fmt::Debug for dyn ExecutableFileFormat {
57+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58+
f.debug_struct("ExecutableFileFormat")
59+
.field("format", &self.format().to_string())
60+
.field("executable_sections", &self.executable_sections().len())
61+
.field("cpu_type", &self.cpu_type())
62+
.field("entry_point", &self.entry_point())
63+
.finish()
64+
}
65+
}
66+
5067
/// Attempt to determine the file
5168
pub fn guess_file_format(file: &PathBuf) -> GenericResult<Box<dyn ExecutableFileFormat>> {
5269
if !file.as_path().exists() {
@@ -73,7 +90,6 @@ pub fn guess_file_format(file: &PathBuf) -> GenericResult<Box<dyn ExecutableFile
7390
pub fn try_parse(buf: &[u8]) -> GenericResult<FileFormat> {
7491
match buf.get(0..4) {
7592
Some(magic) => {
76-
println!("{:?}", magic);
7793
if &magic[0..pe::IMAGE_DOS_SIGNATURE.len()] == pe::IMAGE_DOS_SIGNATURE {
7894
Ok(FileFormat::Pe)
7995
} else if &magic[0..elf::ELF_HEADER_MAGIC.len()] == elf::ELF_HEADER_MAGIC {

src/format/pe.rs

+24-14
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
///! Basic implementation of a PE parser, supports x86/64 to extract quickly the sections
33
///!
44
use std::convert::TryInto;
5-
use std::fs::File;
6-
use std::io::Read;
7-
use std::path::PathBuf;
5+
// use std::fs::File;
6+
// use std::io::Read;
7+
// use std::path::PathBuf;
88
use std::{fmt, mem};
99

1010
// use goblin;
@@ -21,7 +21,7 @@ use super::ExecutableFileFormat;
2121
#[derive(Debug, Default)]
2222
pub struct Pe {
2323
// path: PathBuf,
24-
pub sections: Vec<Section>,
24+
pub executable_sections: Vec<Section>,
2525
// cpu: Box<dyn cpu::Cpu>,
2626
pub entry_point: u64,
2727
cpu_type: cpu::CpuType,
@@ -163,6 +163,8 @@ const IMAGE_NT_HEADER_SIZE: usize = mem::size_of::<ImageFileHeader>();
163163
pub const IMAGE_FILE_MACHINE_I386: u16 = 0x014c;
164164
pub const IMAGE_FILE_MACHINE_X86_64: u16 = 0x8664;
165165
pub const IMAGE_FILE_MACHINE_ARM64: u16 = 0xaa64;
166+
pub const IMAGE_FILE_MACHINE_ARMNT: u16 = 0x1c4;
167+
166168
pub const IMAGE_SCN_MEM_EXECUTE: u32 = 0x20000000;
167169
pub const IMAGE_SCN_MEM_READ: u32 = 0x40000000;
168170
pub const IMAGE_SCN_MEM_WRITE: u32 = 0x80000000;
@@ -231,6 +233,7 @@ impl<'a> PeParser<'a> {
231233
IMAGE_FILE_MACHINE_I386 => Ok(cpu::CpuType::X86),
232234
IMAGE_FILE_MACHINE_X86_64 => Ok(cpu::CpuType::X64),
233235
IMAGE_FILE_MACHINE_ARM64 => Ok(cpu::CpuType::ARM64),
236+
IMAGE_FILE_MACHINE_ARMNT => Ok(cpu::CpuType::ARM),
234237
_ => Err(error::Error::UnsupportedCpuError),
235238
}
236239
}?;
@@ -285,9 +288,12 @@ impl<'a> PeParser<'a> {
285288

286289
let opt_hdrs = pe_header.get(IMAGE_NT_HEADER_SIZE..).unwrap();
287290
let image_base_off = match machine {
288-
cpu::CpuType::X86 => mem::offset_of!(ImageOptionalHeader32, image_base),
289-
cpu::CpuType::X64 => mem::offset_of!(ImageOptionalHeader64, image_base),
290-
cpu::CpuType::ARM64 => mem::offset_of!(ImageOptionalHeader64, image_base),
291+
cpu::CpuType::X86 | cpu::CpuType::ARM => {
292+
mem::offset_of!(ImageOptionalHeader32, image_base)
293+
}
294+
cpu::CpuType::X64 | cpu::CpuType::ARM64 => {
295+
mem::offset_of!(ImageOptionalHeader64, image_base)
296+
}
291297
_ => unreachable!(),
292298
} as usize;
293299

@@ -298,9 +304,13 @@ impl<'a> PeParser<'a> {
298304
) as u64;
299305

300306
let entry_point_off = match machine {
301-
cpu::CpuType::X86 => mem::offset_of!(ImageOptionalHeader32, address_of_entry_point),
302-
cpu::CpuType::X64 => mem::offset_of!(ImageOptionalHeader64, address_of_entry_point),
303-
cpu::CpuType::ARM64 => mem::offset_of!(ImageOptionalHeader64, address_of_entry_point),
307+
cpu::CpuType::X86 | cpu::CpuType::ARM => {
308+
mem::offset_of!(ImageOptionalHeader32, address_of_entry_point)
309+
}
310+
311+
cpu::CpuType::X64 | cpu::CpuType::ARM64 => {
312+
mem::offset_of!(ImageOptionalHeader64, address_of_entry_point)
313+
}
304314
_ => unreachable!(),
305315
} as usize;
306316

@@ -483,7 +493,7 @@ impl Pe {
483493
let executable_sections = pe
484494
.sections()?
485495
.into_iter()
486-
.filter(|s| s.permission.contains(Permission::EXECUTABLE))
496+
.filter(|s| s.is_executable())
487497
.collect();
488498

489499
debug!("{:?}", &executable_sections);
@@ -535,7 +545,7 @@ impl Pe {
535545

536546
Ok(Self {
537547
// path: path.clone(),
538-
sections: executable_sections,
548+
executable_sections,
539549
// cpu,
540550
cpu_type: machine,
541551
entry_point: entry_point,
@@ -553,8 +563,8 @@ impl ExecutableFileFormat for Pe {
553563
FileFormat::Pe
554564
}
555565

556-
fn sections(&self) -> &Vec<Section> {
557-
&self.sections
566+
fn executable_sections(&self) -> &Vec<Section> {
567+
&self.executable_sections
558568
}
559569

560570
// fn cpu(&self) -> &dyn cpu::Cpu {

0 commit comments

Comments
 (0)