Compare commits

..

427 Commits

Author SHA1 Message Date
Ole André Vadla Ravnås ee92ba7dea Wire up some more 2026-01-18 11:17:14 +01:00
Ole André Vadla Ravnås 9f0ce44424 Wire up some more 2026-01-18 11:17:14 +01:00
Ole André Vadla Ravnås bbea00ce9f Wire up some more 2026-01-18 11:17:14 +01:00
Ole André Vadla Ravnås 8527e5f830 [WIP] Auto-generate from .gir 2026-01-18 11:17:12 +01:00
Ole André Vadla Ravnås 985410b6ff subprojects: Prepare for release 2026-01-17 08:43:35 +01:00
Ole André Vadla Ravnås 21c7b9ee6a subprojects: Bump outdated 2026-01-17 00:24:37 +01:00
Ole André Vadla Ravnås 7fba1cdc67 subprojects: Bump outdated 2026-01-16 15:32:05 +01:00
Ole André Vadla Ravnås a709856e2a subprojects: Bump outdated 2026-01-16 13:44:50 +01:00
Ole André Vadla Ravnås c3afe6089d submodules: Bump releng 2026-01-16 13:44:49 +01:00
Ole André Vadla Ravnås 6435a78d13 subprojects: Bump outdated 2026-01-15 18:08:16 +01:00
Ole André Vadla Ravnås 09175036ea submodules: Bump releng 2026-01-15 18:08:16 +01:00
Ole André Vadla Ravnås e0c90c5203 subprojects: Bump outdated 2026-01-11 00:48:16 +01:00
Abhi 9f463fb602 Fix regressions reported by mypi and black (#269) 2026-01-07 09:14:51 +01:00
Ole André Vadla Ravnås 9fdee2270f subprojects: Bump outdated 2026-01-06 22:40:32 +01:00
Ole André Vadla Ravnås 6e536a56b1 submodules: Bump releng 2026-01-06 22:40:32 +01:00
Ole André Vadla Ravnås 74925d082e subprojects: Prepare for release 2025-12-15 21:28:40 +01:00
Etienne Maheux bf1245ddb0 typing: Remove generic @overload on handlers
Generic @overload definitions on signal handlers were masking
type-checking errors.
2025-12-15 21:23:57 +01:00
Etienne Maheux 0f247e9439 typing: Improve @cancellable; add flag literals
Refine @cancellable typing to better model control flow and
introduce Literal types for optional Compiler flags to
improve static checking and autocomplete.
2025-12-15 21:23:57 +01:00
Ole André Vadla Ravnås 17aae5fe5c subprojects: Bump outdated 2025-12-15 21:17:51 +01:00
Ole André Vadla Ravnås 477a90534e submodules: Bump releng 2025-12-15 21:17:51 +01:00
Ole André Vadla Ravnås c87cdca293 subprojects: Prepare for release 2025-11-05 18:59:11 +01:00
Ole André Vadla Ravnås 30968b3805 subprojects: Bump outdated 2025-11-05 18:57:30 +01:00
Ole André Vadla Ravnås 5e3f27d0cb subprojects: Prepare for release 2025-11-04 10:30:58 +01:00
Ole André Vadla Ravnås 904461eb01 subprojects: Bump outdated 2025-11-04 10:29:40 +01:00
Ole André Vadla Ravnås dc652faa90 package-manager: Plug leak in specs option parsing 2025-11-04 10:23:37 +01:00
Ole André Vadla Ravnås f5ba22ad36 compiler: Expose platform and externals options 2025-11-04 10:23:00 +01:00
Ole André Vadla Ravnås dccb6810ca subprojects: Prepare for release 2025-11-01 00:38:17 +01:00
Ole André Vadla Ravnås 82441c6d61 subprojects: Bump outdated 2025-11-01 00:36:38 +01:00
Ole André Vadla Ravnås 323dca48c2 subprojects: Prepare for release 2025-10-31 20:24:11 +01:00
Ole André Vadla Ravnås ef71f0fa92 subprojects: Bump outdated 2025-10-31 20:21:50 +01:00
Ole André Vadla Ravnås e92e829f6d subprojects: Prepare for release 2025-10-29 16:48:00 +01:00
Ole André Vadla Ravnås 5793fb5528 subprojects: Bump outdated 2025-10-29 16:45:57 +01:00
Ole André Vadla Ravnås cac6993d87 subprojects: Prepare for release 2025-10-24 15:25:21 +02:00
Ole André Vadla Ravnås 714b7f8626 subprojects: Bump outdated 2025-10-24 15:23:52 +02:00
Ole André Vadla Ravnås ab0b9e98ae submodules: Bump releng 2025-10-24 15:23:52 +02:00
Ole André Vadla Ravnås 19a7fa4f45 subprojects: Prepare for release 2025-10-11 19:22:55 +02:00
Ole André Vadla Ravnås 38552a368a subprojects: Bump outdated 2025-10-11 11:47:08 +02:00
Ole André Vadla Ravnås 38724cab58 subprojects: Bump outdated 2025-10-11 11:09:13 +02:00
Ole André Vadla Ravnås b60d085ad9 subprojects: Bump outdated 2025-10-01 10:53:01 +02:00
Ole André Vadla Ravnås 1a4afbcc62 subprojects: Bump outdated 2025-10-01 10:50:11 +02:00
Ole André Vadla Ravnås 9e15cab647 subprojects: Prepare for release 2025-09-19 17:16:25 +02:00
Ole André Vadla Ravnås 9ef1c9c1f7 subprojects: Bump outdated 2025-09-19 17:14:35 +02:00
Ole André Vadla Ravnås 3da6af4759 subprojects: Prepare for release 2025-09-18 07:39:44 +02:00
Ole André Vadla Ravnås a9075822b1 subprojects: Bump outdated 2025-09-17 22:10:34 +02:00
Ole André Vadla Ravnås 2e61509c04 submodules: Bump releng 2025-09-17 22:10:34 +02:00
Ole André Vadla Ravnås aa9396c6b0 subprojects: Prepare for release 2025-09-15 22:57:06 +02:00
Ole André Vadla Ravnås 6530b2a7d4 subprojects: Bump outdated 2025-09-15 22:12:16 +02:00
Ole André Vadla Ravnås 2d833af062 subprojects: Bump outdated 2025-09-11 10:32:08 +02:00
Ole André Vadla Ravnås 9f6ab2d384 subprojects: Prepare for release 2025-08-20 12:07:22 +02:00
Ole André Vadla Ravnås a005f1bf4c subprojects: Bump outdated 2025-08-20 12:06:15 +02:00
Ole André Vadla Ravnås 59a24aa48f subprojects: Prepare for release 2025-08-12 10:15:48 +02:00
Ole André Vadla Ravnås 782d626419 subprojects: Bump outdated 2025-08-12 09:48:45 +02:00
Ole André Vadla Ravnås 3aa122f4fd subprojects: Prepare for release 2025-08-02 09:42:51 +02:00
Ole André Vadla Ravnås ef315fc0ad subprojects: Bump outdated 2025-08-02 08:53:40 +02:00
Ole André Vadla Ravnås daf93eea54 subprojects: Bump outdated 2025-08-01 20:21:16 +02:00
Ole André Vadla Ravnås 5d02a36906 submodules: Bump releng 2025-08-01 20:21:16 +02:00
Ole André Vadla Ravnås ba8daa423d subprojects: Bump outdated 2025-08-01 18:18:22 +02:00
Ole André Vadla Ravnås afb27bfa7c subprojects: Bump outdated 2025-08-01 15:48:53 +02:00
Ole André Vadla Ravnås 93a201acf2 submodules: Bump releng 2025-08-01 15:48:53 +02:00
Ole André Vadla Ravnås ca1cdad96a subprojects: Prepare for release 2025-07-24 11:16:46 +02:00
Ole André Vadla Ravnås fbc83cc9bf subprojects: Bump outdated 2025-07-24 11:15:23 +02:00
Ole André Vadla Ravnås b838e1df9a subprojects: Prepare for release 2025-07-21 15:06:22 +02:00
Ole André Vadla Ravnås e2409be987 subprojects: Bump outdated 2025-07-21 15:04:50 +02:00
Ole André Vadla Ravnås b061ea43d2 subprojects: Prepare for release 2025-07-18 10:32:24 +02:00
Ole André Vadla Ravnås a50a62999a subprojects: Bump outdated 2025-07-18 10:28:42 +02:00
Ole André Vadla Ravnås 3a47d33ee8 submodules: Bump releng 2025-07-18 10:28:42 +02:00
Ole André Vadla Ravnås ea93d827bb subprojects: Prepare for release 2025-07-03 16:10:18 +02:00
Ole André Vadla Ravnås 8d4c05f664 subprojects: Bump outdated 2025-07-03 16:09:28 +02:00
Ole André Vadla Ravnås 2f78c96622 subprojects: Prepare for release 2025-07-03 12:57:05 +02:00
Ole André Vadla Ravnås 4b5aa28119 subprojects: Bump outdated 2025-07-03 12:55:57 +02:00
Ole André Vadla Ravnås 4f87afa0f1 subprojects: Prepare for release 2025-07-02 12:59:12 +02:00
Ole André Vadla Ravnås 82272945ac subprojects: Bump outdated 2025-07-02 12:56:24 +02:00
Ole André Vadla Ravnås bf496a81d9 subprojects: Prepare for release 2025-07-02 00:09:19 +02:00
Ole André Vadla Ravnås c2dcae3ff4 subprojects: Bump outdated 2025-07-02 00:08:44 +02:00
Ole André Vadla Ravnås 0cb42c47dc subprojects: Prepare for release 2025-07-01 23:40:07 +02:00
Ole André Vadla Ravnås 0e3a9fb551 subprojects: Bump outdated 2025-07-01 23:39:09 +02:00
Ole André Vadla Ravnås 4e16e5c667 package-manager: Fix the PackageRole declaration 2025-07-01 21:25:59 +02:00
Ole André Vadla Ravnås 09d6c7b044 package-manager: Update to the new API 2025-07-01 21:22:01 +02:00
Ole André Vadla Ravnås e11efce5c2 subprojects: Prepare for release 2025-06-27 15:59:55 +02:00
Ole André Vadla Ravnås e174be9998 subprojects: Bump outdated 2025-06-27 15:58:47 +02:00
Ole André Vadla Ravnås eae3d1dc65 subprojects: Bump outdated 2025-06-27 15:50:40 +02:00
Ole André Vadla Ravnås 2d26b94c7d subprojects: Prepare for release 2025-06-23 18:44:30 +02:00
Ole André Vadla Ravnås f396958dfe subprojects: Bump outdated 2025-06-23 18:41:22 +02:00
Ole André Vadla Ravnås 93fb33206f subprojects: Prepare for release 2025-06-20 15:45:37 +02:00
Ole André Vadla Ravnås aed3c1b7bf subprojects: Bump outdated 2025-06-20 15:44:21 +02:00
Ole André Vadla Ravnås 690da0652d package-manager: Remove unused install phase 2025-06-20 11:48:08 +02:00
Ole André Vadla Ravnås bec6221c02 subprojects: Prepare for release 2025-06-20 01:13:59 +02:00
Ole André Vadla Ravnås 53479e1814 subprojects: Bump outdated 2025-06-20 01:12:37 +02:00
Ole André Vadla Ravnås 68bc65ecd4 subprojects: Prepare for release 2025-06-19 23:25:49 +02:00
Ole André Vadla Ravnås 6492081c92 subprojects: Bump outdated 2025-06-19 23:23:57 +02:00
Ole André Vadla Ravnås 262b984e23 subprojects: Prepare for release 2025-06-19 21:03:48 +02:00
Ole André Vadla Ravnås 730ec03652 subprojects: Bump outdated 2025-06-19 21:01:50 +02:00
Ole André Vadla Ravnås 25f96f92d3 subprojects: Bump outdated 2025-06-19 20:19:02 +02:00
Ole André Vadla Ravnås dec23f9ef5 extension: Expose PackageManager.registry 2025-06-19 12:17:09 +02:00
Ole André Vadla Ravnås 906d27bcb7 extension: Add missing toplevel counter logic
We previously only bumped it when instantiating DeviceManager and
PortalService objects. We also need to do it for Compiler,
PackageManager, and FileMonitor. Otherwise signal emissions won't
work in some applications.
2025-06-19 11:51:38 +02:00
Ole André Vadla Ravnås b0018c9812 extension: Add __repr__ to PackageManager types 2025-06-19 11:51:38 +02:00
Ole André Vadla Ravnås 5e011e6d64 subprojects: Prepare for release 2025-06-18 23:35:02 +02:00
Ole André Vadla Ravnås b68dda4eb5 subprojects: Bump outdated 2025-06-18 23:33:55 +02:00
Ole André Vadla Ravnås 6fbe238c1a extension: Simplify the Compiler constructor
The DeviceManager is no longer needed.
2025-06-18 22:49:42 +02:00
Ole André Vadla Ravnås 4d750dfe58 extension: Fix the Compiler docstring 2025-06-18 22:49:42 +02:00
Ole André Vadla Ravnås fe1c61ce5d Add PackageManager bindings 2025-06-18 22:49:42 +02:00
Ole André Vadla Ravnås ea91df0d77 subprojects: Prepare for release 2025-06-13 16:28:23 +02:00
Ole André Vadla Ravnås b78ae7555f subprojects: Bump outdated 2025-06-13 16:27:32 +02:00
Ole André Vadla Ravnås b456683f2d subprojects: Prepare for release 2025-06-10 22:09:55 +02:00
Ole André Vadla Ravnås ddfe2b1a3b subprojects: Bump outdated 2025-06-10 22:06:06 +02:00
Ole André Vadla Ravnås 329795dbfc subprojects: Prepare for release 2025-06-07 13:32:31 +02:00
Ole André Vadla Ravnås e9c62fd581 subprojects: Bump outdated 2025-06-07 13:30:37 +02:00
Ole André Vadla Ravnås 40e945107d subprojects: Bump outdated 2025-06-07 11:23:25 +02:00
Ole André Vadla Ravnås 6c27bf0da7 subprojects: Prepare for release 2025-06-06 22:11:42 +02:00
Ole André Vadla Ravnås d37451f3bc subprojects: Bump outdated 2025-06-06 22:10:42 +02:00
Ole André Vadla Ravnås 6d4e4e27ee subprojects: Prepare for release 2025-06-06 14:11:20 +02:00
Ole André Vadla Ravnås 33a9c51387 subprojects: Bump outdated 2025-06-06 13:27:32 +02:00
Ole André Vadla Ravnås 4344eb9220 subprojects: Bump outdated 2025-06-06 12:38:36 +02:00
Ole André Vadla Ravnås 3a94e642d7 subprojects: Prepare for release 2025-06-05 22:05:26 +02:00
Ole André Vadla Ravnås 7a5948a95a subprojects: Bump outdated 2025-06-05 21:11:38 +02:00
Ole André Vadla Ravnås bbe926c606 subprojects: Bump outdated 2025-06-05 19:40:13 +02:00
Ole André Vadla Ravnås b653958fa4 subprojects: Bump outdated 2025-06-05 19:22:52 +02:00
Ole André Vadla Ravnås bca5146b74 subprojects: Bump outdated 2025-06-05 17:02:30 +02:00
Ole André Vadla Ravnås 2bd254702c submodules: Bump releng 2025-06-05 17:02:30 +02:00
Ole André Vadla Ravnås 82ee16d299 subprojects: Bump outdated 2025-06-02 00:10:05 +02:00
Ole André Vadla Ravnås 51501ceacb Add support for the new Compiler options
I.e. `output_format`, `bundle_format`, and `type_check`.
2025-06-01 23:48:37 +02:00
Ole André Vadla Ravnås ef45347385 subprojects: Bump outdated 2025-06-01 11:05:11 +02:00
Ole André Vadla Ravnås 0024f6719a submodules: Bump releng 2025-06-01 11:05:11 +02:00
Ole André Vadla Ravnås 87de091250 subprojects: Prepare for release 2025-05-29 17:32:12 +02:00
Ole André Vadla Ravnås cf4870e13d subprojects: Bump outdated 2025-05-29 17:30:22 +02:00
Ole André Vadla Ravnås 2ac00cb1e2 subprojects: Prepare for release 2025-05-28 23:17:06 +02:00
Ole André Vadla Ravnås dd94c73d4f subprojects: Bump outdated 2025-05-28 23:16:30 +02:00
Ole André Vadla Ravnås 40eb2dae38 subprojects: Prepare for release 2025-05-24 21:03:25 +02:00
Ole André Vadla Ravnås 73004f9598 subprojects: Bump outdated 2025-05-24 21:02:11 +02:00
Ole André Vadla Ravnås a0e9e64346 subprojects: Prepare for release 2025-05-22 21:39:37 +02:00
Ole André Vadla Ravnås 2706e19615 subprojects: Bump outdated 2025-05-22 21:22:51 +02:00
Ole André Vadla Ravnås 6edaf679ac subprojects: Bump outdated 2025-05-22 18:22:49 +02:00
Ole André Vadla Ravnås c2c45ce231 subprojects: Prepare for release 2025-05-20 23:12:16 +02:00
Ole André Vadla Ravnås 0180450178 subprojects: Bump outdated 2025-05-20 23:10:29 +02:00
Ole André Vadla Ravnås e07370158d subprojects: Prepare for release 2025-05-20 22:40:56 +02:00
Ole André Vadla Ravnås f73fdff4ee subprojects: Bump outdated 2025-05-20 22:40:02 +02:00
Ole André Vadla Ravnås b565fa19dc subprojects: Bump outdated 2025-05-20 22:06:51 +02:00
Ole André Vadla Ravnås 58d5ea9e2f submodules: Bump releng 2025-05-20 22:06:51 +02:00
Ole André Vadla Ravnås 91826487e1 subprojects: Prepare for release 2025-05-17 23:48:16 +02:00
Ole André Vadla Ravnås b1abfd53fa subprojects: Bump outdated 2025-05-17 23:47:03 +02:00
Ole André Vadla Ravnås 1afde6cb34 subprojects: Prepare for release 2025-05-17 19:45:41 +02:00
Ole André Vadla Ravnås 6bee5f45f3 subprojects: Bump outdated 2025-05-17 19:10:59 +02:00
Ole André Vadla Ravnås efc1009ece subprojects: Bump outdated 2025-05-17 11:46:46 +02:00
Ole André Vadla Ravnås 3def865cf8 subprojects: Prepare for release 2025-05-14 15:26:52 +02:00
Ole André Vadla Ravnås 3c41862ac5 subprojects: Bump outdated 2025-05-14 15:25:41 +02:00
Ole André Vadla Ravnås 4bd11602d7 subprojects: Bump outdated 2025-05-14 09:40:31 +02:00
Ole André Vadla Ravnås d07c8a16cd submodules: Bump releng 2025-05-14 09:40:31 +02:00
Ole André Vadla Ravnås 4e6d28cba7 subprojects: Prepare for release 2025-05-09 17:43:33 +02:00
Ole André Vadla Ravnås e0562ed0bc subprojects: Bump outdated 2025-05-09 17:42:35 +02:00
Ole André Vadla Ravnås 9dc17772cd subprojects: Prepare for release 2025-05-09 11:56:01 +02:00
Ole André Vadla Ravnås 0f9f4a5da8 subprojects: Bump outdated 2025-05-09 11:55:02 +02:00
Ole André Vadla Ravnås 4a9fb75adf subprojects: Prepare for release 2025-05-08 22:43:18 +02:00
Ole André Vadla Ravnås c37ef15695 subprojects: Bump outdated 2025-05-08 22:41:37 +02:00
Ole André Vadla Ravnås f6ad8a504d subprojects: Prepare for release 2025-05-08 21:31:01 +02:00
Ole André Vadla Ravnås 808e4ab6b5 subprojects: Bump outdated 2025-05-08 20:05:50 +02:00
Ole André Vadla Ravnås 50ee91f63f subprojects: Bump outdated 2025-05-08 17:06:37 +02:00
Ole André Vadla Ravnås 56dc49b5fb subprojects: Prepare for release 2025-04-25 22:36:01 +02:00
Ole André Vadla Ravnås 4cbb5881bd subprojects: Bump outdated 2025-04-25 22:34:39 +02:00
Ole André Vadla Ravnås 6ff0e34ca3 subprojects: Bump outdated 2025-04-17 18:37:11 +02:00
Ole André Vadla Ravnås 4df903dca5 subprojects: Bump outdated 2025-04-17 18:15:50 +02:00
Ole André Vadla Ravnås 6ed81cbfb6 subprojects: Prepare for release 2025-04-17 13:53:50 +02:00
Ole André Vadla Ravnås 98cc4c44bc subprojects: Bump outdated 2025-04-17 13:52:19 +02:00
Ole André Vadla Ravnås 6190b3c57b subprojects: Prepare for release 2025-04-16 20:26:51 +02:00
Ole André Vadla Ravnås 212973bbc1 subprojects: Bump outdated 2025-04-16 20:25:40 +02:00
Ole André Vadla Ravnås 79f7ae1deb subprojects: Bump outdated 2025-04-16 20:16:58 +02:00
Ole André Vadla Ravnås 522366a55e subprojects: Prepare for release 2025-04-14 17:59:52 +02:00
Ole André Vadla Ravnås 8017d10e3e subprojects: Bump outdated 2025-04-14 17:58:34 +02:00
Ole André Vadla Ravnås e78a5fd3b3 subprojects: Prepare for release 2025-04-09 21:50:24 +02:00
Ole André Vadla Ravnås 5cbef2fb1f subprojects: Bump outdated 2025-04-09 21:48:51 +02:00
Ole André Vadla Ravnås 8694918de7 subprojects: Prepare for release 2025-04-07 19:32:49 +02:00
Ole André Vadla Ravnås ab16fe04c5 subprojects: Bump outdated 2025-04-07 19:32:05 +02:00
Ole André Vadla Ravnås a1d1740541 subprojects: Prepare for release 2025-04-07 10:09:01 +02:00
Ole André Vadla Ravnås 09d2a1aa54 subprojects: Bump outdated 2025-04-07 10:08:15 +02:00
Ole André Vadla Ravnås 215669c151 subprojects: Prepare for release 2025-04-05 14:47:05 +02:00
Ole André Vadla Ravnås f7b08f8375 subprojects: Bump outdated 2025-04-05 11:14:26 +02:00
Ole André Vadla Ravnås 133687aafc subprojects: Prepare for release 2025-04-05 11:10:39 +02:00
Ole André Vadla Ravnås 06130770e1 subprojects: Bump outdated 2025-04-05 09:38:46 +02:00
Ole André Vadla Ravnås 2d72d0be57 subprojects: Prepare for release 2025-04-05 08:52:21 +02:00
Ole André Vadla Ravnås d463d7f2f2 subprojects: Bump outdated 2025-04-05 08:51:11 +02:00
Ole André Vadla Ravnås 11613adee6 subprojects: Prepare for release 2025-03-31 21:22:58 +02:00
Ole André Vadla Ravnås 8dc6509929 subprojects: Bump outdated 2025-03-31 20:17:46 +02:00
Ole André Vadla Ravnås 3f8b122ce7 extension: Fix IOStream.read_all() EOS handling 2025-03-30 22:27:27 +02:00
Ole André Vadla Ravnås 29abf88e31 subprojects: Prepare for release 2025-03-21 14:20:56 +01:00
Ole André Vadla Ravnås 5370147e85 subprojects: Bump outdated 2025-03-21 14:19:38 +01:00
Ole André Vadla Ravnås 507917744d subprojects: Prepare for release 2025-03-21 13:57:19 +01:00
Ole André Vadla Ravnås 8f2858fd8d subprojects: Bump outdated 2025-03-20 20:39:04 +01:00
Ole André Vadla Ravnås c2cf7fa951 subprojects: Bump outdated 2025-03-20 17:00:38 +01:00
Ole André Vadla Ravnås 9ff0651481 submodules: Bump releng 2025-03-20 17:00:38 +01:00
Ole André Vadla Ravnås 2674d6ef7d subprojects: Bump outdated 2025-03-19 10:51:49 +01:00
Ole André Vadla Ravnås 5d65919693 submodules: Bump releng 2025-03-19 10:51:49 +01:00
Ole André Vadla Ravnås d453cdd5ba subprojects: Bump outdated 2025-03-18 19:51:22 +01:00
Ole André Vadla Ravnås e8fd88f3d4 submodules: Bump releng 2025-03-18 19:51:22 +01:00
Ole André Vadla Ravnås 414cf0e029 subprojects: Prepare for release 2025-03-13 19:09:44 +01:00
Ole André Vadla Ravnås 76825537e8 subprojects: Bump outdated 2025-03-13 19:08:40 +01:00
Ole André Vadla Ravnås 2ab18cf80f subprojects: Bump outdated 2025-03-13 15:07:51 +01:00
Ole André Vadla Ravnås aaa703436b subprojects: Bump outdated 2025-03-13 14:44:41 +01:00
Ole André Vadla Ravnås 387962ab9d subprojects: Bump outdated 2025-03-13 14:09:34 +01:00
Ole André Vadla Ravnås 97f4c236a6 submodules: Bump releng 2025-03-13 14:09:34 +01:00
Ole André Vadla Ravnås 88cb2c97b8 subprojects: Bump outdated 2025-02-18 11:15:28 +01:00
Ole André Vadla Ravnås ec5035fd96 submodules: Bump releng 2025-02-18 11:15:28 +01:00
Ole André Vadla Ravnås bd883147ed subprojects: Prepare for release 2025-01-27 20:54:34 +01:00
Ole André Vadla Ravnås f7c32b2772 subprojects: Bump outdated 2025-01-27 20:52:06 +01:00
Ole André Vadla Ravnås 68009a8df9 subprojects: Prepare for release 2025-01-23 20:47:04 +01:00
Ole André Vadla Ravnås 85d56a0e45 subprojects: Bump outdated 2025-01-23 20:31:44 +01:00
Ole André Vadla Ravnås 228610a79c subprojects: Prepare for release 2025-01-17 16:49:13 +01:00
Ole André Vadla Ravnås d4b1b6aa8b subprojects: Bump outdated 2025-01-17 16:47:08 +01:00
Ole André Vadla Ravnås 29661c6b3b subprojects: Prepare for release 2025-01-14 19:35:35 +01:00
Ole André Vadla Ravnås d5b2a6fd18 subprojects: Bump outdated 2025-01-14 19:33:30 +01:00
Ole André Vadla Ravnås b862e9ae82 submodules: Bump releng 2025-01-14 19:33:30 +01:00
Ole André Vadla Ravnås 6e6f84969d subprojects: Prepare for release 2025-01-13 22:20:45 +01:00
Ole André Vadla Ravnås d6933eccf3 subprojects: Bump outdated 2025-01-13 22:18:15 +01:00
Ole André Vadla Ravnås 3bee61ffdb subprojects: Prepare for release 2025-01-10 02:04:13 +01:00
Ole André Vadla Ravnås 647e45f8bf subprojects: Bump outdated 2025-01-10 02:02:15 +01:00
Ole André Vadla Ravnås 5b6cfeba8b subprojects: Bump outdated 2025-01-09 23:35:35 +01:00
Ole André Vadla Ravnås c2b8043d8d submodules: Bump releng 2025-01-09 23:35:35 +01:00
Ole André Vadla Ravnås 69a4fa2ad2 subprojects: Prepare for release 2025-01-09 13:18:44 +01:00
Ole André Vadla Ravnås 546f65f25b subprojects: Bump outdated 2025-01-09 13:17:12 +01:00
Ole André Vadla Ravnås 168fcd5fe6 subprojects: Bump outdated 2025-01-08 19:06:57 +01:00
Ole André Vadla Ravnås 2ae7df42d0 subprojects: Bump outdated 2025-01-06 16:38:33 +01:00
Ole André Vadla Ravnås e8eff270ce subprojects: Bump outdated 2025-01-06 16:03:40 +01:00
Ole André Vadla Ravnås 62b6839d12 subprojects: Bump outdated 2025-01-06 01:11:52 +01:00
Ole André Vadla Ravnås d83456efe7 submodules: Bump releng 2025-01-06 01:11:52 +01:00
Ole André Vadla Ravnås fa62593fed Create FUNDING.yml 2024-12-12 13:37:36 +01:00
Ole André Vadla Ravnås 305d2c1360 subprojects: Bump outdated 2024-12-09 00:58:16 +01:00
Ole André Vadla Ravnås 67b563a72c subprojects: Prepare for release 2024-12-09 00:52:32 +01:00
Ole André Vadla Ravnås d988aa2920 subprojects: Prepare for release 2024-12-09 00:32:23 +01:00
Ole André Vadla Ravnås d346babcf9 subprojects: Bump outdated 2024-12-09 00:29:06 +01:00
Ole André Vadla Ravnås 96a3777eb0 subprojects: Bump outdated 2024-12-08 16:32:08 +01:00
Ole André Vadla Ravnås 6c4ad9bf98 submodules: Bump releng 2024-12-08 16:32:08 +01:00
Ole André Vadla Ravnås 0490814f79 subprojects: Prepare for release 2024-11-14 00:30:44 +01:00
Ole André Vadla Ravnås 3c21f23327 subprojects: Bump outdated 2024-11-14 00:29:11 +01:00
Ole André Vadla Ravnås fe24ef56d1 submodules: Bump releng 2024-11-14 00:29:11 +01:00
Ole André Vadla Ravnås 2d8dca8d53 subprojects: Bump outdated 2024-11-06 10:48:49 +01:00
Ole André Vadla Ravnås 77f7d0f3c3 subprojects: Bump outdated 2024-11-06 10:21:26 +01:00
Ole André Vadla Ravnås c8f3b40aad submodules: Bump releng 2024-11-06 10:21:26 +01:00
Ole André Vadla Ravnås 7416839ae5 subprojects: Prepare for release 2024-10-14 15:32:22 +02:00
Ole André Vadla Ravnås 5c782dcc1c subprojects: Bump outdated 2024-10-14 15:30:27 +02:00
Ole André Vadla Ravnås de4f0e906d subprojects: Prepare for release 2024-10-11 11:18:34 +02:00
Ole André Vadla Ravnås 623cb160f8 subprojects: Bump outdated 2024-10-11 11:16:20 +02:00
Ole André Vadla Ravnås 3c265a483d subprojects: Prepare for release 2024-10-10 22:07:56 +02:00
Ole André Vadla Ravnås f43a1ed12c subprojects: Bump outdated 2024-10-10 22:07:03 +02:00
Ole André Vadla Ravnås 9201c4c007 subprojects: Prepare for release 2024-10-10 20:18:29 +02:00
Ole André Vadla Ravnås 135dac88ec subprojects: Bump outdated 2024-10-10 20:16:14 +02:00
Ole André Vadla Ravnås 28e8b1f32e submodules: Bump releng 2024-10-10 20:16:14 +02:00
Ole André Vadla Ravnås 0b7bde2fd4 Revert "Use ParamSpec for better type hints"
This reverts commit 9a3ec81843.
2024-10-10 20:13:54 +02:00
Ole André Vadla Ravnås 6a18d4c4cc Fix a stylistic inconsistency 2024-10-10 20:09:50 +02:00
Nick 9a3ec81843 Use ParamSpec for better type hints 2024-10-10 20:07:23 +02:00
Ole André Vadla Ravnås ec55dcb3bc subprojects: Bump outdated 2024-10-05 17:25:10 +02:00
Ole André Vadla Ravnås e5404ae4eb submodules: Bump releng 2024-10-05 17:25:10 +02:00
Ole André Vadla Ravnås 64396bce72 subprojects: Bump outdated 2024-10-05 16:14:58 +02:00
Ole André Vadla Ravnås ccdd63dccc submodules: Bump releng 2024-10-05 16:14:57 +02:00
Ole André Vadla Ravnås e8f69618da subprojects: Bump outdated 2024-10-05 16:13:02 +02:00
Ole André Vadla Ravnås d809147cd0 submodules: Bump releng 2024-10-05 16:13:02 +02:00
Ole André Vadla Ravnås 24cc1fbcc9 subprojects: Prepare for release 2024-09-19 00:00:55 +02:00
Ole André Vadla Ravnås 7a2762ecc7 subprojects: Bump outdated 2024-09-18 23:57:43 +02:00
Ole André Vadla Ravnås d92b8e684c subprojects: Prepare for release 2024-09-18 14:33:21 +02:00
Ole André Vadla Ravnås 7c17bd5330 subprojects: Bump outdated 2024-09-18 14:31:52 +02:00
Ole André Vadla Ravnås 5991067e4e submodules: Bump releng 2024-09-18 14:31:52 +02:00
Ole André Vadla Ravnås 0780e5f813 subprojects: Prepare for release 2024-09-06 22:59:57 +02:00
Ole André Vadla Ravnås ce326094be subprojects: Bump outdated 2024-09-06 22:59:03 +02:00
Ole André Vadla Ravnås 092f6c38a1 subprojects: Prepare for release 2024-09-06 21:57:11 +02:00
Ole André Vadla Ravnås 9e83d29bd9 subprojects: Bump outdated 2024-09-06 21:55:00 +02:00
Ole André Vadla Ravnås 90533db5d4 subprojects: Bump outdated 2024-08-30 23:00:33 +02:00
Ole André Vadla Ravnås 30e009997e subprojects: Bump outdated 2024-08-26 12:27:35 +02:00
Ole André Vadla Ravnås 32e3c1922b subprojects: Bump outdated 2024-08-26 01:52:05 +02:00
Ole André Vadla Ravnås 69c5696aee submodules: Bump releng 2024-08-26 01:52:05 +02:00
Ole André Vadla Ravnås 0394ff3585 subprojects: Bump outdated 2024-08-25 23:56:15 +02:00
Ole André Vadla Ravnås c15b92fd55 subprojects: Bump outdated 2024-08-25 13:42:02 +02:00
Ole André Vadla Ravnås c53b453059 subprojects: Prepare for release 2024-08-22 15:40:52 +02:00
Ole André Vadla Ravnås d467d91e4f subprojects: Bump outdated 2024-08-22 15:39:15 +02:00
Ole André Vadla Ravnås ed3fdb8ce0 subprojects: Prepare for release 2024-08-20 21:50:48 +02:00
Ole André Vadla Ravnås 4d4632dbbe subprojects: Bump outdated 2024-08-20 21:48:36 +02:00
Ole André Vadla Ravnås aab9c4e76f subprojects: Prepare for release 2024-08-02 14:05:20 +02:00
Ole André Vadla Ravnås 2be19bcdad subprojects: Bump outdated 2024-08-02 14:03:56 +02:00
Ole André Vadla Ravnås 915c0678bd subprojects: Bump outdated 2024-07-29 11:00:52 +02:00
Ole André Vadla Ravnås 573a5a7d24 submodules: Bump releng 2024-07-29 11:00:52 +02:00
Ole André Vadla Ravnås 148ca1461d subprojects: Prepare for release 2024-07-23 10:15:02 +02:00
Ole André Vadla Ravnås 8eb4987563 subprojects: Bump outdated 2024-07-23 10:12:11 +02:00
Ole André Vadla Ravnås 84c7375044 subprojects: Prepare for release 2024-07-22 11:49:12 +02:00
Ole André Vadla Ravnås 267d5d555d subprojects: Bump outdated 2024-07-22 11:38:02 +02:00
Ole André Vadla Ravnås e219e5edbc submodules: Bump releng 2024-07-22 11:38:02 +02:00
Ole André Vadla Ravnås 70aaa04070 subprojects: Prepare for release 2024-07-17 22:43:16 +02:00
Ole André Vadla Ravnås 463fd65f03 subprojects: Bump outdated 2024-07-17 22:41:06 +02:00
Ole André Vadla Ravnås 41c3092dfe subprojects: Bump outdated 2024-07-17 22:10:16 +02:00
Ole André Vadla Ravnås 1b11eeab12 subprojects: Prepare for release 2024-07-16 15:25:01 +02:00
Ole André Vadla Ravnås 10aad4273c subprojects: Bump outdated 2024-07-16 15:20:49 +02:00
Ole André Vadla Ravnås d921e98e0c extension: Eliminate usage of unstable ref-counting APIs
Fixes #244.
2024-07-15 22:54:19 +02:00
Ole André Vadla Ravnås 8935cf3651 extension: Remove unused macro 2024-07-15 18:46:01 +02:00
Ole André Vadla Ravnås 2e3b9474bf extension: Drop remaining compatibility macros
As we no longer support Python 2.
2024-07-15 18:43:50 +02:00
Ole André Vadla Ravnås 582c2860c0 subprojects: Prepare for release 2024-07-13 00:34:10 +02:00
Ole André Vadla Ravnås 7c7947ee7c subprojects: Bump outdated 2024-07-13 00:07:05 +02:00
Ole André Vadla Ravnås 0f68038a10 subprojects: Prepare for release 2024-07-08 14:27:12 +02:00
Ole André Vadla Ravnås e9a3a37ea1 subprojects: Bump outdated 2024-07-08 14:25:25 +02:00
Ole André Vadla Ravnås f642de8a6b subprojects: Prepare for release 2024-07-06 00:07:34 +02:00
Ole André Vadla Ravnås c541ac027c subprojects: Bump outdated 2024-07-06 00:06:46 +02:00
Ole André Vadla Ravnås facd6756b2 subprojects: Prepare for release 2024-07-05 15:32:51 +02:00
Ole André Vadla Ravnås f29f486c0d subprojects: Bump outdated 2024-07-05 15:32:13 +02:00
Ole André Vadla Ravnås 2135414777 subprojects: Bump outdated 2024-07-05 15:26:38 +02:00
Ole André Vadla Ravnås ba032180c6 subprojects: Bump outdated 2024-07-04 13:51:07 +02:00
Ole André Vadla Ravnås b29cbcd499 subprojects: Bump outdated 2024-07-04 11:27:12 +02:00
Ole André Vadla Ravnås 55cdadea6a subprojects: Bump outdated 2024-07-03 23:20:23 +02:00
Ole André Vadla Ravnås 17d39c725c submodules: Bump releng 2024-07-03 23:20:23 +02:00
Ole André Vadla Ravnås 72f1d651b6 examples: Add XPC application launching example
Co-authored-by: Håvard Sørbø <havard@hsorbo.no>
2024-07-03 22:33:48 +02:00
Ole André Vadla Ravnås 6d5c64d215 examples: Rename xpc.py to xpc/listprocesses.py
Co-authored-by: Håvard Sørbø <havard@hsorbo.no>
2024-07-03 22:33:44 +02:00
Ole André Vadla Ravnås 2b5f6492a2 extension: Support unmarshaling tuples to GVariant
Co-authored-by: Håvard Sørbø <havard@hsorbo.no>
2024-07-03 22:33:40 +02:00
Ole André Vadla Ravnås 316f88974d extension: Fix unmarshaling of bool to GVariant
A bool also satisfies PyLong_Check(), so we need to PyBool_Check() first.

Co-authored-by: Håvard Sørbø <havard@hsorbo.no>
2024-07-03 22:33:40 +02:00
Ole André Vadla Ravnås fee73e852b extension: Drop PyFrida_is_string()
Now that it does nothing special as we no longer support Python 2.

Co-authored-by: Håvard Sørbø <havard@hsorbo.no>
2024-07-03 22:33:40 +02:00
Ole André Vadla Ravnås 37847fd8c9 subprojects: Prepare for release 2024-06-04 14:14:47 +02:00
Ole André Vadla Ravnås 7158638eb9 subprojects: Bump outdated 2024-06-04 14:12:52 +02:00
Ole André Vadla Ravnås 77d9c51109 subprojects: Prepare for release 2024-06-04 13:41:17 +02:00
Ole André Vadla Ravnås 040fa5536b subprojects: Bump outdated 2024-06-04 13:38:55 +02:00
Ole André Vadla Ravnås c9226b976a examples: Fix the open_service() plist example
Co-authored-by: Håvard Sørbø <havard@hsorbo.no>
2024-06-04 12:36:37 +02:00
Ole André Vadla Ravnås d851e4eb6a subprojects: Prepare for release 2024-05-31 22:52:28 +02:00
Ole André Vadla Ravnås ccea05e00b subprojects: Bump outdated 2024-05-31 22:51:00 +02:00
Ole André Vadla Ravnås 6416edc773 subprojects: Prepare for release 2024-05-31 15:42:55 +02:00
Ole André Vadla Ravnås ce718c1dc9 subprojects: Bump outdated 2024-05-31 15:41:48 +02:00
Ole André Vadla Ravnås 0b854499cd rpc: Fix type hints for make_rpc_call_request()
Co-authored-by: Håvard Sørbø <havard@hsorbo.no>
2024-05-31 15:40:22 +02:00
Ole André Vadla Ravnås 243cce22e6 rpc: Add support for new binary data passing
Which means:
- Pass in data to RPC method.
- Return value and data from RPC method.

Co-authored-by: Håvard Sørbø <havard@hsorbo.no>
2024-05-31 15:11:05 +02:00
Ole André Vadla Ravnås c4d0fe55a5 subprojects: Bump outdated 2024-05-31 06:45:52 +02:00
Ole André Vadla Ravnås f3d767ecb6 submodules: Bump releng 2024-05-31 06:45:51 +02:00
Ole André Vadla Ravnås 8838d885ce _frida: Add missing type hints 2024-05-30 23:45:06 +02:00
Ole André Vadla Ravnås 213e373056 examples: Fix import ordering 2024-05-30 23:35:00 +02:00
Ole André Vadla Ravnås 8b888558c7 device: Add open_service() and Service API
Co-authored-by: Håvard Sørbø <havard@hsorbo.no>
2024-05-30 23:28:36 +02:00
Ole André Vadla Ravnås de55d964a0 extension: Support marshaling uint64 GVariant
Co-authored-by: Håvard Sørbø <havard@hsorbo.no>
2024-05-30 23:28:36 +02:00
Ole André Vadla Ravnås e920bad7f5 extension: Support marshaling double to/from GVariant
Co-authored-by: Håvard Sørbø <havard@hsorbo.no>
2024-05-30 23:28:36 +02:00
Ole André Vadla Ravnås 2b947e6d75 extension: Refactor the variant marshaling logic
Co-authored-by: Håvard Sørbø <havard@hsorbo.no>
2024-05-30 23:28:36 +02:00
Ole André Vadla Ravnås 9992e8ad7a extension: Support marshaling GVariant arrays of variant
Co-authored-by: Håvard Sørbø <havard@hsorbo.no>
2024-05-30 23:28:36 +02:00
Ole André Vadla Ravnås 3c7eb89653 extension: Support unmarshaling more types to GVariant
Co-authored-by: Håvard Sørbø <havard@hsorbo.no>
2024-05-30 23:28:36 +02:00
Ole André Vadla Ravnås 16f1be2a88 subprojects: Bump outdated 2024-05-30 21:59:09 +02:00
Ole André Vadla Ravnås 280c6d73f3 subprojects: Bump outdated 2024-05-30 21:50:49 +02:00
Ole André Vadla Ravnås 140dc6d13a subprojects: Bump outdated 2024-05-30 21:42:41 +02:00
Ole André Vadla Ravnås eac203e327 subprojects: Bump outdated 2024-05-30 20:52:08 +02:00
Ole André Vadla Ravnås bc3429a80d submodules: Bump releng 2024-05-30 20:52:08 +02:00
Ole André Vadla Ravnås e929477ecd subprojects: Prepare for release 2024-05-21 12:50:37 +02:00
Ole André Vadla Ravnås ebeb7a86b1 subprojects: Bump outdated 2024-05-21 12:49:09 +02:00
Ole André Vadla Ravnås 458a1f055a subprojects: Prepare for release 2024-05-20 22:54:32 +02:00
Ole André Vadla Ravnås de0b1643de subprojects: Bump outdated 2024-05-20 22:53:43 +02:00
Ole André Vadla Ravnås 7c39166f77 subprojects: Prepare for release 2024-05-18 23:05:05 +02:00
Ole André Vadla Ravnås 56e92493f5 subprojects: Bump outdated 2024-05-18 22:58:12 +02:00
Ole André Vadla Ravnås efdbd80fc6 submodules: Bump releng 2024-05-18 22:58:12 +02:00
Ole André Vadla Ravnås acfa48ac4a subprojects: Prepare for release 2024-05-17 07:26:34 +02:00
Ole André Vadla Ravnås 799745783d subprojects: Bump outdated 2024-05-17 07:25:27 +02:00
Ole André Vadla Ravnås 9d21327ee6 subprojects: Bump outdated 2024-05-14 21:30:59 +02:00
Ole André Vadla Ravnås 5b4dca5ad3 submodules: Bump releng 2024-05-14 21:30:59 +02:00
Ole André Vadla Ravnås cdba01185d subprojects: Bump outdated 2024-05-14 06:47:41 +02:00
Ole André Vadla Ravnås 57de3f8f39 submodules: Bump releng 2024-05-14 06:47:41 +02:00
Ole André Vadla Ravnås a8d4972d1a subprojects: Bump outdated 2024-05-13 22:44:14 +02:00
Ole André Vadla Ravnås 0c8080dfb1 subprojects: Bump outdated 2024-05-13 15:16:24 +02:00
Ole André Vadla Ravnås 6d9765c16d subprojects: Bump outdated 2024-05-10 07:40:49 +02:00
Ole André Vadla Ravnås e3e77ee884 submodules: Bump releng 2024-05-10 07:40:49 +02:00
Ole André Vadla Ravnås ccafc2f828 Revert "setup: Do not declare _frida as a package"
It seems to be needed for package data to be included.

This reverts commit 25270d43dd.
2024-05-09 23:39:14 +02:00
Ole André Vadla Ravnås 6eeda89bba manifest: Include meson-scripts in sdist
As they're now also needed when running configure.
2024-05-09 23:37:35 +02:00
Ole André Vadla Ravnås c06b6774e3 setup: Fix the build output detection logic
Which was still using the old path from before _frida moved.
2024-05-09 23:34:42 +02:00
Ole André Vadla Ravnås 1086ae645d setup: Support passing version through the environment
By setting FRIDA_VERSION. But only when not in a source package.

This is needed so that our CI can use the same version across our repos,
for non-release builds. For release builds we tag each repo, which means
we don't have to worry about this.
2024-05-09 22:25:34 +02:00
Ole André Vadla Ravnås 25270d43dd setup: Do not declare _frida as a package
As it is implemented in native code.
2024-05-09 18:44:46 +02:00
Ole André Vadla Ravnås 6ebf0fa13f manifest: Remove redundant global-exclude 2024-05-09 18:41:01 +02:00
Ole André Vadla Ravnås 4f7b72c769 manifest: Update to match new layout 2024-05-09 18:14:57 +02:00
Ole André Vadla Ravnås f30febad99 subprojects: Bump outdated 2024-05-09 09:19:16 +02:00
Ole André Vadla Ravnås 088ff058ca subprojects: Bump outdated 2024-05-09 07:58:00 +02:00
Ole André Vadla Ravnås 4d8f87ccaa subprojects: Bump outdated 2024-05-09 00:27:26 +02:00
Ole André Vadla Ravnås 801088b107 submodules: Bump releng 2024-05-09 00:27:26 +02:00
Ole André Vadla Ravnås f17944358d subprojects: Bump outdated 2024-05-02 13:30:55 +02:00
Ole André Vadla Ravnås 290e5f7c42 submodules: Bump releng 2024-05-02 13:30:55 +02:00
Ole André Vadla Ravnås 5643f45b2d subprojects: Bump outdated 2024-05-01 14:29:55 +02:00
Ole André Vadla Ravnås 091dfa2dbb subprojects: Bump outdated 2024-05-01 08:03:00 +02:00
Ole André Vadla Ravnås 78d0c062c7 submodules: Bump releng 2024-05-01 08:03:00 +02:00
Ole André Vadla Ravnås 433b067a50 subprojects: Bump outdated 2024-04-30 21:58:05 +00:00
Ole André Vadla Ravnås 980249dfc3 submodules: Bump releng 2024-04-30 21:58:05 +00:00
Ole André Vadla Ravnås daaa2cf7b3 subprojects: Bump outdated 2024-04-30 12:42:14 +02:00
Ole André Vadla Ravnås 0853244c43 subprojects: Bump outdated 2024-04-30 12:35:52 +02:00
Ole André Vadla Ravnås 555eeee4d8 subprojects: Bump outdated 2024-04-30 11:47:50 +02:00
Ole André Vadla Ravnås 8d85017a49 subprojects: Bump outdated 2024-04-30 11:28:44 +02:00
Ole André Vadla Ravnås 2095592071 subprojects: Bump outdated 2024-04-29 13:01:01 +00:00
Ole André Vadla Ravnås 238286a6c3 subprojects: Bump outdated 2024-04-29 12:01:12 +00:00
Ole André Vadla Ravnås 16061c58b2 submodules: Bump releng 2024-04-29 12:01:12 +00:00
Ole André Vadla Ravnås 961dbd8ea3 subprojects: Bump outdated 2024-04-28 14:42:17 +02:00
Ole André Vadla Ravnås a80896b788 submodules: Bump releng 2024-04-28 14:42:17 +02:00
Ole André Vadla Ravnås 91e2e4ff54 subprojects: Bump outdated 2024-04-27 09:43:05 +02:00
Ole André Vadla Ravnås 341d0e0dd0 submodules: Bump releng 2024-04-27 09:43:05 +02:00
Ole André Vadla Ravnås 49e716f803 subprojects: Bump outdated 2024-04-27 09:35:51 +02:00
Ole André Vadla Ravnås cd19587f34 submodules: Bump releng 2024-04-27 09:35:51 +02:00
Ole André Vadla Ravnås 2ce32efaff subprojects: Bump outdated 2024-04-26 00:03:01 +02:00
Ole André Vadla Ravnås 8935f80619 submodules: Bump releng 2024-04-26 00:03:01 +02:00
Ole André Vadla Ravnås 938e784957 subprojects: Bump outdated 2024-04-25 16:32:14 +02:00
Ole André Vadla Ravnås 73228d61f4 subprojects: Bump outdated 2024-04-24 23:52:14 +02:00
Ole André Vadla Ravnås e2fd7aaf9f submodules: Bump releng 2024-04-24 23:52:14 +02:00
Ole André Vadla Ravnås 338ff6f55f subprojects: Bump outdated 2024-04-24 13:35:05 +02:00
Ole André Vadla Ravnås a78280ea6f submodules: Bump releng 2024-04-24 13:35:05 +02:00
Ole André Vadla Ravnås 56ec6a46e7 Fix stylistic inconsistencies 2024-04-24 13:18:01 +02:00
Ole André Vadla Ravnås 9706e4be99 Move _frida package inside the frida package
So we only have one top-level package, to avoid confusing IDEs.

Also add missing files to the Meson build system.
2024-04-24 12:41:52 +02:00
Ole André Vadla Ravnås 03206cfae4 setup: Refactor a little bit 2024-04-24 11:27:20 +02:00
Ole André Vadla Ravnås dfe260d7ac setup: Improve naming 2024-04-24 11:03:39 +02:00
Ole André Vadla Ravnås 1b34793f14 setup: Drop the executable bit
It lacks a shebang and shouldn't have been executable to begin with.
2024-04-24 00:06:20 +02:00
Ole André Vadla Ravnås 17043a998f setup: Look for releng in MESON_SOURCE_ROOT first
For consistency with the ordering elsewhere.
2024-04-23 23:46:32 +02:00
Ole André Vadla Ravnås 1f3ae462a6 setup: Improve detect_version()
- Look for releng locally first, and in MESON_SOURCE_ROOT if set.
- If releng cannot be found, return "0.0.0".
2024-04-23 23:15:02 +02:00
Ole André Vadla Ravnås 37588948eb setup: Fix version detection when subproject 2024-04-23 22:15:28 +02:00
Ole André Vadla Ravnås 61fbf134c5 setup: Add support for building from source
This means we can finally drop support for building from a devkit, which
was quite fragile and error-prone.
2024-04-23 16:02:23 +02:00
Ole André Vadla Ravnås 1d6f42e85f scripts: Fix the PKG-INFO code-path in version.py 2024-04-23 14:27:10 +02:00
Ole André Vadla Ravnås d42d945be5 meson: Specify Meson version required 2024-04-23 14:09:08 +02:00
Ole André Vadla Ravnås cda2280dfc meson: Compute version and pass it to frida-core 2024-04-23 14:08:09 +02:00
Ole André Vadla Ravnås 279313366b subprojects: Bump outdated 2024-04-23 11:57:36 +02:00
Ole André Vadla Ravnås 8cf13283ec submodules: Bump releng 2024-04-23 11:57:36 +02:00
Ole André Vadla Ravnås b33951be23 subprojects: Bump outdated 2024-04-23 11:29:21 +02:00
Ole André Vadla Ravnås 779dc7456c submodules: Bump releng 2024-04-23 11:29:21 +02:00
Ole André Vadla Ravnås bdece31ffa subprojects: Bump outdated 2024-04-22 16:09:33 +02:00
Ole André Vadla Ravnås 946d111ddd submodules: Bump releng 2024-04-22 16:09:33 +02:00
Ole André Vadla Ravnås a49088b8a0 submodules: Bump releng 2024-04-17 23:36:56 +02:00
Ole André Vadla Ravnås 241a2854c6 meson: Set project version to 0.0.0
To make it clear this project doesn't have its own release cycle.
2024-04-17 23:35:51 +02:00
Ole André Vadla Ravnås d976283ca1 submodules: Bump releng 2024-04-15 16:05:11 +02:00
Ole André Vadla Ravnås 197cc4262c submodules: Bump releng 2024-04-07 14:41:32 +02:00
Ole André Vadla Ravnås 4bf45994a1 submodules: Bump releng 2024-04-07 08:58:51 +02:00
Ole André Vadla Ravnås c193dd49cd git: Update gitignore 2024-03-22 11:46:12 +01:00
Ole André Vadla Ravnås 04e9308368 submodules: Bump releng 2024-03-21 23:26:12 +01:00
Ole André Vadla Ravnås d8da49058d tests: Move RPC tests to exports_sync
So they don't break once we make `exports` async.
2024-03-21 23:21:33 +01:00
Ole André Vadla Ravnås ae7c708934 submodules: Bump releng 2024-03-21 22:27:38 +01:00
Ole André Vadla Ravnås 8bf6a11aee msvs: Drop the MSVS build system
Maintaining it alongside our Meson build system is too much of a burden.
2024-03-21 21:56:45 +01:00
Ole André Vadla Ravnås 88330bfbb9 meson: Simplify the build system
- Make full use of Meson's Python module.
- Drop python_incdir option. It's now possible to use a .pc file to
  specify the include path.
- Drop config.h, as we only needed it for HAVE_MACOS, which we can
  easily check for in the single location that we need it.
2024-03-21 21:53:50 +01:00
Ole André Vadla Ravnås a053489965 submodules: Bump releng 2024-03-20 23:47:08 +01:00
Ole André Vadla Ravnås bd3e280cbf meson: Remove the python option
We can instead rely solely on Meson's Python module, as Meson supports
specifying the `python` binary to use.
2024-03-20 23:23:16 +01:00
Ole André Vadla Ravnås 7df15667cc submodules: Bump releng 2024-03-20 12:52:24 +01:00
Ole André Vadla Ravnås a3c889855a submodules: Bump releng 2024-03-20 10:40:45 +01:00
Ole André Vadla Ravnås 8e2126da9a submodules: Bump releng 2024-03-19 22:08:09 +01:00
Ole André Vadla Ravnås 8685505b3e meson: Improve Python installation detection 2024-03-14 15:53:36 +01:00
Ole André Vadla Ravnås ef1da26d94 meson: Rename options file to the new preferred name 2024-03-14 15:50:12 +01:00
Ole André Vadla Ravnås 59467c03c7 meson: Wire up test-suite 2024-03-14 15:42:49 +01:00
Ole André Vadla Ravnås ada39ecc55 meson: Add frida-core wrap file 2024-03-14 15:35:20 +01:00
Ole André Vadla Ravnås db97443e51 build: Add wrapper scripts to simplify building 2024-03-14 15:34:40 +01:00
53 changed files with 6083 additions and 8263 deletions
+1
View File
@@ -0,0 +1 @@
github: frida
+2 -1
View File
@@ -1,5 +1,6 @@
*.pyc
*.user
/*.egg-info/
/build/
/deps/
/dist/
/subprojects/*
+3
View File
@@ -0,0 +1,3 @@
[submodule "releng"]
path = releng
url = https://github.com/frida/releng.git
+6
View File
@@ -0,0 +1,6 @@
all: .DEFAULT
.DEFAULT:
@gmake ${.MAKEFLAGS} ${.TARGETS}
.PHONY: all
+19
View File
@@ -0,0 +1,19 @@
include meson.build
include frida/meson.build
include frida/_frida/extension.c
include frida/_frida/extension.version
include frida/_frida/meson.build
include subprojects/frida-core.wrap
include BSDmakefile
include Makefile
include configure
include configure.bat
include make.bat
include releng/*.py
include releng/*.toml
graft releng/devkit-assets/
graft releng/meson-scripts/
include releng/meson/meson.py
graft releng/meson/mesonbuild/
graft releng/tomlkit/tomlkit/
+16
View File
@@ -0,0 +1,16 @@
PYTHON ?= $(shell which python3 >/dev/null && echo python3 || echo python)
all $(MAKECMDGOALS):
@$(PYTHON) \
-c "import sys; sys.path.insert(0, sys.argv[1]); from releng.meson_make import main; main()" \
"$(shell pwd)" \
./build \
$(MAKECMDGOALS)
git-submodules:
@if [ ! -f releng/meson/meson.py ]; then \
git submodule update --init --recursive --depth 1; \
fi
-include git-submodules
.PHONY: all $(MAKECMDGOALS)
-663
View File
@@ -1,663 +0,0 @@
from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union
# Exceptions
class AddressInUseError(Exception): ...
class ExecutableNotFoundError(Exception): ...
class ExecutableNotSupportedError(Exception): ...
class ServerNotRunningError(Exception): ...
class TimedOutError(Exception): ...
class TransportError(Exception): ...
class ProcessNotFoundError(Exception): ...
class ProcessNotRespondingError(Exception): ...
class ProtocolError(Exception): ...
class InvalidArgumentError(Exception): ...
class InvalidOperationError(Exception): ...
class NotSupportedError(Exception): ...
class OperationCancelledError(Exception): ...
class PermissionDeniedError(Exception): ...
class Object:
def __init__(self, *args: Any, **kwargs: Any) -> None: ...
def on(self, signal: str, callback: Callable[..., Any]) -> None:
"""
Add a signal handler.
"""
...
def off(self, signal: str, callback: Callable[..., Any]) -> None:
"""
Remove a signal handler.
"""
...
class Application(Object):
@property
def identifier(self) -> str:
"""
Application identifier.
"""
...
@property
def name(self) -> str:
"""
Human-readable application name.
"""
...
@property
def parameters(self) -> Dict[str, Any]:
"""
Parameters.
"""
...
@property
def pid(self) -> int:
"""
Process ID, or 0 if not running.
"""
...
class Bus(Object):
def attach(self) -> None:
"""
Attach to the bus.
"""
...
def post(self, message: str, data: Optional[Union[bytes, str]]) -> None:
"""
Post a JSON-encoded message to the bus.
"""
...
class Cancellable(Object):
def cancel(self) -> None:
"""
Set cancellable to cancelled.
"""
...
def connect(self, callback: Callable[..., Any]) -> int:
"""
Register notification callback.
"""
...
def disconnect(self, handler_id: int) -> None:
"""
Unregister notification callback.
"""
...
@classmethod
def get_current(cls) -> "Cancellable":
"""
Get the top cancellable from the stack.
"""
...
def get_fd(self) -> int:
"""
Get file descriptor for integrating with an event loop.
"""
...
def is_cancelled(self) -> bool:
"""
Query whether cancellable has been cancelled.
"""
...
def pop_current(self) -> None:
"""
Pop cancellable off the cancellable stack.
"""
...
def push_current(self) -> None:
"""
Push cancellable onto the cancellable stack.
"""
...
def raise_if_cancelled(self) -> None:
"""
Raise an exception if cancelled.
"""
...
def release_fd(self) -> None:
"""
Release a resource previously allocated by get_fd().
"""
...
class Child(Object):
@property
def argv(self) -> List[str]:
"""
Argument vector.
"""
...
@property
def envp(self) -> Dict[str, str]:
"""
Environment vector.
"""
...
@property
def identifier(self) -> str:
"""
Application identifier.
"""
...
@property
def origin(self) -> str:
"""
Origin.
"""
...
@property
def parent_pid(self) -> int:
"""
Parent Process ID.
"""
...
@property
def path(self) -> str:
"""
Path of executable.
"""
...
@property
def pid(self) -> int:
"""
Process ID.
"""
...
class Crash(Object):
@property
def parameters(self) -> Dict[str, Any]:
"""
Parameters.
"""
...
@property
def pid(self) -> int:
"""
Process ID.
"""
...
@property
def process_name(self) -> str:
"""
Process name.
"""
...
@property
def report(self) -> str:
"""
Human-readable crash report.
"""
...
@property
def summary(self) -> str:
"""
Human-readable crash summary.
"""
...
class Device(Object):
@property
def id(self) -> Optional[str]:
"""
Device ID.
"""
...
@property
def name(self) -> Optional[str]:
"""
Human-readable device name.
"""
...
@property
def icon(self) -> Optional[Any]:
"""
Icon.
"""
...
@property
def type(self) -> Optional[str]:
"""
Device type. One of: local, remote, usb.
"""
...
@property
def bus(self) -> Optional[Bus]:
"""
Message bus.
"""
...
def attach(self, pid: int, realm: Optional[str] = None, persist_timeout: Optional[int] = None) -> "Session":
"""
Attach to a PID.
"""
...
def disable_spawn_gating(self) -> None:
"""
Disable spawn gating.
"""
...
def enable_spawn_gating(self) -> None:
"""
Enable spawn gating.
"""
...
def enumerate_applications(
self, identifiers: Optional[Sequence[str]] = None, scope: Optional[str] = None
) -> List[Application]:
"""
Enumerate applications.
"""
...
def enumerate_pending_children(self) -> List[Child]:
"""
Enumerate pending children.
"""
...
def enumerate_pending_spawn(self) -> List["Spawn"]:
"""
Enumerate pending spawn.
"""
...
def enumerate_processes(self, pids: Optional[Sequence[int]] = None, scope: Optional[str] = None) -> List[Process]:
"""
Enumerate processes.
"""
...
def get_frontmost_application(self, scope: Optional[str] = None) -> Optional[Application]:
"""
Get details about the frontmost application.
"""
...
def inject_library_blob(self, pid: int, blob_buffer: bytes, entrypoint: str, data: str) -> int:
"""
Inject a library blob to a PID.
"""
...
def inject_library_file(self, pid: int, path: str, entrypoint: str, data: str) -> int:
"""
Inject a library file to a PID.
"""
...
def input(self, pid: int, data: bytes) -> None:
"""
Input data on stdin of a spawned process.
"""
...
def is_lost(self) -> bool:
"""
Query whether the device has been lost.
"""
...
def kill(self, pid: int) -> None:
"""
Kill a PID.
"""
...
def open_channel(self, address: str) -> "IOStream":
"""
Open a device-specific communication channel.
"""
...
def unpair(self) -> None:
"""
Unpair device.
"""
...
def query_system_parameters(self) -> Dict[str, Any]:
"""
Returns a dictionary of information about the host system.
"""
...
def resume(self, pid: int) -> None:
"""
Resume a process from the attachable state.
"""
...
def spawn(
self,
program: str,
argv: Union[None, List[Union[str, bytes]], Tuple[Union[str, bytes]]] = None,
envp: Optional[Dict[str, str]] = None,
env: Optional[Dict[str, str]] = None,
cwd: Optional[str] = None,
stdio: Optional[str] = None,
**kwargs: Any,
) -> int:
"""
Spawn a process into an attachable state.
"""
...
class DeviceManager(Object):
def add_remote_device(
self,
address: str,
certificate: Optional[str] = None,
origin: Optional[str] = None,
token: Optional[str] = None,
keepalive_interval: Optional[int] = None,
) -> Device:
"""
Add a remote device.
"""
...
def close(self) -> None:
"""
Close the device manager.
"""
...
def enumerate_devices(self) -> List[Device]:
"""
Enumerate devices.
"""
...
def get_device_matching(self, predicate: Callable[[Device], bool], timeout: int) -> Device:
"""
Get device matching predicate.
"""
...
def remove_remote_device(self, address: str) -> None:
"""
Remove a remote device.
"""
...
class EndpointParameters(Object): ...
class FileMonitor(Object):
def disable(self) -> None:
"""
Disable the file monitor.
"""
...
def enable(self) -> None:
"""
Enable the file monitor.
"""
...
class IOStream(Object):
def close(self) -> None:
"""
Close the stream.
"""
...
def is_closed(self) -> bool:
"""
Query whether the stream is closed.
"""
...
def read(self, size: int) -> bytes:
"""
Read up to the specified number of bytes from the stream.
"""
...
def read_all(self, size: int) -> bytes:
"""
Read exactly the specified number of bytes from the stream.
"""
...
def write(self, data: bytes) -> int:
"""
Write as much as possible of the provided data to the stream.
"""
...
def write_all(self, data: bytes) -> None:
"""
Write all of the provided data to the stream.
"""
...
class PortalMembership(Object):
def terminate(self) -> None:
"""
Terminate the membership.
"""
...
class PortalService(Object):
@property
def device(self) -> Device:
"""
Device for in-process control.
"""
...
def broadcast(self, message: str, data: Optional[Union[str, bytes]] = None) -> None:
"""
Broadcast a message to all control channels.
"""
...
def enumerate_tags(self, connection_id: int) -> List[str]:
"""
Enumerate tags of a specific connection.
"""
...
def kick(self, connection_id: int) -> None:
"""
Kick out a specific connection.
"""
...
def narrowcast(self, tag: str, message: str, data: Optional[Union[str, bytes]] = None) -> None:
"""
Post a message to control channels with a specific tag.
"""
...
def post(self, connection_id: int, message: str, data: Optional[Union[str, bytes]] = None) -> None:
"""
Post a message to a specific control channel.
"""
...
def start(self) -> None:
"""
Start listening for incoming connections.
"""
...
def stop(self) -> None:
"""
Stop listening for incoming connections, and kick any connected clients.
"""
...
def tag(self, connection_id: int, tag: str) -> None:
"""
Tag a specific control channel.
"""
...
def untag(self, connection_id: int, tag: str) -> None:
"""
Untag a specific control channel.
"""
...
class Process(Object):
@property
def pid(self) -> int:
"""
Process ID.
"""
...
@property
def name(self) -> str:
"""
Human-readable process name.
"""
...
@property
def parameters(self) -> Dict[str, Any]:
"""
Parameters.
"""
...
class Relay(Object):
def __init__(self, address: str, username: str, password: str, kind: str) -> None: ...
@property
def address(self) -> str:
"""
Network address or address:port of the TURN server.
"""
...
@property
def kind(self) -> str:
"""
Relay kind. One of: turn-udp, turn-tcp, turn-tls.
"""
...
@property
def password(self) -> str:
"""
The TURN password to use for the allocate request.
"""
...
@property
def username(self) -> str:
"""
The TURN username to use for the allocate request.
"""
...
class Script(Object):
def eternalize(self) -> None:
"""
Eternalize the script.
"""
...
def is_destroyed(self) -> bool:
"""
Query whether the script has been destroyed.
"""
...
def load(self) -> None:
"""
Load the script.
"""
...
def post(self, message: str, data: Optional[Union[str, bytes]] = None) -> None:
"""
Post a JSON-encoded message to the script.
"""
...
def unload(self) -> None:
"""
Unload the script.
"""
...
def enable_debugger(self, port: Optional[int]) -> None:
"""
Enable the Node.js compatible script debugger
"""
...
def disable_debugger(self) -> None:
"""
Disable the Node.js compatible script debugger
"""
...
class Session(Object):
@property
def pid(self) -> int:
"""
Process ID.
"""
...
def compile_script(self, source: str, name: Optional[str] = None, runtime: Optional[str] = None) -> bytes:
"""
Compile script source code to bytecode.
"""
...
def create_script(self, source: str, name: Optional[str] = None, runtime: Optional[str] = None) -> Script:
"""
Create a new script.
"""
...
def create_script_from_bytes(
self, data: bytes, name: Optional[str] = None, runtime: Optional[str] = None
) -> Script:
"""
Create a new script from bytecode.
"""
...
def snapshot_script(self, embed_script: str, warmup_script: Optional[str], runtime: Optional[str] = None) -> bytes:
"""
Evaluate script and snapshot the resulting VM state
"""
...
def detach(self) -> None:
"""
Detach session from the process.
"""
...
def disable_child_gating(self) -> None:
"""
Disable child gating.
"""
...
def enable_child_gating(self) -> None:
"""
Enable child gating.
"""
...
def is_detached(self) -> bool:
"""
Query whether the session is detached.
"""
...
def join_portal(
self, address: str, certificate: Optional[str] = None, token: Optional[str] = None, acl: Optional[Any] = None
) -> PortalMembership:
"""
Join a portal.
"""
...
def resume(self) -> None:
"""
Resume session after network error.
"""
...
def setup_peer_connection(
self, stun_server: Optional[str] = None, relays: Optional[Sequence[Relay]] = None
) -> None:
"""
Set up a peer connection with the target process.
"""
...
class Spawn(Object):
@property
def identifier(self) -> str:
"""
Application identifier.
"""
...
@property
def pid(self) -> int:
"""
Process ID.
"""
...
class Compiler(Object):
def build(
self,
entrypoint: str,
project_root: Optional[str] = None,
source_maps: Optional[str] = None,
compression: Optional[str] = None,
) -> str:
"""
Build an agent.
"""
...
def watch(
self,
entrypoint: str,
project_root: Optional[str] = None,
source_maps: Optional[str] = None,
compression: Optional[str] = None,
) -> None:
"""
Continuously build an agent.
"""
...
__version__: str
-19
View File
@@ -1,19 +0,0 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if OS is Android based. */
#mesondefine HAVE_ANDROID
/* Define to 1 if OS is Darwin based. */
#mesondefine HAVE_DARWIN
/* Define to 1 if OS is iOS. */
#mesondefine HAVE_IOS
/* Define to 1 if OS is Linux based. */
#mesondefine HAVE_LINUX
/* Define to 1 if OS is macOS. */
#mesondefine HAVE_MACOS
/* Define to 1 if OS is QNX based. */
#mesondefine HAVE_QNX
Vendored Executable
+18
View File
@@ -0,0 +1,18 @@
#!/bin/sh
[ -z "$PYTHON" ] && PYTHON=$(which python3 >/dev/null && echo python3 || echo python)
cd $(dirname $0)
srcroot=$(pwd)
if [ ! -f releng/meson/meson.py ]; then
git submodule update --init --recursive --depth 1 || exit $?
fi
cd - >/dev/null
exec "$PYTHON" \
-c "import sys; sys.path.insert(0, sys.argv[1]); from releng.meson_configure import main; main()" \
"$srcroot" \
"$@"
+22
View File
@@ -0,0 +1,22 @@
@setlocal
@echo off
rem:: Based on: https://github.com/microsoft/terminal/issues/217#issuecomment-737594785
goto :_start_
:set_real_dp0
set dp0=%~dp0
set "dp0=%dp0:~0,-1%"
goto :eof
:_start_
call :set_real_dp0
if not exist "%dp0%\releng\meson\meson.py" (
pushd "%dp0%" & git submodule update --init --recursive --depth 1 & popd
if %errorlevel% neq 0 exit /b %errorlevel%
)
endlocal & goto #_undefined_# 2>nul || title %COMSPEC% & python ^
-c "import sys; sys.path.insert(0, sys.argv[1]); from releng.meson_configure import main; main()" ^
"%dp0%" ^
%*
+9
View File
@@ -0,0 +1,9 @@
import pprint
import frida
device = frida.get_usb_device()
deviceinfo = device.open_service("dtx:com.apple.instruments.server.services.deviceinfo")
response = deviceinfo.request({"method": "runningProcesses"})
pprint.pp(response)
+27
View File
@@ -0,0 +1,27 @@
import sys
import frida
def on_message(message):
print("on_message:", message)
device = frida.get_usb_device()
opengl = device.open_service("dtx:com.apple.instruments.server.services.graphics.opengl")
opengl.on("message", on_message)
opengl.request(
{
"method": "setSamplingRate:",
"args": [5.0],
}
)
opengl.request(
{
"method": "startSamplingAtTimeInterval:",
"args": [0.0],
}
)
sys.stdin.read()
@@ -0,0 +1,31 @@
import sys
import frida
def on_message(message):
print("on_message:", message)
device = frida.get_usb_device()
control = device.open_service("dtx:com.apple.instruments.server.services.processcontrol")
control.on("message", on_message)
pid = control.request(
{
"method": "launchSuspendedProcessWithDevicePath:bundleIdentifier:environment:arguments:options:",
"args": [
"",
"no.oleavr.HelloIOS",
{},
[],
{
"StartSuspendedKey": False,
},
],
}
)
control.request({"method": "startObservingPid:", "args": [pid]})
print(f"App spawned, PID: {pid}. Kill it to see an example message being emitted.")
sys.stdin.read()
+15
View File
@@ -0,0 +1,15 @@
import sys
import frida
if len(sys.argv) != 2:
print(f"Usage: {sys.argv[0]} outfile.png", file=sys.stderr)
sys.exit(1)
outfile = sys.argv[1]
device = frida.get_usb_device()
screenshot = device.open_service("dtx:com.apple.instruments.server.services.screenshot")
png = screenshot.request({"method": "takeScreenshot"})
with open(outfile, "wb") as f:
f.write(png)
+29
View File
@@ -0,0 +1,29 @@
import time
import frida
def on_message(message):
print("on_message:", message)
device = frida.get_usb_device()
sysmon = device.open_service("dtx:com.apple.instruments.server.services.sysmontap")
sysmon.on("message", on_message)
sysmon.request(
{
"method": "setConfig:",
"args": [
{
"ur": 1000,
"cpuUsage": True,
"sampleInterval": 1000000000,
},
],
}
)
sysmon.request({"method": "start"})
time.sleep(5)
sysmon.request({"method": "stop"})
time.sleep(1)
+7
View File
@@ -0,0 +1,7 @@
import frida
device = frida.get_usb_device()
diag = device.open_service("plist:com.apple.mobile.diagnostics_relay")
diag.request({"type": "query", "payload": {"Request": "Sleep", "WaitForDisconnect": True}})
diag.request({"type": "query", "payload": {"Request": "Goodbye"}})
@@ -0,0 +1,64 @@
import pprint
import sys
from threading import Thread
import frida
def main():
device = frida.get_usb_device()
stdout_uuid, stdout_stream = create_stdio_socket(device)
stderr_uuid, stderr_stream = create_stdio_socket(device)
appservice = device.open_service("xpc:com.apple.coredevice.appservice")
response = appservice.request(
{
"CoreDevice.featureIdentifier": "com.apple.coredevice.feature.launchapplication",
"CoreDevice.action": {},
"CoreDevice.input": {
"applicationSpecifier": {
"bundleIdentifier": {"_0": "no.oleavr.HelloIOS"},
},
"options": {
"arguments": [],
"environmentVariables": {},
"standardIOUsesPseudoterminals": True,
"startStopped": False,
"terminateExisting": True,
"user": {"active": True},
"platformSpecificOptions": b'<?xml version="1.0" encoding="UTF-8"?><plist version="1.0"><dict/></plist>',
},
"standardIOIdentifiers": {
"standardOutput": ("uuid", stdout_uuid),
"standardError": ("uuid", stderr_uuid),
},
},
}
)
pprint.pp(response)
workers = set()
for stream, sink in {(stdout_stream, sys.stdout), (stderr_stream, sys.stderr)}:
t = Thread(target=process_console_output, args=(stream, sink))
t.start()
workers.add(t)
for worker in workers:
worker.join()
def create_stdio_socket(device):
stream = device.open_channel("tcp:com.apple.coredevice.openstdiosocket")
return (stream.read_all(16), stream)
def process_console_output(stream, sink):
while True:
chunk = stream.read(4096)
if not chunk:
break
sink.write(chunk.decode("utf-8"))
if __name__ == "__main__":
main()
@@ -0,0 +1,15 @@
import pprint
import frida
device = frida.get_usb_device()
appservice = device.open_service("xpc:com.apple.coredevice.appservice")
response = appservice.request(
{
"CoreDevice.featureIdentifier": "com.apple.coredevice.feature.listprocesses",
"CoreDevice.action": {},
"CoreDevice.input": {},
}
)
pprint.pp(response)
-176
View File
@@ -1,176 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{7505F884-DD69-4F23-ADE6-1E0E049AB018}</ProjectGuid>
<RootNamespace>frida</RootNamespace>
<Keyword>Win32Proj</Keyword>
<ProjectName>frida-python</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(SolutionDir)releng\frida-toolchain.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(SolutionDir)releng\frida-$(Configuration).props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(SolutionDir)releng\frida-$(Configuration).props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(SolutionDir)releng\frida-$(Configuration).props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(SolutionDir)releng\frida-$(Configuration).props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)build\frida-windows\$(PlatformName)-$(Configuration)\lib\python3.10\site-packages\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)build\frida-windows\$(PlatformName)-$(Configuration)\lib\python3.10\site-packages\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)build\frida-windows\$(PlatformName)-$(Configuration)\lib\python3.10\site-packages\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)build\frida-windows\$(PlatformName)-$(Configuration)\lib\python3.10\site-packages\</OutDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_frida</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_frida</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_frida</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_frida</TargetName>
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.pyd</TargetExt>
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.pyd</TargetExt>
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.pyd</TargetExt>
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.pyd</TargetExt>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Link>
<SubSystem>Windows</SubSystem>
<AdditionalLibraryDirectories>$(PythonLocation)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<ClCompile>
<AdditionalIncludeDirectories>$(IntDir)..\frida-core\api;$(PythonLocation)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>$(FridaComponentDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Link>
<SubSystem>Windows</SubSystem>
<AdditionalLibraryDirectories>$(PythonLocation)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<ClCompile>
<AdditionalIncludeDirectories>$(IntDir)..\frida-core\api;$(PythonLocation)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>$(FridaComponentDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Link>
<SubSystem>Windows</SubSystem>
<AdditionalLibraryDirectories>$(PythonLocation)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<ClCompile>
<AdditionalIncludeDirectories>$(IntDir)..\frida-core\api;$(PythonLocation)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>$(FridaComponentDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Link>
<SubSystem>Windows</SubSystem>
<AdditionalLibraryDirectories>$(PythonLocation)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<ClCompile>
<AdditionalIncludeDirectories>$(IntDir)..\frida-core\api;$(PythonLocation)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>$(FridaComponentDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectReference Include="..\frida-core\frida-core.vcxproj">
<Project>{b7dc9b02-a5ff-4aa1-b2a2-dc1653168d44}</Project>
<Private>false</Private>
<ReferenceOutputAssembly>true</ReferenceOutputAssembly>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
<LinkLibraryDependencies>true</LinkLibraryDependencies>
<UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\_frida.c" />
</ItemGroup>
<ItemGroup>
<CustomBuild Include="frida\__init__.py">
<FileType>Document</FileType>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Installing frida package</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Installing frida package</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Installing frida package</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Installing frida package</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">rmdir /S /Q $(OutDir)frida 2&gt;NUL
mkdir $(OutDir)frida || exit 1
copy /B /Y "$(ProjectDir)frida\*.py" $(OutDir)frida || exit 1
echo. &gt; $(IntDir)frida-package.stamp</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)frida-package.stamp</Outputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)frida\core.py</AdditionalInputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">rmdir /S /Q $(OutDir)frida 2&gt;NUL
mkdir $(OutDir)frida || exit 1
copy /B /Y "$(ProjectDir)frida\*.py" $(OutDir)frida || exit 1
echo. &gt; $(IntDir)frida-package.stamp</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)frida-package.stamp</Outputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)frida\core.py</AdditionalInputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">rmdir /S /Q $(OutDir)frida 2&gt;NUL
mkdir $(OutDir)frida || exit 1
copy /B /Y "$(ProjectDir)frida\*.py" $(OutDir)frida || exit 1
echo. &gt; $(IntDir)frida-package.stamp</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)frida-package.stamp</Outputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)frida\core.py</AdditionalInputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">rmdir /S /Q $(OutDir)frida 2&gt;NUL
mkdir $(OutDir)frida || exit 1
copy /B /Y "$(ProjectDir)frida\*.py" $(OutDir)frida || exit 1
echo. &gt; $(IntDir)frida-package.stamp</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)frida-package.stamp</Outputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)frida\core.py</AdditionalInputs>
</CustomBuild>
<None Include="frida\core.py" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
-35
View File
@@ -1,35 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Source Files\frida">
<UniqueIdentifier>{e8366f87-de40-4415-8724-a51c48fc532d}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\_frida.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="frida\core.py">
<Filter>Source Files\frida</Filter>
</None>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="frida\__init__.py">
<Filter>Source Files\frida</Filter>
</CustomBuild>
</ItemGroup>
</Project>
-172
View File
@@ -1,172 +0,0 @@
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
try:
import _frida
except Exception as ex:
print("")
print("***")
if str(ex).startswith("No module named "):
print("Frida native extension not found")
print("Please check your PYTHONPATH.")
else:
print(f"Failed to load the Frida native extension: {ex}")
print("Please ensure that the extension was compiled correctly")
print("***")
print("")
raise ex
from . import core
__version__: str = _frida.__version__
get_device_manager = core.get_device_manager
Relay = _frida.Relay
PortalService = core.PortalService
EndpointParameters = core.EndpointParameters
Compiler = core.Compiler
FileMonitor = _frida.FileMonitor
Cancellable = core.Cancellable
ServerNotRunningError = _frida.ServerNotRunningError
ExecutableNotFoundError = _frida.ExecutableNotFoundError
ExecutableNotSupportedError = _frida.ExecutableNotSupportedError
ProcessNotFoundError = _frida.ProcessNotFoundError
ProcessNotRespondingError = _frida.ProcessNotRespondingError
InvalidArgumentError = _frida.InvalidArgumentError
InvalidOperationError = _frida.InvalidOperationError
PermissionDeniedError = _frida.PermissionDeniedError
AddressInUseError = _frida.AddressInUseError
TimedOutError = _frida.TimedOutError
NotSupportedError = _frida.NotSupportedError
ProtocolError = _frida.ProtocolError
TransportError = _frida.TransportError
OperationCancelledError = _frida.OperationCancelledError
def query_system_parameters() -> Dict[str, Any]:
"""
Returns a dictionary of information about the host system
"""
return get_local_device().query_system_parameters()
def spawn(
program: Union[str, List[Union[str, bytes]], Tuple[Union[str, bytes]]],
argv: Union[None, List[Union[str, bytes]], Tuple[Union[str, bytes]]] = None,
envp: Optional[Dict[str, str]] = None,
env: Optional[Dict[str, str]] = None,
cwd: Optional[str] = None,
stdio: Optional[str] = None,
**kwargs: Any,
) -> int:
"""
Spawn a process into an attachable state
"""
return get_local_device().spawn(program=program, argv=argv, envp=envp, env=env, cwd=cwd, stdio=stdio, **kwargs)
def resume(target: core.ProcessTarget) -> None:
"""
Resume a process from the attachable state
:param target: the PID or name of the process
"""
get_local_device().resume(target)
def kill(target: core.ProcessTarget) -> None:
"""
Kill a process
:param target: the PID or name of the process
"""
get_local_device().kill(target)
def attach(
target: core.ProcessTarget, realm: Optional[str] = None, persist_timeout: Optional[int] = None
) -> core.Session:
"""
Attach to a process
:param target: the PID or name of the process
"""
return get_local_device().attach(target, realm=realm, persist_timeout=persist_timeout)
def inject_library_file(target: core.ProcessTarget, path: str, entrypoint: str, data: str) -> int:
"""
Inject a library file to a process.
:param target: the PID or name of the process
"""
return get_local_device().inject_library_file(target, path, entrypoint, data)
def inject_library_blob(target: core.ProcessTarget, blob: bytes, entrypoint: str, data: str) -> int:
"""
Inject a library blob to a process
:param target: the PID or name of the process
"""
return get_local_device().inject_library_blob(target, blob, entrypoint, data)
def get_local_device() -> core.Device:
"""
Get the local device
"""
return get_device_manager().get_local_device()
def get_remote_device() -> core.Device:
"""
Get the first remote device in the devices list
"""
return get_device_manager().get_remote_device()
def get_usb_device(timeout: int = 0) -> core.Device:
"""
Get the first device connected over USB in the devices list
"""
return get_device_manager().get_usb_device(timeout)
def get_device(id: Optional[str], timeout: int = 0) -> core.Device:
"""
Get a device by its id
"""
return get_device_manager().get_device(id, timeout)
def get_device_matching(predicate: Callable[[core.Device], bool], timeout: int = 0) -> core.Device:
"""
Get device matching predicate.
:param predicate: a function to filter the devices
:param timeout: operation timeout in seconds
"""
return get_device_manager().get_device_matching(predicate, timeout)
def enumerate_devices() -> List[core.Device]:
"""
Enumerate all the devices from the device manager
"""
return get_device_manager().enumerate_devices()
@core.cancellable
def shutdown() -> None:
"""
Shutdown the main device manager
"""
get_device_manager()._impl.close()
-1722
View File
File diff suppressed because it is too large Load Diff
+4
View File
@@ -0,0 +1,4 @@
from .cli import main
if __name__ == "__main__":
main()
@@ -0,0 +1 @@
static GHashTable * pygobject_type_spec_by_type;
@@ -0,0 +1,77 @@
static void
PyGObject_class_init (void)
{
pygobject_type_spec_by_type = g_hash_table_new_full (NULL, NULL, NULL, NULL);
}
static int
PyGObject_init (PyGObject * self)
{
self->handle = NULL;
self->type = PYFRIDA_TYPE (GObject);
self->signal_closures = NULL;
return 0;
}
static void
PyGObject_dealloc (PyGObject * self)
{
gpointer handle;
handle = PyGObject_steal_handle (self);
if (handle != NULL)
{
Py_BEGIN_ALLOW_THREADS
self->type->destroy (handle);
Py_END_ALLOW_THREADS
}
((freefunc) PyType_GetSlot (Py_TYPE (self), Py_tp_free)) (self);
}
static void
PyGObject_take_handle (PyGObject * self,
gpointer handle,
const PyGObjectType * type)
{
self->handle = handle;
self->type = type;
if (handle != NULL)
g_object_set_data (G_OBJECT (handle), "pyobject", self);
}
static gpointer
PyGObject_steal_handle (PyGObject * self)
{
gpointer handle = self->handle;
GSList * entry;
if (handle == NULL)
return NULL;
for (entry = self->signal_closures; entry != NULL; entry = entry->next)
{
PyGObjectSignalClosure * closure = entry->data;
G_GNUC_UNUSED guint num_matches;
num_matches = g_signal_handlers_disconnect_matched (handle, G_SIGNAL_MATCH_CLOSURE, closure->signal_id, 0, &closure->parent, NULL, NULL);
g_assert (num_matches == 1);
}
g_clear_pointer (&self->signal_closures, g_slist_free);
g_object_set_data (G_OBJECT (handle), "pyobject", NULL);
self->handle = NULL;
return handle;
}
static void
PyGObject_register_type (GType instance_type,
PyGObjectType * python_type)
{
g_hash_table_insert (pygobject_type_spec_by_type, GSIZE_TO_POINTER (instance_type), python_type);
}
@@ -0,0 +1,5 @@
static void PyGObject_class_init (void);
static int PyGObject_init (PyGObject * self);
static void PyGObject_dealloc (PyGObject * self);
static gpointer PyGObject_steal_handle (PyGObject * self);
static void PyGObject_register_type (GType instance_type, PyGObjectType * python_type);
@@ -0,0 +1,100 @@
type SignalTransformer<
Source extends SignalHandler,
Target extends SignalHandler
> = (...args: Parameters<Source>) => Parameters<Target>;
type SignalInterceptor<H extends SignalHandler> = (...args: Parameters<H>) => boolean;
interface SignalWrapperOptionsNoTransform<H extends SignalHandler> {
transform?: undefined;
intercept?: SignalInterceptor<H>;
}
interface SignalWrapperOptionsTransform<
Source extends SignalHandler,
Target extends SignalHandler
> {
transform: SignalTransformer<Source, Target>;
intercept?: SignalInterceptor<Target>;
}
type SignalWrapperOptions<
Source extends SignalHandler,
Target extends SignalHandler
> =
| SignalWrapperOptionsNoTransform<Source & Target>
| SignalWrapperOptionsTransform<Source, Target>;
class SignalWrapper<
SourceHandler extends SignalHandler,
TargetHandler extends SignalHandler
> {
#source: Signal<SourceHandler>;
#transform?: SignalTransformer<SourceHandler, TargetHandler>;
#intercept?: SignalInterceptor<any>;
#handlers = new Set<TargetHandler>();
constructor(
source: Signal<SourceHandler>,
options?: SignalWrapperOptions<SourceHandler, TargetHandler>
) {
this.#source = source;
if (options === undefined || options.transform === undefined) {
this.#intercept = options?.intercept;
} else {
this.#transform = options.transform;
this.#intercept = options.intercept;
}
}
connect(handler: TargetHandler): void {
this.#handlers.add(handler);
if (this.#handlers.size === 1) {
this.#source.connect(this.#wrappedHandler);
}
}
disconnect(handler: TargetHandler): void {
this.#handlers.delete(handler);
if (this.#handlers.size === 0) {
this.#source.disconnect(this.#wrappedHandler);
}
}
#wrappedHandler = ((...sourceArgs: Parameters<SourceHandler>) => {
let targetArgs: Parameters<TargetHandler>;
const transform = this.#transform;
if (transform === undefined) {
targetArgs = sourceArgs as unknown as Parameters<TargetHandler>;
} else {
targetArgs = transform(...sourceArgs);
}
const intercept = this.#intercept;
if (intercept !== undefined) {
if (!intercept(...targetArgs)) {
return;
}
}
for (const handler of this.#handlers) {
handler(...targetArgs);
}
}) as SourceHandler;
}
function inspectWrapper(object: any, name: string, properties: string[], depth: number, options: util.InspectOptionsStylized): string {
if (depth < 0) {
return options.stylize(`[${name}]`, "special");
}
const summary = Object.fromEntries(properties.map(name => [name, object[name]]));
const nextOptions = Object.assign({}, options, {
depth: (options.depth === null) ? null : depth - 1
});
return name + " " + inspect(summary, nextOptions);
}
@@ -0,0 +1,60 @@
#define PYFRIDA_TYPE(name) \
(&_PYFRIDA_TYPE_VAR (name, type))
#define PYFRIDA_TYPE_OBJECT(name) \
PYFRIDA_TYPE (name)->object
#define _PYFRIDA_TYPE_VAR(name, var) \
G_PASTE (G_PASTE (G_PASTE (Py, name), _), var)
#define PYFRIDA_DEFINE_BASETYPE(pyname, cname, ...) \
_PYFRIDA_DEFINE_TYPE_SLOTS (cname, __VA_ARGS__); \
_PYFRIDA_DEFINE_TYPE_SPEC (cname, pyname, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE); \
static PyGObjectType _PYFRIDA_TYPE_VAR (cname, type) = \
{ \
.parent = NULL, \
.object = NULL, \
}
#define PYFRIDA_DEFINE_TYPE(pyname, cname, parent_cname, ...) \
_PYFRIDA_DEFINE_TYPE_SLOTS (cname, __VA_ARGS__); \
_PYFRIDA_DEFINE_TYPE_SPEC (cname, pyname, Py_TPFLAGS_DEFAULT); \
static PyGObjectType _PYFRIDA_TYPE_VAR (cname, type) = \
{ \
.parent = PYFRIDA_TYPE (parent_cname), \
.object = NULL, \
}
#define PYFRIDA_REGISTER_TYPE(cname, gtype) \
G_BEGIN_DECLS \
{ \
PyGObjectType * t = PYFRIDA_TYPE (cname); \
t->object = PyType_FromSpecWithBases (&_PYFRIDA_TYPE_VAR (cname, spec), \
(t->parent != NULL) ? PyTuple_Pack (1, t->parent->object) : NULL); \
PyGObject_register_type (gtype, t); \
Py_IncRef (t->object); \
PyModule_AddObject (module, G_STRINGIFY (cname), t->object); \
} \
G_END_DECLS
#define _PYFRIDA_DEFINE_TYPE_SPEC(cname, pyname, type_flags) \
static PyType_Spec _PYFRIDA_TYPE_VAR (cname, spec) = \
{ \
.name = pyname, \
.basicsize = sizeof (G_PASTE (Py, cname)), \
.itemsize = 0, \
.flags = type_flags, \
.slots = _PYFRIDA_TYPE_VAR (cname, slots), \
}
#define _PYFRIDA_DEFINE_TYPE_SLOTS(cname, ...) \
static PyType_Slot _PYFRIDA_TYPE_VAR (cname, slots)[] = \
{ \
__VA_ARGS__ \
{ 0 }, \
}
#define PY_GOBJECT(o) ((PyGObject *) (o))
#define PY_GOBJECT_HANDLE(o) (PY_GOBJECT (o)->handle)
#define PY_GOBJECT_SIGNAL_CLOSURE(o) ((PyGObjectSignalClosure *) (o))
#define PyFrida_RETURN_NONE \
G_STMT_START \
{ \
Py_IncRef (Py_None); \
return Py_None; \
} \
G_STMT_END
@@ -0,0 +1,78 @@
G_GNUC_UNUSED static gboolean fdn_is_null (napi_env env, napi_value value);
static gboolean fdn_is_undefined_or_null (napi_env env, napi_value value);
static gboolean fdn_is_function (napi_env env, napi_value value);
static gboolean fdn_boolean_from_value (napi_env env, napi_value value, gboolean * b);
static napi_value fdn_boolean_to_value (napi_env env, gboolean b);
static gboolean fdn_size_from_value (napi_env env, napi_value value, gsize * s);
static napi_value fdn_size_to_value (napi_env env, gsize s);
static napi_value fdn_ssize_to_value (napi_env env, gssize s);
static gboolean fdn_int_from_value (napi_env env, napi_value value, gint * i);
static napi_value fdn_int_to_value (napi_env env, gint i);
static gboolean fdn_uint_from_value (napi_env env, napi_value value, guint * u);
static napi_value fdn_uint_to_value (napi_env env, guint u);
static gboolean fdn_uint16_from_value (napi_env env, napi_value value, guint16 * u);
static napi_value fdn_uint16_to_value (napi_env env, guint16 u);
static napi_value fdn_uint32_to_value (napi_env env, guint32 u);
static gboolean fdn_int64_from_value (napi_env env, napi_value value, gint64 * i);
static napi_value fdn_int64_to_value (napi_env env, gint64 i);
static napi_value fdn_uint64_to_value (napi_env env, guint64 u);
static gboolean fdn_ulong_from_value (napi_env env, napi_value value, gulong * u);
static gboolean fdn_double_from_value (napi_env env, napi_value value, gdouble * d);
static napi_value fdn_double_to_value (napi_env env, gdouble d);
static gboolean fdn_enum_from_value (napi_env env, GType enum_type, napi_value value, gint * e);
static napi_value fdn_enum_to_value (napi_env env, GType enum_type, gint e);
static gboolean fdn_utf8_from_value (napi_env env, napi_value value, gchar ** str);
static napi_value fdn_utf8_to_value (napi_env env, const gchar * str);
static gboolean fdn_strv_from_value (napi_env env, napi_value value, gchar *** strv);
static napi_value fdn_strv_to_value (napi_env env, gchar ** strv);
static napi_value fdn_buffer_to_value (napi_env env, const guint8 * data, gsize size);
static gboolean fdn_bytes_from_value (napi_env env, napi_value value, GBytes ** bytes);
static napi_value fdn_bytes_to_value (napi_env env, GBytes * bytes);
static gboolean fdn_vardict_from_value (napi_env env, napi_value value, GHashTable ** vardict);
static napi_value fdn_vardict_to_value (napi_env env, GHashTable * vardict);
static gboolean fdn_variant_from_value (napi_env env, napi_value value, GVariant ** variant);
static napi_value fdn_variant_to_value (napi_env env, GVariant * variant);
static gboolean fdn_gvalue_from_value (napi_env env, GType type, napi_value js_value, GValue * value);
static napi_value fdn_gvalue_to_value (napi_env env, GValue * value);
static gboolean fdn_error_from_value (napi_env env, napi_value value, GError ** error);
static napi_value fdn_error_to_value (napi_env env, GError * error);
static gboolean fdn_file_from_value (napi_env env, napi_value value, GFile ** file);
static napi_value fdn_file_to_value (napi_env env, GFile * file);
static gboolean fdn_tls_certificate_from_value (napi_env env, napi_value value, GTlsCertificate ** certificate);
static napi_value fdn_tls_certificate_to_value (napi_env env, GTlsCertificate * certificate);
static gboolean fdn_options_from_value (napi_env env, GType object_type, napi_value value, gpointer * options);
static napi_value fdn_object_subclass_to_value (napi_env env, GObject * object);
static napi_value fdn_object_new (napi_env env, GObject * handle, napi_ref constructor);
static gboolean fdn_object_wrap (napi_env env, napi_value wrapper, GObject * handle, napi_finalize finalizer);
static gboolean fdn_object_unwrap (napi_env env, napi_value wrapper, GType expected_type, GObject ** handle);
static void fdn_object_finalize (napi_env env, void * finalize_data, void * finalize_hint);
static napi_value fdn_object_get_signal (napi_env env, napi_callback_info info, const gchar * name, const gchar * js_storage_name, FdnSignalBehavior behavior);
static napi_value fdn_signal_new (napi_env env, GObject * handle, const gchar * name, FdnSignalBehavior behavior);
static void fdn_signal_register (napi_env env, napi_value exports);
static napi_value fdn_signal_construct (napi_env env, napi_callback_info info);
static void fdn_signal_finalize (napi_env env, void * finalize_data, void * finalize_hint);
static napi_value fdn_signal_connect (napi_env env, napi_callback_info info);
static napi_value fdn_signal_disconnect (napi_env env, napi_callback_info info);
static void fdn_signal_disconnect_closure (FdnSignal * self, FdnSignalClosure * closure);
static gboolean fdn_signal_parse_arguments (napi_env env, napi_callback_info info, FdnSignal ** self, napi_value * js_self, napi_value * handler);
static FdnSignalClosure * fdn_signal_closure_new (napi_env env, FdnSignal * sig, napi_value js_sig, napi_value handler);
static void fdn_signal_closure_finalize (gpointer data, GClosure * closure);
static void fdn_signal_closure_marshal (GClosure * closure, GValue * return_gvalue, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data);
static void fdn_signal_closure_deliver (napi_env env, napi_value js_cb, void * context, void * data);
static void fdn_keep_alive_until (napi_env env, napi_value js_object, GObject * handle, FdnIsDestroyedFunc is_destroyed, const gchar * destroy_signal_name);
static void fdn_keep_alive_on_finalize (napi_env env, void * finalize_data, void * finalize_hint);
static void fdn_keep_alive_on_destroy_signal (GObject * handle, gpointer user_data);
static void fdn_keep_alive_on_destroy_signal_handler_detached (gpointer data, GClosure * closure);
static void fdn_keep_alive_schedule_cleanup (FdnKeepAliveContext * context);
static void fdn_keep_alive_on_tsfn_invoke (napi_env env, napi_value js_cb, void * context, void * data);
static void fdn_inherit_val_val (napi_env env, napi_value sub_ctor, napi_value super_ctor, napi_value object_ctor, napi_value set_proto);
G_GNUC_UNUSED static void fdn_inherit_val_ref (napi_env env, napi_value sub_ctor, napi_ref super_ctor, napi_value object_ctor, napi_value set_proto);
static void fdn_inherit_ref_val (napi_env env, napi_ref sub_ctor, napi_value super_ctor, napi_value object_ctor, napi_value set_proto);
static void fdn_inherit_ref_ref (napi_env env, napi_ref sub_ctor, napi_ref super_ctor, napi_value object_ctor, napi_value set_proto);
static gchar * fdn_camel_case_to_kebab_case (const gchar * name);
@@ -0,0 +1,24 @@
struct _PyGObject
{
PyObject_HEAD
gpointer handle;
const PyGObjectType * type;
GSList * signal_closures;
};
struct _PyGObjectType
{
PyGObjectType * parent;
PyObject * object;
PyGObjectInitFromHandleFunc init_from_handle;
GDestroyNotify destroy;
};
struct _PyGObjectSignalClosure
{
GClosure parent;
guint signal_id;
guint max_arg_count;
};
@@ -0,0 +1,4 @@
typedef struct _PyGObject PyGObject;
typedef void (* PyGObjectInitFromHandleFunc) (PyObject * self, gpointer handle);
typedef struct _PyGObjectType PyGObjectType;
typedef struct _PyGObjectSignalClosure PyGObjectSignalClosure;
@@ -0,0 +1,13 @@
querySystemParameters
spawn
resume
kill
attach
injectLibraryFile
injectLibraryBlob
enumerateDevices
getDeviceManager
getLocalDevice
getRemoteDevice
getUsbDevice
getDevice
@@ -0,0 +1,157 @@
let sharedDeviceManager: DeviceManager | null = null;
export async function querySystemParameters(cancellable?: Cancellable | null): Promise<SystemParameters> {
const device = await getLocalDevice(cancellable);
return await device.querySystemParameters(cancellable);
}
export async function spawn(program: string | string[], options?: SpawnOptions, cancellable?: Cancellable | null): Promise<number> {
const device = await getLocalDevice(cancellable);
return await device.spawn(program, options, cancellable);
}
export async function resume(target: TargetProcess, cancellable?: Cancellable | null): Promise<void> {
const device = await getLocalDevice(cancellable);
await device.resume(target, cancellable);
}
export async function kill(target: TargetProcess, cancellable?: Cancellable | null): Promise<void> {
const device = await getLocalDevice(cancellable);
await device.kill(target, cancellable);
}
export async function attach(target: TargetProcess, options?: SessionOptions, cancellable?: Cancellable | null): Promise<Session> {
const device = await getLocalDevice(cancellable);
return await device.attach(target, options, cancellable);
}
export async function injectLibraryFile(target: TargetProcess, path: string, entrypoint: string, data: string,
cancellable?: Cancellable | null): Promise<number> {
const device = await getLocalDevice(cancellable);
return await device.injectLibraryFile(target, path, entrypoint, data, cancellable);
}
export async function injectLibraryBlob(target: TargetProcess, blob: Buffer, entrypoint: string, data: string,
cancellable?: Cancellable | null): Promise<number> {
const device = await getLocalDevice(cancellable);
return await device.injectLibraryBlob(target, blob, entrypoint, data, cancellable);
}
export async function enumerateDevices(cancellable?: Cancellable | null): Promise<Device[]> {
const deviceManager = getDeviceManager();
return await deviceManager.enumerateDevices(cancellable);
};
export function getDeviceManager(): DeviceManager {
if (sharedDeviceManager === null) {
sharedDeviceManager = new DeviceManager();
}
return sharedDeviceManager;
}
export function getLocalDevice(cancellable?: Cancellable | null): Promise<Device> {
return getMatchingDevice(device => device.type === DeviceType.Local, {}, cancellable);
}
export function getRemoteDevice(cancellable?: Cancellable | null): Promise<Device> {
return getMatchingDevice(device => device.type === DeviceType.Remote, {}, cancellable);
}
export function getUsbDevice(options?: GetDeviceOptions, cancellable?: Cancellable | null): Promise<Device> {
return getMatchingDevice(device => device.type === DeviceType.Usb, options, cancellable);
}
export function getDevice(id: string, options?: GetDeviceOptions, cancellable?: Cancellable | null): Promise<Device> {
return getMatchingDevice(device => device.id === id, options, cancellable);
}
export interface GetDeviceOptions {
timeout?: number | null;
}
async function getMatchingDevice(predicate: DevicePredicate, options: GetDeviceOptions = {}, cancellable: Cancellable | null = null): Promise<Device> {
const device = await findMatchingDevice(predicate, cancellable);
if (device !== null) {
return device;
}
const { timeout = 0 } = options;
if (timeout === 0) {
throw new Error("Device not found");
}
const getDeviceEventually = new Promise((resolve: (device: Device) => void, reject: (error: Error) => void) => {
const deviceManager = getDeviceManager();
deviceManager.added.connect(onDeviceAdded);
const timer = (timeout !== null) ? setTimeout(onTimeout, timeout) : null;
if (cancellable !== null) {
cancellable.cancelled.connect(onCancel);
if (cancellable.isCancelled) {
onCancel();
return;
}
}
findMatchingDevice(predicate, cancellable)
.then(device => {
if (device !== null) {
onSuccess(device);
}
})
.catch(onError);
function onDeviceAdded(device: Device): void {
if (predicate(device)) {
onSuccess(device);
}
}
function onSuccess(device: Device): void {
stopMonitoring();
resolve(device);
}
function onError(error: Error): void {
stopMonitoring();
reject(error);
}
function onTimeout(): void {
onError(new Error("Timed out while waiting for device to appear"));
}
function onCancel(): void {
onError(new Error("Operation was cancelled"));
}
function stopMonitoring(): void {
cancellable?.cancelled.disconnect(onCancel);
if (timer !== null) {
clearTimeout(timer);
}
deviceManager.added.disconnect(onDeviceAdded);
}
});
return await getDeviceEventually;
}
async function findMatchingDevice(predicate: DevicePredicate, cancellable?: Cancellable | null): Promise<Device | null> {
const deviceManager = getDeviceManager();
const devices = await deviceManager.enumerateDevices(cancellable);
const matching = devices.filter(predicate);
if (matching.length === 0) {
return null;
}
return matching[0];
}
type DevicePredicate = (device: Device) => boolean;
@@ -0,0 +1,2 @@
import { Minimatch } from "minimatch";
import { Duplex } from "stream";
@@ -0,0 +1,396 @@
const STANDARD_SPAWN_OPTION_NAMES = new Set<keyof SpawnOptions>([
"argv",
"envp",
"env",
"cwd",
"stdio",
]);
interface LogMessage {
type: "log";
level: LogLevel;
payload: string;
}
class ScriptServices implements RpcController {
exportsProxy = new ScriptExportsProxy(this);
#script: Script;
#pendingRequests = new Map<number, (error: Error | null, result?: any) => void>();
#nextRequestId = 1;
constructor(script: Script) {
this.#script = script;
process.nextTick(() => {
script.message.connect(() => {});
});
}
handleMessageIntercept = (message: Message, data: Buffer | null): boolean => {
if (message.type === MessageType.Send && isRpcSendMessage(message)) {
const [ , id, operation, ...params ] = message.payload;
this.#onRpcMessage(id, operation, params, data);
return false;
} else if (isLogMessage(message)) {
const opaqueMessage: any = message;
const logMessage: LogMessage = opaqueMessage;
this.#script.logHandler(logMessage.level, logMessage.payload);
return false;
}
return true;
};
request(operation: string, params: any[], data: Buffer | null, cancellable: Cancellable | null = null): Promise<any> {
return new Promise((resolve, reject) => {
const id = this.#nextRequestId++;
const complete = (error: Error | null, result?: any): void => {
if (cancellable !== null) {
cancellable.cancelled.disconnect(onOperationCancelled);
}
this.#script.destroyed.disconnect(onScriptDestroyed);
this.#pendingRequests.delete(id);
if (error === null) {
resolve(result);
} else {
reject(error);
}
};
function onScriptDestroyed(): void {
complete(new Error("Script is destroyed"));
}
function onOperationCancelled(): void {
complete(new Error("Operation was cancelled"));
}
this.#pendingRequests.set(id, complete);
this.#script.post(["frida:rpc", id, operation, ...params], data);
this.#script.destroyed.connect(onScriptDestroyed);
if (cancellable !== null) {
cancellable.cancelled.connect(onOperationCancelled);
if (cancellable.isCancelled) {
onOperationCancelled();
return;
}
}
if (this.#script.isDestroyed) {
onScriptDestroyed();
}
});
}
#onRpcMessage(id: number, operation: RpcOperation, params: any[], data: Buffer | null) {
if (operation === RpcOperation.Ok || operation === RpcOperation.Error) {
const callback = this.#pendingRequests.get(id);
if (callback === undefined) {
return;
}
let value = null;
let error = null;
if (operation === RpcOperation.Ok) {
if (data !== null) {
value = (params.length > 1) ? [params[1], data] : data;
} else {
value = params[0];
}
} else {
const [message, name, stack, rawErr] = params;
error = new Error(message);
error.name = name;
error.stack = stack;
Object.assign(error, rawErr);
}
callback(error, value);
}
}
}
class ScriptExportsProxy implements ScriptExports {
[name: string]: (...args: any[]) => Promise<any>;
constructor(rpcController: RpcController) {
return new Proxy(this, {
has(target, property) {
return !isReservedMethodName(property);
},
get(target, property, receiver) {
if (typeof property === "symbol") {
if (property === inspect.custom) {
return inspectProxy;
}
return undefined;
}
if (property in target) {
return target[property];
}
if (isReservedMethodName(property)) {
return undefined;
}
return (...args: any[]): Promise<any> => {
let cancellable: Cancellable | null = null;
if (args[args.length - 1] instanceof Cancellable) {
cancellable = args.pop();
}
let data: Buffer | null = null;
if (Buffer.isBuffer(args[args.length - 1])) {
data = args.pop();
}
return rpcController.request("call", [property, args], data, cancellable);
};
},
set(target, property, value, receiver) {
if (typeof property === "symbol") {
return false;
}
target[property] = value;
return true;
},
ownKeys(target) {
return Object.getOwnPropertyNames(target);
},
getOwnPropertyDescriptor(target, property) {
if (property in target) {
return Object.getOwnPropertyDescriptor(target, property);
}
if (isReservedMethodName(property)) {
return undefined;
}
return {
writable: true,
configurable: true,
enumerable: true
};
},
});
}
}
function inspectProxy() {
return "ScriptExportsProxy {}";
}
interface RpcController {
request(operation: string, params: any[], data: ArrayBuffer | null, cancellable: Cancellable | null): Promise<any>;
}
enum RpcOperation {
Ok = "ok",
Error = "error"
}
function isInternalMessage(message: Message): boolean {
return isRpcMessage(message) || isLogMessage(message);
}
function isRpcMessage(message: Message): boolean {
return message.type === MessageType.Send && isRpcSendMessage(message);
}
function isRpcSendMessage(message: SendMessage): boolean {
const payload = message.payload;
if (!Array.isArray(payload)) {
return false;
}
return payload[0] === "frida:rpc";
}
function isLogMessage(message: Message): boolean {
return message.type as string === "log";
}
function log(level: LogLevel, text: string): void {
switch (level) {
case LogLevel.Info:
console.log(text);
break;
case LogLevel.Warning:
console.warn(text);
break;
case LogLevel.Error:
console.error(text);
break;
}
}
const reservedMethodNames = new Set<string>([
"then",
"catch",
"finally",
]);
function isReservedMethodName(name: string | number | symbol): boolean {
return reservedMethodNames.has(name.toString());
}
const IO_PRIORITY_DEFAULT = 0;
class IOStreamAdapter extends Duplex {
#impl: IOStream;
#input: InputStream;
#output: OutputStream;
#pending = new Set<Promise<void>>();
#cancellable = new Cancellable();
constructor(impl: IOStream) {
super({});
this.#impl = impl;
this.#input = impl.inputStream;
this.#output = impl.outputStream;
}
async _destroy(error: Error | null, callback: (error: Error | null) => void): Promise<void> {
this.#cancellable.cancel();
for (const operation of this.#pending) {
try {
await operation;
} catch (e) {
}
}
try {
await this.#impl.close(IO_PRIORITY_DEFAULT);
} catch (e) {
}
callback(error);
}
_read(size: number): void {
const operation = this.#input.read(size, IO_PRIORITY_DEFAULT, this.#cancellable)
.then((data: Buffer): void => {
const isEof = data.length === 0;
if (isEof) {
this.push(null);
return;
}
this.push(data);
})
.catch((error: Error): void => {
if (this.#impl.closed) {
this.push(null);
}
this.emit("error", error);
});
this.#track(operation);
}
_write(chunk: any, encoding: BufferEncoding, callback: (error?: Error | null) => void): void {
let data: Buffer;
if (Buffer.isBuffer(chunk)) {
data = chunk;
} else {
data = Buffer.from(chunk, encoding);
}
const operation = this.#writeAll(data)
.then((): void => {
callback(null);
})
.catch((error: Error): void => {
callback(error);
});
this.#track(operation);
}
async #writeAll(data: Buffer): Promise<void> {
let offset = 0;
do {
const n = await this.#output.write(data.slice(offset), IO_PRIORITY_DEFAULT, this.#cancellable);
offset += n;
} while (offset !== data.length);
}
#track(operation: Promise<void>): void {
this.#pending.add(operation);
operation
.catch(_ => {})
.finally(() => {
this.#pending.delete(operation);
});
}
}
class CallbackAuthenticationService extends binding.AbstractAuthenticationService {
#callback: AuthenticationCallback;
constructor(callback: AuthenticationCallback) {
super();
this.#callback = callback;
}
async authenticate(token: string, cancellable: Cancellable | null): Promise<string> {
const info = await this.#callback(token);
return JSON.stringify(info);
}
}
function parseSocketAddress(address: BaseSocketAddress): SocketAddress {
const family = address.family;
switch (family) {
case SocketFamily.Unix: {
const addr = address as UnixSocketAddress;
switch (addr.addressType) {
case UnixSocketAddressType.Anonymous:
return {
family: "unix:anonymous",
};
case UnixSocketAddressType.Path:
return {
family: "unix:path",
path: addr.path.toString(),
};
case UnixSocketAddressType.Abstract:
case UnixSocketAddressType.AbstractPadded:
return {
family: "unix:abstract",
path: addr.path,
};
}
break;
}
case SocketFamily.Ipv4: {
const addr = address as InetSocketAddress;
return {
family: "ipv4",
address: addr.address.toString(),
port: addr.port,
};
}
case SocketFamily.Ipv6: {
const addr = address as InetSocketAddress;
return {
family: "ipv6",
address: addr.address.toString(),
port: addr.port,
flowlabel: addr.flowinfo,
scopeid: addr.scopeId,
};
}
}
throw new Error("invalid BaseSocketAddress");
}
function objectToStrv(object: { [name: string]: string }): string[] {
return Object.entries(object).map(([k, v]) => `${k}=${v}`);
}
+96
View File
@@ -0,0 +1,96 @@
from __future__ import annotations
import argparse
from io import StringIO
from pathlib import Path
from . import codegen
from .customization import load_customizations
from .loader import compute_model
def main():
run(build_arguments())
def build_arguments() -> argparse.Namespace:
p = argparse.ArgumentParser(
description="Generate TypeScript and Node-API bindings for Frida."
)
p.add_argument(
"--frida-gir",
required=True,
type=Path,
help="Path to the Frida .gir file.",
)
p.add_argument(
"--glib-gir",
required=True,
type=Path,
help="Path to the GLib .gir file.",
)
p.add_argument(
"--gobject-gir",
required=True,
type=Path,
help="Path to the GObject .gir file.",
)
p.add_argument(
"--gio-gir",
required=True,
type=Path,
help="Path to the GIO .gir file.",
)
p.add_argument(
"--output-py",
required=True,
type=Path,
help="Path to the output .py file.",
)
p.add_argument(
"--output-pyi",
required=True,
type=Path,
help="Path to the output .pyi file.",
)
p.add_argument(
"--output-c",
required=True,
type=Path,
help="Path to the output C file for the Python extension.",
)
return p.parse_args()
def run(args: argparse.Namespace) -> None:
customizations = load_customizations()
model = compute_model(
args.frida_gir, args.glib_gir, args.gobject_gir, args.gio_gir, customizations
)
artefacts = codegen.generate_all(model)
with OutputFile(args.output_py) as f:
f.write(artefacts["py"])
with OutputFile(args.output_pyi) as f:
f.write(artefacts["pyi"])
with OutputFile(args.output_c) as f:
f.write(artefacts["c"])
class OutputFile:
def __init__(self, output_path):
self._output_path = output_path
self._io = StringIO()
def __enter__(self):
return self._io
def __exit__(self, *exc):
result = self._io.getvalue()
if self._output_path.exists():
existing_contents = self._output_path.read_text(encoding="utf-8")
if existing_contents == result:
return False
self._output_path.write_text(result, encoding="utf-8")
return False
File diff suppressed because it is too large Load Diff
+924
View File
@@ -0,0 +1,924 @@
from __future__ import annotations
from pathlib import Path
from typing import List, Mapping
from .model import (ConstructorCustomizations, CustomCode, CustomDeclaration,
Customizations, CustomMethod, CustomType, CustomTypeKind,
EnumerationCustomizations, EnumerationMemberCustomizations,
KeepAliveCustomization, MethodCustomizations,
ObjectTypeCustomizations, PropertyCustomizations,
SignalCustomizations, TypeCustomizations)
ASSETS_DIR = Path(__file__).resolve().parent / "assets"
CUSTOMIZATION_FACADE_EXPORTS = (
(ASSETS_DIR / "customization_facade.exports")
.read_text(encoding="utf-8")
.strip()
.split("\n")
)
CUSTOMIZATION_FACADE_TS = (ASSETS_DIR / "customization_facade.ts").read_text(
encoding="utf-8"
)
CUSTOMIZATION_HELPERS_IMPORTS = (
(ASSETS_DIR / "customization_helpers.imports")
.read_text(encoding="utf-8")
.strip()
.split("\n")
)
CUSTOMIZATION_HELPERS_TS = (ASSETS_DIR / "customization_helpers.ts").read_text(
encoding="utf-8"
)
def load_customizations() -> Customizations:
custom_types: List[CustomType] = {
"TargetProcess": CustomType(CustomTypeKind.TYPE, "ProcessID | ProcessName"),
"ProcessID": CustomType(CustomTypeKind.TYPE, "number"),
"InjecteeID": CustomType(CustomTypeKind.TYPE, "number"),
"FileDescriptor": CustomType(CustomTypeKind.TYPE, "number"),
"ProcessName": CustomType(CustomTypeKind.TYPE, "string"),
"SystemParameters": CustomType(
CustomTypeKind.INTERFACE,
"""
/**
* Operating System details.
*/
os: {
/**
* ID, e.g.: windows, macos, linux, ios, android, qnx, fedora, ubuntu, etc.
*/
id: string;
/**
* Human-readable name, e.g. `"macOS"`.
*/
name: string;
/**
* Human-readable version string, e.g. `"11.2.2"`.
*/
version?: string;
/**
* Build version, e.g. `"21B91"`.
*/
build?: string;
}
/**
* Platform, same as `Process.platform` in GumJS.
*/
platform: "windows" | "darwin" | "linux" | "freebsd" | "qnx";
/**
* Architecture, same as `Process.arch` in GumJS.
*/
arch: "ia32" | "x64" | "arm" | "arm64" | "mips";
/**
* Hardware details.
*/
hardware?: {
/**
* Product type, e.g. `"iPad6,3"`.
*/
product?: string;
/**
* Hardware platform, e.g. `"t8010"`.
*/
platform?: string;
/**
* Hardware model, e.g. `"J71bAP"`.
*/
model?: string;
}
/**
* Level of access.
*/
access: "full" | "jailed";
/**
* System name, e.g. `"Ole André’s iPhone"`.
*/
name?: string;
/**
* iOS UDID (Unique Device ID).
*/
udid?: string;
/**
* Details about cellular and networking interfaces.
*/
interfaces?: SystemInterface[];
/**
* Android API level, e.g.: `30`.
*/
apiLevel?: number;
[name: string]: any;
""",
),
"SystemInterface": CustomType(
CustomTypeKind.TYPE, "NetworkInterface | CellularInterface"
),
"NetworkInterface": CustomType(
CustomTypeKind.INTERFACE,
"""
type: "ethernet" | "wifi" | "bluetooth";
/**
* MAC address, e.g.: `"aa:bb:cc:dd:ee:ff"`.
*/
address: string;
""",
),
"CellularInterface": CustomType(
CustomTypeKind.INTERFACE,
"""
type: "cellular";
/**
* Phone number, e.g. `"+47 123 45 678"`.
*/
phoneNumber: string;
""",
),
"SpawnOptions": CustomType(
CustomTypeKind.INTERFACE,
"""
argv?: string[];
envp?: { [name: string]: string };
env?: { [name: string]: string };
cwd?: string;
stdio?: Stdio;
[name: string]: any;
""",
),
"RelayProperties": CustomType(
CustomTypeKind.INTERFACE,
"""
address: string;
username: string;
password: string;
kind: RelayKind;
""",
),
"Message": CustomType(CustomTypeKind.TYPE, "SendMessage | ErrorMessage"),
"MessageType": CustomType(
CustomTypeKind.ENUM,
"""
Send = "send",
Error = "error"
""",
),
"SendMessage": CustomType(
CustomTypeKind.INTERFACE,
"""
type: MessageType.Send;
payload: any;
""",
),
"ErrorMessage": CustomType(
CustomTypeKind.INTERFACE,
"""
type: MessageType.Error;
description: string;
stack?: string;
fileName?: string;
lineNumber?: number;
columnNumber?: number;
""",
),
"ScriptLogHandler": CustomType(
CustomTypeKind.TYPE, "(level: LogLevel, text: string) => void"
),
"ScriptExports": CustomType(
CustomTypeKind.INTERFACE,
"""
[name: string]: (...args: any[]) => Promise<any>;
""",
),
"LogLevel": CustomType(
CustomTypeKind.ENUM,
"""
Info = "info",
Warning = "warning",
Error = "error",
""",
),
"EnableDebuggerOptions": CustomType(
CustomTypeKind.INTERFACE,
"""
port?: number;
""",
),
"PortalServiceOptions": CustomType(
CustomTypeKind.INTERFACE,
"""
clusterParams?: EndpointParameters;
controlParams?: EndpointParameters;
""",
),
"PortalConnectionId": CustomType(CustomTypeKind.TYPE, "number"),
"PortalConnectionTag": CustomType(CustomTypeKind.TYPE, "string"),
"EndpointParametersSubset": CustomType(
CustomTypeKind.INTERFACE,
"""
address?: string;
port?: number;
certificate?: string;
origin?: string;
authentication?: AuthenticationScheme;
assetRoot?: string;
""",
),
"AuthenticationScheme": CustomType(
CustomTypeKind.TYPE,
"TokenAuthenticationScheme | CallbackAuthenticationScheme",
),
"TokenAuthenticationScheme": CustomType(
CustomTypeKind.INTERFACE,
"""
scheme: "token";
token: string;
""",
),
"CallbackAuthenticationScheme": CustomType(
CustomTypeKind.INTERFACE,
"""
scheme: "callback";
callback: AuthenticationCallback;
""",
),
"AuthenticationCallback": CustomType(
CustomTypeKind.TYPE,
"(token: string) => Promise<AuthenticatedSessionInfo>",
),
"AuthenticatedSessionInfo": CustomType(
CustomTypeKind.INTERFACE,
"""
[key: string]: any;
""",
),
"SocketAddress": CustomType(
CustomTypeKind.TYPE,
"IPV4SocketAddress | IPV6SocketAddress | AnonymousUnixSocketAddress | PathUnixSocketAddress | AbstractUnixSocketAddress",
),
"IPV4SocketAddress": CustomType(
CustomTypeKind.INTERFACE,
"""
family: "ipv4";
address: string;
port: number;
""",
),
"IPV6SocketAddress": CustomType(
CustomTypeKind.INTERFACE,
"""
family: "ipv6";
address: string;
port: number;
flowlabel: number;
scopeid: number;
""",
),
"AnonymousUnixSocketAddress": CustomType(
CustomTypeKind.INTERFACE,
"""
family: "unix:anonymous";
""",
),
"PathUnixSocketAddress": CustomType(
CustomTypeKind.INTERFACE,
"""
family: "unix:path";
path: string;
""",
),
"AbstractUnixSocketAddress": CustomType(
CustomTypeKind.INTERFACE,
"""
family: "unix:abstract";
path: Buffer;
""",
),
"Variant": CustomType(
CustomTypeKind.TYPE, "VariantValue | [type: symbol, value: VariantValue]"
),
"VariantValue": CustomType(
CustomTypeKind.TYPE,
"""
| boolean
| number
| string
| Buffer
| Variant[]
| VariantDict
""",
),
"VariantDict": CustomType(
CustomTypeKind.INTERFACE,
"""
[key: string]: Variant;
""",
),
}
type_customizations: Mapping[str, TypeCustomizations] = {
"DeviceManager": ObjectTypeCustomizations(
signals={
"added": SignalCustomizations(behavior="FDN_SIGNAL_KEEP_ALIVE"),
"removed": SignalCustomizations(behavior="FDN_SIGNAL_KEEP_ALIVE"),
"changed": SignalCustomizations(behavior="FDN_SIGNAL_KEEP_ALIVE"),
},
cleanup="close",
),
"Device": ObjectTypeCustomizations(
methods={
"query_system_parameters": MethodCustomizations(
return_typing="Promise<SystemParameters>",
return_wrapper="as SystemParameters",
),
"spawn": MethodCustomizations(
param_typings=[
"programOrArgv: string | string[]",
"opts?: SpawnOptions",
"cancellable?: Cancellable | null",
],
return_typing="Promise<ProcessID>",
custom_logic="""
const options: RawSpawnOptions = {};
let program: string;
let argv;
if (typeof programOrArgv === "string") {
program = programOrArgv;
argv = opts?.argv;
} else {
program = programOrArgv[0];
argv = programOrArgv;
if (argv.length === 1) {
argv = undefined;
}
}
if (argv !== undefined) {
options.argv = argv;
}
if (opts !== undefined) {
const envp = opts.envp;
if (envp !== undefined) {
options.envp = objectToStrv(envp);
}
const env = opts.env;
if (env !== undefined) {
options.env = objectToStrv(env);
}
const cwd = opts.cwd;
if (cwd !== undefined) {
options.cwd = cwd;
}
options.aux = Object.fromEntries(Object.entries(opts).filter(([k, v]) => !STANDARD_SPAWN_OPTION_NAMES.has(k)));
}
""",
),
"input": MethodCustomizations(
param_typings=[
"target: TargetProcess",
"data: Buffer",
"cancellable?: Cancellable | null",
],
custom_logic="const pid = await this.#getPid(target, cancellable);",
),
"resume": MethodCustomizations(
param_typings=[
"target: TargetProcess",
"cancellable?: Cancellable | null",
],
custom_logic="const pid = await this.#getPid(target, cancellable);",
),
"kill": MethodCustomizations(
param_typings=[
"target: TargetProcess",
"cancellable?: Cancellable | null",
],
custom_logic="const pid = await this.#getPid(target, cancellable);",
),
"attach": MethodCustomizations(
param_typings=[
"target: TargetProcess",
"options?: SessionOptions",
"cancellable?: Cancellable | null",
],
custom_logic="const pid = await this.#getPid(target, cancellable);",
),
"inject_library_file": MethodCustomizations(
param_typings=[
"target: TargetProcess",
"path: string",
"entrypoint: string",
"data: string",
"cancellable?: Cancellable | null",
],
return_typing="Promise<InjecteeID>",
custom_logic="const pid = await this.#getPid(target, cancellable);",
),
"inject_library_blob": MethodCustomizations(
param_typings=[
"target: TargetProcess",
"blob: Buffer",
"entrypoint: string",
"data: string",
"cancellable?: Cancellable | null",
],
return_typing="Promise<InjecteeID>",
custom_logic="const pid = await this.#getPid(target, cancellable);",
),
"open_channel": MethodCustomizations(
return_typing='Promise<import("stream").Duplex>',
return_wrapper="new IOStreamAdapter",
),
},
properties={
"dtype": PropertyCustomizations(
js_name="type",
),
},
signals={
"spawn-added": SignalCustomizations(behavior="FDN_SIGNAL_KEEP_ALIVE"),
"spawn-removed": SignalCustomizations(behavior="FDN_SIGNAL_KEEP_ALIVE"),
"child-added": SignalCustomizations(behavior="FDN_SIGNAL_KEEP_ALIVE"),
"child-removed": SignalCustomizations(behavior="FDN_SIGNAL_KEEP_ALIVE"),
"process-crashed": SignalCustomizations(
behavior="FDN_SIGNAL_KEEP_ALIVE"
),
"output": SignalCustomizations(
behavior="FDN_SIGNAL_KEEP_ALIVE",
transform={
0: ("pid: ProcessID", None),
1: ("fd: FileDescriptor", None),
},
),
"uninjected": SignalCustomizations(
behavior="FDN_SIGNAL_KEEP_ALIVE",
transform={
0: ("id: InjecteeID", None),
},
),
},
custom_code=CustomCode(
methods=[
CustomMethod(
typing="getProcess(name: string, options?: ProcessMatchOptions, cancellable?: Cancellable | null): Promise<Process>",
code="""
async getProcess(name: string, options: ProcessMatchOptions = {}, cancellable?: Cancellable | null): Promise<Process> {
const {
scope = Scope.Minimal,
} = options;
const processes = await this.enumerateProcesses({ scope }, cancellable);
const mm = new Minimatch(name.toLowerCase());
const matching = processes.filter(process => mm.match(process.name.toLowerCase()));
if (matching.length === 1) {
return matching[0];
} else if (matching.length > 1) {
throw new Error("Ambiguous name; it matches: " + matching.map(process => `${process.name} (pid: ${process.pid})`).join(", "));
} else {
throw new Error("Process not found");
}
}
""",
),
CustomMethod(
typing=None,
code="""
async #getPid(target: TargetProcess, cancellable?: Cancellable | null): Promise<ProcessID> {
if (typeof target === "number") {
return target;
}
const process = await this.getProcess(target, {}, cancellable);
return process.pid;
}
""",
),
],
),
),
"SpawnOptions": ObjectTypeCustomizations(js_name="RawSpawnOptions"),
"Bus": ObjectTypeCustomizations(
methods={
"post": MethodCustomizations(
param_typings=[
"message: any",
"data?: Buffer | null",
],
custom_logic="const json = JSON.stringify(message);",
),
},
signals={
"detached": SignalCustomizations(behavior="FDN_SIGNAL_KEEP_ALIVE"),
"message": SignalCustomizations(
behavior="FDN_SIGNAL_KEEP_ALIVE",
transform={
0: ("message: any", "JSON.parse"),
},
),
},
),
"Service": ObjectTypeCustomizations(
keep_alive=KeepAliveCustomization(
is_destroyed_function="is_closed", destroy_signal_name="close"
),
),
"Relay": ObjectTypeCustomizations(
constructor=ConstructorCustomizations(
param_typings=[
"properties: RelayProperties",
],
custom_logic="const { address, username, password, kind } = properties;",
),
),
"RelayKind": EnumerationCustomizations(
members={
"turn_udp": EnumerationMemberCustomizations(js_name="TurnUDP"),
"turn_tcp": EnumerationMemberCustomizations(js_name="TurnTCP"),
"turn_tls": EnumerationMemberCustomizations(js_name="TurnTLS"),
},
),
"Script": ObjectTypeCustomizations(
methods={
"is_destroyed": MethodCustomizations(hide=True),
"post": MethodCustomizations(
param_typings=[
"message: any",
"data?: Buffer | null",
],
custom_logic="const json = JSON.stringify(message);",
),
"enable_debugger": MethodCustomizations(
param_typings=[
"options?: EnableDebuggerOptions",
"cancellable?: Cancellable | null",
],
custom_logic="const port = options?.port ?? 0;",
),
},
signals={
"message": SignalCustomizations(
transform={
0: ("message: Message", "JSON.parse"),
},
intercept="this.#services.handleMessageIntercept",
),
},
custom_code=CustomCode(
declarations=[
CustomDeclaration(
typing=None, code="#services = new ScriptServices(this);"
),
CustomDeclaration(
typing="logHandler: ScriptLogHandler",
code="logHandler: ScriptLogHandler = log;",
),
],
methods=[
CustomMethod(
typing="readonly isDestroyed: boolean",
code="""
get isDestroyed(): boolean {
return this._isDestroyed();
}
""",
),
CustomMethod(
typing="readonly exports: ScriptExports",
code="""
get exports(): ScriptExports {
return this.#services.exportsProxy;
}
""",
),
CustomMethod(
typing="readonly defaultLogHandler: ScriptLogHandler",
code="""
get defaultLogHandler(): ScriptLogHandler {
return log;
}
""",
),
],
),
keep_alive=KeepAliveCustomization(
is_destroyed_function="is_destroyed", destroy_signal_name="destroyed"
),
),
"ScriptRuntime": EnumerationCustomizations(
members={
"qjs": EnumerationMemberCustomizations(js_name="QJS"),
},
),
"ControlService": ObjectTypeCustomizations(
methods={
"start": MethodCustomizations(ref_keep_alive=True),
"stop": MethodCustomizations(unref_keep_alive=True),
"get_endpoint_params": MethodCustomizations(drop=True),
},
properties={
"endpoint-params": PropertyCustomizations(drop=True),
},
),
"PortalService": ObjectTypeCustomizations(
constructor=ConstructorCustomizations(
param_typings=[
"options?: PortalServiceOptions",
],
custom_logic="""
const clusterParams = options?.clusterParams ?? new EndpointParameters();
const controlParams = options?.controlParams ?? null;
""",
),
methods={
"start": MethodCustomizations(ref_keep_alive=True),
"stop": MethodCustomizations(unref_keep_alive=True),
"kick": MethodCustomizations(
param_typings=[
"connectionId: PortalConnectionId",
],
),
"post": MethodCustomizations(
param_typings=[
"connectionId: PortalConnectionId",
"message: any",
"data?: Buffer | null",
],
custom_logic="const json = JSON.stringify(message);",
),
"narrowcast": MethodCustomizations(
param_typings=[
"tag: string",
"message: any",
"data?: Buffer | null",
],
custom_logic="const json = JSON.stringify(message);",
),
"broadcast": MethodCustomizations(
param_typings=[
"message: any",
"data?: Buffer | null",
],
custom_logic="const json = JSON.stringify(message);",
),
"enumerate_tags": MethodCustomizations(
param_typings=[
"connectionId: PortalConnectionId",
],
),
"tag": MethodCustomizations(
param_typings=[
"connectionId: PortalConnectionId",
"tag: string",
],
),
"untag": MethodCustomizations(
param_typings=[
"connectionId: PortalConnectionId",
"tag: string",
],
),
},
signals={
"node-connected": SignalCustomizations(
transform={
0: ("connectionId: PortalConnectionId", None),
1: ("remoteAddress: SocketAddress", "parseSocketAddress"),
},
),
"node-joined": SignalCustomizations(
transform={
0: ("connectionId: PortalConnectionId", None),
},
),
"node-left": SignalCustomizations(
transform={
0: ("connectionId: PortalConnectionId", None),
},
),
"node-disconnected": SignalCustomizations(
transform={
0: ("connectionId: PortalConnectionId", None),
1: ("remoteAddress: SocketAddress", "parseSocketAddress"),
},
),
"controller-connected": SignalCustomizations(
transform={
0: ("connectionId: PortalConnectionId", None),
1: ("remoteAddress: SocketAddress", "parseSocketAddress"),
},
),
"controller-disconnected": SignalCustomizations(
transform={
0: ("connectionId: PortalConnectionId", None),
1: ("remoteAddress: SocketAddress", "parseSocketAddress"),
},
),
"authenticated": SignalCustomizations(
transform={
0: ("connectionId: PortalConnectionId", None),
1: ("sessionInfo: AuthenticatedSessionInfo", "JSON.parse"),
},
),
"subscribe": SignalCustomizations(
transform={
0: ("connectionId: PortalConnectionId", None),
},
),
"message": SignalCustomizations(
transform={
0: ("connectionId: PortalConnectionId", None),
1: ("message: any", "JSON.parse"),
},
),
},
),
"EndpointParameters": ObjectTypeCustomizations(
constructor=ConstructorCustomizations(
param_typings=[
"params?: EndpointParametersSubset",
],
custom_logic="""
const address = params?.address ?? null;
const port = params?.port ?? 0;
const certificate = params?.certificate ?? null;
const origin = params?.origin ?? null;
let authService: AuthenticationService | null = null;
const auth = params?.authentication;
if (auth !== undefined) {
if (auth.scheme === "token") {
authService = new StaticAuthenticationService(auth.token);
} else {
authService = new CallbackAuthenticationService(auth.callback);
}
}
const assetRoot = params?.assetRoot ?? null;
""",
),
),
"Injector": ObjectTypeCustomizations(drop=True),
"RpcClient": ObjectTypeCustomizations(drop=True),
"RpcPeer": ObjectTypeCustomizations(drop=True),
"Cancellable": ObjectTypeCustomizations(
methods={
"is_cancelled": MethodCustomizations(hide=True),
"set_error_if_cancelled": MethodCustomizations(
js_name="throwIfCancelled",
return_typing="void",
),
"make_pollfd": MethodCustomizations(drop=True),
"release_fd": MethodCustomizations(drop=True),
"source_new": MethodCustomizations(drop=True),
},
custom_code=CustomCode(
methods=[
CustomMethod(
typing="readonly isCancelled: boolean",
code="""
get isCancelled(): boolean {
return this._isCancelled();
}
""",
),
],
),
),
"IOStream": ObjectTypeCustomizations(
methods={
"close": MethodCustomizations(drop=True),
"close_async": MethodCustomizations(js_name="close"),
"splice_async": MethodCustomizations(drop=True),
"has_pending": MethodCustomizations(drop=True),
"set_pending": MethodCustomizations(drop=True),
"clear_pending": MethodCustomizations(drop=True),
},
),
"InputStream": ObjectTypeCustomizations(
methods={
"close": MethodCustomizations(drop=True),
"close_async": MethodCustomizations(js_name="close"),
"read": MethodCustomizations(drop=True),
"read_async": MethodCustomizations(drop=True),
"read_all": MethodCustomizations(drop=True),
"read_all_async": MethodCustomizations(drop=True),
"read_bytes": MethodCustomizations(drop=True),
"read_bytes_async": MethodCustomizations(js_name="read"),
"skip": MethodCustomizations(drop=True),
"skip_async": MethodCustomizations(js_name="skip"),
"is_closed": MethodCustomizations(drop=True),
"has_pending": MethodCustomizations(drop=True),
"set_pending": MethodCustomizations(drop=True),
"clear_pending": MethodCustomizations(drop=True),
},
),
"OutputStream": ObjectTypeCustomizations(
methods={
"close": MethodCustomizations(drop=True),
"close_async": MethodCustomizations(js_name="close"),
"flush": MethodCustomizations(drop=True),
"flush_async": MethodCustomizations(js_name="flush"),
"write": MethodCustomizations(drop=True),
"write_async": MethodCustomizations(drop=True),
"write_all": MethodCustomizations(drop=True),
"write_all_async": MethodCustomizations(drop=True),
"write_bytes": MethodCustomizations(drop=True),
"write_bytes_async": MethodCustomizations(js_name="write"),
"writev": MethodCustomizations(drop=True),
"writev_async": MethodCustomizations(drop=True),
"writev_all": MethodCustomizations(drop=True),
"writev_all_async": MethodCustomizations(drop=True),
"splice": MethodCustomizations(drop=True),
"splice_async": MethodCustomizations(drop=True),
"is_closing": MethodCustomizations(drop=True),
"is_closed": MethodCustomizations(drop=True),
"has_pending": MethodCustomizations(drop=True),
"set_pending": MethodCustomizations(drop=True),
"clear_pending": MethodCustomizations(drop=True),
},
),
"UnixSocketAddress": ObjectTypeCustomizations(
methods={
"get_path": MethodCustomizations(
return_typing="Buffer",
return_cconversion="fdn_buffer_to_value (env, (const guint8 *) retval, g_unix_socket_address_get_path_len (handle))",
),
"get_path_len": MethodCustomizations(drop=True),
"get_is_abstract": MethodCustomizations(drop=True),
},
properties={
"path": PropertyCustomizations(typing="path: Buffer"),
"abstract": PropertyCustomizations(drop=True),
"path-as-array": PropertyCustomizations(drop=True),
},
),
"SocketAddress": ObjectTypeCustomizations(
js_name="BaseSocketAddress",
constructor=ConstructorCustomizations(drop=True),
methods={
"to_native": MethodCustomizations(drop=True),
},
),
"SocketConnectable": ObjectTypeCustomizations(drop_abstract_base=True),
"InetAddress": ObjectTypeCustomizations(
properties={
"bytes": PropertyCustomizations(drop=True),
},
),
"Object": ObjectTypeCustomizations(
js_name="BaseObject",
methods={
"is_floating": MethodCustomizations(drop=True),
"ref": MethodCustomizations(drop=True),
"ref_sink": MethodCustomizations(drop=True),
"unref": MethodCustomizations(drop=True),
"getv": MethodCustomizations(drop=True),
"get_property": MethodCustomizations(drop=True),
"set_property": MethodCustomizations(drop=True),
"notify_by_pspec": MethodCustomizations(drop=True),
"freeze_notify": MethodCustomizations(drop=True),
"thaw_notify": MethodCustomizations(drop=True),
"bind_property": MethodCustomizations(drop=True),
"bind_property_full": MethodCustomizations(drop=True),
"bind_property_with_closures": MethodCustomizations(drop=True),
"force_floating": MethodCustomizations(drop=True),
"get_data": MethodCustomizations(drop=True),
"get_qdata": MethodCustomizations(drop=True),
"run_dispose": MethodCustomizations(drop=True),
"set_data": MethodCustomizations(drop=True),
"steal_data": MethodCustomizations(drop=True),
"steal_qdata": MethodCustomizations(drop=True),
"watch_closure": MethodCustomizations(drop=True),
},
signals={
"notify": SignalCustomizations(drop=True),
},
),
}
return Customizations(
custom_types,
type_customizations,
CUSTOMIZATION_FACADE_EXPORTS,
CUSTOMIZATION_FACADE_TS,
CUSTOMIZATION_HELPERS_IMPORTS,
CUSTOMIZATION_HELPERS_TS,
)
+61
View File
@@ -0,0 +1,61 @@
from __future__ import annotations
from collections import OrderedDict
from pathlib import Path
from .model import Customizations, Model, parse_gir
INCLUDED_GIO_OBJECT_TYPES = [
"Cancellable",
"IOStream",
"InputStream",
"OutputStream",
"SocketAddress",
"SocketAddressEnumerator",
"SocketConnectable",
"InetSocketAddress",
"InetAddress",
"UnixSocketAddress",
]
INCLUDED_GIO_ENUMERATIONS = [
"FileMonitorEvent",
"SocketFamily",
"UnixSocketAddressType",
]
def compute_model(
frida_gir: Path,
glib_gir: Path,
gobject_gir: Path,
gio_gir: Path,
customizations: Customizations,
) -> Model:
glib = parse_gir(glib_gir, [])
gobject = parse_gir(gobject_gir, [glib])
gio = parse_gir(gio_gir, [glib, gobject])
frida = parse_gir(frida_gir, [glib, gobject, gio])
object_types = OrderedDict()
object_types["Object"] = gobject.object_types["Object"]
object_types.update(frida.object_types)
for t in INCLUDED_GIO_OBJECT_TYPES:
object_types[t] = gio.object_types[t]
enumerations = OrderedDict(frida.enumerations)
for t in INCLUDED_GIO_ENUMERATIONS:
enumerations[t] = gio.enumerations[t]
model = Model(
frida.namespace,
object_types,
enumerations,
customizations,
)
for t in object_types.values():
t.model = model
for t in enumerations.values():
t.model = model
return model
File diff suppressed because it is too large Load Diff
+94 -5
View File
@@ -1,6 +1,95 @@
frida_sources = [
'__init__.py',
'core.py',
]
if frida_core_dep.type_name() == 'internal'
frida_core_subprj = subproject('frida-core')
frida_gir = frida_core_subprj.get_variable('core_public_gir')
glib_gir = frida_core_subprj.get_variable('glib_gir')
gobject_gir = frida_core_subprj.get_variable('gobject_gir')
gio_gir = frida_core_subprj.get_variable('gio_gir')
else
girdir = frida_core_dep.get_variable('frida_girdir')
frida_gir = girdir / 'Frida-1.0.gir'
glib_gir = girdir / 'GLib-2.0.gir'
gobject_gir = girdir / 'GObject-2.0.gir'
gio_gir = girdir / 'Gio-2.0.gir'
endif
install_data(frida_sources, install_dir: join_paths(python_site_packages, 'frida'))
env = environment()
env.set('PYTHONPATH', meson.current_source_dir())
code = custom_target('binding-code',
output: [
'__init__.py',
'__init__.pyi',
'extension.c',
],
input: [
frida_gir,
glib_gir,
gobject_gir,
gio_gir,
files(
'frida_bindgen' / '__init__.py',
'frida_bindgen' / '__main__.py',
'frida_bindgen' / 'cli.py',
'frida_bindgen' / 'codegen.py',
'frida_bindgen' / 'customization.py',
'frida_bindgen' / 'loader.py',
'frida_bindgen' / 'model.py',
'frida_bindgen' / 'assets' / 'codegen_gobject_globals.c',
'frida_bindgen' / 'assets' / 'codegen_gobject_methods.c',
'frida_bindgen' / 'assets' / 'codegen_gobject_prototypes.h',
'frida_bindgen' / 'assets' / 'codegen_helpers.c',
'frida_bindgen' / 'assets' / 'codegen_helpers.ts',
'frida_bindgen' / 'assets' / 'codegen_macros.h',
'frida_bindgen' / 'assets' / 'codegen_prototypes.h',
'frida_bindgen' / 'assets' / 'codegen_structs.h',
'frida_bindgen' / 'assets' / 'codegen_typedefs.h',
'frida_bindgen' / 'assets' / 'customization_facade.exports',
'frida_bindgen' / 'assets' / 'customization_facade.ts',
'frida_bindgen' / 'assets' / 'customization_helpers.imports',
'frida_bindgen' / 'assets' / 'customization_helpers.ts',
)
],
command: [
python, '-m', 'frida_bindgen',
'--frida-gir=@INPUT0@',
'--glib-gir=@INPUT1@',
'--gobject-gir=@INPUT2@',
'--gio-gir=@INPUT3@',
'--output-py=@OUTPUT0@',
'--output-pyi=@OUTPUT1@',
'--output-c=@OUTPUT2@',
],
env: env,
install: true,
install_dir: [
python.get_install_dir() / 'frida',
python.get_install_dir() / 'frida' / '_frida',
false,
]
)
py_sources = [
'py.typed',
]
python.install_sources(py_sources, subdir: 'frida', pure: false)
extension_py_sources = [
'py.typed',
]
python.install_sources(extension_py_sources, subdir: 'frida' / '_frida', pure: false)
extra_link_args = []
if host_os_family == 'darwin'
extra_link_args += '-Wl,-exported_symbol,_PyInit__frida'
elif host_os_family != 'windows'
extra_link_args += '-Wl,--version-script,' + meson.current_source_dir() / 'extension.version'
endif
extension = python.extension_module('_frida', code[2],
limited_api: '3.7',
c_args: frida_component_cflags,
link_args: extra_link_args,
dependencies: [python_dep, frida_core_dep, os_deps],
install: true,
subdir: 'frida',
)
+23
View File
@@ -0,0 +1,23 @@
@setlocal
@echo off
rem:: Based on: https://github.com/microsoft/terminal/issues/217#issuecomment-737594785
goto :_start_
:set_real_dp0
set dp0=%~dp0
set "dp0=%dp0:~0,-1%"
goto :eof
:_start_
call :set_real_dp0
if not exist "%dp0%\releng\meson\meson.py" (
pushd "%dp0%" & git submodule update --init --recursive --depth 1 & popd
if %errorlevel% neq 0 exit /b %errorlevel%
)
endlocal & goto #_undefined_# 2>nul || title %COMSPEC% & python ^
-c "import sys; sys.path.insert(0, sys.argv[1]); from releng.meson_make import main; main()" ^
"%dp0%" ^
.\build ^
%*
+19 -78
View File
@@ -1,11 +1,11 @@
project('frida-python', 'c', version: '1.0.0')
project('frida-python', 'c',
version: run_command(find_program('python3'), files('setup.py'), '-V',
capture: true,
check: true).stdout().strip(),
meson_version: '>=1.3.0',
)
host_os = host_machine.system()
if host_os == 'android'
host_os_family = 'linux'
else
host_os_family = host_os
endif
python = import('python').find_installation()
cc = meson.get_compiler('c')
@@ -19,81 +19,22 @@ if ndebug == 'true' or (ndebug == 'if-release' and not get_option('debug'))
]
endif
target_conditionals_prefix = '#include <TargetConditionals.h>'
python_dep = python.dependency()
frida_core_dep = dependency('frida-core-1.0', default_options: [
'frida_version=' + meson.project_version().replace('.dev', '-dev.'),
])
is_macos_src = target_conditionals_prefix + '''
#if !TARGET_OS_OSX
# error Not macOS
#endif
'''
if cc.compiles(is_macos_src, name: 'compiling for macOS')
host_os = 'macos'
endif
is_ios_src = target_conditionals_prefix + '''
#if !TARGET_OS_IOS
# error Not iOS
#endif
'''
if cc.compiles(is_ios_src, name: 'compiling for iOS')
host_os = 'ios'
endif
if cc.has_header('android/api-level.h')
host_os = 'android'
endif
python_incdir = get_option('python_incdir')
if python_incdir == ''
python = get_option('python')
if python == ''
python = find_program('python3', required: false)
if not python.found()
python = find_program('python')
endif
endif
result = run_command(python, '-c',
'import sys; sys.stdout.write(f"{sys.version_info[0]}.{sys.version_info[1]}")',
check: true)
python_version = result.stdout()
python_name = 'python' + python_version
result = run_command(python, '-c',
'from distutils import sysconfig; import sys; sys.stdout.write(sysconfig.get_python_inc())',
check: true)
python_incdir = result.stdout()
else
py_major_v = cc.get_define('PY_MAJOR_VERSION',
prefix: '#include <patchlevel.h>',
args: ['-I' + python_incdir])
py_minor_v = cc.get_define('PY_MINOR_VERSION',
prefix: '#include <patchlevel.h>',
args: ['-I' + python_incdir])
python_version = py_major_v + '.' + py_minor_v
python_name = 'python' + python_version
endif
python_site_packages = join_paths(get_option('libdir'), python_name, 'site-packages')
cdata = configuration_data()
cdata.set('HAVE_' + host_os_family.to_upper(), 1)
if host_os != host_os_family
cdata.set('HAVE_' + host_os.to_upper(), 1)
endif
frida_core_dep = dependency('frida-core-1.0')
os_deps = []
host_os_family = host_machine.system()
if host_os_family != 'windows'
os_deps += dependency('gio-unix-2.0')
endif
configure_file(input: 'config.h.in',
output: 'config.h',
configuration: cdata)
subdir('src')
subdir('frida')
#test('frida-python', python,
# args: ['-m', 'unittest', 'discover'],
# workdir: meson.current_source_dir(),
# env: {'PYTHONPATH': meson.current_build_dir() / 'src'},
# timeout: 30,
#)
-11
View File
@@ -1,11 +0,0 @@
option('python',
type: 'string',
value: '',
description: 'Python interpreter to build for'
)
option('python_incdir',
type: 'string',
value: '',
description: 'Python headers directory to build against'
)
Submodule
+1
Submodule releng added at 71f828f7c8
Executable → Regular
+80 -102
View File
@@ -1,109 +1,25 @@
import os
import platform
import shutil
import subprocess
import sys
from pathlib import Path
from typing import Iterator
from setuptools import setup
from setuptools.command.build_ext import build_ext
from setuptools.extension import Extension
package_dir = os.path.dirname(os.path.realpath(__file__))
pkg_info = os.path.join(package_dir, "PKG-INFO")
in_source_package = os.path.isfile(pkg_info)
if in_source_package:
with open(pkg_info, "r", encoding="utf-8") as f:
version_line = [line for line in f if line.startswith("Version: ")][0].strip()
frida_version = version_line[9:]
else:
frida_version = os.environ.get("FRIDA_VERSION", "0.0.0")
with open(os.path.join(package_dir, "README.md"), "r", encoding="utf-8") as f:
long_description = f.read()
frida_extension = os.environ.get("FRIDA_EXTENSION", None)
SOURCE_ROOT = Path(__file__).resolve().parent
FRIDA_EXTENSION = os.environ.get("FRIDA_EXTENSION", None)
class FridaPrebuiltExt(build_ext):
def build_extension(self, ext):
target = self.get_ext_fullpath(ext.name)
target_dir = os.path.dirname(target)
os.makedirs(target_dir, exist_ok=True)
shutil.copyfile(frida_extension, target)
class FridaMissingDevkitBuildExt(build_ext):
def build_extension(self, ext):
raise RuntimeError(
"Need frida-core devkit to build from source.\n"
"Download one from https://github.com/frida/frida/releases, "
"extract it to a directory,\n"
"and then add an environment variable named FRIDA_CORE_DEVKIT "
"pointing at the directory."
)
include_dirs = []
library_dirs = []
libraries = []
extra_link_args = []
cmdclass = {}
if frida_extension is not None:
cmdclass["build_ext"] = FridaPrebuiltExt
else:
devkit_dir = os.environ.get("FRIDA_CORE_DEVKIT", None)
if devkit_dir is not None:
include_dirs += [devkit_dir]
library_dirs += [devkit_dir]
libraries += ["frida-core"]
system = platform.system()
if system == "Windows":
pass
elif system == "Darwin":
extra_link_args += [
"-Wl,-exported_symbol,_PyInit__frida",
"-Wl,-dead_strip",
]
if "_PYTHON_HOST_PLATFORM" not in os.environ:
if platform.machine() == "arm64":
host_arch = "arm64"
macos_req = "11.0"
else:
host_arch = "x86_64"
macos_req = "10.9"
os.environ["_PYTHON_HOST_PLATFORM"] = f"macosx-{macos_req}-{host_arch}"
os.environ["ARCHFLAGS"] = f"-arch {host_arch}"
os.environ["MACOSX_DEPLOYMENT_TARGET"] = macos_req
else:
version_script = os.path.join(package_dir, "src", "_frida.version")
if not os.path.exists(version_script):
with open(version_script, "w", encoding="utf-8") as f:
f.write(
"\n".join(
[
"{",
" global:",
" PyInit__frida;",
"",
" local:",
" *;",
"};",
]
)
)
extra_link_args += [
f"-Wl,--version-script,{version_script}",
"-Wl,--gc-sections",
]
else:
cmdclass["build_ext"] = FridaMissingDevkitBuildExt
if __name__ == "__main__":
def main():
setup(
name="frida",
version=frida_version,
version=detect_version(),
description="Dynamic instrumentation toolkit for developers, reverse-engineers, and security researchers",
long_description=long_description,
long_description=compute_long_description(),
long_description_content_type="text/markdown",
author="Frida Developers",
author_email="oleavr@frida.re",
@@ -134,19 +50,81 @@ if __name__ == "__main__":
"Topic :: Software Development :: Debuggers",
"Topic :: Software Development :: Libraries :: Python Modules",
],
packages=["frida", "_frida"],
package_data={"frida": ["py.typed"], "_frida": ["py.typed", "__init__.pyi"]},
packages=["frida", "frida._frida"],
package_data={"frida": ["py.typed"], "frida._frida": ["py.typed", "__init__.pyi"]},
ext_modules=[
Extension(
name="_frida",
sources=["src/_frida.c"],
include_dirs=include_dirs,
library_dirs=library_dirs,
libraries=libraries,
extra_link_args=extra_link_args,
name="frida._frida",
sources=["frida/_frida/extension.c"],
py_limited_api=True,
)
],
cmdclass=cmdclass,
cmdclass={"build_ext": FridaPrebuiltExt if FRIDA_EXTENSION is not None else FridaDemandBuiltExt},
zip_safe=False,
)
def detect_version() -> str:
pkg_info = SOURCE_ROOT / "PKG-INFO"
in_source_package = pkg_info.exists()
if in_source_package:
version_line = [
line for line in pkg_info.read_text(encoding="utf-8").split("\n") if line.startswith("Version: ")
][0].strip()
return version_line[9:]
version = os.environ.get("FRIDA_VERSION")
if version is not None:
return version
releng_location = next(enumerate_releng_locations(), None)
if releng_location is not None:
sys.path.insert(0, str(releng_location.parent))
from releng.frida_version import detect
return detect(SOURCE_ROOT).name.replace("-dev.", ".dev")
return "0.0.0"
def compute_long_description() -> str:
return (SOURCE_ROOT / "README.md").read_text(encoding="utf-8")
def enumerate_releng_locations() -> Iterator[Path]:
val = os.environ.get("MESON_SOURCE_ROOT")
if val is not None:
parent_releng = Path(val) / "releng"
if releng_location_exists(parent_releng):
yield parent_releng
local_releng = SOURCE_ROOT / "releng"
if releng_location_exists(local_releng):
yield local_releng
def releng_location_exists(location: Path) -> bool:
return (location / "frida_version.py").exists()
class FridaPrebuiltExt(build_ext):
def build_extension(self, ext):
target = self.get_ext_fullpath(ext.name)
Path(target).parent.mkdir(parents=True, exist_ok=True)
shutil.copy(FRIDA_EXTENSION, target)
class FridaDemandBuiltExt(build_ext):
def build_extension(self, ext):
make = SOURCE_ROOT / "make.bat" if platform.system() == "Windows" else "make"
subprocess.run([make], check=True)
outputs = [entry for entry in (SOURCE_ROOT / "build" / "frida" / "_frida").glob("_frida.*") if entry.is_file()]
assert len(outputs) == 1
target = self.get_ext_fullpath(ext.name)
Path(target).parent.mkdir(parents=True, exist_ok=True)
shutil.copy(outputs[0], target)
if __name__ == "__main__":
main()
-5247
View File
File diff suppressed because it is too large Load Diff
-17
View File
@@ -1,17 +0,0 @@
extra_link_args = []
if host_os_family == 'darwin'
extra_link_args += ['-Wl,-exported_symbol,_PyInit__frida']
elif host_os_family != 'windows'
extra_link_args += ['-Wl,--version-script,' + join_paths(meson.current_source_dir(), '_frida.version')]
endif
extension = shared_module('_frida', '_frida.c',
name_prefix: '',
name_suffix: 'so',
c_args: frida_component_cflags,
include_directories: include_directories(python_incdir),
link_args: extra_link_args,
dependencies: [frida_core_dep] + os_deps,
install: true,
install_dir: python_site_packages,
)
+8
View File
@@ -0,0 +1,8 @@
[wrap-git]
url = https://github.com/frida/frida-core.git
revision = 17.6.0
depth = 1
[provide]
dependency_names = frida-core-1.0
+29 -15
View File
@@ -31,27 +31,41 @@ class TestRpc(unittest.TestCase):
name="test-rpc",
source="""\
rpc.exports = {
add: function (a, b) {
var result = a + b;
add(a, b) {
const result = a + b;
if (result < 0)
throw new Error("No");
throw new Error("No");
return result;
},
sub: function (a, b) {
sub(a, b) {
return a - b;
},
speak: function () {
var buf = Memory.allocUtf8String("Yo");
speak() {
const buf = Memory.allocUtf8String("Yo");
return Memory.readByteArray(buf, 2);
}
},
speakWithMetadata() {
const buf = Memory.allocUtf8String("Yo");
return ['soft', Memory.readByteArray(buf, 2)];
},
processData(val, data) {
return { val, dump: hexdump(data, { header: false }) };
},
};
""",
)
script.load()
self.assertEqual(script.exports.add(2, 3), 5)
self.assertEqual(script.exports.sub(5, 3), 2)
self.assertRaises(Exception, lambda: script.exports.add(1, -2))
self.assertListEqual([x for x in iter(script.exports.speak())], [0x59, 0x6F])
agent = script.exports_sync
self.assertEqual(agent.add(2, 3), 5)
self.assertEqual(agent.sub(5, 3), 2)
self.assertRaises(Exception, lambda: agent.add(1, -2))
self.assertEqual(agent.speak(), b"\x59\x6f")
meta, data = agent.speak_with_metadata()
self.assertEqual(meta, "soft")
self.assertEqual(data, b"\x59\x6f")
result = agent.process_data(1337, b"\x13\x37")
self.assertEqual(result["val"], 1337)
self.assertEqual(result["dump"], "00000000 13 37 .7")
def test_post_failure(self):
script = self.session.create_script(
@@ -64,7 +78,7 @@ rpc.exports = {
""",
)
script.load()
agent = script.exports
agent = script.exports_sync
self.session.detach()
self.assertRaisesScriptDestroyed(lambda: agent.init())
@@ -82,7 +96,7 @@ rpc.exports = {
""",
)
script.load()
agent = script.exports
agent = script.exports_sync
def unload_script_after_100ms():
time.sleep(0.1)
@@ -104,7 +118,7 @@ rpc.exports = {
""",
)
script.load()
agent = script.exports
agent = script.exports_sync
def terminate_target_after_100ms():
time.sleep(0.1)
@@ -126,7 +140,7 @@ rpc.exports = {
""",
)
script.load()
agent = script.exports
agent = script.exports_sync
def cancel_after_100ms():
time.sleep(0.1)