Repository navigation
Expand file tree
/
Copy pathvaddr.py
More file actions
53 lines (45 loc) · 2.08 KB
/
Copy pathvaddr.py
File metadata and controls
53 lines (45 loc) · 2.08 KB
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
from __future__ import annotations
from refinery.lib.argformats import metavars
from refinery.lib.executable import LT, Executable
from refinery.lib.types import Param
from refinery.units import Arg, Unit
class vaddr(Unit):
"""
Convert a file offset to a virtual address within PE, ELF, or MachO executables.
This unit converts a metadata variable holding a file offset to a virtual address. The variable
will be substituted in place. If you would like to retain the original value, it is recommended
to use the `refinery.put` unit first to create a copy of an already existing variable, and then
convert the copy.
"""
@classmethod
def handles(cls, data) -> bool | None:
from refinery.lib.id import get_executable_type
if get_executable_type(data) is not None:
return True
def __init__(
self, *name: Param[str, Arg.String(help='The name of a metadata variable holding an integer.')],
base: Param[int | None, Arg.Number('-b', metavar='ADDR', help='Optionally specify a custom base address B.')] = None
):
return super().__init__(names=name, base=base)
def _convert(self, data, t: LT):
try:
exe = Executable.Load(data, self.args.base)
except Exception:
self.log_warn('unable to parse input as executable; no variable conversion was performed')
return data
meta = metavars(data)
w = 2 + exe.pointer_size_in_bytes * 2
for name in self.args.names:
value = meta[name]
if not isinstance(value, int):
raise ValueError(F'The variable {name} is not an integer.')
pos = exe.lookup_location(value, t)
self.log_debug('determined location:', pos)
val = pos.virtual.position if t == LT.PHYSICAL else pos.physical.position
self.log_info(F'{value:#0{w}x} to {val:#0{w}x}')
meta[name] = val
return data
def process(self, data):
return self._convert(data, LT.PHYSICAL)
def reverse(self, data):
return self._convert(data, LT.VIRTUAL)