smallworld-re 1.0.3__py3-none-any.whl → 2.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 (306) hide show
  1. smallworld/analyses/__init__.py +8 -0
  2. smallworld/analyses/analysis.py +8 -67
  3. smallworld/analyses/code_coverage.py +1 -2
  4. smallworld/analyses/colorizer.py +301 -534
  5. smallworld/analyses/colorizer_def_use.py +217 -0
  6. smallworld/analyses/colorizer_summary.py +173 -83
  7. smallworld/analyses/field_detection/field_analysis.py +7 -8
  8. smallworld/analyses/field_detection/hints.py +1 -1
  9. smallworld/analyses/field_detection/malloc.py +2 -2
  10. smallworld/analyses/trace_execution.py +160 -0
  11. smallworld/analyses/trace_execution_types.py +42 -0
  12. smallworld/analyses/unstable/angr/divergence.py +1 -2
  13. smallworld/analyses/unstable/angr/model.py +5 -6
  14. smallworld/analyses/unstable/angr_nwbt.py +3 -4
  15. smallworld/analyses/unstable/code_coverage.py +2 -3
  16. smallworld/analyses/unstable/code_reachable.py +2 -3
  17. smallworld/analyses/unstable/control_flow_tracer.py +2 -3
  18. smallworld/analyses/unstable/pointer_finder.py +2 -3
  19. smallworld/analyses/unstable/utils/tui.py +71 -0
  20. smallworld/emulators/__init__.py +3 -1
  21. smallworld/emulators/angr/angr.py +30 -9
  22. smallworld/emulators/angr/machdefs/__init__.py +2 -0
  23. smallworld/emulators/angr/machdefs/aarch64.py +1 -1
  24. smallworld/emulators/angr/machdefs/amd64.py +0 -4
  25. smallworld/emulators/angr/machdefs/arm.py +0 -2
  26. smallworld/emulators/angr/machdefs/i386.py +0 -2
  27. smallworld/emulators/angr/machdefs/loongarch.py +340 -0
  28. smallworld/emulators/angr/machdefs/machdef.py +1 -8
  29. smallworld/emulators/angr/machdefs/mips.py +0 -2
  30. smallworld/emulators/angr/machdefs/mips64.py +0 -2
  31. smallworld/emulators/angr/machdefs/ppc.py +1 -2
  32. smallworld/emulators/angr/machdefs/riscv.py +8 -10
  33. smallworld/emulators/angr/machdefs/xtensa.py +7 -4
  34. smallworld/emulators/emulator.py +22 -0
  35. smallworld/emulators/ghidra/__init__.py +37 -0
  36. smallworld/emulators/ghidra/ghidra.py +513 -0
  37. smallworld/emulators/ghidra/machdefs/__init__.py +31 -0
  38. smallworld/emulators/ghidra/machdefs/aarch64.py +289 -0
  39. smallworld/emulators/ghidra/machdefs/amd64.py +185 -0
  40. smallworld/emulators/ghidra/machdefs/arm.py +370 -0
  41. smallworld/emulators/ghidra/machdefs/i386.py +109 -0
  42. smallworld/emulators/ghidra/machdefs/loongarch.py +162 -0
  43. smallworld/emulators/ghidra/machdefs/machdef.py +81 -0
  44. smallworld/emulators/ghidra/machdefs/mips.py +163 -0
  45. smallworld/emulators/ghidra/machdefs/mips64.py +186 -0
  46. smallworld/emulators/ghidra/machdefs/ppc.py +98 -0
  47. smallworld/emulators/ghidra/machdefs/riscv.py +208 -0
  48. smallworld/emulators/ghidra/machdefs/xtensa.py +21 -0
  49. smallworld/emulators/ghidra/typing.py +28 -0
  50. smallworld/emulators/hookable.py +18 -4
  51. smallworld/emulators/panda/machdefs/__init__.py +2 -2
  52. smallworld/emulators/panda/machdefs/aarch64.py +186 -11
  53. smallworld/emulators/panda/machdefs/amd64.py +103 -11
  54. smallworld/emulators/panda/machdefs/arm.py +216 -20
  55. smallworld/emulators/panda/machdefs/i386.py +30 -7
  56. smallworld/emulators/panda/machdefs/machdef.py +9 -16
  57. smallworld/emulators/panda/machdefs/mips.py +49 -5
  58. smallworld/emulators/panda/machdefs/mips64.py +57 -5
  59. smallworld/emulators/panda/machdefs/ppc.py +38 -13
  60. smallworld/emulators/panda/panda.py +146 -44
  61. smallworld/emulators/unicorn/__init__.py +2 -0
  62. smallworld/emulators/unicorn/machdefs/aarch64.py +253 -264
  63. smallworld/emulators/unicorn/machdefs/amd64.py +254 -259
  64. smallworld/emulators/unicorn/machdefs/arm.py +200 -212
  65. smallworld/emulators/unicorn/machdefs/i386.py +84 -90
  66. smallworld/emulators/unicorn/machdefs/machdef.py +2 -23
  67. smallworld/emulators/unicorn/machdefs/mips.py +127 -135
  68. smallworld/emulators/unicorn/unicorn.py +52 -13
  69. smallworld/helpers.py +4 -19
  70. smallworld/hinting/hinting.py +22 -192
  71. smallworld/hinting/hints.py +50 -18
  72. smallworld/instructions/bsid.py +8 -8
  73. smallworld/logging.py +4 -2
  74. smallworld/platforms/__init__.py +12 -0
  75. smallworld/platforms/defs/__init__.py +36 -0
  76. smallworld/platforms/defs/aarch64.py +450 -0
  77. smallworld/platforms/defs/amd64.py +463 -0
  78. smallworld/platforms/defs/arm.py +519 -0
  79. smallworld/platforms/defs/i386.py +258 -0
  80. smallworld/platforms/defs/loongarch.py +270 -0
  81. smallworld/platforms/defs/mips.py +321 -0
  82. smallworld/platforms/defs/mips64.py +313 -0
  83. smallworld/platforms/defs/platformdef.py +97 -0
  84. smallworld/platforms/defs/powerpc.py +259 -0
  85. smallworld/platforms/defs/riscv.py +257 -0
  86. smallworld/platforms/defs/xtensa.py +96 -0
  87. smallworld/{platforms.py → platforms/platforms.py} +3 -0
  88. smallworld/state/cpus/__init__.py +2 -0
  89. smallworld/state/cpus/aarch64.py +0 -9
  90. smallworld/state/cpus/amd64.py +6 -28
  91. smallworld/state/cpus/arm.py +0 -11
  92. smallworld/state/cpus/cpu.py +0 -11
  93. smallworld/state/cpus/i386.py +0 -7
  94. smallworld/state/cpus/loongarch.py +299 -0
  95. smallworld/state/cpus/mips.py +4 -47
  96. smallworld/state/cpus/mips64.py +18 -58
  97. smallworld/state/cpus/powerpc.py +2 -9
  98. smallworld/state/cpus/riscv.py +1 -11
  99. smallworld/state/cpus/xtensa.py +0 -5
  100. smallworld/state/memory/code.py +38 -2
  101. smallworld/state/memory/elf/__init__.py +5 -1
  102. smallworld/state/memory/elf/coredump/__init__.py +3 -0
  103. smallworld/state/memory/elf/coredump/coredump.py +46 -0
  104. smallworld/state/memory/elf/coredump/prstatus/__init__.py +27 -0
  105. smallworld/state/memory/elf/coredump/prstatus/aarch64.py +46 -0
  106. smallworld/state/memory/elf/coredump/prstatus/amd64.py +40 -0
  107. smallworld/state/memory/elf/coredump/prstatus/arm.py +53 -0
  108. smallworld/state/memory/elf/coredump/prstatus/i386.py +30 -0
  109. smallworld/state/memory/elf/coredump/prstatus/mips.py +55 -0
  110. smallworld/state/memory/elf/coredump/prstatus/mips64.py +57 -0
  111. smallworld/state/memory/elf/coredump/prstatus/ppc.py +82 -0
  112. smallworld/state/memory/elf/coredump/prstatus/prstatus.py +129 -0
  113. smallworld/state/memory/elf/elf.py +211 -57
  114. smallworld/state/memory/elf/register_state.py +36 -0
  115. smallworld/state/memory/elf/rela/__init__.py +2 -0
  116. smallworld/state/memory/elf/rela/aarch64.py +3 -1
  117. smallworld/state/memory/elf/rela/amd64.py +4 -2
  118. smallworld/state/memory/elf/rela/arm.py +4 -2
  119. smallworld/state/memory/elf/rela/i386.py +4 -2
  120. smallworld/state/memory/elf/rela/loongarch.py +32 -0
  121. smallworld/state/memory/elf/rela/mips.py +39 -18
  122. smallworld/state/memory/elf/rela/ppc.py +31 -14
  123. smallworld/state/memory/elf/structs.py +3 -0
  124. smallworld/state/memory/heap.py +2 -2
  125. smallworld/state/memory/memory.py +18 -0
  126. smallworld/state/memory/pe/__init__.py +3 -0
  127. smallworld/state/memory/pe/pe.py +361 -0
  128. smallworld/state/memory/pe/structs.py +60 -0
  129. smallworld/state/memory/stack/__init__.py +2 -0
  130. smallworld/state/memory/stack/loongarch.py +26 -0
  131. smallworld/state/models/__init__.py +29 -2
  132. smallworld/state/models/aarch64/__init__.py +1 -0
  133. smallworld/state/models/aarch64/systemv/__init__.py +6 -0
  134. smallworld/state/models/aarch64/systemv/c99/__init__.py +12 -0
  135. smallworld/state/models/aarch64/systemv/c99/signal.py +16 -0
  136. smallworld/state/models/aarch64/systemv/c99/stdio.py +265 -0
  137. smallworld/state/models/aarch64/systemv/c99/stdlib.py +169 -0
  138. smallworld/state/models/aarch64/systemv/c99/string.py +139 -0
  139. smallworld/state/models/aarch64/systemv/c99/time.py +61 -0
  140. smallworld/state/models/aarch64/systemv/posix/__init__.py +6 -0
  141. smallworld/state/models/aarch64/systemv/posix/libgen.py +16 -0
  142. smallworld/state/models/aarch64/systemv/posix/signal.py +157 -0
  143. smallworld/state/models/aarch64/systemv/systemv.py +80 -0
  144. smallworld/state/models/amd64/__init__.py +1 -0
  145. smallworld/state/models/amd64/systemv/__init__.py +6 -0
  146. smallworld/state/models/amd64/systemv/c99/__init__.py +12 -0
  147. smallworld/state/models/amd64/systemv/c99/signal.py +16 -0
  148. smallworld/state/models/amd64/systemv/c99/stdio.py +265 -0
  149. smallworld/state/models/amd64/systemv/c99/stdlib.py +169 -0
  150. smallworld/state/models/amd64/systemv/c99/string.py +139 -0
  151. smallworld/state/models/amd64/systemv/c99/time.py +61 -0
  152. smallworld/state/models/amd64/systemv/posix/__init__.py +6 -0
  153. smallworld/state/models/amd64/systemv/posix/libgen.py +16 -0
  154. smallworld/state/models/amd64/systemv/posix/signal.py +157 -0
  155. smallworld/state/models/amd64/systemv/systemv.py +78 -0
  156. smallworld/state/models/armel/__init__.py +1 -0
  157. smallworld/state/models/armel/systemv/__init__.py +6 -0
  158. smallworld/state/models/armel/systemv/c99/__init__.py +12 -0
  159. smallworld/state/models/armel/systemv/c99/signal.py +16 -0
  160. smallworld/state/models/armel/systemv/c99/stdio.py +265 -0
  161. smallworld/state/models/armel/systemv/c99/stdlib.py +169 -0
  162. smallworld/state/models/armel/systemv/c99/string.py +139 -0
  163. smallworld/state/models/armel/systemv/c99/time.py +61 -0
  164. smallworld/state/models/armel/systemv/posix/__init__.py +6 -0
  165. smallworld/state/models/armel/systemv/posix/libgen.py +16 -0
  166. smallworld/state/models/armel/systemv/posix/signal.py +157 -0
  167. smallworld/state/models/armel/systemv/systemv.py +82 -0
  168. smallworld/state/models/armhf/__init__.py +1 -0
  169. smallworld/state/models/armhf/systemv/__init__.py +6 -0
  170. smallworld/state/models/armhf/systemv/c99/__init__.py +12 -0
  171. smallworld/state/models/armhf/systemv/c99/signal.py +16 -0
  172. smallworld/state/models/armhf/systemv/c99/stdio.py +265 -0
  173. smallworld/state/models/armhf/systemv/c99/stdlib.py +169 -0
  174. smallworld/state/models/armhf/systemv/c99/string.py +139 -0
  175. smallworld/state/models/armhf/systemv/c99/time.py +61 -0
  176. smallworld/state/models/armhf/systemv/posix/__init__.py +6 -0
  177. smallworld/state/models/armhf/systemv/posix/libgen.py +16 -0
  178. smallworld/state/models/armhf/systemv/posix/signal.py +157 -0
  179. smallworld/state/models/armhf/systemv/systemv.py +77 -0
  180. smallworld/state/models/c99/__init__.py +12 -0
  181. smallworld/state/models/c99/fmt_print.py +915 -0
  182. smallworld/state/models/c99/fmt_scan.py +864 -0
  183. smallworld/state/models/c99/math.py +362 -0
  184. smallworld/state/models/c99/signal.py +71 -0
  185. smallworld/state/models/c99/stdio.py +1305 -0
  186. smallworld/state/models/c99/stdlib.py +595 -0
  187. smallworld/state/models/c99/string.py +674 -0
  188. smallworld/state/models/c99/time.py +340 -0
  189. smallworld/state/models/c99/utils.py +89 -0
  190. smallworld/state/models/cstd.py +759 -0
  191. smallworld/state/models/errno.py +581 -0
  192. smallworld/state/models/filedesc.py +515 -0
  193. smallworld/state/models/i386/__init__.py +1 -0
  194. smallworld/state/models/i386/systemv/__init__.py +6 -0
  195. smallworld/state/models/i386/systemv/c99/__init__.py +12 -0
  196. smallworld/state/models/i386/systemv/c99/signal.py +16 -0
  197. smallworld/state/models/i386/systemv/c99/stdio.py +265 -0
  198. smallworld/state/models/i386/systemv/c99/stdlib.py +169 -0
  199. smallworld/state/models/i386/systemv/c99/string.py +139 -0
  200. smallworld/state/models/i386/systemv/c99/time.py +61 -0
  201. smallworld/state/models/i386/systemv/posix/__init__.py +6 -0
  202. smallworld/state/models/i386/systemv/posix/libgen.py +16 -0
  203. smallworld/state/models/i386/systemv/posix/signal.py +157 -0
  204. smallworld/state/models/i386/systemv/systemv.py +71 -0
  205. smallworld/state/models/loongarch64/__init__.py +1 -0
  206. smallworld/state/models/loongarch64/systemv/__init__.py +6 -0
  207. smallworld/state/models/loongarch64/systemv/c99/__init__.py +12 -0
  208. smallworld/state/models/loongarch64/systemv/c99/signal.py +16 -0
  209. smallworld/state/models/loongarch64/systemv/c99/stdio.py +265 -0
  210. smallworld/state/models/loongarch64/systemv/c99/stdlib.py +169 -0
  211. smallworld/state/models/loongarch64/systemv/c99/string.py +139 -0
  212. smallworld/state/models/loongarch64/systemv/c99/time.py +61 -0
  213. smallworld/state/models/loongarch64/systemv/posix/__init__.py +6 -0
  214. smallworld/state/models/loongarch64/systemv/posix/libgen.py +16 -0
  215. smallworld/state/models/loongarch64/systemv/posix/signal.py +157 -0
  216. smallworld/state/models/loongarch64/systemv/systemv.py +83 -0
  217. smallworld/state/models/mips/__init__.py +1 -0
  218. smallworld/state/models/mips/systemv/__init__.py +6 -0
  219. smallworld/state/models/mips/systemv/c99/__init__.py +12 -0
  220. smallworld/state/models/mips/systemv/c99/signal.py +16 -0
  221. smallworld/state/models/mips/systemv/c99/stdio.py +265 -0
  222. smallworld/state/models/mips/systemv/c99/stdlib.py +169 -0
  223. smallworld/state/models/mips/systemv/c99/string.py +139 -0
  224. smallworld/state/models/mips/systemv/c99/time.py +61 -0
  225. smallworld/state/models/mips/systemv/posix/__init__.py +6 -0
  226. smallworld/state/models/mips/systemv/posix/libgen.py +16 -0
  227. smallworld/state/models/mips/systemv/posix/signal.py +157 -0
  228. smallworld/state/models/mips/systemv/systemv.py +78 -0
  229. smallworld/state/models/mips64/__init__.py +1 -0
  230. smallworld/state/models/mips64/systemv/__init__.py +6 -0
  231. smallworld/state/models/mips64/systemv/c99/__init__.py +12 -0
  232. smallworld/state/models/mips64/systemv/c99/signal.py +16 -0
  233. smallworld/state/models/mips64/systemv/c99/stdio.py +265 -0
  234. smallworld/state/models/mips64/systemv/c99/stdlib.py +169 -0
  235. smallworld/state/models/mips64/systemv/c99/string.py +139 -0
  236. smallworld/state/models/mips64/systemv/c99/time.py +61 -0
  237. smallworld/state/models/mips64/systemv/posix/__init__.py +6 -0
  238. smallworld/state/models/mips64/systemv/posix/libgen.py +16 -0
  239. smallworld/state/models/mips64/systemv/posix/signal.py +157 -0
  240. smallworld/state/models/mips64/systemv/systemv.py +98 -0
  241. smallworld/state/models/mips64el/__init__.py +1 -0
  242. smallworld/state/models/mips64el/systemv/__init__.py +6 -0
  243. smallworld/state/models/mips64el/systemv/c99/__init__.py +12 -0
  244. smallworld/state/models/mips64el/systemv/c99/signal.py +16 -0
  245. smallworld/state/models/mips64el/systemv/c99/stdio.py +265 -0
  246. smallworld/state/models/mips64el/systemv/c99/stdlib.py +169 -0
  247. smallworld/state/models/mips64el/systemv/c99/string.py +139 -0
  248. smallworld/state/models/mips64el/systemv/c99/time.py +61 -0
  249. smallworld/state/models/mips64el/systemv/posix/__init__.py +6 -0
  250. smallworld/state/models/mips64el/systemv/posix/libgen.py +16 -0
  251. smallworld/state/models/mips64el/systemv/posix/signal.py +157 -0
  252. smallworld/state/models/mips64el/systemv/systemv.py +96 -0
  253. smallworld/state/models/mipsel/__init__.py +1 -0
  254. smallworld/state/models/mipsel/systemv/__init__.py +6 -0
  255. smallworld/state/models/mipsel/systemv/c99/__init__.py +12 -0
  256. smallworld/state/models/mipsel/systemv/c99/signal.py +16 -0
  257. smallworld/state/models/mipsel/systemv/c99/stdio.py +265 -0
  258. smallworld/state/models/mipsel/systemv/c99/stdlib.py +169 -0
  259. smallworld/state/models/mipsel/systemv/c99/string.py +139 -0
  260. smallworld/state/models/mipsel/systemv/c99/time.py +61 -0
  261. smallworld/state/models/mipsel/systemv/posix/__init__.py +6 -0
  262. smallworld/state/models/mipsel/systemv/posix/libgen.py +16 -0
  263. smallworld/state/models/mipsel/systemv/posix/signal.py +157 -0
  264. smallworld/state/models/mipsel/systemv/systemv.py +78 -0
  265. smallworld/state/models/model.py +27 -2
  266. smallworld/state/models/posix/__init__.py +6 -0
  267. smallworld/state/models/posix/libgen.py +123 -0
  268. smallworld/state/models/posix/signal.py +690 -0
  269. smallworld/state/models/powerpc/__init__.py +1 -0
  270. smallworld/state/models/powerpc/systemv/__init__.py +6 -0
  271. smallworld/state/models/powerpc/systemv/c99/__init__.py +12 -0
  272. smallworld/state/models/powerpc/systemv/c99/signal.py +16 -0
  273. smallworld/state/models/powerpc/systemv/c99/stdio.py +265 -0
  274. smallworld/state/models/powerpc/systemv/c99/stdlib.py +169 -0
  275. smallworld/state/models/powerpc/systemv/c99/string.py +139 -0
  276. smallworld/state/models/powerpc/systemv/c99/time.py +61 -0
  277. smallworld/state/models/powerpc/systemv/posix/__init__.py +6 -0
  278. smallworld/state/models/powerpc/systemv/posix/libgen.py +16 -0
  279. smallworld/state/models/powerpc/systemv/posix/signal.py +157 -0
  280. smallworld/state/models/powerpc/systemv/systemv.py +93 -0
  281. smallworld/state/models/riscv64/__init__.py +1 -0
  282. smallworld/state/models/riscv64/systemv/__init__.py +6 -0
  283. smallworld/state/models/riscv64/systemv/c99/__init__.py +12 -0
  284. smallworld/state/models/riscv64/systemv/c99/signal.py +16 -0
  285. smallworld/state/models/riscv64/systemv/c99/stdio.py +265 -0
  286. smallworld/state/models/riscv64/systemv/c99/stdlib.py +169 -0
  287. smallworld/state/models/riscv64/systemv/c99/string.py +139 -0
  288. smallworld/state/models/riscv64/systemv/c99/time.py +61 -0
  289. smallworld/state/models/riscv64/systemv/posix/__init__.py +6 -0
  290. smallworld/state/models/riscv64/systemv/posix/libgen.py +16 -0
  291. smallworld/state/models/riscv64/systemv/posix/signal.py +157 -0
  292. smallworld/state/models/riscv64/systemv/systemv.py +85 -0
  293. smallworld/state/state.py +65 -24
  294. smallworld/state/unstable/elf.py +16 -31
  295. smallworld/utils.py +6 -1
  296. {smallworld_re-1.0.3.dist-info → smallworld_re-2.0.0.dist-info}/METADATA +74 -42
  297. smallworld_re-2.0.0.dist-info/RECORD +374 -0
  298. {smallworld_re-1.0.3.dist-info → smallworld_re-2.0.0.dist-info}/WHEEL +1 -1
  299. smallworld/state/models/x86/__init__.py +0 -2
  300. smallworld/state/models/x86/microsoftcdecl.py +0 -35
  301. smallworld/state/models/x86/systemv.py +0 -240
  302. smallworld_re-1.0.3.dist-info/RECORD +0 -166
  303. /smallworld/state/models/{posix.py → _posix.py} +0 -0
  304. {smallworld_re-1.0.3.dist-info → smallworld_re-2.0.0.dist-info}/entry_points.txt +0 -0
  305. {smallworld_re-1.0.3.dist-info → smallworld_re-2.0.0.dist-info}/licenses/LICENSE.txt +0 -0
  306. {smallworld_re-1.0.3.dist-info → smallworld_re-2.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,340 @@
1
+ import enum
2
+ import typing
3
+
4
+ import angr
5
+ import archinfo
6
+ import pypcode
7
+
8
+ from ....exceptions import EmulationError
9
+ from ....platforms import Architecture, Byteorder
10
+ from .machdef import GhidraMachineDef
11
+
12
+
13
+ class UpdatedEnumMeta(enum.EnumMeta):
14
+ def __contains__(cls, obj):
15
+ if isinstance(obj, int):
16
+ return obj in cls._value2member_map_
17
+ return enum.EnumMeta.__contains__(enum.EnumMeta, obj)
18
+
19
+
20
+ def handle_nop(irsb, i):
21
+ # This op has no impact on user-facing machine state.
22
+ irsb._ops.pop(i)
23
+ return i
24
+
25
+
26
+ def handle_sigtrap(irsb, i):
27
+ # This op should terminate this block with SIGTRAP
28
+ next_addr = irsb._ops[i - 1].inputs[0].offset + 3
29
+ irsb._ops = irsb._ops[0:i]
30
+ irsb.next = next_addr
31
+ irsb._size = next_addr - irsb.addr
32
+ irsb._instruction_addresses = list(
33
+ filter(lambda x: x < next_addr, irsb._instruction_addresses)
34
+ )
35
+ irsb.jumpkind = "Ijk_SigTRAP"
36
+ return i
37
+
38
+
39
+ def handle_syscall(irsb, i):
40
+ # This op should terminate this block with a syscall
41
+ next_addr = irsb._ops[i - 1].inputs[0].offset + 3
42
+ irsb._ops = irsb._ops[0:i]
43
+ irsb.next = next_addr
44
+ irsb._size = next_addr - irsb.addr
45
+ irsb._instruction_addresses = list(
46
+ filter(lambda x: x < next_addr, irsb._instruction_addresses)
47
+ )
48
+ irsb.jumpkind = "Ijk_Sys_syscall"
49
+
50
+ return i
51
+
52
+
53
+ def handle_unimpl(irsb, i):
54
+ # I don't know what this op does yet
55
+ userop = LoongArchUserOp(irsb._ops[i].inputs[0].offset)
56
+ raise EmulationError(f"Unimplemented user op {userop!r}")
57
+
58
+
59
+ class LoongArchUserOp(enum.IntEnum, metaclass=UpdatedEnumMeta):
60
+ def __new__(
61
+ cls, val: int, name: str = "", handler: typing.Any = None, desc: str = ""
62
+ ):
63
+ obj = int.__new__(cls, val)
64
+ obj._value_ = val
65
+ obj.short_name = name
66
+ obj.handler = handler
67
+ obj.description = desc
68
+ return obj
69
+
70
+ def __init__(
71
+ self, val: int, name: str = "", handler: typing.Any = None, desc: str = ""
72
+ ):
73
+ self._value_: int = val
74
+ self.short_name: str = name
75
+ self.handler: typing.Any = handler
76
+ self.description: str = desc
77
+
78
+ def __repr__(self):
79
+ return f"{hex(self.value)}: {self.short_name} - {self.description}"
80
+
81
+ BREAK = 0x00, "break", handle_sigtrap, "Breakpoint instruction"
82
+ CPUCFG = 0x01, "cpucfg", handle_unimpl, "CPU config instruction"
83
+ ADDR_BOUND_EXCEPTION = 0x02, "addr_bound_exception", handle_unimpl, "Unknown"
84
+ BOUND_CHECK_EXCEPTION = 0x03, "bound_check_exception", handle_unimpl, "Unknown"
85
+ CRC_IEEE802_3 = 0x04, "crc_ieee802.3", handle_unimpl, "Unknown"
86
+ CRC_CASTAGNOLI = 0x05, "crc_castagnoli", handle_unimpl, "Unknown"
87
+ DBCL = 0x06, "dbcl", handle_unimpl, "Unknown"
88
+ DBAR = 0x07, "dbar", handle_nop, "Data Barrier"
89
+ IBAR = 0x08, "ibar", handle_nop, "Instruction Barrier"
90
+ IOCSRRD = 0x09, "iocsrrd", handle_unimpl, "Unknown"
91
+ IOCSRWR = 0x0A, "iocsrwr", handle_unimpl, "Unknown"
92
+ PRELD_LOADL1CACHE = 0x0B, "preld_loadl1cache", handle_unimpl, "Unknown"
93
+ PRELD_STOREL1CACHE = 0x0C, "preld_storel1cache", handle_unimpl, "Unknown"
94
+ PRELD_NOP = 0x0D, "preld_nop", handle_unimpl, "Unknown"
95
+ PRELDX_LOADL1CACHE = 0x0E, "preldx_loadl1cache", handle_unimpl, "Unknown"
96
+ PRELDX_STOREL1CACHE = 0x0F, "preldx_storel1cache", handle_unimpl, "Unknown"
97
+ PRELDX_NOP = 0x10, "preldx_nop", handle_unimpl, "Unknown"
98
+ RDTIME_COUNTER = 0x11, "rdtime.counter", handle_unimpl, "Unknown"
99
+ RDTIME_COUNTERID = 0x12, "rdtime.counterid", handle_unimpl, "Unknown"
100
+ SYSCALL = 0x13, "syscall", handle_syscall, "Unknown"
101
+ F_SCALEB = 0x14, "f_scaleb", handle_unimpl, "Unknown"
102
+ F_LOGB = 0x15, "f_logb", handle_unimpl, "Unknown"
103
+ F_CLASS = 0x16, "f_class", handle_unimpl, "Unknown"
104
+ ROUND_EVEN = 0x17, "round_even", handle_unimpl, "Unknown"
105
+
106
+
107
+ class LoongArchMachineDef(GhidraMachineDef):
108
+ byteorder = Byteorder.LITTLE
109
+
110
+ _registers = {
111
+ "pc": "pc",
112
+ # Zero register
113
+ "r0": "zero",
114
+ "zero": "zero",
115
+ # Return address
116
+ "r1": "ra",
117
+ "ra": "ra",
118
+ # TLS pointer
119
+ "r2": "tp",
120
+ "tp": "tp",
121
+ # Stack pointer
122
+ "r3": "sp",
123
+ "sp": "sp",
124
+ # Arguments.
125
+ # a0 and a1 are also the return registers
126
+ "r4": "a0",
127
+ "a0": "a0",
128
+ "v0": "a0",
129
+ "r5": "a1",
130
+ "a1": "a1",
131
+ "v1": "a1",
132
+ "r6": "a2",
133
+ "a2": "a2",
134
+ "r7": "a3",
135
+ "a3": "a3",
136
+ "r8": "a4",
137
+ "a4": "a4",
138
+ "r9": "a5",
139
+ "a5": "a5",
140
+ "r10": "a6",
141
+ "a6": "a6",
142
+ "r11": "a7",
143
+ "a7": "a7",
144
+ # Temporary registers
145
+ "r12": "t0",
146
+ "t0": "t0",
147
+ "r13": "t1",
148
+ "t1": "t1",
149
+ "r14": "t2",
150
+ "t2": "t2",
151
+ "r15": "t3",
152
+ "t3": "t3",
153
+ "r16": "t4",
154
+ "t4": "t4",
155
+ "r17": "t5",
156
+ "t5": "t5",
157
+ "r18": "t6",
158
+ "t6": "t6",
159
+ "r19": "t7",
160
+ "t7": "t7",
161
+ "r20": "t8",
162
+ "t8": "t8",
163
+ # Per-CPU Base Address
164
+ "r21": "r21",
165
+ "u0": "r21",
166
+ # Frame Pointer
167
+ "r22": "fp",
168
+ "fp": "fp",
169
+ # Static registers
170
+ "r23": "s0",
171
+ "s0": "s0",
172
+ "r24": "s1",
173
+ "s1": "s1",
174
+ "r25": "s2",
175
+ "s2": "s2",
176
+ "r26": "s3",
177
+ "s3": "s3",
178
+ "r27": "s4",
179
+ "s4": "s4",
180
+ "r28": "s5",
181
+ "s5": "s5",
182
+ "r29": "s6",
183
+ "s6": "s6",
184
+ "r30": "s7",
185
+ "s7": "s7",
186
+ "r31": "s8",
187
+ "s8": "s8",
188
+ # Floating-point arguments.
189
+ # fa0 and fa1 are also return values
190
+ "f0": "fa0",
191
+ "fa0": "fa0",
192
+ "f1": "fa1",
193
+ "fa1": "fa1",
194
+ "f2": "fa2",
195
+ "fa2": "fa2",
196
+ "f3": "fa3",
197
+ "fa3": "fa3",
198
+ "f4": "fa4",
199
+ "fa4": "fa4",
200
+ "f5": "fa5",
201
+ "fa5": "fa5",
202
+ "f6": "fa6",
203
+ "fa6": "fa6",
204
+ "f7": "fa7",
205
+ "fa7": "fa7",
206
+ # Floating-point temporary registers
207
+ "f8": "ft0",
208
+ "ft0": "ft0",
209
+ "f9": "ft1",
210
+ "ft1": "ft1",
211
+ "f10": "ft2",
212
+ "ft2": "ft2",
213
+ "f11": "ft3",
214
+ "ft3": "ft3",
215
+ "f12": "ft4",
216
+ "ft4": "ft4",
217
+ "f13": "ft5",
218
+ "ft5": "ft5",
219
+ "f14": "ft6",
220
+ "ft6": "ft6",
221
+ "f15": "ft7",
222
+ "ft7": "ft7",
223
+ "f16": "ft8",
224
+ "ft8": "ft8",
225
+ "f17": "ft9",
226
+ "ft9": "ft9",
227
+ "f18": "ft10",
228
+ "ft10": "ft10",
229
+ "f19": "ft11",
230
+ "ft11": "ft11",
231
+ "f20": "ft12",
232
+ "ft12": "ft12",
233
+ "f21": "ft13",
234
+ "ft13": "ft13",
235
+ "f22": "ft14",
236
+ "ft14": "ft14",
237
+ "f23": "ft15",
238
+ "ft15": "ft15",
239
+ # Floating-point static registers
240
+ "f24": "fs0",
241
+ "fs0": "fs0",
242
+ "f25": "fs1",
243
+ "fs1": "fs1",
244
+ "f26": "fs2",
245
+ "fs2": "fs2",
246
+ "f27": "fs3",
247
+ "fs3": "fs3",
248
+ "f28": "fs4",
249
+ "fs4": "fs4",
250
+ "f29": "fs5",
251
+ "fs5": "fs5",
252
+ "f30": "fs6",
253
+ "fs6": "fs6",
254
+ "f31": "fs7",
255
+ "fs7": "fs7",
256
+ }
257
+
258
+ def successors(self, state: angr.SimState, **kwargs) -> typing.Any:
259
+ # xtensa includes a _LOT_ of custom pcode operations.
260
+
261
+ # Fetch or compute the IR block for our state
262
+ if "irsb" in kwargs and kwargs["irsb"] is not None:
263
+ # Someone's already specified an IR block.
264
+ irsb = kwargs["irsb"]
265
+ else:
266
+ # Disable optimization; it doesn't work
267
+ kwargs["opt_level"] = 0
268
+
269
+ # Compute the block from the state.
270
+ # Pray to the Powers that kwargs are compatible.
271
+ irsb = state.block(**kwargs).vex
272
+
273
+ i = 0
274
+ while i < len(irsb._ops):
275
+ op = irsb._ops[i]
276
+ if op.opcode == pypcode.OpCode.CALLOTHER:
277
+ # This is a user-defined Pcode op.
278
+ # Alter irsb to mimic its behavior, if we can.
279
+ opnum = op.inputs[0].offset
280
+
281
+ if opnum not in LoongArchUserOp:
282
+ # Not a userop.
283
+ raise EmulationError(f"Undefined user op {hex(opnum)}")
284
+ # get the enum struct
285
+ userop = LoongArchUserOp(opnum)
286
+
287
+ # Invoke the handler
288
+ i = userop.handler(irsb, i)
289
+ else:
290
+ i += 1
291
+
292
+ # Force the engine to use our IR block
293
+ kwargs["irsb"] = irsb
294
+
295
+ # Turn the crank on the engine
296
+ return super().successors(state, **kwargs)
297
+
298
+
299
+ class SimCCLoongArchLinux(angr.calling_conventions.SimCC):
300
+ ARG_REGS = ["a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7"]
301
+ FP_ARG_REGS = ["fa0", "fa1", "fa2", "fa3", "fa4", "fa5", "fa6", "fa7"]
302
+ RETURN_VAL = angr.calling_conventions.SimRegArg("a0", 8)
303
+ RETURN_ADDR = angr.calling_conventions.SimRegArg("ra", 8)
304
+ ARCH = archinfo.ArchPcode("Loongarch:LE:64:lp64d") # type: ignore
305
+
306
+
307
+ angr.calling_conventions.register_default_cc(
308
+ "Loongarch:LE:64:lp64d", SimCCLoongArchLinux
309
+ )
310
+
311
+
312
+ class SimCCLoongArchLinuxSyscall(angr.calling_conventions.SimCCSyscall):
313
+ ARG_REGS = ["a0", "a1", "a2", "a3", "a4", "a5"]
314
+ FP_ARG_REGS: typing.List[str] = []
315
+ RETURN_VAL = angr.calling_conventions.SimRegArg("a0", 8)
316
+ RETURN_ADDR = angr.calling_conventions.SimRegArg("ip_at_syscall", 8)
317
+ ARCH = None
318
+
319
+ @classmethod
320
+ def _match(cls, arch, args, sp_data):
321
+ # Never match; only occurs durring syscalls
322
+ return False
323
+
324
+ @staticmethod
325
+ def syscall_num(state):
326
+ # This is a massive guess from RE'ing libc
327
+ return state.regs.a7
328
+
329
+
330
+ angr.calling_conventions.register_syscall_cc(
331
+ "Loongarch:LE:64:lp64d", "default", SimCCLoongArchLinuxSyscall
332
+ )
333
+
334
+
335
+ class LoongArch64MachineDef(LoongArchMachineDef):
336
+ arch = Architecture.LOONGARCH64
337
+ pcode_language = "Loongarch:LE:64:lp64d"
338
+
339
+
340
+ __all__ = ["LoongArch64MachineDef"]
@@ -28,12 +28,6 @@ class AngrMachineDef:
28
28
  """The angr architecture to use"""
29
29
  raise NotImplementedError("This is an abstract method.")
30
30
 
31
- @property
32
- @abc.abstractmethod
33
- def pc_reg(self) -> str:
34
- """The program counter register name"""
35
- return ""
36
-
37
31
  # Is this thumb?
38
32
  # Almost always no, but angr needs to ask.
39
33
  is_thumb: bool = False
@@ -98,7 +92,6 @@ class AngrMachineDef:
98
92
 
99
93
  Arguments:
100
94
  arch: The architecture ID you want
101
- mode: The mode ID you want
102
95
  byteorder: The byteorderness you want
103
96
 
104
97
  Returns:
@@ -117,7 +110,7 @@ class AngrMachineDef:
117
110
  raise ValueError(f"No machine model for {platform}")
118
111
 
119
112
 
120
- class PcodeMachineDef(AngrMachineDef):
113
+ class GhidraMachineDef(AngrMachineDef):
121
114
  """Container class for pcode-dependent angr architecture-specific definitions"""
122
115
 
123
116
  @property
@@ -7,8 +7,6 @@ from .machdef import AngrMachineDef
7
7
  class MIPSMachineDef(AngrMachineDef):
8
8
  arch = Architecture.MIPS32
9
9
 
10
- pc_reg = "pc"
11
-
12
10
  # NOTE: MIPS registers have a name and a number
13
11
  # angr's machine state doesn't use the number,
14
12
  # so... name.
@@ -7,8 +7,6 @@ from .machdef import AngrMachineDef
7
7
  class MIPS64MachineDef(AngrMachineDef):
8
8
  arch = Architecture.MIPS64
9
9
 
10
- pc_reg = "pc"
11
-
12
10
  # NOTE: MIPS registers have a name and a number
13
11
  # angr's machine state doesn't use the number,
14
12
  # so... name.
@@ -7,8 +7,6 @@ from .machdef import AngrMachineDef
7
7
  class PowerPCMachineDef(AngrMachineDef):
8
8
  byteorder = Byteorder.BIG
9
9
 
10
- pc_reg = "pc"
11
-
12
10
  _registers = {
13
11
  "r0": "r0",
14
12
  "r1": "r1",
@@ -43,6 +41,7 @@ class PowerPCMachineDef(AngrMachineDef):
43
41
  "r29": "r29",
44
42
  "r30": "r30",
45
43
  "r31": "r31",
44
+ "bp": "r31",
46
45
  "pc": "pc",
47
46
  "lr": "lr",
48
47
  "ctr": "ctr",
@@ -58,8 +58,6 @@ class RISCV64MachineDef(AngrMachineDef):
58
58
 
59
59
  angr_arch = archinfo.ArchRISCV64()
60
60
 
61
- pc_reg = "pc"
62
-
63
61
  _registers = {
64
62
  # *** General-Purpose Registers ***
65
63
  # x0 is wired to 0, and aliased as "zero"
@@ -194,28 +192,28 @@ class RISCV64MachineDef(AngrMachineDef):
194
192
  "fs1": "fs1",
195
193
  # f10 is argument 0
196
194
  "f10": "f10",
197
- "a0": "a0",
195
+ "fa0": "fa0",
198
196
  # f11 is argument 1
199
197
  "f11": "f11",
200
- "a1": "a1",
198
+ "fa1": "fa1",
201
199
  # f12 is argument 2
202
200
  "f12": "f12",
203
- "a2": "a2",
201
+ "fa2": "fa2",
204
202
  # f13 is argument 3
205
203
  "f13": "f13",
206
- "a3": "a3",
204
+ "fa3": "fa3",
207
205
  # f14 is argument 4
208
206
  "f14": "f14",
209
- "a4": "a4",
207
+ "fa4": "fa4",
210
208
  # f15 is argument 5
211
209
  "f15": "f15",
212
- "a5": "a5",
210
+ "fa5": "fa5",
213
211
  # f16 is argument 6
214
212
  "f16": "f16",
215
- "a6": "a6",
213
+ "fa6": "fa6",
216
214
  # f7 is argument 7
217
215
  "f17": "f17",
218
- "a7": "a7",
216
+ "fa7": "fa7",
219
217
  # f18 is a callee-saved register
220
218
  "f18": "f18",
221
219
  "fs2": "fs2",
@@ -6,7 +6,7 @@ import pypcode
6
6
 
7
7
  from ....exceptions import EmulationError
8
8
  from ....platforms import Architecture, Byteorder
9
- from .machdef import PcodeMachineDef
9
+ from .machdef import GhidraMachineDef
10
10
 
11
11
 
12
12
  def handle_nop(irsb, i):
@@ -199,10 +199,13 @@ angr.calling_conventions.register_syscall_cc(
199
199
  )
200
200
 
201
201
 
202
- class XTensaMachineDef(PcodeMachineDef):
202
+ class XTensaMachineDef(GhidraMachineDef):
203
203
  arch = Architecture.XTENSA
204
- _registers = {f"a{i}": f"a{i}" for i in range(0, 16)} | {"pc": "pc", "sar": "sar"}
205
- pc_reg = "pc"
204
+ _registers = {f"a{i}": f"a{i}" for i in range(0, 16)} | {
205
+ "pc": "pc",
206
+ "sar": "sar",
207
+ "sp": "a1",
208
+ }
206
209
 
207
210
  def successors(self, state: angr.SimState, **kwargs) -> typing.Any:
208
211
  # xtensa includes a _LOT_ of custom pcode operations.
@@ -600,6 +600,13 @@ class MemoryReadHookable(metaclass=abc.ABCMeta):
600
600
  ) -> None:
601
601
  """Hook memory reads within a given range, handling concrete values
602
602
 
603
+ Note that this will trigger for any read that overlaps the specified range,
604
+ and will report all data read, not just the overlap.
605
+ Hooks should expect to handle partial or oddly-sized reads.
606
+
607
+ If the hook chooses to override the data being read,
608
+ it must return data of the same size as the original read.
609
+
603
610
  Arguments:
604
611
  start: The start address of the memory range to hook.
605
612
  end: The end address of the memory range to hook.
@@ -633,6 +640,13 @@ class MemoryReadHookable(metaclass=abc.ABCMeta):
633
640
  ) -> None:
634
641
  """Hook memory reads within a given range, handling symbolic values
635
642
 
643
+ Note that this will trigger for any read that overlaps the specified range,
644
+ and will report all data read, not just the overlap.
645
+ Hooks should expect to handle partial or oddly-sized reads.
646
+
647
+ If the hook chooses to override the data being read,
648
+ it must return data of the same size as the original read.
649
+
636
650
  Arguments:
637
651
  start: The start address of the memory range to hook.
638
652
  end: The end address of the memory range to hook.
@@ -739,6 +753,10 @@ class MemoryWriteHookable(metaclass=abc.ABCMeta):
739
753
  ) -> None:
740
754
  """Hook memory writes within a given range, handling concrete values.
741
755
 
756
+ Note that this will trigger for any write that overlaps the specified range,
757
+ and will report all data written, not just the overlap.
758
+ Hooks should expect to handle partial or oddly-sized writes.
759
+
742
760
  Arguments:
743
761
  start: The start address of the memory range to hook.
744
762
  end: The end address of the memory range to hook.
@@ -763,6 +781,10 @@ class MemoryWriteHookable(metaclass=abc.ABCMeta):
763
781
  ) -> None:
764
782
  """Hook memory writes within a given range, handling symbolic values
765
783
 
784
+ Note that this will trigger for any write that overlaps the specified range,
785
+ and will report all data written, not just the overlap.
786
+ Hooks should expect to handle partial or oddly-sized writes.
787
+
766
788
  Arguments:
767
789
  start: The start address of the memory range to hook.
768
790
  end: The end address of the memory range to hook.
@@ -0,0 +1,37 @@
1
+ from ... import platforms
2
+ from .typing import AbstractGhidraEmulator
3
+
4
+
5
+ def GhidraEmulator(platform: platforms.Platform) -> AbstractGhidraEmulator:
6
+ """Factory for creating a GhidraEmulator
7
+
8
+ Importing any of the pyghidra packages requires
9
+ booting up a JVM, which takes several seconds.
10
+ It also doesn't work if Java and Ghidra are not configured.
11
+
12
+ Rather than requiring all SmallWorld users to sit through
13
+ this process, export a factory method that looks
14
+ exactly like an Emulator constructor.
15
+ Only boot pyghidra if the factory is called,
16
+ and only import GhidraEmulator if successful.
17
+
18
+ See GhidraEmulator in pcode.py for the actua emulator class.
19
+
20
+ Arguments:
21
+ platform: The platform to use when creating the emulator
22
+
23
+ Returns:
24
+ A GhidraEmulator object
25
+ """
26
+
27
+ import pyghidra
28
+
29
+ if not pyghidra.started():
30
+ pyghidra.start()
31
+
32
+ from .ghidra import GhidraEmulator as Emu
33
+
34
+ return Emu(platform)
35
+
36
+
37
+ __all__ = ["GhidraEmulator"]