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
@@ -0,0 +1,340 @@
1
+ import os
2
+ import time
3
+ import typing
4
+
5
+ from ....emulators import Emulator
6
+ from ..cstd import ArgumentType, CStdModel
7
+ from .utils import _emu_strlen
8
+
9
+ # NOTE: time_t and clock_t are longs.
10
+ # As such, all your 32-bit routers are vulnerable to the 2038 bug.
11
+
12
+
13
+ class TimeModel(CStdModel):
14
+ def time_struct_to_tuple(self, ptr: int, emulator: Emulator):
15
+ # Load the fields out of the struct
16
+ tm_sec = self.read_integer(ptr, ArgumentType.INT, emulator)
17
+ tm_min = self.read_integer(ptr + 0x4, ArgumentType.INT, emulator)
18
+ tm_hour = self.read_integer(ptr + 0x8, ArgumentType.INT, emulator)
19
+ tm_mday = self.read_integer(ptr + 0xC, ArgumentType.INT, emulator)
20
+ tm_mon = self.read_integer(ptr + 0x10, ArgumentType.INT, emulator)
21
+ tm_year = self.read_integer(ptr + 0x14, ArgumentType.INT, emulator)
22
+ tm_wday = self.read_integer(ptr + 0x18, ArgumentType.INT, emulator)
23
+ tm_yday = self.read_integer(ptr + 0x1C, ArgumentType.INT, emulator)
24
+ tm_isdst = self.read_integer(ptr + 0x20, ArgumentType.INT, emulator)
25
+
26
+ # Load data into a python struct
27
+ # A few of the fields are represented a bit differently
28
+ out = (
29
+ tm_year + 1900,
30
+ tm_mon + 1,
31
+ tm_mday,
32
+ tm_hour,
33
+ tm_min,
34
+ tm_sec,
35
+ tm_wday - 1,
36
+ tm_yday + 1,
37
+ tm_isdst,
38
+ )
39
+
40
+ return out
41
+
42
+ def tuple_to_time_struct(
43
+ self,
44
+ tp: typing.Tuple[int, int, int, int, int, int, int, int, int],
45
+ ptr: int,
46
+ emulator: Emulator,
47
+ ):
48
+ (
49
+ tm_year,
50
+ tm_mon,
51
+ tm_mday,
52
+ tm_hour,
53
+ tm_min,
54
+ tm_sec,
55
+ tm_wday,
56
+ tm_yday,
57
+ tm_isdst,
58
+ ) = tp
59
+
60
+ # Convert the Python representation to C's representation
61
+ tm_year -= 1900
62
+ tm_mon -= 1
63
+ tm_wday += 1
64
+ tm_yday -= 1
65
+
66
+ # Store the fields back to the struct
67
+ self.write_integer(ptr, tm_sec, ArgumentType.INT, emulator)
68
+ self.write_integer(ptr + 0x4, tm_min, ArgumentType.INT, emulator)
69
+ self.write_integer(ptr + 0x8, tm_hour, ArgumentType.INT, emulator)
70
+ self.write_integer(ptr + 0xC, tm_mday, ArgumentType.INT, emulator)
71
+ self.write_integer(ptr + 0x10, tm_mon, ArgumentType.INT, emulator)
72
+ self.write_integer(ptr + 0x14, tm_year, ArgumentType.INT, emulator)
73
+ self.write_integer(ptr + 0x18, tm_wday, ArgumentType.INT, emulator)
74
+ self.write_integer(ptr + 0x1C, tm_yday, ArgumentType.INT, emulator)
75
+ self.write_integer(ptr + 0x20, tm_isdst, ArgumentType.INT, emulator)
76
+
77
+
78
+ class Time(TimeModel):
79
+ name = "time"
80
+
81
+ # time_t time(time_t *tloc);
82
+ argument_types = [ArgumentType.POINTER]
83
+ return_type = ArgumentType.LONG
84
+
85
+ def model(self, emulator: Emulator) -> None:
86
+ super().model(emulator)
87
+
88
+ ptr = self.get_arg1(emulator)
89
+
90
+ assert isinstance(ptr, int)
91
+
92
+ intval = int(time.time())
93
+
94
+ if ptr != 0:
95
+ self.write_integer(ptr, intval, ArgumentType.LONG, emulator)
96
+
97
+ self.set_return_value(emulator, intval)
98
+
99
+
100
+ class Localtime(TimeModel):
101
+ name = "localtime"
102
+
103
+ # struct tm *localtime(const time_t *timep);
104
+ argument_types = [ArgumentType.POINTER]
105
+ return_type = ArgumentType.POINTER
106
+
107
+ # Need a static struct tm
108
+ # NOTE: This looks bigger, because GNU struct tms have extra fields.
109
+ static_space_required = 64
110
+
111
+ def model(self, emulator: Emulator) -> None:
112
+ super().model(emulator)
113
+
114
+ ptr = self.get_arg1(emulator)
115
+
116
+ assert isinstance(ptr, int)
117
+
118
+ tv = self.read_integer(ptr, ArgumentType.LONG, emulator)
119
+
120
+ timetuple = time.localtime(tv)
121
+
122
+ assert self.static_buffer_address is not None
123
+
124
+ self.tuple_to_time_struct(timetuple, self.static_buffer_address, emulator)
125
+ self.set_return_value(emulator, self.static_buffer_address)
126
+
127
+
128
+ class Gmtime(TimeModel):
129
+ name = "gmtime"
130
+
131
+ # struct tm *gmtime(const time_t *timep);
132
+ argument_types = [ArgumentType.POINTER]
133
+ return_type = ArgumentType.POINTER
134
+
135
+ # Need a static struct tm
136
+ # NOTE: This looks bigger, because GNU struct tms have extra fields.
137
+ static_space_required = 64
138
+
139
+ def model(self, emulator: Emulator) -> None:
140
+ super().model(emulator)
141
+
142
+ ptr = self.get_arg1(emulator)
143
+
144
+ assert isinstance(ptr, int)
145
+
146
+ tv = self.read_integer(ptr, ArgumentType.LONG, emulator)
147
+
148
+ timetuple = time.gmtime(tv)
149
+
150
+ assert self.static_buffer_address is not None
151
+
152
+ self.tuple_to_time_struct(timetuple, self.static_buffer_address, emulator)
153
+ self.set_return_value(emulator, self.static_buffer_address)
154
+
155
+
156
+ class Ctime(TimeModel):
157
+ name = "ctime"
158
+
159
+ # struct tm *ctime(const time_t *timep);
160
+ argument_types = [ArgumentType.POINTER]
161
+ return_type = ArgumentType.POINTER
162
+
163
+ static_space_required = 26
164
+
165
+ def model(self, emulator: Emulator) -> None:
166
+ super().model(emulator)
167
+
168
+ ptr = self.get_arg1(emulator)
169
+
170
+ assert isinstance(ptr, int)
171
+
172
+ tv = self.read_integer(ptr, ArgumentType.LONG, emulator)
173
+
174
+ timestr = time.ctime(tv)
175
+ timebytes = timestr.encode("utf-8") + b"\n\0"
176
+
177
+ assert len(timebytes) <= 26
178
+ assert self.static_buffer_address is not None
179
+
180
+ emulator.write_memory(self.static_buffer_address, timebytes)
181
+ self.set_return_value(emulator, self.static_buffer_address)
182
+
183
+
184
+ class Asctime(TimeModel):
185
+ name = "asctime"
186
+
187
+ # char *asctime(const struct tm *tp);
188
+ argument_types = [ArgumentType.POINTER]
189
+ return_type = ArgumentType.POINTER
190
+
191
+ # Need a 26-byte static buffer to store the output string
192
+ static_space_required = 26
193
+
194
+ def model(self, emulator: Emulator) -> None:
195
+ super().model(emulator)
196
+
197
+ ptr = self.get_arg1(emulator)
198
+
199
+ assert isinstance(ptr, int)
200
+
201
+ timetuple = self.time_struct_to_tuple(ptr, emulator)
202
+
203
+ # FIXME: mktime is timezone dependent
204
+ # This is actually something of a pain to handle. For now, assume UTC.
205
+ old_tz = None
206
+ if "TZ" in os.environ:
207
+ old_tz = os.environ["TZ"]
208
+ os.environ["TZ"] = "UTC"
209
+ time.tzset()
210
+
211
+ print(timetuple)
212
+ timestr = time.asctime(timetuple)
213
+ print(timestr)
214
+
215
+ if old_tz is None:
216
+ del os.environ["TZ"]
217
+ else:
218
+ os.environ["TZ"] = old_tz
219
+ time.tzset()
220
+
221
+ timebytes = timestr.encode("utf-8") + b"\n\0"
222
+
223
+ assert len(timebytes) <= 26
224
+ assert self.static_buffer_address is not None
225
+
226
+ emulator.write_memory(self.static_buffer_address, timebytes)
227
+
228
+ self.set_return_value(emulator, self.static_buffer_address)
229
+
230
+
231
+ class Strftime(TimeModel):
232
+ name = "strftime"
233
+
234
+ # size_t strftime(char *dst, size_t max, const char *fmt, const struct tm *tp);
235
+ argument_types = [
236
+ ArgumentType.POINTER,
237
+ ArgumentType.SIZE_T,
238
+ ArgumentType.POINTER,
239
+ ArgumentType.POINTER,
240
+ ]
241
+ return_type = ArgumentType.SIZE_T
242
+
243
+ def model(self, emulator: Emulator) -> None:
244
+ super().model(emulator)
245
+
246
+ dst = self.get_arg1(emulator)
247
+ max = self.get_arg2(emulator)
248
+ fmt = self.get_arg3(emulator)
249
+ ptr = self.get_arg4(emulator)
250
+
251
+ assert isinstance(dst, int)
252
+ assert isinstance(max, int)
253
+ assert isinstance(fmt, int)
254
+ assert isinstance(ptr, int)
255
+
256
+ fmtlen = _emu_strlen(emulator, fmt)
257
+ fmtbytes = emulator.read_memory(fmt, fmtlen)
258
+ fmtstr = fmtbytes.decode("utf-8")
259
+
260
+ timetuple = self.time_struct_to_tuple(ptr, emulator)
261
+ timestr = time.strftime(fmtstr, timetuple)
262
+ timebytes = timestr.encode("utf-8")
263
+ timebytes += b"\0"
264
+
265
+ if len(timebytes) > max:
266
+ self.set_return_value(emulator, 0)
267
+ else:
268
+ emulator.write_memory(dst, timebytes)
269
+ self.set_return_value(emulator, len(timebytes))
270
+
271
+
272
+ class Difftime(TimeModel):
273
+ name = "difftime"
274
+
275
+ # double difftime(time_t time0, time_t time1);
276
+ argument_types = [ArgumentType.LONG, ArgumentType.LONG]
277
+ return_type = ArgumentType.DOUBLE
278
+
279
+ def model(self, emulator: Emulator) -> None:
280
+ super().model(emulator)
281
+
282
+ time0 = self.get_arg1(emulator)
283
+ time1 = self.get_arg2(emulator)
284
+
285
+ assert isinstance(time0, int)
286
+ assert isinstance(time1, int)
287
+
288
+ # Times are longs. Why does this return a double?
289
+ # The world is full of mysteries...
290
+ diff = float(time1 - time0)
291
+
292
+ self.set_return_value(emulator, diff)
293
+
294
+
295
+ class Mktime(TimeModel):
296
+ name = "mktime"
297
+
298
+ # time_t mktime(struct tm *tp);
299
+ argument_types = [ArgumentType.POINTER]
300
+ return_type = ArgumentType.LONG
301
+
302
+ def model(self, emulator: Emulator) -> None:
303
+ super().model(emulator)
304
+
305
+ ptr = self.get_arg1(emulator)
306
+
307
+ assert isinstance(ptr, int)
308
+
309
+ timetuple = self.time_struct_to_tuple(ptr, emulator)
310
+ timefloat = time.mktime(timetuple)
311
+
312
+ self.set_return_value(emulator, int(timefloat))
313
+
314
+
315
+ class Clock(TimeModel):
316
+ name = "clock"
317
+
318
+ # clock_t clock(void)
319
+ argument_types = []
320
+ return_type = ArgumentType.LONG
321
+
322
+ def model(self, emulator: Emulator) -> None:
323
+ super().model(emulator)
324
+ floatval = time.clock_gettime(time.CLOCK_PROCESS_CPUTIME_ID)
325
+ floatval /= time.clock_getres(time.CLOCK_PROCESS_CPUTIME_ID)
326
+
327
+ self.set_return_value(emulator, int(floatval))
328
+
329
+
330
+ __all__ = [
331
+ "Time",
332
+ "Localtime",
333
+ "Gmtime",
334
+ "Ctime",
335
+ "Asctime",
336
+ "Strftime",
337
+ "Difftime",
338
+ "Mktime",
339
+ "Clock",
340
+ ]
@@ -0,0 +1,89 @@
1
+ import logging
2
+
3
+ from .... import emulators
4
+
5
+ logger = logging.getLogger(__name__)
6
+
7
+ # Maximum string length.
8
+ # Used to terminate unbounded string operations
9
+ MAX_STRLEN = 0x10000
10
+
11
+ # Common memory manipulation operations used by a lot of library functions.
12
+
13
+
14
+ def _emu_strnlen(emulator: emulators.Emulator, addr: int, n: int) -> int:
15
+ sl = 0
16
+ while sl <= n:
17
+ b_opt = emulator.read_memory(addr + sl, 1)
18
+ if b_opt is not None:
19
+ b = b_opt[0]
20
+ if b == 0:
21
+ break
22
+ sl += 1
23
+ else:
24
+ assert b_opt is not None
25
+ return sl
26
+
27
+
28
+ def _emu_strlen(emulator: emulators.Emulator, addr: int) -> int:
29
+ return _emu_strnlen(emulator, addr, MAX_STRLEN)
30
+
31
+
32
+ def _emu_memcpy(emulator: emulators.Emulator, dst: int, src: int, n: int) -> None:
33
+ src_bytes = emulator.read_memory(src, n)
34
+ emulator.write_memory(dst, src_bytes)
35
+
36
+
37
+ def _emu_strncpy(emulator: emulators.Emulator, dst: int, src: int, n: int) -> None:
38
+ # strncpy is slightly different from strcpy and memcpy;
39
+ # it zero-fills any unused space in the buffer.
40
+ actual = n
41
+ src_len = _emu_strlen(emulator, src) + 1
42
+ if src_len < n:
43
+ actual = src_len
44
+
45
+ data = emulator.read_memory(src, actual)
46
+ data += b"\0" * (n - actual)
47
+
48
+ print(f"Writing {n} bytes to {hex(dst)}")
49
+ emulator.write_memory(dst, data)
50
+
51
+
52
+ def _emu_memcmp(emulator: emulators.Emulator, ptr1: int, ptr2: int, n: int) -> int:
53
+ for i in range(0, n):
54
+ char1 = emulator.read_memory(ptr1 + i, 1)[0]
55
+ char2 = emulator.read_memory(ptr2 + i, 1)[0]
56
+ if char1 != char2:
57
+ return char1 - char2
58
+ return 0
59
+
60
+
61
+ def _emu_strncmp(emulator: emulators.Emulator, ptr1: int, ptr2: int, n: int) -> int:
62
+ for i in range(0, n):
63
+ char1 = emulator.read_memory(ptr1 + i, 1)[0]
64
+ char2 = emulator.read_memory(ptr2 + i, 1)[0]
65
+ if char1 == 0 or char2 == 0:
66
+ return char1 - char2
67
+ elif char1 != char2:
68
+ return char1 - char2
69
+ return 0
70
+
71
+
72
+ def _emu_strncat(emulator: emulators.Emulator, dst: int, src: int, n: int) -> None:
73
+ if n == 0:
74
+ return
75
+ if emulator.read_memory(src, 1) is None:
76
+ logger.debug("MEM not available in strncpy read @ {src:x}")
77
+ elif emulator.read_memory(dst, 1) is None:
78
+ logger.debug("MEM not available in strncpy write @ {dst:x}")
79
+ else:
80
+ # at least a byte is available at both src and dst
81
+ ld = _emu_strnlen(emulator, dst, MAX_STRLEN)
82
+ ls = _emu_strnlen(emulator, src, MAX_STRLEN)
83
+ lsn = min(ls, n)
84
+ b_opt = emulator.read_memory(src, lsn)
85
+ if b_opt is not None:
86
+ src_bytes = b_opt + b"\0"
87
+ emulator.write_memory(dst + ld, src_bytes)
88
+ else:
89
+ assert b_opt is not None