smallworld-re 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- smallworld/__init__.py +35 -0
- smallworld/analyses/__init__.py +14 -0
- smallworld/analyses/analysis.py +88 -0
- smallworld/analyses/code_coverage.py +31 -0
- smallworld/analyses/colorizer.py +682 -0
- smallworld/analyses/colorizer_summary.py +100 -0
- smallworld/analyses/field_detection/__init__.py +14 -0
- smallworld/analyses/field_detection/field_analysis.py +536 -0
- smallworld/analyses/field_detection/guards.py +26 -0
- smallworld/analyses/field_detection/hints.py +133 -0
- smallworld/analyses/field_detection/malloc.py +211 -0
- smallworld/analyses/forced_exec/__init__.py +3 -0
- smallworld/analyses/forced_exec/forced_exec.py +87 -0
- smallworld/analyses/underlays/__init__.py +4 -0
- smallworld/analyses/underlays/basic.py +13 -0
- smallworld/analyses/underlays/underlay.py +31 -0
- smallworld/analyses/unstable/__init__.py +4 -0
- smallworld/analyses/unstable/angr/__init__.py +0 -0
- smallworld/analyses/unstable/angr/base.py +12 -0
- smallworld/analyses/unstable/angr/divergence.py +274 -0
- smallworld/analyses/unstable/angr/model.py +383 -0
- smallworld/analyses/unstable/angr/nwbt.py +63 -0
- smallworld/analyses/unstable/angr/typedefs.py +170 -0
- smallworld/analyses/unstable/angr/utils.py +25 -0
- smallworld/analyses/unstable/angr/visitor.py +315 -0
- smallworld/analyses/unstable/angr_nwbt.py +106 -0
- smallworld/analyses/unstable/code_coverage.py +54 -0
- smallworld/analyses/unstable/code_reachable.py +44 -0
- smallworld/analyses/unstable/control_flow_tracer.py +71 -0
- smallworld/analyses/unstable/pointer_finder.py +90 -0
- smallworld/arch/__init__.py +0 -0
- smallworld/arch/aarch64_arch.py +286 -0
- smallworld/arch/amd64_arch.py +86 -0
- smallworld/arch/i386_arch.py +44 -0
- smallworld/emulators/__init__.py +14 -0
- smallworld/emulators/angr/__init__.py +7 -0
- smallworld/emulators/angr/angr.py +1652 -0
- smallworld/emulators/angr/default.py +15 -0
- smallworld/emulators/angr/exceptions.py +7 -0
- smallworld/emulators/angr/exploration/__init__.py +9 -0
- smallworld/emulators/angr/exploration/bounds.py +27 -0
- smallworld/emulators/angr/exploration/default.py +17 -0
- smallworld/emulators/angr/exploration/terminate.py +22 -0
- smallworld/emulators/angr/factory.py +55 -0
- smallworld/emulators/angr/machdefs/__init__.py +35 -0
- smallworld/emulators/angr/machdefs/aarch64.py +292 -0
- smallworld/emulators/angr/machdefs/amd64.py +192 -0
- smallworld/emulators/angr/machdefs/arm.py +387 -0
- smallworld/emulators/angr/machdefs/i386.py +221 -0
- smallworld/emulators/angr/machdefs/machdef.py +138 -0
- smallworld/emulators/angr/machdefs/mips.py +184 -0
- smallworld/emulators/angr/machdefs/mips64.py +189 -0
- smallworld/emulators/angr/machdefs/ppc.py +101 -0
- smallworld/emulators/angr/machdefs/riscv.py +261 -0
- smallworld/emulators/angr/machdefs/xtensa.py +255 -0
- smallworld/emulators/angr/memory/__init__.py +7 -0
- smallworld/emulators/angr/memory/default.py +10 -0
- smallworld/emulators/angr/memory/fixups.py +43 -0
- smallworld/emulators/angr/memory/memtrack.py +105 -0
- smallworld/emulators/angr/scratch.py +43 -0
- smallworld/emulators/angr/simos.py +53 -0
- smallworld/emulators/angr/utils.py +70 -0
- smallworld/emulators/emulator.py +1013 -0
- smallworld/emulators/hookable.py +252 -0
- smallworld/emulators/panda/__init__.py +5 -0
- smallworld/emulators/panda/machdefs/__init__.py +28 -0
- smallworld/emulators/panda/machdefs/aarch64.py +93 -0
- smallworld/emulators/panda/machdefs/amd64.py +71 -0
- smallworld/emulators/panda/machdefs/arm.py +89 -0
- smallworld/emulators/panda/machdefs/i386.py +36 -0
- smallworld/emulators/panda/machdefs/machdef.py +86 -0
- smallworld/emulators/panda/machdefs/mips.py +94 -0
- smallworld/emulators/panda/machdefs/mips64.py +91 -0
- smallworld/emulators/panda/machdefs/ppc.py +79 -0
- smallworld/emulators/panda/panda.py +575 -0
- smallworld/emulators/unicorn/__init__.py +13 -0
- smallworld/emulators/unicorn/machdefs/__init__.py +28 -0
- smallworld/emulators/unicorn/machdefs/aarch64.py +310 -0
- smallworld/emulators/unicorn/machdefs/amd64.py +326 -0
- smallworld/emulators/unicorn/machdefs/arm.py +321 -0
- smallworld/emulators/unicorn/machdefs/i386.py +137 -0
- smallworld/emulators/unicorn/machdefs/machdef.py +117 -0
- smallworld/emulators/unicorn/machdefs/mips.py +202 -0
- smallworld/emulators/unicorn/unicorn.py +684 -0
- smallworld/exceptions/__init__.py +5 -0
- smallworld/exceptions/exceptions.py +85 -0
- smallworld/exceptions/unstable/__init__.py +1 -0
- smallworld/exceptions/unstable/exceptions.py +25 -0
- smallworld/extern/__init__.py +4 -0
- smallworld/extern/ctypes.py +94 -0
- smallworld/extern/unstable/__init__.py +1 -0
- smallworld/extern/unstable/ghidra.py +129 -0
- smallworld/helpers.py +107 -0
- smallworld/hinting/__init__.py +8 -0
- smallworld/hinting/hinting.py +214 -0
- smallworld/hinting/hints.py +427 -0
- smallworld/hinting/unstable/__init__.py +2 -0
- smallworld/hinting/utils.py +19 -0
- smallworld/instructions/__init__.py +18 -0
- smallworld/instructions/aarch64.py +20 -0
- smallworld/instructions/arm.py +18 -0
- smallworld/instructions/bsid.py +67 -0
- smallworld/instructions/instructions.py +258 -0
- smallworld/instructions/mips.py +21 -0
- smallworld/instructions/x86.py +100 -0
- smallworld/logging.py +90 -0
- smallworld/platforms.py +95 -0
- smallworld/py.typed +0 -0
- smallworld/state/__init__.py +6 -0
- smallworld/state/cpus/__init__.py +32 -0
- smallworld/state/cpus/aarch64.py +563 -0
- smallworld/state/cpus/amd64.py +676 -0
- smallworld/state/cpus/arm.py +630 -0
- smallworld/state/cpus/cpu.py +71 -0
- smallworld/state/cpus/i386.py +239 -0
- smallworld/state/cpus/mips.py +374 -0
- smallworld/state/cpus/mips64.py +372 -0
- smallworld/state/cpus/powerpc.py +229 -0
- smallworld/state/cpus/riscv.py +357 -0
- smallworld/state/cpus/xtensa.py +80 -0
- smallworld/state/memory/__init__.py +7 -0
- smallworld/state/memory/code.py +70 -0
- smallworld/state/memory/elf/__init__.py +3 -0
- smallworld/state/memory/elf/elf.py +564 -0
- smallworld/state/memory/elf/rela/__init__.py +32 -0
- smallworld/state/memory/elf/rela/aarch64.py +27 -0
- smallworld/state/memory/elf/rela/amd64.py +32 -0
- smallworld/state/memory/elf/rela/arm.py +51 -0
- smallworld/state/memory/elf/rela/i386.py +32 -0
- smallworld/state/memory/elf/rela/mips.py +45 -0
- smallworld/state/memory/elf/rela/ppc.py +45 -0
- smallworld/state/memory/elf/rela/rela.py +63 -0
- smallworld/state/memory/elf/rela/riscv64.py +27 -0
- smallworld/state/memory/elf/rela/xtensa.py +15 -0
- smallworld/state/memory/elf/structs.py +55 -0
- smallworld/state/memory/heap.py +85 -0
- smallworld/state/memory/memory.py +181 -0
- smallworld/state/memory/stack/__init__.py +31 -0
- smallworld/state/memory/stack/aarch64.py +22 -0
- smallworld/state/memory/stack/amd64.py +42 -0
- smallworld/state/memory/stack/arm.py +66 -0
- smallworld/state/memory/stack/i386.py +22 -0
- smallworld/state/memory/stack/mips.py +34 -0
- smallworld/state/memory/stack/mips64.py +34 -0
- smallworld/state/memory/stack/ppc.py +34 -0
- smallworld/state/memory/stack/riscv.py +22 -0
- smallworld/state/memory/stack/stack.py +127 -0
- smallworld/state/memory/stack/xtensa.py +34 -0
- smallworld/state/models/__init__.py +6 -0
- smallworld/state/models/mmio.py +186 -0
- smallworld/state/models/model.py +163 -0
- smallworld/state/models/posix.py +455 -0
- smallworld/state/models/x86/__init__.py +2 -0
- smallworld/state/models/x86/microsoftcdecl.py +35 -0
- smallworld/state/models/x86/systemv.py +240 -0
- smallworld/state/state.py +962 -0
- smallworld/state/unstable/__init__.py +0 -0
- smallworld/state/unstable/elf.py +393 -0
- smallworld/state/x86_registers.py +30 -0
- smallworld/utils.py +935 -0
- smallworld_re-1.0.0.dist-info/LICENSE.txt +21 -0
- smallworld_re-1.0.0.dist-info/METADATA +189 -0
- smallworld_re-1.0.0.dist-info/RECORD +166 -0
- smallworld_re-1.0.0.dist-info/WHEEL +5 -0
- smallworld_re-1.0.0.dist-info/entry_points.txt +2 -0
- smallworld_re-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,427 @@
|
|
1
|
+
import typing
|
2
|
+
from dataclasses import dataclass
|
3
|
+
|
4
|
+
from .. import hinting
|
5
|
+
|
6
|
+
|
7
|
+
@dataclass(frozen=True)
|
8
|
+
class PointerHint(hinting.Hint):
|
9
|
+
"""We found a pointer
|
10
|
+
|
11
|
+
Arguments:
|
12
|
+
instruction: The instruction containing the pointer.
|
13
|
+
pointer: The pointer.
|
14
|
+
"""
|
15
|
+
|
16
|
+
instruction: typing.Any
|
17
|
+
pointer: typing.Any
|
18
|
+
|
19
|
+
|
20
|
+
@dataclass(frozen=True)
|
21
|
+
class ControlFlowHint(hinting.Hint):
|
22
|
+
"""Represents control flow going from the from_instruction to the to_instruction.
|
23
|
+
|
24
|
+
Arguments:
|
25
|
+
from_instruction: The from instruction
|
26
|
+
to_instruction: The to instruction
|
27
|
+
"""
|
28
|
+
|
29
|
+
from_instruction: typing.Any
|
30
|
+
to_instruction: typing.Any
|
31
|
+
|
32
|
+
|
33
|
+
@dataclass(frozen=True)
|
34
|
+
class CoverageHint(hinting.Hint):
|
35
|
+
"""Holds the a map of program counter to hit counter for an execution.
|
36
|
+
|
37
|
+
Arguments:
|
38
|
+
coverage: A map from program counter to hit count
|
39
|
+
"""
|
40
|
+
|
41
|
+
coverage: typing.Dict[int, int]
|
42
|
+
|
43
|
+
|
44
|
+
@dataclass(frozen=True)
|
45
|
+
class ReachableCodeHint(hinting.Hint):
|
46
|
+
"""Indicates that we can get to a given program counter with symbolic execution.
|
47
|
+
|
48
|
+
Arguments:
|
49
|
+
address: The address we can reach
|
50
|
+
"""
|
51
|
+
|
52
|
+
address: int
|
53
|
+
|
54
|
+
|
55
|
+
@dataclass(frozen=True)
|
56
|
+
class EmulationException(hinting.Hint):
|
57
|
+
"""Something went wrong emulating this instruction"""
|
58
|
+
|
59
|
+
# instruction: typing.Any
|
60
|
+
pc: int
|
61
|
+
instruction_num: int
|
62
|
+
exception: str
|
63
|
+
|
64
|
+
|
65
|
+
@dataclass(frozen=True)
|
66
|
+
class UnderSpecifiedValueHint(hinting.Hint):
|
67
|
+
"""Super class for UnderSpecified Value Hints"""
|
68
|
+
|
69
|
+
instruction: typing.Any
|
70
|
+
|
71
|
+
|
72
|
+
@dataclass(frozen=True)
|
73
|
+
class UnderSpecifiedRegisterHint(UnderSpecifiedValueHint):
|
74
|
+
"""Represents a register whose value can't be fully determined from the environment.
|
75
|
+
|
76
|
+
Arguments:
|
77
|
+
register: The register in question
|
78
|
+
"""
|
79
|
+
|
80
|
+
register: str
|
81
|
+
|
82
|
+
|
83
|
+
@dataclass(frozen=True)
|
84
|
+
class UnderSpecifiedMemoryHint(UnderSpecifiedValueHint):
|
85
|
+
"""Represents a memory range whose value can't be fully determined from the environment.
|
86
|
+
|
87
|
+
Arguments:
|
88
|
+
address: The address of the beginning of the range
|
89
|
+
size: The size of the range
|
90
|
+
"""
|
91
|
+
|
92
|
+
address: int
|
93
|
+
size: int
|
94
|
+
|
95
|
+
|
96
|
+
@dataclass(frozen=True)
|
97
|
+
class UnderSpecifiedMemoryRefHint(UnderSpecifiedValueHint):
|
98
|
+
"""Represents a memory range whose value can't be fully determined from the environment.
|
99
|
+
|
100
|
+
Arguments:
|
101
|
+
address: The address of the beginning of the range
|
102
|
+
size: The size of the range
|
103
|
+
"""
|
104
|
+
|
105
|
+
base: typing.Tuple[str, int]
|
106
|
+
index: typing.Tuple[str, int]
|
107
|
+
offset: int
|
108
|
+
|
109
|
+
|
110
|
+
@dataclass(frozen=True)
|
111
|
+
class UnderSpecifiedAddressHint(UnderSpecifiedValueHint):
|
112
|
+
"""Represents a symbolic address that can't be resolved from the environment.
|
113
|
+
Arguments:
|
114
|
+
symbol: Name of the symbolic value
|
115
|
+
addr: Address expression containing the symbol
|
116
|
+
"""
|
117
|
+
|
118
|
+
symbol: str
|
119
|
+
addr: str
|
120
|
+
|
121
|
+
|
122
|
+
@dataclass(frozen=True)
|
123
|
+
class TypedUnderSpecifiedRegisterHint(UnderSpecifiedRegisterHint):
|
124
|
+
typedef: str
|
125
|
+
value: str
|
126
|
+
|
127
|
+
|
128
|
+
@dataclass(frozen=True)
|
129
|
+
class UntypedUnderSpecifiedRegisterHint(UnderSpecifiedRegisterHint):
|
130
|
+
value: str
|
131
|
+
|
132
|
+
|
133
|
+
@dataclass(frozen=True)
|
134
|
+
class TypedUnderSpecifiedMemoryHint(UnderSpecifiedMemoryHint):
|
135
|
+
typedef: str
|
136
|
+
value: str
|
137
|
+
|
138
|
+
|
139
|
+
@dataclass(frozen=True)
|
140
|
+
class UntypedUnderSpecifiedMemoryHint(UnderSpecifiedMemoryHint):
|
141
|
+
value: str
|
142
|
+
|
143
|
+
|
144
|
+
@dataclass(frozen=True)
|
145
|
+
class TypedUnderSpecifiedAddressHint(UnderSpecifiedAddressHint):
|
146
|
+
typedef: str
|
147
|
+
value: str
|
148
|
+
|
149
|
+
|
150
|
+
@dataclass(frozen=True)
|
151
|
+
class UntypedUnderSpecifiedAddressHint(UnderSpecifiedAddressHint):
|
152
|
+
value: str
|
153
|
+
|
154
|
+
|
155
|
+
@dataclass(frozen=True)
|
156
|
+
class UnderSpecifiedBranchHint(UnderSpecifiedValueHint):
|
157
|
+
"""Represents a program fork based on an under-specified condition."""
|
158
|
+
|
159
|
+
|
160
|
+
@dataclass(frozen=True)
|
161
|
+
class UnderSpecifiedMemoryBranchHint(UnderSpecifiedBranchHint):
|
162
|
+
"""Represents conditional data flow with an under-specified conditional
|
163
|
+
|
164
|
+
Arguments:
|
165
|
+
addr: Offending address expression
|
166
|
+
options: Possible evaluations of addr, paired with their guard expressions.
|
167
|
+
"""
|
168
|
+
|
169
|
+
address: str
|
170
|
+
options: typing.List[typing.Tuple[str, str]]
|
171
|
+
|
172
|
+
|
173
|
+
@dataclass(frozen=True)
|
174
|
+
class UnderSpecifiedControlBranchHint(UnderSpecifiedBranchHint):
|
175
|
+
"""Represents conditional control flow with an under-specified conditional
|
176
|
+
|
177
|
+
Arguments:
|
178
|
+
targets: Possible branch target addresses, paired with guard expressions.
|
179
|
+
"""
|
180
|
+
|
181
|
+
targets: typing.Dict[str, str]
|
182
|
+
|
183
|
+
|
184
|
+
@dataclass(frozen=True)
|
185
|
+
class InputUseHint(UnderSpecifiedValueHint):
|
186
|
+
"""Represents an instruction at which some register input value is used,
|
187
|
+
i.e. an information flow from input to some instruction
|
188
|
+
|
189
|
+
Arguments:
|
190
|
+
input_reg: The name of the register input value (source)
|
191
|
+
instr: The instruction in which the input is used
|
192
|
+
pc: program counter of that instruction
|
193
|
+
use_reg: The name of the register in instr that is using the input value
|
194
|
+
"""
|
195
|
+
|
196
|
+
input_register: str
|
197
|
+
micro_exec_num: int
|
198
|
+
instruction_num: int
|
199
|
+
use_register: str
|
200
|
+
|
201
|
+
|
202
|
+
@dataclass(frozen=True)
|
203
|
+
class TypeHint(hinting.Hint):
|
204
|
+
"""Super class for Type Hints"""
|
205
|
+
|
206
|
+
pass
|
207
|
+
|
208
|
+
|
209
|
+
@dataclass(frozen=True)
|
210
|
+
class RegisterPointerHint(TypeHint):
|
211
|
+
"""Signal that a register is probably a pointer.
|
212
|
+
|
213
|
+
Arguments:
|
214
|
+
register: The register in question
|
215
|
+
"""
|
216
|
+
|
217
|
+
register: str
|
218
|
+
|
219
|
+
|
220
|
+
@dataclass(frozen=True)
|
221
|
+
class RegisterPointsToHint(RegisterPointerHint):
|
222
|
+
"""Signal that a register is probably a pointer and points to a type.
|
223
|
+
|
224
|
+
Arguments:
|
225
|
+
type: The type in question
|
226
|
+
"""
|
227
|
+
|
228
|
+
type: str
|
229
|
+
|
230
|
+
|
231
|
+
@dataclass(frozen=True)
|
232
|
+
class MemoryPointerHint(TypeHint):
|
233
|
+
"""Signal that a memory address is probably a pointer.
|
234
|
+
|
235
|
+
Arguments:
|
236
|
+
address: The address in question
|
237
|
+
"""
|
238
|
+
|
239
|
+
address: int
|
240
|
+
|
241
|
+
|
242
|
+
@dataclass(frozen=True)
|
243
|
+
class MemoryPointsToHint(RegisterPointerHint):
|
244
|
+
"""Signal that a memory address is probably a pointer and points to a type.
|
245
|
+
|
246
|
+
Arguments:
|
247
|
+
type: The type in question
|
248
|
+
"""
|
249
|
+
|
250
|
+
type: str
|
251
|
+
|
252
|
+
|
253
|
+
@dataclass(frozen=True)
|
254
|
+
class StructureHint(TypeHint):
|
255
|
+
"""Signals the probable layout of a struct
|
256
|
+
|
257
|
+
Arguments:
|
258
|
+
layout: A dictionary of offset to type
|
259
|
+
"""
|
260
|
+
|
261
|
+
layout: typing.Dict[int, str]
|
262
|
+
|
263
|
+
|
264
|
+
@dataclass(frozen=True)
|
265
|
+
class OutputHint(hinting.Hint):
|
266
|
+
registers: typing.Dict[str, str]
|
267
|
+
memory: typing.Dict[int, str]
|
268
|
+
|
269
|
+
|
270
|
+
# These next three are used by the colorizer
|
271
|
+
|
272
|
+
|
273
|
+
@dataclass(frozen=True)
|
274
|
+
class MemoryUnavailableHint(hinting.Hint):
|
275
|
+
"""Represents a load or store that was unavailable memory.
|
276
|
+
|
277
|
+
Arguments:
|
278
|
+
is_read: true if a load else a store
|
279
|
+
size: size of read/write in bytes
|
280
|
+
base_reg_name: name of base register (if known)
|
281
|
+
base_reg_val: value of base register (if known)
|
282
|
+
index_reg_name: name of index register (if known)
|
283
|
+
index_reg_val: value of index register (if known)
|
284
|
+
offset: offset (if known, else 0)
|
285
|
+
scale: scale (if known, else 0)
|
286
|
+
address: memory address of this value
|
287
|
+
instruction: a smallworld instruction
|
288
|
+
pc: program counter of that instruction
|
289
|
+
micro_exec_num: micro-execution run number
|
290
|
+
instruction_num: for micro-execution the instr count
|
291
|
+
"""
|
292
|
+
|
293
|
+
is_read: bool
|
294
|
+
size: int
|
295
|
+
base_reg_name: str
|
296
|
+
base_reg_val: int
|
297
|
+
index_reg_name: str
|
298
|
+
index_reg_val: int
|
299
|
+
offset: int
|
300
|
+
scale: int
|
301
|
+
address: int
|
302
|
+
pc: int
|
303
|
+
micro_exec_num: int
|
304
|
+
instruction_num: int
|
305
|
+
|
306
|
+
|
307
|
+
@dataclass(frozen=True)
|
308
|
+
class MemoryUnavailableProbHint(hinting.Hint):
|
309
|
+
is_read: bool
|
310
|
+
size: int
|
311
|
+
base_reg_name: str
|
312
|
+
index_reg_name: str
|
313
|
+
offset: int
|
314
|
+
scale: int
|
315
|
+
pc: int
|
316
|
+
prob: float
|
317
|
+
|
318
|
+
|
319
|
+
@dataclass(frozen=True)
|
320
|
+
class DynamicValueHint(hinting.Hint):
|
321
|
+
"""Represents a concrete value either in a register or memory
|
322
|
+
encountered during emulation-base analysis
|
323
|
+
|
324
|
+
Arguments:
|
325
|
+
instruction: a smallworld instruction
|
326
|
+
pc: program counter of that instruction
|
327
|
+
micro_exec_num: micro-execution run number
|
328
|
+
instruction_num: for micro-execution the instr count
|
329
|
+
dynamic_value: this is the actual value as bytes
|
330
|
+
size: the size of the value in bytes
|
331
|
+
use: True if its a "use" of this value, else its a "def"
|
332
|
+
new: True if its a new value, first sighting
|
333
|
+
"""
|
334
|
+
|
335
|
+
# instruction: typing.Any
|
336
|
+
pc: int
|
337
|
+
micro_exec_num: int
|
338
|
+
instruction_num: int
|
339
|
+
dynamic_value: str
|
340
|
+
color: int
|
341
|
+
size: int
|
342
|
+
use: bool
|
343
|
+
new: bool
|
344
|
+
|
345
|
+
|
346
|
+
@dataclass(frozen=True)
|
347
|
+
class DynamicRegisterValueHint(DynamicValueHint):
|
348
|
+
"""Represents a concrete register value encountered during
|
349
|
+
analysis, either used or defined by some instruction.
|
350
|
+
|
351
|
+
Arguments:
|
352
|
+
reg_name: name of the register
|
353
|
+
dynamic_value: this is the actual value as bytes
|
354
|
+
use: True if its a "use" of this value, else its a "def"
|
355
|
+
capstone_instruction: the instruction in capstone parlance
|
356
|
+
pc: program counter of that instruction
|
357
|
+
micro_exec_num: micro-execution run number
|
358
|
+
instruction_num: for micro-execution the instr count
|
359
|
+
info: extra info about use or def if available
|
360
|
+
"""
|
361
|
+
|
362
|
+
reg_name: str
|
363
|
+
|
364
|
+
|
365
|
+
@dataclass(frozen=True)
|
366
|
+
class DynamicMemoryValueHint(DynamicValueHint):
|
367
|
+
"""Represents a concrete memory value encountered during
|
368
|
+
analysis, either used or defined by some instruction.
|
369
|
+
|
370
|
+
Arguments:
|
371
|
+
address: memory address of this value
|
372
|
+
base: base address (if known, else 0)
|
373
|
+
index: index (if known, else 0)
|
374
|
+
scale: scale (if known, else 0)
|
375
|
+
offset: offset (if known, else 0)
|
376
|
+
dynamic_value: this is the actual value as bytes
|
377
|
+
use: True if its a "use" of this value, else its a "def"
|
378
|
+
capstone_instruction: the instruction in capstone parlance
|
379
|
+
pc: program counter of that instruction
|
380
|
+
micro_exec_num: micro-execution run number
|
381
|
+
instruction_num: for micro-execution the instr count
|
382
|
+
info: extra info about use or def if available
|
383
|
+
"""
|
384
|
+
|
385
|
+
address: int
|
386
|
+
base: str
|
387
|
+
index: str
|
388
|
+
scale: int
|
389
|
+
offset: int
|
390
|
+
|
391
|
+
|
392
|
+
@dataclass(frozen=True)
|
393
|
+
class DynamicValueProbHint(hinting.Hint):
|
394
|
+
# instruction: typing.Any
|
395
|
+
pc: int
|
396
|
+
color: int
|
397
|
+
size: int
|
398
|
+
use: bool
|
399
|
+
new: bool
|
400
|
+
prob: float
|
401
|
+
|
402
|
+
|
403
|
+
@dataclass(frozen=True)
|
404
|
+
class DynamicMemoryValueProbHint(DynamicValueProbHint):
|
405
|
+
base: str
|
406
|
+
index: str
|
407
|
+
scale: int
|
408
|
+
offset: int
|
409
|
+
|
410
|
+
|
411
|
+
@dataclass(frozen=True)
|
412
|
+
class DynamicRegisterValueProbHint(DynamicValueProbHint):
|
413
|
+
reg_name: str
|
414
|
+
|
415
|
+
|
416
|
+
__all__ = [
|
417
|
+
"DynamicRegisterValueHint",
|
418
|
+
"DynamicMemoryValueHint",
|
419
|
+
"MemoryUnavailableHint",
|
420
|
+
"DynamicRegisterValueProbHint",
|
421
|
+
"DynamicMemoryValueProbHint",
|
422
|
+
"MemoryUnavailableProbHint",
|
423
|
+
"EmulationException",
|
424
|
+
"CoverageHint",
|
425
|
+
"ControlFlowHint",
|
426
|
+
"ReachableCodeHint",
|
427
|
+
]
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import logging
|
2
|
+
import typing
|
3
|
+
|
4
|
+
from .. import hinting
|
5
|
+
|
6
|
+
|
7
|
+
class HintSubclassFilter(logging.Filter):
|
8
|
+
"""A custom logging filter based on Hint class."""
|
9
|
+
|
10
|
+
def __init__(self, hint: typing.Type[hinting.Hint], *args, **kwargs):
|
11
|
+
super().__init__(*args, **kwargs)
|
12
|
+
|
13
|
+
self.hint = hint
|
14
|
+
|
15
|
+
def filter(self, record):
|
16
|
+
return isinstance(record.msg, self.hint)
|
17
|
+
|
18
|
+
|
19
|
+
__all__ = ["HintSubclassFilter"]
|
@@ -0,0 +1,18 @@
|
|
1
|
+
from .aarch64 import AArch64Instruction
|
2
|
+
from .arm import ARMInstruction
|
3
|
+
from .bsid import BSIDMemoryReferenceOperand
|
4
|
+
from .instructions import Instruction, Operand, RegisterOperand
|
5
|
+
from .mips import MIPSInstruction
|
6
|
+
from .x86 import AMD64Instruction, x86Instruction
|
7
|
+
|
8
|
+
__all__ = [
|
9
|
+
"AArch64Instruction",
|
10
|
+
"ARMInstruction",
|
11
|
+
"AMD64Instruction",
|
12
|
+
"BSIDMemoryReferenceOperand",
|
13
|
+
"Instruction",
|
14
|
+
"MIPSInstruction",
|
15
|
+
"Operand",
|
16
|
+
"RegisterOperand",
|
17
|
+
"x86Instruction",
|
18
|
+
]
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import capstone
|
2
|
+
|
3
|
+
from .bsid import BSIDMemoryReferenceOperand
|
4
|
+
from .instructions import Instruction, MemoryReferenceOperand
|
5
|
+
|
6
|
+
|
7
|
+
class AArch64Instruction(Instruction):
|
8
|
+
angr_arch = "AARCH64"
|
9
|
+
cs_arch = capstone.CS_ARCH_ARM64
|
10
|
+
cs_mode = capstone.CS_MODE_ARM
|
11
|
+
|
12
|
+
def _memory_reference(self, operand) -> MemoryReferenceOperand:
|
13
|
+
# TODO: AArch64 operands have no size; what should it be?
|
14
|
+
# I suspect it's always the same; is it always 64-bit?
|
15
|
+
return BSIDMemoryReferenceOperand(
|
16
|
+
base=self._instruction.reg_name(operand.value.mem.base),
|
17
|
+
index=self._instruction.reg_name(operand.value.mem.index),
|
18
|
+
offset=operand.value.mem.disp,
|
19
|
+
size=8,
|
20
|
+
)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import capstone
|
2
|
+
|
3
|
+
from .bsid import BSIDMemoryReferenceOperand
|
4
|
+
from .instructions import Instruction, MemoryReferenceOperand
|
5
|
+
|
6
|
+
|
7
|
+
class ARMInstruction(Instruction):
|
8
|
+
angr_arch = "ARM"
|
9
|
+
cs_arch = capstone.CS_ARCH_ARM
|
10
|
+
cs_mode = capstone.CS_MODE_ARM
|
11
|
+
|
12
|
+
def _memory_reference(self, operand) -> MemoryReferenceOperand:
|
13
|
+
return BSIDMemoryReferenceOperand(
|
14
|
+
base=self._instruction.reg_name(operand.value.mem.base),
|
15
|
+
index=self._instruction.reg_name(operand.value.mem.index),
|
16
|
+
offset=operand.value.mem.disp,
|
17
|
+
size=4,
|
18
|
+
)
|
@@ -0,0 +1,67 @@
|
|
1
|
+
import typing
|
2
|
+
|
3
|
+
from .. import emulators
|
4
|
+
from .instructions import MemoryReferenceOperand
|
5
|
+
|
6
|
+
|
7
|
+
class BSIDMemoryReferenceOperand(MemoryReferenceOperand):
|
8
|
+
"""Memory Operand based on the base-scale-index-displacement pattern."""
|
9
|
+
|
10
|
+
def __init__(
|
11
|
+
self,
|
12
|
+
base: typing.Optional[str] = None,
|
13
|
+
index: typing.Optional[str] = None,
|
14
|
+
scale: int = 1,
|
15
|
+
offset: int = 0,
|
16
|
+
*args,
|
17
|
+
**kwargs,
|
18
|
+
):
|
19
|
+
super().__init__(*args, **kwargs)
|
20
|
+
|
21
|
+
self.base = base
|
22
|
+
self.index = index
|
23
|
+
self.scale = scale
|
24
|
+
self.offset = offset
|
25
|
+
|
26
|
+
def address(self, emulator: emulators.Emulator) -> int:
|
27
|
+
base = 0
|
28
|
+
if self.base is not None:
|
29
|
+
base = emulator.read_register(self.base)
|
30
|
+
|
31
|
+
index = 0
|
32
|
+
if self.index is not None:
|
33
|
+
index = emulator.read_register(self.index)
|
34
|
+
|
35
|
+
return base + self.scale * index + self.offset
|
36
|
+
|
37
|
+
# def to_json(self) -> dict:
|
38
|
+
# return {
|
39
|
+
# "base": self.base,
|
40
|
+
# "index": self.index,
|
41
|
+
# "scale": self.scale,
|
42
|
+
# "offset": self.offset,
|
43
|
+
# }
|
44
|
+
|
45
|
+
@classmethod
|
46
|
+
def from_json(cls, dict):
|
47
|
+
if any(k not in dict for k in ("base", "index", "scale", "offset")):
|
48
|
+
raise ValueError(f"malformed {cls.__name__}: {dict!r}")
|
49
|
+
|
50
|
+
return cls(**dict)
|
51
|
+
|
52
|
+
def __repr__(self) -> str:
|
53
|
+
string = ""
|
54
|
+
|
55
|
+
if self.base:
|
56
|
+
string = f"{self.base}"
|
57
|
+
|
58
|
+
if self.index:
|
59
|
+
if self.scale:
|
60
|
+
string = f"{string}+{self.scale}*{self.index}"
|
61
|
+
else:
|
62
|
+
string = f"{string}+{self.index}"
|
63
|
+
|
64
|
+
if self.offset:
|
65
|
+
string = f"{string}+{self.offset}"
|
66
|
+
|
67
|
+
return f"{self.__class__.__name__}({string})"
|