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,595 @@
1
+ import logging
2
+ import random
3
+ import typing
4
+
5
+ import claripy
6
+
7
+ from .... import emulators, exceptions
8
+ from ...memory.heap import Heap
9
+ from ..cstd import ArgumentType, CStdModel
10
+ from .utils import _emu_strlen
11
+
12
+ logger = logging.getLogger("__name__")
13
+
14
+
15
+ class Abort(CStdModel):
16
+ name = "abort"
17
+
18
+ # void abort(void);
19
+ argument_types = []
20
+ return_type = ArgumentType.VOID
21
+
22
+ def model(self, emulator: emulators.Emulator) -> None:
23
+ super().model(emulator)
24
+ raise exceptions.EmulationStop("Called abort()")
25
+
26
+
27
+ class Abs(CStdModel):
28
+ name = "abs"
29
+
30
+ # int abs(int val);
31
+ argument_types = [ArgumentType.INT]
32
+ return_type = ArgumentType.INT
33
+
34
+ @property
35
+ def sign_mask(self):
36
+ return self._int_sign_mask
37
+
38
+ @property
39
+ def inv_mask(self):
40
+ return self._int_inv_mask
41
+
42
+ def model(self, emulator: emulators.Emulator) -> None:
43
+ super().model(emulator)
44
+ val = self.get_arg1(emulator)
45
+
46
+ assert isinstance(val, int)
47
+
48
+ if val & self.sign_mask:
49
+ val = ((val ^ self.inv_mask) + 1) & self.inv_mask
50
+
51
+ self.set_return_value(emulator, val)
52
+
53
+
54
+ class LAbs(Abs):
55
+ name = "labs"
56
+
57
+ # long labs(long x);
58
+ argument_types = [ArgumentType.LONG]
59
+ return_type = ArgumentType.LONG
60
+
61
+ @property
62
+ def sign_mask(self):
63
+ return self._long_sign_mask
64
+
65
+ @property
66
+ def inv_mask(self):
67
+ return self._long_inv_mask
68
+
69
+
70
+ class LLAbs(Abs):
71
+ name = "llabs"
72
+
73
+ # long long llabs(long long x);
74
+ argument_types = [ArgumentType.LONGLONG]
75
+ return_type = ArgumentType.LONGLONG
76
+
77
+ @property
78
+ def sign_mask(self):
79
+ return self._long_long_sign_mask
80
+
81
+ @property
82
+ def inv_mask(self):
83
+ return self._long_long_inv_mask
84
+
85
+
86
+ class Atexit(CStdModel):
87
+ name = "atexit"
88
+
89
+ # NOTE: In glibc binaries, relocate atexit against __cxa_atexit
90
+ # atexit is a statically-linked helper that calls __cxa_atexit
91
+
92
+ # void atexit(void);
93
+ argument_types = [ArgumentType.POINTER]
94
+ return_type = ArgumentType.INT
95
+
96
+ # This will not actually result in an exit handler getting registered.
97
+ imprecise = True
98
+
99
+ def model(self, emulator: emulators.Emulator) -> None:
100
+ super().model(emulator)
101
+ self.set_return_value(emulator, 0)
102
+
103
+
104
+ class Atof(CStdModel):
105
+ name = "atof"
106
+
107
+ # float atof(const char *str);
108
+ argument_types = [ArgumentType.POINTER]
109
+ return_type = ArgumentType.FLOAT
110
+
111
+ def model(self, emulator: emulators.Emulator) -> None:
112
+ super().model(emulator)
113
+ # TODO: Support other locales for atof
114
+ ptr = self.get_arg1(emulator)
115
+
116
+ assert isinstance(ptr, int)
117
+
118
+ n = _emu_strlen(emulator, ptr)
119
+
120
+ data = emulator.read_memory(ptr, n)
121
+ text = data.decode("utf-8")
122
+
123
+ # This is a bit tricky. Python is much less accepting than C.
124
+ text = text.strip()
125
+ found_dot = False
126
+ for i in range(0, len(text)):
127
+ if text[i].isnumeric():
128
+ continue
129
+ elif text[i] == ".":
130
+ if found_dot:
131
+ text = text[0:i]
132
+ break
133
+ else:
134
+ found_dot = True
135
+ else:
136
+ text = text[0:i]
137
+ break
138
+ if len(text) == 0:
139
+ text = "0"
140
+
141
+ self.set_return_value(emulator, float(text))
142
+
143
+
144
+ class Atoi(CStdModel):
145
+ name = "atoi"
146
+
147
+ # int atoi(const char *str);
148
+ argument_types = [ArgumentType.POINTER]
149
+ return_type = ArgumentType.INT
150
+
151
+ size_mask = 0xFFFFFFFF
152
+
153
+ def model(self, emulator: emulators.Emulator) -> None:
154
+ super().model(emulator)
155
+ # TODO: Support other locales for atoi
156
+ ptr = self.get_arg1(emulator)
157
+
158
+ assert isinstance(ptr, int)
159
+
160
+ n = _emu_strlen(emulator, ptr)
161
+
162
+ data = emulator.read_memory(ptr, n)
163
+ text = data.decode("utf-8").strip()
164
+ print(f"Converting {text} ({len(text)})")
165
+
166
+ for i in range(0, len(text)):
167
+ if not text[i].isnumeric() and text[i] != "-":
168
+ text = text[0:i]
169
+ break
170
+
171
+ if len(text) == 0:
172
+ # No valid number
173
+ self.set_return_value(emulator, 0)
174
+ return
175
+
176
+ # TODO: Not entirely sure if this is how truncation will work.
177
+ newval = int(text) & self.size_mask
178
+ self.set_return_value(emulator, newval)
179
+
180
+
181
+ class Atol(Atoi):
182
+ name = "atol"
183
+
184
+ # long atoll(const char *str);
185
+ argument_types = [ArgumentType.POINTER]
186
+ return_type = ArgumentType.LONG
187
+
188
+ size_mask = 0xFFFFFFFFFFFFFFFF
189
+
190
+
191
+ class Atoll(Atoi):
192
+ name = "atoll"
193
+
194
+ # long long atoll(const char *str);
195
+ argument_types = [ArgumentType.POINTER]
196
+ return_type = ArgumentType.LONGLONG
197
+
198
+ size_mask = 0xFFFFFFFFFFFFFFFF
199
+
200
+
201
+ class Bsearch(CStdModel):
202
+ name = "bsearch"
203
+
204
+ # void *bsearch(const void *key, const void *base,
205
+ # size_t nitems, size_t size,
206
+ # int (*compar)(const void *, const void *));
207
+ argument_types = [
208
+ ArgumentType.POINTER,
209
+ ArgumentType.POINTER,
210
+ ArgumentType.SIZE_T,
211
+ ArgumentType.SIZE_T,
212
+ ArgumentType.POINTER,
213
+ ]
214
+ return_type = ArgumentType.POINTER
215
+
216
+ def model(self, emulator: emulators.Emulator) -> None:
217
+ super().model(emulator)
218
+ # Not easily possible; need to call a comparator function.
219
+ raise NotImplementedError(
220
+ "bsearch uses a function pointer; not sure how to model"
221
+ )
222
+
223
+
224
+ class Calloc(CStdModel):
225
+ name = "calloc"
226
+
227
+ # void *calloc(size_t amount, size_t size);
228
+ argument_types = [ArgumentType.SIZE_T, ArgumentType.SIZE_T]
229
+ return_type = ArgumentType.POINTER
230
+
231
+ def __init__(self, address: int):
232
+ super().__init__(address)
233
+ # Use the same heap model the harness used.
234
+ # NOTE: This will get cloned on a deep copy.
235
+ self.heap: typing.Optional[Heap] = None
236
+
237
+ def model(self, emulator: emulators.Emulator) -> None:
238
+ super().model(emulator)
239
+ if self.heap is None:
240
+ raise exceptions.ConfigurationError(
241
+ "calloc needs a heap; please assign self.heap"
242
+ )
243
+
244
+ amt = self.get_arg1(emulator)
245
+ size = self.get_arg2(emulator)
246
+
247
+ assert isinstance(amt, int)
248
+ assert isinstance(size, int)
249
+
250
+ data = b"\0" * amt * size
251
+
252
+ res = self.heap.allocate_bytes(data, None)
253
+ # This is calloc; zero out the memory
254
+ emulator.write_memory(res, data)
255
+
256
+ self.set_return_value(emulator, res)
257
+
258
+
259
+ class Div(CStdModel):
260
+ name = "div"
261
+
262
+ # div_t result(int dividend, int divisor);
263
+ argument_types = [ArgumentType.INT, ArgumentType.INT]
264
+ # FIXME: Figure out how different platforms return structs by value
265
+
266
+ def model(self, emulator: emulators.Emulator) -> None:
267
+ super().model(emulator)
268
+ # div_t result(int dividend, int divisor);
269
+ raise NotImplementedError()
270
+
271
+
272
+ class LDiv(Div):
273
+ name = "ldiv"
274
+
275
+ # ldiv_t result(long dividend, long divisor);
276
+ argument_types = [ArgumentType.LONG, ArgumentType.LONG]
277
+ # FIXME: Figure out how different platforms return structs by value
278
+
279
+
280
+ class LLDiv(Div):
281
+ name = "lldiv"
282
+
283
+ # lldiv_t result(long long dividend, long long divisor);
284
+ argument_types = [ArgumentType.LONGLONG, ArgumentType.LONGLONG]
285
+ # FIXME: Figure out how different platforms return structs by value
286
+
287
+
288
+ class Exit(CStdModel):
289
+ name = "exit"
290
+
291
+ # void exit(int code);
292
+ argument_types = [ArgumentType.INT]
293
+ return_type = ArgumentType.VOID
294
+
295
+ def model(self, emulator: emulators.Emulator) -> None:
296
+ super().model(emulator)
297
+ raise exceptions.EmulationStop("Called exit()")
298
+
299
+
300
+ class Free(CStdModel):
301
+ name = "free"
302
+
303
+ # void free(void *ptr);
304
+ argument_types = [ArgumentType.POINTER]
305
+ return_type = ArgumentType.VOID
306
+
307
+ def __init__(self, address: int):
308
+ super().__init__(address)
309
+ # Use the same heap model the harness used.
310
+ # NOTE: This will get cloned on a deep copy.
311
+ self.heap: typing.Optional[Heap] = None
312
+
313
+ def model(self, emulator: emulators.Emulator) -> None:
314
+ super().model(emulator)
315
+ if self.heap is None:
316
+ raise exceptions.ConfigurationError(
317
+ "malloc needs a heap; please assign self.heap"
318
+ )
319
+
320
+ ptr = self.get_arg1(emulator)
321
+
322
+ assert isinstance(ptr, int)
323
+
324
+ self.heap.free(ptr)
325
+
326
+
327
+ class Getenv(CStdModel):
328
+ name = "getenv"
329
+
330
+ # char *getenv(char *name);
331
+ argument_types = [ArgumentType.POINTER]
332
+ return_type = ArgumentType.POINTER
333
+
334
+ # We don't have a model of envp,
335
+ # so this will always return NULL
336
+ imprecise = True
337
+
338
+ def model(self, emulator: emulators.Emulator) -> None:
339
+ super().model(emulator)
340
+ ptr = self.get_arg1(emulator)
341
+
342
+ assert isinstance(ptr, int)
343
+
344
+ size = _emu_strlen(emulator, ptr)
345
+ data = emulator.read_memory(ptr, size)
346
+ name = data.decode("utf-8")
347
+
348
+ logger.info(f"getenv({name});")
349
+ self.set_return_value(emulator, 0)
350
+
351
+
352
+ class Malloc(CStdModel):
353
+ name = "malloc"
354
+
355
+ # void *malloc(size_t size);
356
+ argument_types = [ArgumentType.SIZE_T]
357
+ return_type = ArgumentType.POINTER
358
+
359
+ def __init__(self, address: int):
360
+ super().__init__(address)
361
+ # Use the same heap model the harness used.
362
+ # NOTE: This will get cloned on a deep copy.
363
+ self.heap: typing.Optional[Heap] = None
364
+
365
+ def model(self, emulator: emulators.Emulator) -> None:
366
+ super().model(emulator)
367
+ if self.heap is None:
368
+ raise exceptions.ConfigurationError(
369
+ "malloc needs a heap; please assign self.heap"
370
+ )
371
+
372
+ size = self.get_arg1(emulator)
373
+
374
+ assert isinstance(size, int)
375
+
376
+ res = self.heap.allocate_bytes(b"\0" * size, None)
377
+
378
+ self.set_return_value(emulator, res)
379
+
380
+
381
+ class Mblen(CStdModel):
382
+ name = "mblen"
383
+
384
+ # int mblen(char *str, size_t n);
385
+ argument_types = [ArgumentType.POINTER, ArgumentType.SIZE_T]
386
+ return_type = ArgumentType.INT
387
+
388
+ def model(self, emulator: emulators.Emulator) -> None:
389
+ super().model(emulator)
390
+ # Depends the locale.
391
+ raise NotImplementedError()
392
+
393
+
394
+ class Mbstowcs(CStdModel):
395
+ name = "mbstowcs"
396
+
397
+ # size_t mbstowcs(schar_t *pwcs, char *str, size_t n);
398
+ argument_types = [ArgumentType.POINTER, ArgumentType.POINTER, ArgumentType.SIZE_T]
399
+ return_type = ArgumentType.SIZE_T
400
+
401
+ def model(self, emulator: emulators.Emulator) -> None:
402
+ super().model(emulator)
403
+ # Depends the locale.
404
+ raise NotImplementedError()
405
+
406
+
407
+ class Mbtowc(CStdModel):
408
+ name = "mbtowc"
409
+
410
+ # size_t mbtowc(wchar_t *pwcs, char *str, size_t n);
411
+ argument_types = [ArgumentType.POINTER, ArgumentType.POINTER, ArgumentType.SIZE_T]
412
+ return_type = ArgumentType.INT
413
+
414
+ def model(self, emulator: emulators.Emulator) -> None:
415
+ super().model(emulator)
416
+ # Depends the locale.
417
+ raise NotImplementedError()
418
+
419
+
420
+ class QSort(CStdModel):
421
+ name = "qsort"
422
+
423
+ # void qsort(void *arr, size_t amount, size_t size, int (*compare)(const void *, const void *));
424
+ argument_types = [
425
+ ArgumentType.POINTER,
426
+ ArgumentType.SIZE_T,
427
+ ArgumentType.SIZE_T,
428
+ ArgumentType.POINTER,
429
+ ]
430
+ return_type = ArgumentType.VOID
431
+
432
+ def model(self, emulator: emulators.Emulator) -> None:
433
+ super().model(emulator)
434
+ # Not easily possible; need to call a comparator function.
435
+ raise NotImplementedError(
436
+ "qsort uses a function pointer; not sure how to model"
437
+ )
438
+
439
+
440
+ class Rand(CStdModel):
441
+ name = "rand"
442
+
443
+ # int rand(void);
444
+ argument_types = []
445
+ return_type = ArgumentType.INT
446
+
447
+ rand = random.Random()
448
+
449
+ def model(self, emulator: emulators.Emulator) -> None:
450
+ super().model(emulator)
451
+ # TODO: Rand is easy to do simply, harder to do right.
452
+ # If someone is relying on srand/rand to produce a specific sequence,
453
+ # this won't behave correctly.
454
+ val = self.rand.randint(0, 2147483647)
455
+ self.set_return_value(emulator, val)
456
+
457
+
458
+ class Realloc(CStdModel):
459
+ name = "realloc"
460
+
461
+ # void *realloc(void *ptr, size_t size);
462
+ argument_types = [ArgumentType.POINTER, ArgumentType.SIZE_T]
463
+ return_type = ArgumentType.POINTER
464
+
465
+ def __init__(self, address: int):
466
+ super().__init__(address)
467
+ # Use the same heap model the harness used.
468
+ # NOTE: This will get cloned on a deep copy.
469
+ self.heap: typing.Optional[Heap] = None
470
+
471
+ def model(self, emulator: emulators.Emulator) -> None:
472
+ super().model(emulator)
473
+ if self.heap is None:
474
+ raise exceptions.ConfigurationError(
475
+ "realloc needs a heap; please assign self.heap"
476
+ )
477
+
478
+ ptr = self.get_arg1(emulator)
479
+ size = self.get_arg2(emulator)
480
+
481
+ assert isinstance(ptr, int)
482
+ assert isinstance(size, int)
483
+
484
+ logger.warning(f"REALLOC {hex(ptr)}, {size}")
485
+
486
+ if ptr == 0:
487
+ res = self.heap.allocate_bytes(b"\0" * size, None)
488
+ elif ptr - self.heap.address not in self.heap:
489
+ raise exceptions.EmulationError(
490
+ f"Attempted to realloc {hex(ptr)}, which was not malloc'd on this heap"
491
+ )
492
+ else:
493
+ oldsize = self.heap[ptr - self.heap.address].get_size()
494
+ data: typing.Union[bytes, claripy.ast.bv.BV]
495
+ try:
496
+ data = emulator.read_memory(ptr, oldsize)
497
+ except exceptions.SymbolicValueError:
498
+ data = emulator.read_memory_symbolic(ptr, oldsize)
499
+
500
+ self.heap.free(ptr)
501
+
502
+ res = self.heap.allocate_bytes(b"\0" * size, None)
503
+ emulator.write_memory(res, data)
504
+
505
+ self.set_return_value(emulator, res)
506
+
507
+
508
+ class Srand(CStdModel):
509
+ name = "srand"
510
+
511
+ # void srand(int seed);
512
+ argument_types = [ArgumentType.INT]
513
+ return_type = ArgumentType.VOID
514
+
515
+ def model(self, emulator: emulators.Emulator) -> None:
516
+ super().model(emulator)
517
+ seed = self.get_arg1(emulator)
518
+ Rand.rand.seed(a=seed)
519
+
520
+
521
+ class System(CStdModel):
522
+ name = "system"
523
+
524
+ argument_types = [ArgumentType.POINTER]
525
+ return_type = ArgumentType.INT
526
+
527
+ def model(self, emulator: emulators.Emulator) -> None:
528
+ super().model(emulator)
529
+ ptr = self.get_arg1(emulator)
530
+
531
+ assert isinstance(ptr, int)
532
+
533
+ size = _emu_strlen(emulator, ptr)
534
+ data = emulator.read_memory(ptr, size)
535
+ cmd = data.decode("utf-8")
536
+
537
+ logger.info(f"system({cmd});")
538
+ self.set_return_value(emulator, 0)
539
+
540
+
541
+ class Wcstombs(CStdModel):
542
+ name = "wctombs"
543
+
544
+ # size_t wctombs(char *str, wchar_t *pwcs, size_t n);
545
+ argument_types = [ArgumentType.POINTER, ArgumentType.POINTER, ArgumentType.SIZE_T]
546
+ return_type = ArgumentType.SIZE_T
547
+
548
+ def model(self, emulator: emulators.Emulator) -> None:
549
+ super().model(emulator)
550
+ # Depends the locale.
551
+ raise NotImplementedError()
552
+
553
+
554
+ class Wctomb(CStdModel):
555
+ name = "wctomb"
556
+
557
+ # int wctomb(char *str, wchar_t wchar);
558
+ argument_types = [ArgumentType.POINTER, ArgumentType.UINT]
559
+ return_type = ArgumentType.INT
560
+
561
+ def model(self, emulator: emulators.Emulator) -> None:
562
+ super().model(emulator)
563
+ # Depends the locale.
564
+ raise NotImplementedError()
565
+
566
+
567
+ __all__ = [
568
+ "Abs",
569
+ "LAbs",
570
+ "LLAbs",
571
+ "Abort",
572
+ "Atexit",
573
+ "Atof",
574
+ "Atoi",
575
+ "Atol",
576
+ "Atoll",
577
+ "Calloc",
578
+ "Div",
579
+ "LDiv",
580
+ "LLDiv",
581
+ "Exit",
582
+ "Free",
583
+ "Getenv",
584
+ "Malloc",
585
+ "Mblen",
586
+ "Mbstowcs",
587
+ "Mbtowc",
588
+ "QSort",
589
+ "Rand",
590
+ "Realloc",
591
+ "Srand",
592
+ "System",
593
+ "Wcstombs",
594
+ "Wctomb",
595
+ ]