1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use yaxpeax_arch::{Arch, AddressBase};
use memory::repr::ReadCursor;
use memory::{LayoutError, MemoryRange, MemoryRepr, Named, PatchyMemoryRepr};
use memory::repr::process::ModuleInfo;
use std::ops::Range;
#[derive(Clone, Debug)]
pub struct FlatMemoryRepr {
data: Vec<u8>,
pub name: String
}
impl FlatMemoryRepr {
pub fn empty(name: String) -> FlatMemoryRepr {
FlatMemoryRepr {
data: vec![],
name: name
}
}
pub fn of(data: Vec<u8>) -> FlatMemoryRepr {
let mut mem = FlatMemoryRepr::empty("anon_flat_repr".to_string());
mem.add(data, 0 as usize).unwrap();
mem
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn add(&mut self, data: Vec<u8>, offset: usize) -> Result<(), LayoutError> {
let mut cursor = 0;
if data.len() + offset > self.data.len() {
let needed = (data.len() + offset) - self.data.len();
self.data.reserve(needed);
}
if offset < self.data.len() {
while (cursor + offset) < self.data.len() && cursor < data.len() {
self.data[cursor + offset] = self.data[cursor];
cursor += 1;
}
}
while cursor < data.len() {
self.data.push(data[cursor]);
cursor += 1;
}
Ok(())
}
pub(crate) fn data(&self) -> &[u8] {
&self.data[..]
}
}
impl <A: Arch> MemoryRepr<A> for FlatMemoryRepr {
fn read(&self, addr: A::Address) -> Option<u8> {
if addr.to_linear() < self.data.len() {
Some(self.data[addr.to_linear()])
} else {
None
}
}
fn as_flat(&self) -> Option<FlatMemoryRepr> {
Some(self.clone())
}
fn module_info(&self) -> Option<&ModuleInfo> { None }
fn module_for(&self, _addr: A::Address) -> Option<&dyn MemoryRepr<A>> {
Some(self)
}
fn size(&self) -> Option<u64> {
Some(self.data.len() as u64)
}
}
impl Named for FlatMemoryRepr {
fn name(&self) -> &str {
&self.name
}
}
impl <A: Arch> PatchyMemoryRepr<A> for FlatMemoryRepr {
fn add(&mut self, data: Vec<u8>, addr: A::Address) -> Result<(), LayoutError> {
FlatMemoryRepr::add(self, data, addr.to_linear())
}
}
impl <A: Arch> MemoryRange<A> for FlatMemoryRepr {
fn range<'a>(&'a self, range: Range<A::Address>) -> Option<ReadCursor<'a, A, Self>> {
if range.start.to_linear() < self.data.len() && range.end.to_linear() < self.data.len() && range.start < range.end {
Some(ReadCursor::from(self, range.start, Some(range.end)))
} else {
None
}
}
fn range_from<'a>(&'a self, start: A::Address) -> Option<ReadCursor<'a, A, Self>> {
if start.to_linear() < self.data.len() {
Some(ReadCursor::from(self, start, None))
} else {
None
}
}
}