1from typing import Optional, Union
2
3from pyvex.block import IRSB
4from pyvex.types import Arch, LiftSource
5
6# pylint:disable=attribute-defined-outside-init
7
8
9class Lifter:
10 __slots__ = (
11 "data",
12 "bytes_offset",
13 "opt_level",
14 "traceflags",
15 "allow_arch_optimizations",
16 "strict_block_end",
17 "collect_data_refs",
18 "max_inst",
19 "max_bytes",
20 "skip_stmts",
21 "irsb",
22 "arch",
23 "addr",
24 "cross_insn_opt",
25 "load_from_ro_regions",
26 "disasm",
27 "dump_irsb",
28 )
29
30 """
31 A lifter is a class of methods for processing a block.
32
33 :ivar data: The bytes to lift as either a python string of bytes or a cffi buffer object.
34 :ivar bytes_offset: The offset into `data` to start lifting at.
35 :ivar max_bytes: The maximum number of bytes to lift. If set to None, no byte limit is used.
36 :ivar max_inst: The maximum number of instructions to lift. If set to None, no instruction limit is used.
37 :ivar opt_level: The level of optimization to apply to the IR, 0-2. Most likely will be ignored in any lifter
38 other then LibVEX.
39 :ivar traceflags: The libVEX traceflags, controlling VEX debug prints. Most likely will be ignored in any
40 lifter other than LibVEX.
41 :ivar allow_arch_optimizations: Should the LibVEX lifter be allowed to perform lift-time preprocessing
42 optimizations (e.g., lookback ITSTATE optimization on THUMB)
43 Most likely will be ignored in any lifter other than LibVEX.
44 :ivar strict_block_end: Should the LibVEX arm-thumb split block at some instructions, for example CB{N}Z.
45 :ivar skip_stmts: Should LibVEX ignore statements.
46 """
47 REQUIRE_DATA_C = False
48 REQUIRE_DATA_PY = False
49
50 def __init__(self, arch: Arch, addr: int):
51 self.arch: Arch = arch
52 self.addr: int = addr
53
54 def lift(
55 self,
56 data: LiftSource,
57 bytes_offset: Optional[int] = None,
58 max_bytes: Optional[int] = None,
59 max_inst: Optional[int] = None,
60 opt_level: Union[int, float] = 1,
61 traceflags: Optional[int] = None,
62 allow_arch_optimizations: Optional[bool] = None,
63 strict_block_end: Optional[bool] = None,
64 skip_stmts: bool = False,
65 collect_data_refs: bool = False,
66 cross_insn_opt: bool = True,
67 load_from_ro_regions: bool = False,
68 disasm: bool = False,
69 dump_irsb: bool = False,
70 ):
71 """
72 Wrapper around the `_lift` method on Lifters. Should not be overridden in child classes.
73
74 :param data: The bytes to lift as either a python string of bytes or a cffi buffer object.
75 :param bytes_offset: The offset into `data` to start lifting at.
76 :param max_bytes: The maximum number of bytes to lift. If set to None, no byte limit is used.
77 :param max_inst: The maximum number of instructions to lift. If set to None, no instruction limit is
78 used.
79 :param opt_level: The level of optimization to apply to the IR, 0-2. Most likely will be ignored in
80 any lifter other then LibVEX.
81 :param traceflags: The libVEX traceflags, controlling VEX debug prints. Most likely will be ignored in
82 any lifter other than LibVEX.
83 :param allow_arch_optimizations: Should the LibVEX lifter be allowed to perform lift-time preprocessing
84 optimizations (e.g., lookback ITSTATE optimization on THUMB) Most likely will be
85 ignored in any lifter other than LibVEX.
86 :param strict_block_end: Should the LibVEX arm-thumb split block at some instructions, for example CB{N}Z.
87 :param skip_stmts: Should the lifter skip transferring IRStmts from C to Python.
88 :param collect_data_refs: Should the LibVEX lifter collect data references in C.
89 :param cross_insn_opt: If cross-instruction-boundary optimizations are allowed or not.
90 :param disasm: Should the GymratLifter generate disassembly during lifting.
91 :param dump_irsb: Should the GymratLifter log the lifted IRSB.
92 """
93 irsb: IRSB = IRSB.empty_block(self.arch, self.addr)
94 self.data = data
95 self.bytes_offset = bytes_offset
96 self.opt_level = opt_level
97 self.traceflags = traceflags
98 self.allow_arch_optimizations = allow_arch_optimizations
99 self.strict_block_end = strict_block_end
100 self.collect_data_refs = collect_data_refs
101 self.max_inst = max_inst
102 self.max_bytes = max_bytes
103 self.skip_stmts = skip_stmts
104 self.irsb = irsb
105 self.cross_insn_opt = cross_insn_opt
106 self.load_from_ro_regions = load_from_ro_regions
107 self.disasm = disasm
108 self.dump_irsb = dump_irsb
109 self._lift()
110 return self.irsb
111
112 def _lift(self):
113 """
114 Lifts the data using the information passed into _lift. Should be overridden in child classes.
115
116 Should set the lifted IRSB to self.irsb.
117 If a lifter raises a LiftingException on the data, this signals that the lifter cannot lift this data and arch
118 and the lifter is skipped.
119 If a lifter can lift any amount of data, it should lift it and return the lifted block with a jumpkind of
120 Ijk_NoDecode, signalling to pyvex that other lifters should be used on the undecodable data.
121
122 """
123 raise NotImplementedError()