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.
Files changed (166) hide show
  1. smallworld/__init__.py +35 -0
  2. smallworld/analyses/__init__.py +14 -0
  3. smallworld/analyses/analysis.py +88 -0
  4. smallworld/analyses/code_coverage.py +31 -0
  5. smallworld/analyses/colorizer.py +682 -0
  6. smallworld/analyses/colorizer_summary.py +100 -0
  7. smallworld/analyses/field_detection/__init__.py +14 -0
  8. smallworld/analyses/field_detection/field_analysis.py +536 -0
  9. smallworld/analyses/field_detection/guards.py +26 -0
  10. smallworld/analyses/field_detection/hints.py +133 -0
  11. smallworld/analyses/field_detection/malloc.py +211 -0
  12. smallworld/analyses/forced_exec/__init__.py +3 -0
  13. smallworld/analyses/forced_exec/forced_exec.py +87 -0
  14. smallworld/analyses/underlays/__init__.py +4 -0
  15. smallworld/analyses/underlays/basic.py +13 -0
  16. smallworld/analyses/underlays/underlay.py +31 -0
  17. smallworld/analyses/unstable/__init__.py +4 -0
  18. smallworld/analyses/unstable/angr/__init__.py +0 -0
  19. smallworld/analyses/unstable/angr/base.py +12 -0
  20. smallworld/analyses/unstable/angr/divergence.py +274 -0
  21. smallworld/analyses/unstable/angr/model.py +383 -0
  22. smallworld/analyses/unstable/angr/nwbt.py +63 -0
  23. smallworld/analyses/unstable/angr/typedefs.py +170 -0
  24. smallworld/analyses/unstable/angr/utils.py +25 -0
  25. smallworld/analyses/unstable/angr/visitor.py +315 -0
  26. smallworld/analyses/unstable/angr_nwbt.py +106 -0
  27. smallworld/analyses/unstable/code_coverage.py +54 -0
  28. smallworld/analyses/unstable/code_reachable.py +44 -0
  29. smallworld/analyses/unstable/control_flow_tracer.py +71 -0
  30. smallworld/analyses/unstable/pointer_finder.py +90 -0
  31. smallworld/arch/__init__.py +0 -0
  32. smallworld/arch/aarch64_arch.py +286 -0
  33. smallworld/arch/amd64_arch.py +86 -0
  34. smallworld/arch/i386_arch.py +44 -0
  35. smallworld/emulators/__init__.py +14 -0
  36. smallworld/emulators/angr/__init__.py +7 -0
  37. smallworld/emulators/angr/angr.py +1652 -0
  38. smallworld/emulators/angr/default.py +15 -0
  39. smallworld/emulators/angr/exceptions.py +7 -0
  40. smallworld/emulators/angr/exploration/__init__.py +9 -0
  41. smallworld/emulators/angr/exploration/bounds.py +27 -0
  42. smallworld/emulators/angr/exploration/default.py +17 -0
  43. smallworld/emulators/angr/exploration/terminate.py +22 -0
  44. smallworld/emulators/angr/factory.py +55 -0
  45. smallworld/emulators/angr/machdefs/__init__.py +35 -0
  46. smallworld/emulators/angr/machdefs/aarch64.py +292 -0
  47. smallworld/emulators/angr/machdefs/amd64.py +192 -0
  48. smallworld/emulators/angr/machdefs/arm.py +387 -0
  49. smallworld/emulators/angr/machdefs/i386.py +221 -0
  50. smallworld/emulators/angr/machdefs/machdef.py +138 -0
  51. smallworld/emulators/angr/machdefs/mips.py +184 -0
  52. smallworld/emulators/angr/machdefs/mips64.py +189 -0
  53. smallworld/emulators/angr/machdefs/ppc.py +101 -0
  54. smallworld/emulators/angr/machdefs/riscv.py +261 -0
  55. smallworld/emulators/angr/machdefs/xtensa.py +255 -0
  56. smallworld/emulators/angr/memory/__init__.py +7 -0
  57. smallworld/emulators/angr/memory/default.py +10 -0
  58. smallworld/emulators/angr/memory/fixups.py +43 -0
  59. smallworld/emulators/angr/memory/memtrack.py +105 -0
  60. smallworld/emulators/angr/scratch.py +43 -0
  61. smallworld/emulators/angr/simos.py +53 -0
  62. smallworld/emulators/angr/utils.py +70 -0
  63. smallworld/emulators/emulator.py +1013 -0
  64. smallworld/emulators/hookable.py +252 -0
  65. smallworld/emulators/panda/__init__.py +5 -0
  66. smallworld/emulators/panda/machdefs/__init__.py +28 -0
  67. smallworld/emulators/panda/machdefs/aarch64.py +93 -0
  68. smallworld/emulators/panda/machdefs/amd64.py +71 -0
  69. smallworld/emulators/panda/machdefs/arm.py +89 -0
  70. smallworld/emulators/panda/machdefs/i386.py +36 -0
  71. smallworld/emulators/panda/machdefs/machdef.py +86 -0
  72. smallworld/emulators/panda/machdefs/mips.py +94 -0
  73. smallworld/emulators/panda/machdefs/mips64.py +91 -0
  74. smallworld/emulators/panda/machdefs/ppc.py +79 -0
  75. smallworld/emulators/panda/panda.py +575 -0
  76. smallworld/emulators/unicorn/__init__.py +13 -0
  77. smallworld/emulators/unicorn/machdefs/__init__.py +28 -0
  78. smallworld/emulators/unicorn/machdefs/aarch64.py +310 -0
  79. smallworld/emulators/unicorn/machdefs/amd64.py +326 -0
  80. smallworld/emulators/unicorn/machdefs/arm.py +321 -0
  81. smallworld/emulators/unicorn/machdefs/i386.py +137 -0
  82. smallworld/emulators/unicorn/machdefs/machdef.py +117 -0
  83. smallworld/emulators/unicorn/machdefs/mips.py +202 -0
  84. smallworld/emulators/unicorn/unicorn.py +684 -0
  85. smallworld/exceptions/__init__.py +5 -0
  86. smallworld/exceptions/exceptions.py +85 -0
  87. smallworld/exceptions/unstable/__init__.py +1 -0
  88. smallworld/exceptions/unstable/exceptions.py +25 -0
  89. smallworld/extern/__init__.py +4 -0
  90. smallworld/extern/ctypes.py +94 -0
  91. smallworld/extern/unstable/__init__.py +1 -0
  92. smallworld/extern/unstable/ghidra.py +129 -0
  93. smallworld/helpers.py +107 -0
  94. smallworld/hinting/__init__.py +8 -0
  95. smallworld/hinting/hinting.py +214 -0
  96. smallworld/hinting/hints.py +427 -0
  97. smallworld/hinting/unstable/__init__.py +2 -0
  98. smallworld/hinting/utils.py +19 -0
  99. smallworld/instructions/__init__.py +18 -0
  100. smallworld/instructions/aarch64.py +20 -0
  101. smallworld/instructions/arm.py +18 -0
  102. smallworld/instructions/bsid.py +67 -0
  103. smallworld/instructions/instructions.py +258 -0
  104. smallworld/instructions/mips.py +21 -0
  105. smallworld/instructions/x86.py +100 -0
  106. smallworld/logging.py +90 -0
  107. smallworld/platforms.py +95 -0
  108. smallworld/py.typed +0 -0
  109. smallworld/state/__init__.py +6 -0
  110. smallworld/state/cpus/__init__.py +32 -0
  111. smallworld/state/cpus/aarch64.py +563 -0
  112. smallworld/state/cpus/amd64.py +676 -0
  113. smallworld/state/cpus/arm.py +630 -0
  114. smallworld/state/cpus/cpu.py +71 -0
  115. smallworld/state/cpus/i386.py +239 -0
  116. smallworld/state/cpus/mips.py +374 -0
  117. smallworld/state/cpus/mips64.py +372 -0
  118. smallworld/state/cpus/powerpc.py +229 -0
  119. smallworld/state/cpus/riscv.py +357 -0
  120. smallworld/state/cpus/xtensa.py +80 -0
  121. smallworld/state/memory/__init__.py +7 -0
  122. smallworld/state/memory/code.py +70 -0
  123. smallworld/state/memory/elf/__init__.py +3 -0
  124. smallworld/state/memory/elf/elf.py +564 -0
  125. smallworld/state/memory/elf/rela/__init__.py +32 -0
  126. smallworld/state/memory/elf/rela/aarch64.py +27 -0
  127. smallworld/state/memory/elf/rela/amd64.py +32 -0
  128. smallworld/state/memory/elf/rela/arm.py +51 -0
  129. smallworld/state/memory/elf/rela/i386.py +32 -0
  130. smallworld/state/memory/elf/rela/mips.py +45 -0
  131. smallworld/state/memory/elf/rela/ppc.py +45 -0
  132. smallworld/state/memory/elf/rela/rela.py +63 -0
  133. smallworld/state/memory/elf/rela/riscv64.py +27 -0
  134. smallworld/state/memory/elf/rela/xtensa.py +15 -0
  135. smallworld/state/memory/elf/structs.py +55 -0
  136. smallworld/state/memory/heap.py +85 -0
  137. smallworld/state/memory/memory.py +181 -0
  138. smallworld/state/memory/stack/__init__.py +31 -0
  139. smallworld/state/memory/stack/aarch64.py +22 -0
  140. smallworld/state/memory/stack/amd64.py +42 -0
  141. smallworld/state/memory/stack/arm.py +66 -0
  142. smallworld/state/memory/stack/i386.py +22 -0
  143. smallworld/state/memory/stack/mips.py +34 -0
  144. smallworld/state/memory/stack/mips64.py +34 -0
  145. smallworld/state/memory/stack/ppc.py +34 -0
  146. smallworld/state/memory/stack/riscv.py +22 -0
  147. smallworld/state/memory/stack/stack.py +127 -0
  148. smallworld/state/memory/stack/xtensa.py +34 -0
  149. smallworld/state/models/__init__.py +6 -0
  150. smallworld/state/models/mmio.py +186 -0
  151. smallworld/state/models/model.py +163 -0
  152. smallworld/state/models/posix.py +455 -0
  153. smallworld/state/models/x86/__init__.py +2 -0
  154. smallworld/state/models/x86/microsoftcdecl.py +35 -0
  155. smallworld/state/models/x86/systemv.py +240 -0
  156. smallworld/state/state.py +962 -0
  157. smallworld/state/unstable/__init__.py +0 -0
  158. smallworld/state/unstable/elf.py +393 -0
  159. smallworld/state/x86_registers.py +30 -0
  160. smallworld/utils.py +935 -0
  161. smallworld_re-1.0.0.dist-info/LICENSE.txt +21 -0
  162. smallworld_re-1.0.0.dist-info/METADATA +189 -0
  163. smallworld_re-1.0.0.dist-info/RECORD +166 -0
  164. smallworld_re-1.0.0.dist-info/WHEEL +5 -0
  165. smallworld_re-1.0.0.dist-info/entry_points.txt +2 -0
  166. smallworld_re-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,387 @@
1
+ import archinfo
2
+
3
+ from ....platforms import Architecture, Byteorder
4
+ from .machdef import AngrMachineDef
5
+
6
+
7
+ class ARMMachineDef(AngrMachineDef):
8
+ pc_reg = "pc"
9
+
10
+ def __init__(self):
11
+ self._registers = {
12
+ # *** General-purpose registers ***
13
+ "r0": "r0",
14
+ "r1": "r1",
15
+ "r2": "r2",
16
+ "r3": "r3",
17
+ "r4": "r4",
18
+ "r5": "r5",
19
+ "r6": "r6",
20
+ "r7": "r7",
21
+ "r8": "r8",
22
+ # r9 doubles as the Static base pointer
23
+ "r9": "r9",
24
+ "sb": "sb",
25
+ # r10 doubles as the Stack Limit pointer
26
+ "r10": "r10",
27
+ "sl": "sl",
28
+ # r11 doubles as the Frame Pointer, if desired.
29
+ "r11": "r11",
30
+ "fp": "fp",
31
+ # r12 doubles as the Intra-call scratch register
32
+ "r12": "r12",
33
+ "ip": "ip",
34
+ "sp": "sp",
35
+ "lr": "lr",
36
+ "pc": "pc",
37
+ }
38
+
39
+
40
+ class ARMMachineMixinM:
41
+ """Mixin class for M-series CPUs.
42
+
43
+ The main difference between M and R/A
44
+ is the available system status registers.
45
+ """
46
+
47
+ def __init__(self):
48
+ super().__init__()
49
+ self._registers.update(
50
+ {
51
+ # *** Special Registers ***
52
+ # Program Status Register
53
+ # NOTE: PSR can be accessed through several masked aliases.
54
+ # These are read-only, so I'm not including them.
55
+ # - apsr: Just the condition flags
56
+ # - ipsr: Just exception information
57
+ # - epsr: Just execution state info
58
+ # - iapsr: apsr | ipsr
59
+ # - eapsr: apsr | epsr
60
+ # - iepsr: ipsr | epsr
61
+ # - xpsr: apsr | ipsr | epsr
62
+ "psr": "cpsr",
63
+ # Exception Mask Register
64
+ "primask": "primask",
65
+ # Base Priority Mask Register
66
+ "basepri": "basepri",
67
+ # Fault Mask Register
68
+ "faultmask": "faultmask",
69
+ # Control register; includes a lot of flags.
70
+ "control": "control",
71
+ # *** Stack Pointer Bank ***
72
+ # sp is actually an alias to one of these two.
73
+ # Exactly which one depends on a bit in control.
74
+ # Emulators that care should be careful when loading state.
75
+ # Main Stack Pointer
76
+ "msp": "msp",
77
+ # Process Stack Pointer
78
+ "psp": "psp",
79
+ }
80
+ )
81
+
82
+
83
+ class ARMMachineMixinRA:
84
+ """Mixin for ARM series A and R CPUs"""
85
+
86
+ def __init__(self):
87
+ super().__init__()
88
+ self._registers.update(
89
+ {
90
+ # *** Special Registers ***
91
+ # Current Program Status Register
92
+ # NOTE: CPSR can be accessed through several masked aliases.
93
+ # These are read-only, so I'm not including them.
94
+ # - isetstate: Just includes instruction set control bits
95
+ # - itstate: Just includes state bits for Thumb IT instruction
96
+ "cpsr": "cpsr",
97
+ # Saved Program Status Register
98
+ "spsr": "spsr",
99
+ # *** Register Banks ***
100
+ # sp, lr, and spsr are actually aliases to one of these.
101
+ # Which one they reference depends on execution mode.
102
+ # Emulators that care should be careful when loading state.
103
+ # NOTE: Use User-mode copies of registers unless the mode has its own.
104
+ # User-mode Stack Pointer
105
+ "sp_usr": "sp_usr",
106
+ # User-mode Link Register
107
+ "lr_usr": "lr_usr",
108
+ # User-mode r8
109
+ "r8_usr": "r8_usr",
110
+ # User-mode r9
111
+ "r9_usr": "r9_usr",
112
+ # User-mode r10
113
+ "r10_usr": "r10_usr",
114
+ # User-mode r11
115
+ "r11_usr": "r11_usr",
116
+ # User-mode r12
117
+ "r12_usr": "r12_usr",
118
+ # Hypervisor Stack Pointer
119
+ "sp_hyp": "sp_hyp",
120
+ # Hypervisor Saved PSR
121
+ "spsr_hyp": "spsr_hyp",
122
+ # Hypervisor Exception Link Register
123
+ # NOTE: This isn't so much banked, as it only exists in hypervisor mode.
124
+ "elr_hyp": "elr_hyp",
125
+ # Supervisor Stack Pointer
126
+ "sp_svc": "sp_svc",
127
+ # Supervisor Link Register
128
+ "lr_svc": "lr_svc",
129
+ # Supervisor Saved PSR
130
+ "spsr_svc": "spsr_svc",
131
+ # Abort-state Stack Pointer
132
+ "sp_abt": "sp_abt",
133
+ # Abort-state Link Register
134
+ "lr_abt": "lr_abt",
135
+ # Abort-state Saved PSR
136
+ "spsr_abt": "spsr_abt",
137
+ # Undefined-mode Stack Pointer
138
+ "sp_und": "sp_und",
139
+ # Undefined-mode Link Register
140
+ "lr_und": "lr_und",
141
+ # Undefined-mode Saved PSR
142
+ "spsr_und": "spsr_und",
143
+ # Monitor-mode Stack Pointer
144
+ "sp_mon": "sp_mon",
145
+ # Monitor-mode Link Register
146
+ "lr_mon": "lr_mon",
147
+ # Monitor-mode Saved PSR
148
+ "spsr_mon": "spsr_mon",
149
+ # IRQ-mode Stack Pointer
150
+ "sp_irq": "sp_irq",
151
+ # IRQ-mode Link Register
152
+ "lr_irq": "lr_irq",
153
+ # IRQ-mode Saved PSR
154
+ "spsr_irq": "spsr_irq",
155
+ # FIQ-mode Stack Pointer
156
+ "sp_fiq": "sp_fiq",
157
+ # FIQ-mode Link Register
158
+ "lr_fiq": "lr_fiq",
159
+ # FIQ-mode Saved PSR
160
+ "spsr_fiq": "spsr_fiq",
161
+ # FIQ-mode r8
162
+ "r8_fiq": "r8_fiq",
163
+ # FIQ-mode r9
164
+ "r9_fiq": "r9_fiq",
165
+ # FIQ-mode r10
166
+ "r10_fiq": "r10_fiq",
167
+ # FIQ-mode r11
168
+ "r11_fiq": "r11_fiq",
169
+ # FIQ-mode r12
170
+ "r12_fiq": "r12_fiq",
171
+ }
172
+ )
173
+
174
+
175
+ class ARMMachineMixinFP:
176
+ """Mixin for ARM CPUs with FP extensions
177
+
178
+ This is one kind of floating-point extension
179
+ which offers 64-bit scalar operations.
180
+ """
181
+
182
+ def __init__(self):
183
+ super().__init__()
184
+ self._registers.update(
185
+ {
186
+ # *** Floating point control registers ***
187
+ # Floating-point Status and Control Register
188
+ "fpscr": "fpscr",
189
+ # Floating-point Exception Control Register
190
+ "fpexc": "fpexc",
191
+ # Floating-point System ID Register
192
+ "fpsid": "fpsid",
193
+ # Media and VFP Feature Register 0
194
+ "mvfr0": "mvfr0",
195
+ # Media and VFP Feature Register 1
196
+ "mvfr1": "mvfr1",
197
+ # *** Floating point registers ***
198
+ "d0": "d0",
199
+ "s0": "s0",
200
+ "s1": "s1",
201
+ "d1": "d1",
202
+ "s2": "s2",
203
+ "s3": "s3",
204
+ "d2": "d2",
205
+ "s4": "s4",
206
+ "s5": "s5",
207
+ "d3": "d3",
208
+ "s6": "s6",
209
+ "s7": "s7",
210
+ "d4": "d4",
211
+ "s8": "s8",
212
+ "s9": "s9",
213
+ "d5": "d5",
214
+ "s10": "s10",
215
+ "s11": "s11",
216
+ "d6": "d6",
217
+ "s12": "s12",
218
+ "s13": "s13",
219
+ "d7": "d7",
220
+ "s14": "s14",
221
+ "s15": "s15",
222
+ "d8": "d8",
223
+ "s16": "s16",
224
+ "s17": "s17",
225
+ "d9": "d9",
226
+ "s18": "s18",
227
+ "s19": "s19",
228
+ "d10": "d10",
229
+ "s20": "s20",
230
+ "s21": "s21",
231
+ "d11": "d11",
232
+ "s22": "s22",
233
+ "s23": "s23",
234
+ "d12": "d12",
235
+ "s24": "s24",
236
+ "s25": "s25",
237
+ "d13": "d13",
238
+ "s26": "s26",
239
+ "s27": "s27",
240
+ "d14": "d14",
241
+ "s28": "s28",
242
+ "s29": "s29",
243
+ "d15": "d15",
244
+ "s30": "s30",
245
+ "s31": "s31",
246
+ }
247
+ )
248
+
249
+
250
+ class ARMMachineMixinVFPEL:
251
+ def __init__(self):
252
+ super().__init__()
253
+ self._registers.update(
254
+ {
255
+ # *** Floating-point Control Registers ***
256
+ # Floating-point Status and Control Register
257
+ "fpscr": "fpscr",
258
+ # Floating-point Exception Control Register
259
+ "fpexc": "fpexc",
260
+ # Floating-point System ID Register
261
+ "fpsid": "fpsid",
262
+ # Media and VFP Feature Register 0
263
+ "mvfr0": "mvfr0",
264
+ # Media and VFP Feature Register 1
265
+ "mvfr1": "mvfr1",
266
+ # *** Floating-point Registers ****
267
+ "q0": "q0",
268
+ "d0": "d0",
269
+ "s0": "s0",
270
+ "s1": "s1",
271
+ "d1": "d1",
272
+ "s2": "s2",
273
+ "s3": "s3",
274
+ "q1": "q1",
275
+ "d2": "d2",
276
+ "s4": "s4",
277
+ "s5": "s5",
278
+ "d3": "d3",
279
+ "s6": "s6",
280
+ "s7": "s7",
281
+ "q2": "q2",
282
+ "d4": "d4",
283
+ "s8": "s8",
284
+ "s9": "s9",
285
+ "d5": "d5",
286
+ "s10": "s10",
287
+ "s11": "s11",
288
+ "q3": "q3",
289
+ "d6": "d6",
290
+ "s12": "s12",
291
+ "s13": "s13",
292
+ "d7": "d7",
293
+ "s14": "s14",
294
+ "s15": "s15",
295
+ "q4": "q4",
296
+ "d8": "d8",
297
+ "s16": "s16",
298
+ "s17": "s17",
299
+ "d9": "d9",
300
+ "s18": "s18",
301
+ "s19": "s19",
302
+ "q5": "q5",
303
+ "d10": "d10",
304
+ "s20": "s20",
305
+ "s21": "s21",
306
+ "d11": "d11",
307
+ "s22": "s22",
308
+ "s23": "s23",
309
+ "q6": "q6",
310
+ "d12": "d12",
311
+ "s24": "s24",
312
+ "s25": "s25",
313
+ "d13": "d13",
314
+ "s26": "s26",
315
+ "s27": "s27",
316
+ "q7": "q7",
317
+ "d14": "d14",
318
+ "s28": "s28",
319
+ "s29": "s29",
320
+ "d15": "d15",
321
+ "s30": "s30",
322
+ "s31": "s31",
323
+ # NOTE: This isn't a typo; there are only 32 single-precision sX registers
324
+ # This does mean that only half the VFP register space can be used
325
+ # for single-precision arithmetic.
326
+ "q8": "q8",
327
+ "d16": "d16",
328
+ "d17": "d17",
329
+ "q9": "q9",
330
+ "d18": "d18",
331
+ "d19": "d19",
332
+ "q10": "q10",
333
+ "d20": "d20",
334
+ "d21": "d21",
335
+ "q11": "q11",
336
+ "d22": "d22",
337
+ "d23": "d23",
338
+ "q12": "q12",
339
+ "d24": "d24",
340
+ "d25": "d25",
341
+ "q13": "q13",
342
+ "d26": "d26",
343
+ "d27": "d27",
344
+ "q14": "q14",
345
+ "d28": "d28",
346
+ "d29": "d29",
347
+ "q15": "q15",
348
+ "d30": "d30",
349
+ "d31": "d31",
350
+ }
351
+ )
352
+
353
+
354
+ class ARMv5TMachineDef(ARMMachineMixinM, ARMMachineDef):
355
+ angr_arch = archinfo.arch_arm.ArchARMEL()
356
+ arch = Architecture.ARM_V5T
357
+ byteorder = Byteorder.LITTLE
358
+
359
+
360
+ class ARMv6MMachineDef(ARMMachineMixinFP, ARMMachineMixinM, ARMMachineDef):
361
+ angr_arch = archinfo.arch_arm.ArchARMEL()
362
+ arch = Architecture.ARM_V6M
363
+ byteorder = Byteorder.LITTLE
364
+
365
+
366
+ class ARMv6MThumbMachineDef(ARMv6MMachineDef):
367
+ angr_arch = archinfo.arch_arm.ArchARMCortexM()
368
+ arch = Architecture.ARM_V6M_THUMB
369
+ byteorder = Byteorder.LITTLE
370
+ is_thumb = True
371
+
372
+
373
+ class ARMv7MMachineDef(ARMMachineMixinFP, ARMMachineMixinM, ARMMachineDef):
374
+ angr_arch = archinfo.arch_arm.ArchARMHF()
375
+ arch = Architecture.ARM_V7M
376
+ byteorder = Byteorder.LITTLE
377
+
378
+
379
+ class ARMv7AMachineDef(ARMMachineMixinVFPEL, ARMMachineMixinRA, ARMMachineDef):
380
+ # TODO: This is a user-space integer only model
381
+ angr_arch = archinfo.arch_arm.ArchARMHF()
382
+ arch = Architecture.ARM_V7A
383
+ byteorder = Byteorder.LITTLE
384
+
385
+
386
+ # angr does not have good enough R- or A- series support,
387
+ # or any support for NEON that I can see.
@@ -0,0 +1,221 @@
1
+ import typing
2
+
3
+ import angr
4
+ import archinfo
5
+ import pyvex
6
+
7
+ from ....platforms import Architecture, Byteorder
8
+ from .machdef import AngrMachineDef
9
+
10
+
11
+ class i386MachineDef(AngrMachineDef):
12
+ arch = Architecture.X86_32
13
+ byteorder = Byteorder.LITTLE
14
+
15
+ angr_arch = archinfo.arch_x86.ArchX86()
16
+
17
+ pc_reg = "eip"
18
+
19
+ _registers = {
20
+ # *** General Purpose Registers ***
21
+ "eax": "eax",
22
+ "ax": "ax",
23
+ "al": "al",
24
+ "ah": "ah",
25
+ "ebx": "ebx",
26
+ "bx": "bx",
27
+ "bl": "bl",
28
+ "bh": "bh",
29
+ "ecx": "ecx",
30
+ "cx": "cx",
31
+ "cl": "cl",
32
+ "ch": "ch",
33
+ "edx": "edx",
34
+ "dx": "dx",
35
+ "dl": "dl",
36
+ "dh": "dh",
37
+ "esi": "esi",
38
+ "si": "si",
39
+ "sil": "sil",
40
+ "edi": "edi",
41
+ "di": "di",
42
+ "dil": "dil",
43
+ "ebp": "ebp",
44
+ "bp": "bp",
45
+ "bpl": "bpl",
46
+ "esp": "esp",
47
+ "sp": "sp",
48
+ "spl": "spl",
49
+ # *** Instruction Pointer ***
50
+ "eip": "eip",
51
+ "ip": "ip",
52
+ # *** Segment Registers ***
53
+ "cs": "cs",
54
+ "ds": "ds",
55
+ "es": "es",
56
+ "fs": "fs",
57
+ "gs": "gs",
58
+ "ss": "ss",
59
+ # *** Flags Register ***
60
+ "eflags": "eflags",
61
+ "flags": "flags",
62
+ # *** Control Registers ***
63
+ "cr0": "",
64
+ "cr1": "",
65
+ "cr2": "",
66
+ "cr3": "",
67
+ "cr4": "",
68
+ "cr8": "",
69
+ # *** Debug Registers ***
70
+ "dr0": "",
71
+ "dr1": "",
72
+ "dr2": "",
73
+ "dr3": "",
74
+ "dr6": "",
75
+ "dr7": "",
76
+ # *** Descriptor Table Registers ***
77
+ "gdtr": "gdt",
78
+ "idtr": "idt",
79
+ "ldtr": "ldt",
80
+ # *** Task Register ***
81
+ "tr": "",
82
+ # *** x87 Registers ***
83
+ # TODO: angr seems to support x87, but I have no idea how its register file works
84
+ # I can't find most of the control registers,
85
+ # and there don't seem to be separate "fprN" registers; just one giant blob
86
+ "fpr0": "",
87
+ "fpr1": "",
88
+ "fpr2": "",
89
+ "fpr3": "",
90
+ "fpr4": "",
91
+ "fpr5": "",
92
+ "fpr6": "",
93
+ "fpr7": "",
94
+ "fctrl": "",
95
+ "fstat": "",
96
+ "ftag": "fptag",
97
+ "fip": "",
98
+ "fdp": "",
99
+ "fop": "",
100
+ # *** MMX Registers ***
101
+ "mm0": "mm0",
102
+ "mm1": "mm1",
103
+ "mm2": "mm2",
104
+ "mm3": "mm3",
105
+ "mm4": "mm4",
106
+ "mm5": "mm5",
107
+ "mm6": "mm6",
108
+ "mm7": "mm7",
109
+ # *** SSE Registers ***
110
+ "xmm0": "xmm0",
111
+ "xmm1": "xmm1",
112
+ "xmm2": "xmm2",
113
+ "xmm3": "xmm3",
114
+ "xmm4": "xmm4",
115
+ "xmm5": "xmm5",
116
+ "xmm6": "xmm6",
117
+ "xmm7": "xmm7",
118
+ }
119
+
120
+ def rebuild_irsb(self, addr, good_bytes):
121
+ # Lift good_bytes to an IRSB
122
+ return pyvex.lift(good_bytes, addr, self.angr_arch)
123
+
124
+ def build_sysexit_irsb(self, insn, good_bytes):
125
+ # Build a new IRSB just containing sysexit:
126
+ # 0: IMARK (addr, 2, 0)
127
+ # 1: t0 = GET:I32(ecx)
128
+ # 2: t1 = GET:I32(edx)
129
+ # 3: PUT(esp) = t0
130
+ # NEXT: PUT(eip) = t1; Iji_Sys_sysexit
131
+
132
+ # Get the offsetfs of ecd and edx
133
+ ecx_off, _ = self.angr_arch.registers["ecx"]
134
+ edx_off, _ = self.angr_arch.registers["edx"]
135
+ esp_off, _ = self.angr_arch.registers["esp"]
136
+
137
+ # Type environment; we need two variables of type int32
138
+ irsb_tyenv = pyvex.IRTypeEnv(self.angr_arch, ["Ity_I32", "Ity_I32"])
139
+
140
+ # Statements
141
+ irsb_stmts = [
142
+ # Statement 0: Instruction mark
143
+ pyvex.stmt.IMark(insn.address, 2, 0),
144
+ # Statement 1: Load ecx into t0
145
+ pyvex.stmt.WrTmp(
146
+ 0, # Load into t0
147
+ pyvex.expr.Get( # Get a register
148
+ ecx_off,
149
+ "Ity_I32",
150
+ ),
151
+ ),
152
+ # Statement 2: Load edx into t1
153
+ pyvex.stmt.WrTmp(
154
+ 1, # Load into t1
155
+ pyvex.expr.Get( # Get a register
156
+ edx_off,
157
+ "Ity_I32",
158
+ ),
159
+ ),
160
+ # Statement 3: Load t0 into esp
161
+ pyvex.stmt.Put(pyvex.expr.RdTmp.get_instance(0), esp_off),
162
+ ]
163
+
164
+ # "next" expression; Value of t1
165
+ irsb_next = pyvex.expr.RdTmp.get_instance(1)
166
+ # Jump kind
167
+ irsb_jumpkind = "Ijk_Boring"
168
+
169
+ irsb = pyvex.IRSB.from_py(
170
+ irsb_tyenv,
171
+ irsb_stmts,
172
+ irsb_next,
173
+ irsb_jumpkind,
174
+ insn.address,
175
+ self.angr_arch,
176
+ )
177
+ if len(good_bytes) > 0:
178
+ prefix = self.rebuild_irsb(insn.address - len(good_bytes), good_bytes)
179
+ # Fuse the two together
180
+ irsb = prefix.extend(irsb)
181
+
182
+ return irsb
183
+
184
+ def successors(self, state: angr.SimState, **kwargs) -> typing.Any:
185
+ # VEX doesn't correctly model SYSENTER and SYSEXIT
186
+
187
+ # Fetch or compute the IR block for our state
188
+ if "irsb" in kwargs and kwargs["irsb"] is not None:
189
+ # Someone's already specified an IR block.
190
+ irsb = kwargs["irsb"]
191
+ else:
192
+ # Disable optimization; it doesn't work
193
+
194
+ # Compute the block from the state
195
+ # Pray to the Powers that kwargs are compatible.
196
+ irsb = state.block(**kwargs).vex
197
+
198
+ if irsb.jumpkind == "Ijk_NoDecode":
199
+ # VEX is stumped regarding this instruction.
200
+ # Unfortunately, this also means basic block detection failed.
201
+ irsb = None
202
+ disas = state.block(**kwargs).disassembly
203
+ good_bytes = b""
204
+ for insn in disas.insns:
205
+ if insn.mnemonic == "sysexit":
206
+ irsb = self.build_sysexit_irsb(insn, good_bytes)
207
+ break
208
+ else:
209
+ good_bytes += insn.insn.bytes
210
+ if irsb is None:
211
+ irsb = self.rebuild_irsb(disas.insns[0].address, good_bytes)
212
+
213
+ # Force the engine to use our IR block
214
+ kwargs["irsb"] = irsb
215
+
216
+ # Turn the crank on the engine
217
+ try:
218
+ return super().successors(state, **kwargs)
219
+ except angr.errors.SimIRSBNoDecodeError as e:
220
+ print(f"Bad IRSB:\n{irsb}")
221
+ raise e