smallworld-re 1.0.2__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 +44 -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 +225 -61
  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.2.dist-info → smallworld_re-2.0.0.dist-info}/METADATA +76 -43
  297. smallworld_re-2.0.0.dist-info/RECORD +374 -0
  298. {smallworld_re-1.0.2.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.2.dist-info/RECORD +0 -166
  303. /smallworld/state/models/{posix.py → _posix.py} +0 -0
  304. {smallworld_re-1.0.2.dist-info → smallworld_re-2.0.0.dist-info}/entry_points.txt +0 -0
  305. {smallworld_re-1.0.2.dist-info → smallworld_re-2.0.0.dist-info/licenses}/LICENSE.txt +0 -0
  306. {smallworld_re-1.0.2.dist-info → smallworld_re-2.0.0.dist-info}/top_level.txt +0 -0
@@ -5,11 +5,9 @@ import lief
5
5
 
6
6
  from ..emulators import Emulator
7
7
  from ..exceptions import ConfigurationError
8
- from ..hinting import Hint, get_hinter
9
8
  from .state import Code, Memory
10
9
 
11
10
  log = logging.getLogger(__name__)
12
- hinter = get_hinter(__name__)
13
11
 
14
12
  # Prorgam header types
15
13
  PT_NULL = 0 # Empty/unused program header
@@ -89,10 +87,9 @@ class ELFImage(Code):
89
87
  # Progam file does not need a specific base address
90
88
  # Use a default
91
89
  # FIXME: Using a fixed value will not be valid if we load multiple files
92
- hint = Hint(
93
- message=f"No base address requested, and ELF is PIC. Using {hex(self.default_base)}"
90
+ log.info(
91
+ f"No base address requested, and ELF is PIC. Using {hex(self.default_base)}"
94
92
  )
95
- hinter.info(hint)
96
93
  self.base = self.default_base
97
94
  else:
98
95
  # Program file needs a specific base address
@@ -111,10 +108,9 @@ class ELFImage(Code):
111
108
  else:
112
109
  # Program file needs a specific base address
113
110
  # Not possible to rebase
114
- hint = Hint(
115
- message=f"Requested base address {hex(self.user_base)}, but program needs {hex(self.file_base)}"
111
+ log.error(
112
+ f"Requested base address {hex(self.user_base)}, but program needs {hex(self.file_base)}"
116
113
  )
117
- hinter.error(hint)
118
114
  raise ConfigurationError("Contradictory base addresses.")
119
115
 
120
116
  def determine_entry(self):
@@ -219,8 +215,7 @@ class ELFImage(Code):
219
215
  # Use lief to check if this is an ELF
220
216
  # NOTE: for some reason, this takes list[int], not bytes
221
217
  if not lief.is_elf(list(self.image)):
222
- hint = Hint(message="File is not an elf.")
223
- hinter.error(hint)
218
+ log.error("File is not an elf.")
224
219
  raise ConfigurationError("Input is not an elf")
225
220
 
226
221
  # Use lief to parse the ELF
@@ -245,14 +240,12 @@ class ELFImage(Code):
245
240
  if ehdr.program_header_offset == 0:
246
241
  # NULL phoff means no program headers.
247
242
  # This file is not loadable; time to use another ELF loader.
248
- hint = Hint(message="No program headers; file is not loadable")
249
- hinter.error(hint)
243
+ log.error("No program headers; file is not loadable")
250
244
  raise ConfigurationError("File not loadable")
251
245
  if ehdr.program_header_offset >= len(self.image):
252
- hint = Hint(
253
- message=f"Invalid program header offset: {hex(ehdr.program_header_offset)}"
246
+ log.error(
247
+ f"Invalid program header offset: {hex(ehdr.program_header_offset)}"
254
248
  )
255
- hinter.error(hint)
256
249
  raise ConfigurationError("Invalid program header offset")
257
250
 
258
251
  # Determine the file base address,
@@ -272,8 +265,7 @@ class ELFImage(Code):
272
265
  elif phdr.type == PT_DYNAMIC:
273
266
  # Dynamic linking metadata.
274
267
  # This ELF needs dynamic linking
275
- hint = Hint(message="Program includes dynamic linking metadata")
276
- hinter.info(hint)
268
+ log.info("Program includes dynamic linking metadata")
277
269
  elif phdr.type == PT_INTERP:
278
270
  # Program interpreter
279
271
  # This completely changes how program loading works.
@@ -281,8 +273,7 @@ class ELFImage(Code):
281
273
  interp = self.image[
282
274
  phdr.file_offset : phdr.file_offset + phdr.physical_size
283
275
  ]
284
- hint = Hint(message=f"Program specifies interpreter {interp!r}")
285
- hinter.info(hint)
276
+ log.info(f"Program specifies interpreter {interp!r}")
286
277
  elif phdr.type == PT_NOTE:
287
278
  # Auxiliary information
288
279
  # Possibly useful for comparing machine/OS type.
@@ -294,8 +285,7 @@ class ELFImage(Code):
294
285
  elif phdr.type == PT_TLS:
295
286
  # TLS Segment
296
287
  # Your analysis is about to get nasty :(
297
- hint = Hint(message="Program includes thread-local storage")
298
- hinter.info(hint)
288
+ log.info("Program includes thread-local storage")
299
289
  elif phdr.type == PT_GNU_EH_FRAME:
300
290
  # Exception handler frame.
301
291
  # GCC puts one of these in everything. Do we care?
@@ -303,13 +293,11 @@ class ELFImage(Code):
303
293
  elif phdr.type == PT_GNU_STACK:
304
294
  # Stack executability
305
295
  # If this is missing, assume executable stack
306
- hint = Hint(message="Program specifies stack permissions")
307
- hinter.info(hint)
296
+ log.info("Program specifies stack permissions")
308
297
  elif phdr.type == PT_GNU_RELRO:
309
298
  # Read-only after relocation
310
299
  # Only the dynamic linker should write this data.
311
- hint = Hint(message="Program specifies RELRO data")
312
- hinter.info(hint)
300
+ log.info("Program specifies RELRO data")
313
301
  elif phdr.type == PT_GNU_PROPERTY:
314
302
  # GNU property segment
315
303
  # Contains extra metadata which I'm not sure anything uses
@@ -318,19 +306,16 @@ class ELFImage(Code):
318
306
  # Unknown OS-specific program header
319
307
  # Either this is a weird ISA that extends the generic GNU ABI,
320
308
  # or this isn't a Linux ELF.
321
- hint = Hint(f"Unknown OS-specific program header: {phdr.type:08x}")
322
- hinter.warn(hint)
309
+ log.warn(f"Unknown OS-specific program header: {phdr.type:08x}")
323
310
  elif phdr.type >= PT_LOPROC and phdr.type <= PT_HIPROC:
324
311
  # Unknown machine-specific program header
325
312
  # This is probably a non-Intel ISA.
326
313
  # Most of these are harmless, serving to tell the RTLD
327
314
  # where to find machine-specific metadata
328
- hint = Hint(f"Unknown machine-specific program header: {phdr.type:08x}")
329
- hinter.warn(hint)
315
+ log.warn(f"Unknown machine-specific program header: {phdr.type:08x}")
330
316
  else:
331
317
  # Unknown program header outside the allowed custom ranges
332
- hint = Hint(f"Invalid program header: {phdr.type:08x}")
333
- hinter.warn(hint)
318
+ log.warn(f"Invalid program header: {phdr.type:08x}")
334
319
 
335
320
  def map_segment(self, phdr):
336
321
  """Map a segment into a SmallWorld machine state object
smallworld/utils.py CHANGED
@@ -541,12 +541,17 @@ class RBTree(Iterable):
541
541
  return iter(self.values())
542
542
 
543
543
 
544
+ def _range_collection_key(x):
545
+ # Used to be a lambda, but can't pickle lambdas
546
+ return x[0]
547
+
548
+
544
549
  class RangeCollection(Iterable):
545
550
  """A collection of non-overlapping ranges"""
546
551
 
547
552
  def __init__(self):
548
553
  # Back with an RBTree keyed off the start of the range
549
- self._ranges = RBTree(key=lambda x: x[0])
554
+ self._ranges = RBTree(key=_range_collection_key)
550
555
 
551
556
  def is_empty(self) -> bool:
552
557
  """Check if this collection is empty
@@ -1,20 +1,43 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: smallworld-re
3
- Version: 1.0.2
3
+ Version: 2.0.0
4
4
  Summary: An emulation stack tracking library
5
- Home-page: https://github.com/smallworld-re/smallworld
6
5
  Author: MIT Lincoln Laboratory
7
6
  Author-email: smallworld@ll.mit.edu
8
- License: MIT
7
+ License: MIT License
8
+
9
+ © 2023 Massachusetts Institute of Technology
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
12
+ this software and associated documentation files (the "Software"), to deal in
13
+ the Software without restriction, including without limitation the rights to
14
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
15
+ of the Software, and to permit persons to whom the Software is furnished to do
16
+ so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
28
+
29
+ Project-URL: Homepage, https://github.com/smallworld-re/smallworld
30
+ Project-URL: Issues, https://github.com/smallworld-re/smallworld/issues
9
31
  Requires-Python: >=3.10
10
32
  Description-Content-Type: text/markdown
11
33
  License-File: LICENSE.txt
34
+ Requires-Dist: angr
35
+ Requires-Dist: capstone
36
+ Requires-Dist: jsons
37
+ Requires-Dist: lief
12
38
  Requires-Dist: pyhidra==1.3.0
13
- Requires-Dist: angr==9.2.137
14
- Requires-Dist: capstone==5.0.3
15
- Requires-Dist: lief==0.14.1
16
- Requires-Dist: pypcode==3.0
17
- Requires-Dist: unicorn==2.0.1.post1
39
+ Requires-Dist: pypcode
40
+ Requires-Dist: unicorn
18
41
  Provides-Extra: development
19
42
  Requires-Dist: black; extra == "development"
20
43
  Requires-Dist: isort; extra == "development"
@@ -24,16 +47,10 @@ Requires-Dist: pip-tools; extra == "development"
24
47
  Requires-Dist: pre-commit; extra == "development"
25
48
  Requires-Dist: sphinx; extra == "development"
26
49
  Requires-Dist: sphinxcontrib-programoutput; extra == "development"
27
- Dynamic: author
28
- Dynamic: author-email
29
- Dynamic: description
30
- Dynamic: description-content-type
31
- Dynamic: home-page
32
- Dynamic: license
33
- Dynamic: provides-extra
34
- Dynamic: requires-dist
35
- Dynamic: requires-python
36
- Dynamic: summary
50
+ Requires-Dist: jupyterlab; extra == "development"
51
+ Requires-Dist: notebook; extra == "development"
52
+ Requires-Dist: timeout-decorator; extra == "development"
53
+ Dynamic: license-file
37
54
 
38
55
  # SmallWorld
39
56
 
@@ -56,19 +73,19 @@ There are two fundamental tenets behind SmallWorld
56
73
 
57
74
  The first of these tenets we hope to support with good software APIs. As a very
58
75
  simple example, consider the harnessing script
59
- [stack.py](https://github.com/smallworld-re/smallworld/blob/main/tests/square.py),
76
+ [square.amd64.py](https://github.com/smallworld-re/smallworld/blob/main/tests/square/square.amd64.py),
60
77
  composed using SmallWorld, in which registers are initialized and a stack is
61
78
  arranged for running the code in
62
- [stack.s](https://github.com/smallworld-re/smallworld/blob/main/tests/stack.s).
79
+ [square.amd64.s](https://github.com/smallworld-re/smallworld/blob/main/tests/square/square.amd64.s).
63
80
  For a more sophisticated example of SmallWorld's harnessing facitilites,
64
81
  consider the code snippet
65
- [struct.s](https://github.com/smallworld-re/smallworld/blob/main/tests/struct.s),
82
+ [struct.amd64.s](https://github.com/smallworld-re/smallworld/blob/main/tests/struct/struct.amd64.s),
66
83
  which assumes a stack and input pointers to a linked list with very specific
67
84
  format. The harnessing script in this case is more complicated, including
68
85
  specifying type information for the linked list element structures as well as
69
86
  use of a simple allocator abstraction provided by SmallWorld to instantiate
70
87
  nodes and link them together appropriately:
71
- [struct.py](https://github.com/smallworld-re/smallworld/blob/main/tests/struct.py).
88
+ [struct.amd64.py](https://github.com/smallworld-re/smallworld/blob/main/tests/struct/struct.amd64.py).
72
89
 
73
90
  The second tenet we address with purpose-built analyses which leverage a
74
91
  (possibly incomplete) harness script and that use techniques such as [Micro
@@ -84,33 +101,40 @@ SmallWorld directly supports yet.
84
101
 
85
102
  ## Installation
86
103
 
87
- To install SmallWorld from this repo, run:
88
-
104
+ SmallWorld can be installed [directly from PyPi](https://pypi.org/project/smallworld-re/), just:
89
105
  ```bash
90
- pip install .
106
+ pip install smallworld-re
91
107
  ```
92
108
 
93
- ## Usage
94
-
95
- Print basic usage and help:
109
+ If you'd like to install the latest changes or do development, you can install directly. To install SmallWorld from this repo, [optionally set up a venv](https://docs.python.org/3/library/venv.html) and then run:
96
110
 
97
111
  ```bash
98
- smallworld --help
112
+ pip install .
99
113
  ```
100
114
 
115
+ The result will be a library that can be used for harnessing and analyzing. See the examples for a walkthrough.
116
+
101
117
  ## Contributing
102
118
 
103
119
  Pull requests and issues more than welcome.
104
120
 
105
121
  ### Development
106
122
 
107
- To set up a development environment from this repo, install SmallWorld in
123
+ #### The Easy Way
124
+ To set up a development environment from this repo, the easiest method is to use
125
+ the install script `install.sh`. This has been tested on Ubuntu 22.04 and may be run
126
+ as the root user, or a non-root user with sudo permissions.
127
+ This will both install SmallWorld and build the unit and integration tests.
128
+ Note that installation will not work fully on an ARM and is not supported.
129
+
130
+ #### The Hard Way
131
+ To manually set up a development environment from this repo, install SmallWorld in
108
132
  editable mode with extras for development and testing. Use the include
109
133
  constraints to install frozen versions and ensure a consistent development
110
134
  environment.
111
135
 
112
136
  ```bash
113
- pip install -e .[development] -c constraints.txt
137
+ pip install -e ".[development]" -c constraints.txt
114
138
  ```
115
139
 
116
140
  #### Code Style
@@ -123,17 +147,6 @@ installing development dependencies), run:
123
147
  pre-commit install
124
148
  ```
125
149
 
126
- ### Documentation
127
-
128
- To build the full SmallWorld documentation, after installing SmallWorld with
129
- `development` extras enabled, from the `docs/` directory, run:
130
-
131
- ```bash
132
- make html
133
- ```
134
-
135
- Or other [supported Sphinx output formats](https://www.sphinx-doc.org/en/master/usage/builders/index.html).
136
-
137
150
  ### Testing
138
151
 
139
152
  #### Prerequisites
@@ -149,6 +162,9 @@ You can then build the tests by running:
149
162
 
150
163
  ```bash
151
164
  make -C tests
165
+
166
+ ulimit -c unlimited
167
+ make -C tests/elf_core
152
168
  ```
153
169
 
154
170
  #### Running Tests
@@ -161,6 +177,23 @@ python3 tests/unit.py
161
177
  python3 tests/integration.py
162
178
  ```
163
179
 
180
+ ### Documentation
181
+
182
+ To build the full SmallWorld documentation
183
+ * verify [Sphinx](https://www.sphinx-doc.org/) has been installed
184
+ * install SmallWorld with `development` extras enabled
185
+ * make sure you have built the tests since the documentation generation requires output from those tests
186
+ * from the `docs/` directory, run:
187
+
188
+ ```bash
189
+ make html
190
+ ```
191
+
192
+ The resulting documentation will be in `docs/build/html/`
193
+
194
+ Other [supported Sphinx output formats](https://www.sphinx-doc.org/en/master/usage/builders/index.html) can also be generated.
195
+
196
+
164
197
  ## Distribution
165
198
 
166
199
  DISTRIBUTION STATEMENT A. Approved for public release. Distribution is