yaxpeax_core/memory/repr/
adapter.rs

1use yaxpeax_arch::{Arch, Address};
2use memory::{MemoryRange, MemoryRepr, Named};
3use memory::repr::{FlatMemoryRepr, ReadCursor};
4use memory::repr::process::ModuleInfo;
5use std::ops::Range;
6
7pub trait MemoryAdapter<
8    'a,
9    AAddr: Address,
10    BAddr: Address,
11    A: Arch<Address = AAddr>,
12    B: Arch<Address = BAddr, Word = A::Word>,
13    M: MemoryRepr<A> + ?Sized
14> {
15    fn to_address_space(&'a self) -> MemoryReprAdapter<'a, AAddr, BAddr, A, B, M>;
16}
17
18#[derive(Debug)]
19pub struct MemoryReprAdapter<
20    'a,
21    AAddr: Address,
22    BAddr: Address,
23    A: Arch<Address = AAddr>,
24    B: Arch<Address = BAddr, Word = A::Word>,
25    M: MemoryRepr<A> + ?Sized
26> {
27    repr: &'a M,
28    f: fn(B::Address) -> A::Address
29}
30
31fn f_u16_to_usize(u: u16) -> usize { u as usize }
32
33impl <
34    'a,
35    A: Arch<Address = usize>,
36    B: Arch<Word = A::Word, Address = u16>,
37    M: MemoryRepr<A> + ?Sized
38> MemoryAdapter<'a, usize, u16, A, B, M> for M {
39    fn to_address_space(&'a self) -> MemoryReprAdapter<'a, usize, u16, A, B, M> {
40        MemoryReprAdapter {
41            repr: self,
42            f: f_u16_to_usize
43        }
44    }
45}
46
47impl <
48    'a,
49    A: Arch<Address = usize>,
50    B: Arch<Word = A::Word, Address = u16>,
51    M: MemoryRepr<A>
52> MemoryRepr<B> for MemoryReprAdapter<'a, usize, u16, A, B, M> {
53    fn read(&self, addr: u16) -> Option<u8> {
54        self.repr.read((self.f)(addr))
55    }
56    fn as_flat(&self) -> Option<FlatMemoryRepr> { None }
57    fn module_info(&self) -> Option<&ModuleInfo> { self.repr.module_info() }
58    fn module_for(&self, _addr: u16) -> Option<&dyn MemoryRepr<B>> {
59        None
60        // TODO: figure out if it's possible to write this?
61        // this really messes up stuff...
62    }
63    fn size(&self) -> Option<u64> { self.repr.size() }
64}
65
66impl <
67    'a,
68    A: Arch<Address = usize>,
69    B: Arch<Word = A::Word, Address = u16>,
70    M: MemoryRepr<A>
71> Named for MemoryReprAdapter<'a, usize, u16, A, B, M> {
72    fn name(&self) -> &str { self.repr.name() }
73}
74
75fn f_u32_to_usize(u: u32) -> usize { u as usize }
76
77impl <
78    'a,
79    A: Arch<Address = usize>,
80    B: Arch<Word = A::Word, Address = u32>,
81    M: MemoryRepr<A>
82> MemoryAdapter<'a, usize, u32, A, B, M> for M {
83    fn to_address_space(&'a self) -> MemoryReprAdapter<'a, usize, u32, A, B, M> {
84        MemoryReprAdapter {
85            repr: self,
86            f: f_u32_to_usize
87        }
88    }
89}
90
91impl <
92    'a,
93    A: Arch<Address = usize>,
94    B: Arch<Word = A::Word, Address = u32>,
95    M: MemoryRepr<A>
96> MemoryRepr<B> for MemoryReprAdapter<'a, usize, u32, A, B, M> {
97    fn read(&self, addr: u32) -> Option<u8> {
98        self.repr.read((self.f)(addr))
99    }
100    fn as_flat(&self) -> Option<FlatMemoryRepr> { None }
101    fn module_info(&self) -> Option<&ModuleInfo> { self.repr.module_info() }
102    fn module_for(&self, _addr: u32) -> Option<&dyn MemoryRepr<B>> {
103        None
104        // TODO: figure out if it's possible to write this?
105        // self.repr.module_for((self.f)(addr))
106    }
107    fn size(&self) -> Option<u64> { self.repr.size() }
108}
109
110impl <
111    'a,
112    A: Arch<Address = usize>,
113    B: Arch<Word = A::Word, Address = u32>,
114    M: MemoryRepr<A>
115> Named for MemoryReprAdapter<'a, usize, u32, A, B, M> {
116    fn name(&self) -> &str { self.repr.name() }
117}
118
119fn f_u64_to_usize(u: u64) -> usize { u as usize }
120
121impl <
122    'a,
123    A: Arch<Address = usize>,
124    B: Arch<Word = A::Word, Address = u64>,
125    M: MemoryRepr<A>
126> MemoryAdapter<'a, usize, u64, A, B, M> for M {
127    fn to_address_space(&'a self) -> MemoryReprAdapter<'a, usize, u64, A, B, M> {
128        MemoryReprAdapter {
129            repr: self,
130            f: f_u64_to_usize
131        }
132    }
133}
134
135impl <
136    'a,
137    A: Arch<Address = usize>,
138    B: Arch<Word = A::Word, Address = u64>,
139    M: MemoryRepr<A>
140> MemoryRepr<B> for MemoryReprAdapter<'a, usize, u64, A, B, M> {
141    fn read(&self, addr: u64) -> Option<u8> {
142        self.repr.read((self.f)(addr))
143    }
144    fn as_flat(&self) -> Option<FlatMemoryRepr> { None }
145    fn module_info(&self) -> Option<&ModuleInfo> { self.repr.module_info() }
146    fn module_for(&self, _addr: u64) -> Option<&dyn MemoryRepr<B>> {
147        None
148        // TODO: figure out if it's possible to write this?
149        // self.repr.module_for((self.f)(addr))
150    }
151    fn size(&self) -> Option<u64> { self.repr.size() }
152}
153
154impl <
155    'a,
156    A: Arch<Address = usize>,
157    B: Arch<Word = A::Word, Address = u64>,
158    M: MemoryRepr<A>
159> Named for MemoryReprAdapter<'a, usize, u64, A, B, M> {
160    fn name(&self) -> &str { self.repr.name() }
161}
162
163impl <
164    'a,
165    A: Arch,
166    B: Arch<Word = A::Word>,
167    M: MemoryRepr<A> + MemoryRange<A>
168> MemoryRange<B> for MemoryReprAdapter<'a, A::Address, B::Address, A, B, M> where Self: MemoryRepr<B> {
169    // TODO: I am incredibly lazy, plz ignore
170    fn range<'c>(&'c self, range: Range<B::Address>) -> Option<ReadCursor<'c, B, Self>> {
171        let valid_range = self.repr.range((self.f)(range.start)..(self.f)(range.end));
172        if valid_range.is_some() {
173            Some(ReadCursor::from(self, range.start, Some(range.end)))
174        } else {
175            None
176        }
177    }
178    fn range_from<'c>(&'c self, start: B::Address) -> Option<ReadCursor<'c, B, Self>> {
179        let valid_range = self.repr.range_from((self.f)(start));
180        if valid_range.is_some() {
181            Some(ReadCursor::from(self, start, None))
182        } else {
183            None
184        }
185    }
186}