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,36 @@
1
+ class RegisterState:
2
+ def __init__(self, registers: dict, pc: int, sp: int, status: int, arch: str):
3
+ self.arch = arch
4
+ self.pc = pc
5
+ self.sp = sp
6
+ self.status = status
7
+
8
+ # The rest of the registers
9
+ self._registers = registers
10
+
11
+ def __getattr__(self, name: str):
12
+ if name in self._registers:
13
+ return self._registers[name]
14
+
15
+ raise AttributeError(f"No register named '{name}' in this core dump.")
16
+
17
+ def __setattr__(self, name: str, value):
18
+ if name.startswith("_") or name in ("arch", "pc", "sp", "status"):
19
+ super().__setattr__(name, value)
20
+ else:
21
+ if hasattr(self, "_registers") and (name in self._registers):
22
+ self._registers[name] = value
23
+ else:
24
+ super().__setattr__(name, value)
25
+
26
+ def apply_to_cpu(self, cpu):
27
+ """
28
+ Set the CPU registers from this RegisterState object.
29
+ """
30
+ cpu.pc.set(self.pc)
31
+ cpu.sp.set(self.sp)
32
+
33
+ for reg_name, reg_val in self._registers.items():
34
+ reg_name_lower = reg_name.lower()
35
+ if hasattr(cpu, reg_name_lower):
36
+ getattr(cpu, reg_name_lower).set(reg_val)
@@ -8,6 +8,7 @@ from .arm import (
8
8
  Armv7RElfRelocator,
9
9
  )
10
10
  from .i386 import I386ElfRelocator
11
+ from .loongarch import LoongArch64ElfRelocator
11
12
  from .mips import MIPSELElfRelocator, MIPSElfRelocator
12
13
  from .ppc import PowerPCElfRelocator
13
14
  from .rela import ElfRelocator
@@ -23,6 +24,7 @@ __all__ = [
23
24
  "Armv7MElfRelocator",
24
25
  "Armv7RElfRelocator",
25
26
  "I386ElfRelocator",
27
+ "LoongArch64ElfRelocator",
26
28
  "MIPSElfRelocator",
27
29
  "MIPSELElfRelocator",
28
30
  "PowerPCElfRelocator",
@@ -3,6 +3,7 @@ from .....exceptions import ConfigurationError
3
3
  from ..structs import ElfRela
4
4
  from .rela import ElfRelocator
5
5
 
6
+ R_AARCH64_ABS64 = 257 # Direct 64-bit
6
7
  R_AARCH64_GLOB_DAT = 1025 # Create GOT entry
7
8
  R_AARCH64_JUMP_SLOT = 1026 # Create PLT entry
8
9
  R_AARCH64_RELATIVE = 1027 # Adjust by program base
@@ -17,11 +18,12 @@ class AArch64ElfRelocator(ElfRelocator):
17
18
  rela.type == R_AARCH64_GLOB_DAT
18
19
  or rela.type == R_AARCH64_JUMP_SLOT
19
20
  or rela.type == R_AARCH64_RELATIVE
21
+ or rela.type == R_AARCH64_ABS64
20
22
  ):
21
23
  # Different semantics, all behave the same
22
24
  val = rela.symbol.value + rela.symbol.baseaddr + rela.addend
23
25
  return val.to_bytes(8, "little")
24
26
  else:
25
27
  raise ConfigurationError(
26
- "Unknown relocation type for {rela.symbol.name}: {rela.type}"
28
+ f"Unknown relocation type for {rela.symbol.name}: {rela.type}"
27
29
  )
@@ -3,6 +3,7 @@ from .....exceptions import ConfigurationError
3
3
  from ..structs import ElfRela
4
4
  from .rela import ElfRelocator
5
5
 
6
+ R_X86_64_64 = 1 # Direct 64-bit
6
7
  R_X86_64_GLOB_DAT = 6 # Create GOT entry
7
8
  R_X86_64_JUMP_SLOT = 7 # Create PLT entry
8
9
  R_X86_64_RELATIVE = 8 # Adjust by program base
@@ -18,15 +19,16 @@ class AMD64ElfRelocator(ElfRelocator):
18
19
  rela.type == R_X86_64_GLOB_DAT
19
20
  or rela.type == R_X86_64_JUMP_SLOT
20
21
  or rela.type == R_X86_64_RELATIVE
22
+ or rela.type == R_X86_64_64
21
23
  ):
22
24
  # Different semantics, all behave the same
23
25
  val = rela.symbol.value + rela.symbol.baseaddr + rela.addend
24
26
  return val.to_bytes(8, "little")
25
27
  elif rela.type >= 0 and rela.type < R_X86_64_NUM:
26
28
  raise ConfigurationError(
27
- "Valid, but unsupported relocation for {rela.symbol.name}: {rela.type}"
29
+ f"Valid, but unsupported relocation for {rela.symbol.name}: {rela.type}"
28
30
  )
29
31
  else:
30
32
  raise ConfigurationError(
31
- "Invalid relocation type for {rela.symbol.name}: {rela.type}"
33
+ f"Invalid relocation type for {rela.symbol.name}: {rela.type}"
32
34
  )
@@ -3,6 +3,7 @@ from .....exceptions import ConfigurationError
3
3
  from ..structs import ElfRela
4
4
  from .rela import ElfRelocator
5
5
 
6
+ R_ARM_ABS32 = 2 # Direct 32-bit
6
7
  R_ARM_GLOB_DAT = 21 # Create GOT entry
7
8
  R_ARM_JUMP_SLOT = 22 # Create PLT entry
8
9
  R_ARM_RELATIVE = 23 # Adjust by program base
@@ -17,17 +18,18 @@ class ArmElfRelocator(ElfRelocator):
17
18
  rela.type == R_ARM_GLOB_DAT
18
19
  or rela.type == R_ARM_JUMP_SLOT
19
20
  or rela.type == R_ARM_RELATIVE
21
+ or rela.type == R_ARM_ABS32
20
22
  ):
21
23
  # Different semantics, all behave the same
22
24
  val = rela.symbol.value + rela.symbol.baseaddr + rela.addend
23
25
  return val.to_bytes(4, "little")
24
26
  elif rela.type >= 0 and rela.type < R_ARM_NUM:
25
27
  raise ConfigurationError(
26
- "Valid, but unsupported relocation for {rela.symbol.name}: {rela.type}"
28
+ f"Valid, but unsupported relocation for {rela.symbol.name}: {rela.type}"
27
29
  )
28
30
  else:
29
31
  raise ConfigurationError(
30
- "Invalid relocation type for {rela.symbol.name}: {rela.type}"
32
+ f"Invalid relocation type for {rela.symbol.name}: {rela.type}"
31
33
  )
32
34
 
33
35
 
@@ -3,6 +3,7 @@ from .....exceptions import ConfigurationError
3
3
  from ..structs import ElfRela
4
4
  from .rela import ElfRelocator
5
5
 
6
+ R_386_32 = 1 # Direct 32-bit
6
7
  R_386_GLOB_DAT = 6 # Create GOT entry
7
8
  R_386_JUMP_SLOT = 7 # Create PLT entry
8
9
  R_386_RELATIVE = 8 # Adjust by program base
@@ -18,15 +19,16 @@ class I386ElfRelocator(ElfRelocator):
18
19
  rela.type == R_386_GLOB_DAT
19
20
  or rela.type == R_386_JUMP_SLOT
20
21
  or rela.type == R_386_RELATIVE
22
+ or rela.type == R_386_32
21
23
  ):
22
24
  # Different semantics, all behave the same
23
25
  val = rela.symbol.value + rela.symbol.baseaddr + rela.addend
24
26
  return val.to_bytes(4, "little")
25
27
  elif rela.type >= 0 and rela.type < R_386_NUM:
26
28
  raise ConfigurationError(
27
- "Valid, but unsupported relocation for {rela.symbol.name}: {rela.type}"
29
+ f"Valid, but unsupported relocation for {rela.symbol.name}: {rela.type}"
28
30
  )
29
31
  else:
30
32
  raise ConfigurationError(
31
- "Invalid relocation type for {rela.symbol.name}: {rela.type}"
33
+ f"Invalid relocation type for {rela.symbol.name}: {rela.type}"
32
34
  )
@@ -0,0 +1,32 @@
1
+ from ..... import platforms
2
+ from .....exceptions import ConfigurationError
3
+ from ..structs import ElfRela
4
+ from .rela import ElfRelocator
5
+
6
+ R_LARCH_64 = 2 # Direct 64-bit
7
+ R_LARCH_RELATIVE = 4 # Adjust by program base
8
+ R_LARCH_JUMP_SLOT = 5 # Create PLT entry
9
+ R_LARCH_NUM = 127 # This and higher aren't valid
10
+
11
+
12
+ class LoongArch64ElfRelocator(ElfRelocator):
13
+ arch = platforms.Architecture.LOONGARCH64
14
+ byteorder = platforms.Byteorder.LITTLE
15
+
16
+ def _compute_value(self, rela: ElfRela):
17
+ if (
18
+ rela.type == R_LARCH_JUMP_SLOT
19
+ or rela.type == R_LARCH_RELATIVE
20
+ or rela.type == R_LARCH_64
21
+ ):
22
+ # Different semantics, all behave the same
23
+ val = rela.symbol.value + rela.symbol.baseaddr + rela.addend
24
+ return val.to_bytes(8, "little")
25
+ elif rela.type >= 0 and rela.type < R_LARCH_NUM:
26
+ raise ConfigurationError(
27
+ f"Valid, but unsupported relocation for {rela.symbol.name}: {rela.type}"
28
+ )
29
+ else:
30
+ raise ConfigurationError(
31
+ f"Invalid relocation type for {rela.symbol.name}: {rela.type}"
32
+ )
@@ -3,7 +3,9 @@ from .....exceptions import ConfigurationError
3
3
  from ..structs import ElfRela
4
4
  from .rela import ElfRelocator
5
5
 
6
+ R_MIPS_NONE = 0
6
7
  R_MIPS_32 = 2 # 32-bit direct
8
+ R_MIPS_REL32 = 3
7
9
  R_MIPS_64 = 18 # 64-bit direct
8
10
 
9
11
 
@@ -12,24 +14,43 @@ class MIPSElfRelocator(ElfRelocator):
12
14
  byteorder = platforms.Byteorder.BIG
13
15
 
14
16
  def _compute_value(self, rela: ElfRela):
15
- # Because mypy doesn't believe I know what I'm doing...
16
-
17
- if rela.type == R_MIPS_32:
18
- # 32-bit direct
19
- val = rela.symbol.value + rela.symbol.baseaddr + rela.addend
20
- return val.to_bytes(
21
- 4, "big" if self.byteorder == platforms.Byteorder.BIG else "little"
22
- )
23
- elif rela.type == R_MIPS_64:
24
- # 64-bit direct
25
- val = rela.symbol.value + rela.symbol.baseaddr + rela.addend
26
- return val.to_bytes(
27
- 8, "big" if self.byteorder == platforms.Byteorder.BIG else "little"
28
- )
29
- else:
30
- raise ConfigurationError(
31
- "Invalid relocation type for {rela.symbol.name}: {rela.type}"
32
- )
17
+ # Unpack a MIPS64 relocation.
18
+ #
19
+ # It's not possible to build a 64-bit address in one instruction in MIPS64.
20
+ # Rather than tell the linker to live with it,
21
+ # MIPS64 relocation entries can define up to three nested relocations,
22
+ # with relocations 2 and 3 acting as if the symbol value were the result
23
+ # of the previous relocation.
24
+ #
25
+ # There's a fourth argument, which is a parameter to relocation 2, I think.
26
+ # Don't want to waste those bytes...
27
+ rela_types = []
28
+ # rela_special = (rela.type >> 24) & 0xFF
29
+ for i in range(0, 3):
30
+ rela_types.append((rela.type >> (i * 8)) & 0xFF)
31
+
32
+ val = rela.symbol.value + rela.symbol.baseaddr
33
+ is_64 = False
34
+ for i in range(0, 3):
35
+ rela_type = rela_types[i]
36
+ if rela_type == R_MIPS_NONE:
37
+ break
38
+ elif rela_type == R_MIPS_32 or rela_type == R_MIPS_REL32:
39
+ # 32-bit direct
40
+ val = val + rela.addend
41
+ elif rela_type == R_MIPS_64:
42
+ # 64-bit direct
43
+ val = val + rela.addend
44
+ is_64 = True
45
+ else:
46
+ raise ConfigurationError(
47
+ f"Invalid relocation type {i} for {rela.symbol.name}: {rela_type}"
48
+ )
49
+
50
+ return val.to_bytes(
51
+ 8 if is_64 else 4,
52
+ "big" if self.byteorder == platforms.Byteorder.BIG else "little",
53
+ )
33
54
 
34
55
 
35
56
  class MIPSELElfRelocator(MIPSElfRelocator):
@@ -3,6 +3,7 @@ from .....exceptions import ConfigurationError
3
3
  from ..structs import ElfRela
4
4
  from .rela import ElfRelocator
5
5
 
6
+ R_PPC_ABS32 = 1 # Direct 32-bit
6
7
  R_PPC_GLOB_DAT = 20 # Create GOT entry
7
8
  R_PPC_JUMP_SLOT = 21 # Create PLT entry
8
9
  R_PPC_RELATIVE = 22 # Adjust by program base
@@ -14,7 +15,10 @@ class PowerPCElfRelocator(ElfRelocator):
14
15
  addrsz = 4
15
16
 
16
17
  def _compute_value(self, rela: ElfRela):
17
- if (
18
+ if rela.type == R_PPC_ABS32:
19
+ val = rela.symbol.value + rela.symbol.baseaddr + rela.addend
20
+ return val.to_bytes(4, "big")
21
+ elif (
18
22
  rela.type == R_PPC_GLOB_DAT
19
23
  or rela.type == R_PPC_JUMP_SLOT
20
24
  or rela.type == R_PPC_RELATIVE
@@ -24,22 +28,35 @@ class PowerPCElfRelocator(ElfRelocator):
24
28
  return val.to_bytes(self.addrsz, "big")
25
29
  else:
26
30
  raise ConfigurationError(
27
- "Invalid relocation type for {rela.symbol.name}: {rela.type}"
31
+ f"Invalid relocation type for {rela.symbol.name}: {rela.type}"
28
32
  )
29
33
 
30
34
 
35
+ R_PPC64_ADDR64 = 38 # Adjust by program base, I think...
36
+
37
+
31
38
  class PowerPC64ElfRelocator(PowerPCElfRelocator):
32
39
  arch = platforms.Architecture.POWERPC64
40
+ byteorder = platforms.Byteorder.BIG
33
41
  addrsz = 8
34
- # TODO: This is only the beginning
35
- #
36
- # The PowerPC64 JUMP_SLOT relocation is much more complicated,
37
- # possibly the most complicated I've ever seen.
38
- # It actually fills in three 64-bit values:
39
- #
40
- # 1. The actual function address
41
- # 2. The TOC base address; serves a similar purpose to the Global Pointer in MIPS.
42
- # 3. An "environment" pointer, not used by C.
43
- #
44
- # We're currently correctly filling in 1.
45
- # Entry 2. is the address of the GOT section of the containing binary + 0x8000.
42
+
43
+ def _compute_value(self, rela: ElfRela):
44
+ if rela.type == R_PPC64_ADDR64:
45
+ val = rela.symbol.value + rela.symbol.baseaddr + rela.addend
46
+ return val.to_bytes(self.addrsz, "big")
47
+ elif rela.type == R_PPC_JUMP_SLOT:
48
+ # The PowerPC64 JUMP_SLOT relocation is much more complicated.
49
+ # It actually fills in three 64-bit values:
50
+ #
51
+ # 1. The actual function address
52
+ # 2. The TOC base address; serves a similar purpose to the Global Pointer in MIPS.
53
+ # 3. An "environment" pointer, not used by C.
54
+ #
55
+ # We're currently correctly filling in 1.
56
+ # Entry 2. is the address of the GOT section of the containing binary + 0x8000.
57
+ #
58
+ # This requires a reference to the containing binary,
59
+ # which I have no idea how to pass.
60
+ raise NotImplementedError("R_PPC64_JUMP_SLOT not implemented")
61
+ else:
62
+ return super()._compute_value(rela)
@@ -24,11 +24,14 @@ class ElfSymbol:
24
24
  without a separate dict.
25
25
  """
26
26
 
27
+ idx: int # Symbol table index
28
+ dynamic: bool # Is this in the static or dynamic symbol table?
27
29
  name: str # Symbol name
28
30
  type: int # Symbol type
29
31
  bind: int # Symbol binding
30
32
  visibility: int # Symbol visibility
31
33
  shndx: int # Symbol section index, or reserved flags
34
+ defined: bool # Is this symbol defined?
32
35
  value: int # Symbol value
33
36
  size: int # Symbol size
34
37
  baseaddr: int # Base address for relative symbol values
@@ -42,7 +42,7 @@ class Heap(memory.Memory):
42
42
  return self.allocate(value)
43
43
 
44
44
  def allocate_bytes(
45
- self, content: typing.Union[bytes, bytearray], label: str
45
+ self, content: typing.Union[bytes, bytearray], label: typing.Optional[str]
46
46
  ) -> int:
47
47
  """Allocate space for and write bytes to the heap.
48
48
 
@@ -79,7 +79,7 @@ class BumpAllocator(Heap):
79
79
  return self.address + offset
80
80
 
81
81
  def free(self, address: int) -> None:
82
- raise NotImplementedError("freeing with a BumpAllocator is not yet implemented")
82
+ pass
83
83
 
84
84
 
85
85
  __all__ = ["Heap", "BumpAllocator"]
@@ -114,6 +114,24 @@ class Memory(state.Stateful, dict):
114
114
  self.clear()
115
115
  self[0] = value
116
116
 
117
+ def write_bytes(self, address: int, data: bytes) -> None:
118
+ """Overwrite part of this memory region with specific bytes
119
+
120
+ This will fail if the data you want to overwrite is in a symbolic sub-region.
121
+ """
122
+
123
+ for segment_offset, segment in self.items():
124
+ segment_address = self.address + segment_offset
125
+ if address >= segment_address and address < segment_address + segment._size:
126
+ contents = segment.get_content()
127
+ if not isinstance(contents, bytes):
128
+ raise exceptions.SymbolicValueError(
129
+ f"Tried to write {len(data)} bytes at {hex(address)}; data in {segment_address:x} - {segment_address + segment._size:x} is symbolic."
130
+ )
131
+ offset = address - segment_address
132
+ contents = contents[0:offset] + data + contents[offset + len(data) :]
133
+ segment.set_content(contents)
134
+
117
135
  def __hash__(self):
118
136
  return super(dict, self).__hash__()
119
137
 
@@ -0,0 +1,3 @@
1
+ from .pe import PEExecutable
2
+
3
+ __all__ = ["PEExecutable"]