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
use yaxpeax_arch::{Arch, AddressBase};
use std::cell::RefCell;
use memory::repr::FlatMemoryRepr;
use memory::{MemoryRange, MemoryRepr, Named};
use debug::Peek;
use std::ops::Range;
use memory::repr::process::ModuleInfo;
use memory::repr::cursor::ReadCursor;
pub struct RemoteMemoryRepr<T: Peek> {
pub cache: RefCell<Vec<(usize, Vec<u8>)>>,
pub last_addr: RefCell<usize>,
pub dirty_bit: bool,
pub target: T
}
impl <A: Arch, T: Peek> MemoryRange<A> for RemoteMemoryRepr<T> {
fn range<'a>(&'a self, range: Range<A::Address>) -> Option<ReadCursor<'a, A, Self>> {
Some(ReadCursor::from(self, range.start, Some(range.end)))
}
fn range_from<'a>(&'a self, start: A::Address) -> Option<ReadCursor<'a, A, Self>> {
Some(ReadCursor::from(self, start, None))
}
}
impl <A: Arch, T: Peek> MemoryRepr<A> for RemoteMemoryRepr<T> {
fn read(&self, addr: A::Address) -> Option<u8> {
let mut cache = self.cache.borrow_mut();
if *self.last_addr.borrow() + 1 != addr.to_linear() {
*cache = Vec::new();
}
let addr = addr.to_linear();
let line = cache.iter().find(|(start, data)| addr >= *start && addr < *start + data.len());
eprintln!("cache line result for address {:#x}: {:?}", addr.to_linear(), line.map(|(s, _)| s));
if line.is_none() {
let mut new_data = vec![];
if self.target.read_bytes(addr & !255, 256, &mut new_data).is_some() {
cache.push((addr & !255, new_data));
}
}
cache.iter().find(|(start, data)| addr >= *start && addr < *start + data.len()).map(|(start, data)| {
*self.last_addr.borrow_mut() = addr;
data[addr - start]
})
}
fn as_flat(&self) -> Option<FlatMemoryRepr> {
None
}
fn module_info(&self) -> Option<&ModuleInfo> { None }
fn module_for(&self, _addr: A::Address) -> Option<&dyn MemoryRepr<A>> {
None
}
fn size(&self) -> Option<u64> {
Some(std::u64::MAX)
}
}
impl <T: Peek> Named for RemoteMemoryRepr<T> {
fn name(&self) -> &str {
"remote target"
}
}