Compare commits

...
1505 Commits
Author SHA1 Message Date
87owo 8c1112b517 Add files via upload 2026-09-22 14:32:16 +08:00
87owo 8c2085d851 Update PYAS Security interface image link
Updated the image link for the PYAS Security interface in the README.
2026-09-22 14:30:21 +08:00
87owo 5b9fd96dfe Fix spacing in command-line argument examples 2026-09-22 14:18:42 +08:00
87owo 9a69acece8 Fix formatting of project description in README 2026-09-22 14:16:26 +08:00
87owo 4367226be8 Enhance README with badges and formatting
Updated the README to include badges and improved formatting.
2026-09-22 14:15:48 +08:00
87owo be2088f6f3 Fix README links and Python API client reference
Updated links and file references in the README.
2026-09-22 14:15:07 +08:00
87owo 9de779ba3f Revise README with project details and installation info
Updated project description, added badges, and improved overview section. Included installation instructions and clarified optional dependencies.
2026-09-22 14:02:19 +08:00
87owo 6cb8b801c7 Add files via upload 2026-09-22 13:33:35 +08:00
87owo b89e91cdb8 Add files via upload 2026-09-22 10:09:21 +08:00
87owo 50b8378e0a Add files via upload 2026-09-22 10:08:15 +08:00
87owo dd108b5c8a Add files via upload 2026-09-22 02:26:15 +08:00
87owo be1d86ca66 Add files via upload 2026-09-22 01:51:17 +08:00
87owo 2ef0fe145f Delete Engine/Properties/train_user.py 2026-09-22 01:50:44 +08:00
87owo af3a92c7d2 Add files via upload 2026-09-20 16:27:08 +08:00
87owo 411e6dba8f Add files via upload 2026-09-20 16:25:52 +08:00
87owo 9db8d33df4 Add files via upload 2026-09-15 00:12:12 +08:00
87owo 814baadbdf Add files via upload 2026-09-15 00:09:47 +08:00
87owo bc21628387 Add files via upload 2026-09-15 00:07:58 +08:00
87owo e7634c3c37 Add files via upload 2026-09-05 09:22:22 +08:00
87owo 05e952c5ee Add files via upload 2026-09-04 13:11:56 +08:00
87owo 8a0209a99a Add files via upload 2026-09-04 13:10:39 +08:00
87owo 65bc5c7c2a Add files via upload 2026-09-04 09:20:51 +08:00
87owo 07c64042be Add files via upload 2026-08-24 22:39:54 +08:00
87owo 22c04063cf Add files via upload 2026-08-23 10:33:53 +08:00
87owo 68a7ab657a Update README.md 2026-08-21 16:33:16 +08:00
87owo 630dc67058 Add files via upload 2026-08-21 14:19:12 +08:00
87owo 591507512c Delete Plugins/Rules/Report.json 2026-08-21 13:33:13 +08:00
87owo ff49cafc74 Add files via upload 2026-08-21 13:32:08 +08:00
87owo b077ba06bd Add files via upload 2026-08-19 17:20:02 +08:00
87owo a2b66aec64 Add files via upload 2026-08-14 12:43:24 +08:00
87owo 4b692b0c87 Add files via upload 2026-08-11 13:17:24 +08:00
87owo 99d1b20d0f Add files via upload 2026-08-09 19:52:15 +08:00
87owo fae5edb57b Add files via upload 2026-08-09 19:50:38 +08:00
87owo 6db91483a0 Add files via upload 2026-08-09 19:36:22 +08:00
87owo 90383f3d09 Add files via upload 2026-08-04 22:31:09 +08:00
87owo 966a5a3592 Add files via upload 2026-08-04 22:29:20 +08:00
87owo 48e14cd143 Add files via upload 2026-07-28 12:29:39 +08:00
87owo 4264f50ba3 Add files via upload 2026-07-28 12:12:10 +08:00
87owo 887e0718d0 Add files via upload 2026-07-28 12:10:36 +08:00
87owo 4870a5c480 Add files via upload 2026-07-28 12:09:57 +08:00
87owo e8cadf0537 Add files via upload 2026-07-27 17:30:57 +08:00
87owo f5124e0ef2 Add files via upload 2026-07-25 20:33:44 +08:00
87owo da9a520632 Add files via upload 2026-07-25 20:12:57 +08:00
87owo 81bebeda63 Add files via upload 2026-07-25 00:08:11 +08:00
87owo 4df1432be1 Add files via upload 2026-07-24 23:25:19 +08:00
87owo e699be6b2e Update Rules_Driver_P1.json 2026-07-24 23:22:26 +08:00
87owo e8dda40e7f Add files via upload 2026-07-22 17:21:30 +08:00
87owo 5b4cd6e879 Add files via upload 2026-07-22 16:55:36 +08:00
87owo 316b061d34 Add files via upload 2026-07-22 13:22:34 +08:00
87owo 6ff27679e7 Add files via upload 2026-07-22 13:17:06 +08:00
87owo 8f3adbc870 Add files via upload 2026-07-22 13:13:08 +08:00
87owo 5798a35456 Add files via upload 2026-07-18 18:08:03 +08:00
87owo a8a2060978 Add files via upload 2026-07-18 17:38:02 +08:00
87owo 7cf2763511 Add files via upload 2026-07-18 17:34:32 +08:00
87owo fc59619518 Revise Driver Signature notice in LICENSE
Updated the language in the Driver Signature section for clarity.
2026-07-18 17:17:58 +08:00
87owo d01cfd2dd6 Update LICENSE.txt with new date and driver notice
Updated the last modified date in the license agreement and added a new section regarding driver signature notice.
2026-07-18 17:03:00 +08:00
87owo 9563a4806a Add files via upload 2026-07-17 17:55:26 +08:00
87owo fa1be109e3 Add files via upload 2026-07-17 17:41:26 +08:00
87owo 89a5a5928c Add files via upload 2026-07-17 11:36:43 +08:00
87owo 7830378f23 Add files via upload 2026-07-17 09:42:55 +08:00
87owo 043f616469 Add files via upload 2026-07-17 09:40:34 +08:00
87owo 3bf631313a Add files via upload 2026-07-17 09:38:11 +08:00
87owo a416e2d4a8 Add files via upload 2026-07-16 16:21:57 +08:00
87owo 53218cf1ce Add files via upload 2026-07-15 22:06:33 +08:00
87owo c5f0c8ed47 Add files via upload 2026-07-15 21:52:37 +08:00
87owo 05e1c45adb Add files via upload 2026-07-15 21:20:11 +08:00
87owo e3787523c7 Add files via upload 2026-07-15 21:19:15 +08:00
87owo 1c4e908b1b Add files via upload 2026-07-14 04:54:50 +08:00
87owo 98b60b9833 Add files via upload 2026-07-14 04:54:15 +08:00
87owo 71f8232ef0 Delete Plugins/Rules directory 2026-07-14 04:54:03 +08:00
87owo 0e4de407e3 Add files via upload 2026-07-14 04:53:34 +08:00
87owo 802d732b3f Add files via upload 2026-07-13 19:36:21 +08:00
87owo 373897f579 Add files via upload 2026-07-12 12:01:26 +08:00
87owo 3ef72917c8 Add files via upload 2026-07-12 12:00:57 +08:00
87owo 0d27125453 Add files via upload 2026-07-12 11:50:19 +08:00
87owo 82c519b7d9 Add files via upload 2026-07-12 11:49:34 +08:00
87owo 3c57a8a53c Add files via upload 2026-07-11 21:21:12 +08:00
87owo 727ba6ccbf Add files via upload 2026-07-11 15:16:35 +08:00
87owo b32f1df9ec Add files via upload 2026-07-10 00:23:20 +08:00
87owo 76b9afc6ec Add files via upload 2026-07-10 00:22:49 +08:00
87owo 9fbf7baf76 Add files via upload 2026-07-10 00:12:16 +08:00
87owo 9e69dac4e0 Add files via upload 2026-07-07 22:35:31 +08:00
87owo 839599eed1 Add files via upload 2026-07-07 22:24:26 +08:00
87owo 965b3d2863 Add files via upload 2026-07-07 02:56:36 +08:00
87owo 64b206bc9e Add files via upload 2026-07-07 02:50:06 +08:00
87owo 3b53e542da Add files via upload 2026-07-07 02:31:38 +08:00
87owo 9974a0944a Add files via upload 2026-07-07 02:31:04 +08:00
87owo d40be1d740 Add files via upload 2026-07-07 02:11:23 +08:00
87owo 14832d112e Add files via upload 2026-07-07 02:10:56 +08:00
87owo 3b5f67f046 Add files via upload 2026-07-07 02:09:44 +08:00
87owo d1a074b2d3 Add files via upload 2026-07-05 18:52:14 +08:00
87owo 03f3efb954 Add files via upload 2026-07-05 18:43:41 +08:00
87owo f82fa135c9 Add files via upload 2026-07-05 18:36:09 +08:00
87owo 0e78b970ac Add files via upload 2026-07-05 18:35:56 +08:00
87owo cd2cf87b8f Add files via upload 2026-07-05 18:35:17 +08:00
87owo 20d2f94146 Add files via upload 2026-07-05 18:15:09 +08:00
87owo 06e0e6a01c Add files via upload 2026-07-05 18:14:34 +08:00
87owo 901ee8e34a Add files via upload 2026-07-05 18:13:56 +08:00
87owo 511a00cf84 Add files via upload 2026-07-05 00:48:18 +08:00
87owo 30629a2363 Add files via upload 2026-07-05 00:47:53 +08:00
87owo 7fc9aab048 Add files via upload 2026-07-05 00:46:55 +08:00
87owo 3a468791c3 Add files via upload 2026-07-05 00:45:40 +08:00
87owo 05a7103184 Add files via upload 2026-07-02 22:22:31 +08:00
87owo 4ed8173c40 Add files via upload 2026-07-02 22:21:35 +08:00
87owo fb35bc372e Add files via upload 2026-07-02 22:12:14 +08:00
87owo 11da9eb3bd Add files via upload 2026-07-01 14:13:11 +08:00
87owo 5da8464bb4 Add files via upload 2026-07-01 14:12:54 +08:00
87owo f42524dcd5 Add files via upload 2026-07-01 14:12:26 +08:00
87owo 3be437dc6e Add files via upload 2026-07-01 14:12:05 +08:00
87owo 13291c36f5 Add files via upload 2026-06-29 21:10:01 +08:00
87owo 948eb51ab8 Add files via upload 2026-06-29 20:45:12 +08:00
87owo 0cef48771b Add files via upload 2026-06-28 13:29:11 +08:00
87owo a45b10b5c3 Add files via upload 2026-06-28 12:58:54 +08:00
87owo 7627d4e5d7 Add files via upload 2026-06-26 22:06:22 +08:00
87owo 5c88711094 Add files via upload 2026-06-26 22:04:47 +08:00
87owo a7fdd41530 Add files via upload 2026-06-26 19:44:46 +08:00
87owo c315b322cd Merge pull request #65 from Wangbotao2013/main 2026-06-26 19:43:42 +08:00
87owo 181bfc5b44 Add files via upload 2026-06-23 20:14:39 +08:00
wangbotao d9ea2b522a Merge branch 'main' into main 2026-06-19 18:57:39 +08:00
87owo dc498949c7 Add files via upload 2026-06-16 04:27:36 +08:00
87owo f804a5b7f0 Add files via upload 2026-06-16 04:20:08 +08:00
wangbotao c3ef1da373 PYAS 自保护增强
任务管理器通过匹配 Rule_Process_TrustedPaths 中的 *\\Windows\\* 规则被误判为可信进程,导致黑名单检查失效。
2026-06-14 17:27:05 +08:00
87owo b0a3482f25 Add files via upload 2026-06-13 13:04:04 +08:00
87owo 018b497575 Add files via upload 2026-06-09 16:45:28 +08:00
87owo 130b040de1 Add files via upload 2026-06-09 16:08:44 +08:00
87owo bc0a62224a Add files via upload 2026-06-09 15:59:16 +08:00
87owo 77525fc7c5 Add files via upload 2026-06-09 15:15:53 +08:00
87owo a304a2f02d Add files via upload 2026-06-09 13:49:52 +08:00
87owo 9456659544 Add files via upload 2026-06-09 13:49:23 +08:00
87owo 3ec340e0da Add files via upload 2026-06-09 13:48:47 +08:00
87owo f1f35badcb Update LICENSE.txt 2026-06-09 04:08:32 +08:00
87owo 045160c482 Update LICENSE.txt 2026-06-09 04:06:41 +08:00
87owo 559c493997 Update LICENSE.txt 2026-06-09 04:03:01 +08:00
87owo 936475f5bf Merge pull request #63 from WBT907/main
Fixed a bug where PYAS process protection was not working. (To be verified)
2026-06-08 10:41:36 +08:00
wangbotao e97f8eed54 修复 PYAS 进程保护失效 Bug
修复任务管理器可以成功终止 PYAS 进程的问题。原代码中进程保护完全依赖于 GlobalData.PyasPid ,而该变量只有在用户模式程序成功连接到驱动通信端口后才会被设置。如果连接未建立或断开, PyasPid 为 0,导致 IsTargetProtected() 始终返回 FALSE ,进程保护完全失效。
2026-06-07 20:05:38 +08:00
87owo eb1955779b Add files via upload 2026-06-06 12:39:10 +08:00
87owo 2e5b4cc5a1 Add files via upload 2026-06-05 21:25:07 +08:00
87owo 38b4f96437 Add files via upload 2026-06-05 21:24:24 +08:00
87owo 173922d0ce Add files via upload 2026-06-05 19:21:52 +08:00
87owo 99303a237e Add files via upload 2026-06-05 14:30:56 +08:00
87owo 8f7baf2790 Add files via upload 2026-06-05 13:49:43 +08:00
87owo b673336b3f Add files via upload 2026-06-01 19:41:23 +08:00
87owo e37400a0f3 Add files via upload 2026-06-01 18:58:54 +08:00
87owo 7b9474521d Add files via upload 2026-06-01 17:37:51 +08:00
87owo 78c3f2c9b8 Add files via upload 2026-06-01 16:59:04 +08:00
87owo ad256abb7c Add files via upload 2026-06-01 13:59:39 +08:00
87owo 86d160ae5f Add files via upload 2026-06-01 12:55:09 +08:00
87owo fde6afb39e Add files via upload 2026-05-31 23:59:07 +08:00
87owo 7c3e78296a Add files via upload 2026-05-31 23:35:58 +08:00
87owo 9cc06ff767 Add files via upload 2026-05-31 23:09:51 +08:00
87owo 766b6e81d0 Add files via upload 2026-05-28 16:20:20 +08:00
87owo 0349e01629 Add files via upload 2026-05-28 15:53:52 +08:00
87owo 0bd9da2bbc Add files via upload 2026-05-28 14:31:24 +08:00
87owo f14c7c3f55 Add files via upload 2026-05-28 14:05:15 +08:00
87owo ef5793fb15 Add files via upload 2026-05-26 09:30:27 +08:00
87owo 9f22fe6d97 Add files via upload 2026-05-26 09:29:51 +08:00
87owo 3147d576ee Add files via upload 2026-05-25 22:53:18 +08:00
87owo 2ceec2588c Add files via upload 2026-05-25 14:19:26 +08:00
87owo 5b4d88b9c7 Add files via upload 2026-05-25 14:18:52 +08:00
87owo 55043cca36 Add files via upload 2026-05-24 02:44:05 +08:00
87owo 097ebe025f Add files via upload 2026-05-23 14:10:33 +08:00
87owo 9f92307f64 Add files via upload 2026-05-22 13:49:52 +08:00
87owo c220035fd9 Add files via upload 2026-05-21 00:27:56 +08:00
87owo d7b98d3cde Add files via upload 2026-05-21 00:27:38 +08:00
87owo 0ab876633f Add files via upload 2026-05-21 00:27:01 +08:00
87owo cabe76ca54 Add files via upload 2026-05-21 00:26:14 +08:00
87owo c57224e258 Add files via upload 2026-05-21 00:25:35 +08:00
87owo b56101d2e6 Add files via upload 2026-05-18 21:31:43 +08:00
87owo 16211c28d1 Add files via upload 2026-05-17 16:48:13 +08:00
87owo 139d3e0c3d Add files via upload 2026-05-17 16:47:14 +08:00
87owo f0652fc5ec Add files via upload 2026-05-17 01:32:52 +08:00
87owo 55489cd634 Add files via upload 2026-05-17 01:31:49 +08:00
87owo 742887c0e4 Add files via upload 2026-05-15 22:34:23 +08:00
87owo c3e5cd2c0d Add files via upload 2026-05-15 22:33:13 +08:00
87owo 63e125627c Update README.md 2026-05-15 14:39:15 +08:00
87owo c0189e9d05 Add files via upload 2026-05-14 22:31:46 +08:00
87owo 133e3208ec Add files via upload 2026-05-14 20:02:53 +08:00
87owo 17c6fd6d0f Add files via upload 2026-05-13 18:37:07 +08:00
87owo 2aa7ea43b8 Add files via upload 2026-05-13 17:56:05 +08:00
87owo 6d7dbfac31 Add files via upload 2026-05-13 00:51:04 +08:00
87owo d4942c6dd6 Add files via upload 2026-05-13 00:49:54 +08:00
87owo 39ae3c24f6 Add files via upload 2026-05-12 22:41:11 +08:00
87owo a04d74a949 Add files via upload 2026-05-10 17:54:55 +08:00
87owo b93a7ebd94 Add files via upload 2026-05-10 17:45:08 +08:00
87owo cbc7b0340f Add files via upload 2026-05-10 17:38:28 +08:00
87owo ea7a197848 Add files via upload 2026-05-10 17:31:14 +08:00
87owo 82d4df889e Add files via upload 2026-05-10 13:06:24 +08:00
87owo df3a2a1010 Add files via upload 2026-05-10 13:06:05 +08:00
87owo 67cd6c2f59 Add files via upload 2026-05-10 02:30:07 +08:00
87owo b1788e7df9 Add files via upload 2026-05-10 02:28:27 +08:00
87owo 1cb8a81518 Add files via upload 2026-05-10 00:06:45 +08:00
87owo e1b61f2675 Update README.md 2026-05-09 22:53:01 +08:00
87owo 834d44856c Add files via upload 2026-05-09 22:49:48 +08:00
87owo c088eeb5bc Add files via upload 2026-05-09 22:47:09 +08:00
87owo 921510b7b7 Add files via upload 2026-05-09 22:27:36 +08:00
87owo 17a54f7a8a Add files via upload 2026-05-08 20:02:34 +08:00
87owo 43ff924efc Add files via upload 2026-05-08 18:24:36 +08:00
87owo f9bd4b6628 Add files via upload 2026-05-08 18:20:52 +08:00
87owo 702aa22139 Delete Interface/static/js/style.css 2026-05-08 18:20:37 +08:00
87owo 57d53f63e5 Add files via upload 2026-05-08 18:17:20 +08:00
87owo 835ada4a53 Add files via upload 2026-05-08 13:51:08 +08:00
87owo 7f204f3e1b Add files via upload 2026-05-08 10:53:11 +08:00
87owo 70e13b8414 Delete Engine/Properties/train_server_lfp.py 2026-05-07 14:13:19 +08:00
87owo df9bb8cbb8 Add files via upload 2026-05-07 14:12:56 +08:00
87owo cebdb32502 Add files via upload 2026-05-07 13:58:44 +08:00
87owo 58bd61343a Add files via upload 2026-05-06 14:27:54 +08:00
87owo 90faf1007e Add files via upload 2026-05-06 14:14:48 +08:00
87owo f8dbd12b69 Add files via upload 2026-05-06 12:54:54 +08:00
87owo cf6ba66dd2 Add files via upload 2026-05-04 23:29:36 +08:00
87owo 2080b5d10a Add files via upload 2026-05-04 23:29:14 +08:00
87owo dd180977d9 Add files via upload 2026-05-04 23:28:48 +08:00
87owo 221dcbaf1b Add files via upload 2026-05-04 23:28:13 +08:00
87owo 1a2098f4fb Add files via upload 2026-05-04 23:27:50 +08:00
87owo 73eab17110 Add files via upload 2026-05-03 11:34:05 +08:00
87owo 978a336358 Update README.md 2026-05-03 03:27:57 +08:00
87owo 6a0fd4e427 Update README.md 2026-05-03 03:23:58 +08:00
87owo 5fd4efd920 Add files via upload 2026-05-03 03:20:31 +08:00
87owo 43be2987f5 Add files via upload 2026-05-02 17:47:38 +08:00
87owo 06cc048fdc Add files via upload 2026-05-02 17:47:03 +08:00
87owo 5752471420 Add files via upload 2026-05-02 16:16:46 +08:00
87owo 3dfe12b90a Add files via upload 2026-05-02 15:48:47 +08:00
87owo ad1e3501b1 Add files via upload 2026-05-02 15:33:52 +08:00
87owo 1b46572e4c Add files via upload 2026-05-02 15:09:42 +08:00
87owo 9d8e42d34c Add files via upload 2026-05-02 15:09:28 +08:00
87owo 3f6e9dab3e Add files via upload 2026-05-02 15:09:06 +08:00
87owo ad85f11875 Add files via upload 2026-05-02 01:49:17 +08:00
87owo 9ae31834cc Add files via upload 2026-05-02 01:16:32 +08:00
87owo 49a4dc6942 Add files via upload 2026-05-02 01:16:05 +08:00
87owo a9f58cc30f Add files via upload 2026-05-02 01:15:51 +08:00
87owo bdb2198582 Add files via upload 2026-05-02 01:15:28 +08:00
87owo f32a77ca8b Add files via upload 2026-05-01 23:16:30 +08:00
87owo 121d3fb0ae Add files via upload 2026-05-01 23:15:59 +08:00
87owo 1dd72f7600 Add files via upload 2026-05-01 23:15:22 +08:00
87owo c7c168b007 Add files via upload 2026-05-01 23:14:45 +08:00
87owo 441b41c6af Add files via upload 2026-05-01 23:13:56 +08:00
87owo 49a907283a Add files via upload 2026-05-01 15:41:33 +08:00
87owo 0ffc52f9ba Add files via upload 2026-05-01 13:10:33 +08:00
87owo 4e96ec49e7 Update README.md 2026-04-29 21:04:53 +08:00
87owo dfb4646f51 Delete Embed directory 2026-04-29 21:04:30 +08:00
87owo a8e82c38c9 Add files via upload 2026-04-29 18:09:24 +08:00
87owo dba23289fd Add files via upload 2026-04-29 17:41:00 +08:00
87owo c2c1eb98d9 Add files via upload 2026-04-29 16:19:44 +08:00
87owo 364176912d Add files via upload 2026-04-28 14:38:35 +08:00
87owo 202245baad Add files via upload 2026-04-28 14:10:07 +08:00
87owo c3fa99640c Add files via upload 2026-04-27 15:03:53 +08:00
87owo a7c34b5a6a Add files via upload 2026-04-27 10:19:47 +08:00
87owo 05de092642 Update README.md 2026-04-26 22:35:28 +08:00
87owo 1bfa40c841 Add files via upload 2026-04-26 21:13:42 +08:00
87owo c325435ae8 Add files via upload 2026-04-26 15:41:47 +08:00
87owo b978bd41c3 Add files via upload 2026-04-26 14:31:23 +08:00
87owo f03d8733b0 Add files via upload 2026-04-26 14:30:49 +08:00
87owo a624b3b759 Update README.md 2026-04-26 14:29:57 +08:00
87owo d683398ba9 Add files via upload 2026-04-26 14:28:24 +08:00
87owo 42f692b82d Add files via upload 2026-04-26 14:27:33 +08:00
87owo 855fe9115e Delete Engine/Pattern directory 2026-04-26 14:26:30 +08:00
87owo d6bd383822 Add files via upload 2026-04-26 02:13:58 +08:00
87owo b1b77b73ac Add files via upload 2026-04-25 21:45:46 +08:00
87owo 8d87adcc50 Add files via upload 2026-04-25 21:45:32 +08:00
87owo 49bf6c54e7 Delete Interface/main.py 2026-04-25 20:53:22 +08:00
87owo 7e92e0b1d9 Add files via upload 2026-04-25 20:52:55 +08:00
87owo f0805d320c Add files via upload 2026-04-25 19:19:36 +08:00
87owo 364f48a6f0 Update README.md 2026-04-25 16:55:34 +08:00
87owo cfebf6df0e Update README.md 2026-04-25 16:40:38 +08:00
87owo 688855b72d Update README.md 2026-04-25 16:38:08 +08:00
87owo 77b275a04b Update README.md 2026-04-25 16:30:11 +08:00
87owo 98b142df12 Update README.md 2026-04-25 16:01:11 +08:00
87owo c5fe845f18 Delete PYAS_Resource.py 2026-04-25 15:59:56 +08:00
87owo e5e9629d31 Delete PYAS_Interface.py 2026-04-25 15:59:48 +08:00
87owo b65b9e6bfb Delete PYAS_Config.py 2026-04-25 15:59:26 +08:00
87owo 93ae8b02e3 Add files via upload 2026-04-25 15:55:56 +08:00
87owo 5c183ea200 Add files via upload 2026-04-25 15:54:58 +08:00
87owo 661765f08c Add files via upload 2026-04-25 15:54:33 +08:00
87owo 60fa19c681 Add files via upload 2026-04-25 15:53:27 +08:00
87owo 606eddba53 Add files via upload 2026-04-21 14:56:52 +08:00
87owo 71605ade31 Add files via upload 2026-04-19 02:21:41 +08:00
87owo ee409e4872 Add files via upload 2026-04-18 01:41:13 +08:00
87owo 91024abc4a Add files via upload 2026-04-15 19:59:41 +08:00
87owo 99de36a6cf Add files via upload 2026-04-15 19:57:35 +08:00
87owo ac1e48dc30 Add files via upload 2026-04-12 13:49:40 +08:00
87owo 494bab3380 Add files via upload 2026-04-12 13:42:38 +08:00
87owo 6696ca93ce Add files via upload 2026-04-11 16:50:33 +08:00
87owo b7e80fb8ed Add files via upload 2026-04-10 17:47:07 +08:00
87owo ce5b642d3e Add files via upload 2026-04-10 15:50:15 +08:00
87owo 76d414164a Update PYAS.py 2026-04-10 15:16:07 +08:00
87owo b6d13047ba Merge pull request #40 from MichaelMVS/fix-bare-except-clauses
Fix bare except clauses to catch only Exception types
2026-04-10 15:05:22 +08:00
87owo f1ba295796 Update README.md 2026-04-10 14:45:49 +08:00
zocomputer 415abef4fc Fix bare except clauses to catch only Exception types
Replace bare 'except:' with 'except Exception:' in three locations:
- check_process_survival (line ~1632): when accessing pe.szExeFile
- get_process_name (line ~1782): when getting process name from snapshot
- pipe_server_thread (line ~2340): when terminating malicious processes

Bare except clauses also catch SystemExit and KeyboardInterrupt,
which can prevent proper shutdown and mask serious issues.
Using 'except Exception:' allows the code to properly handle
expected errors while letting system-exiting events propagate.
2026-04-10 06:40:26 +00:00
87owo 95af2014d8 Update README.md 2026-04-10 14:39:38 +08:00
87owo f75b039daf Add files via upload 2026-04-10 14:35:02 +08:00
87owo 65b1ac78f3 Rename train_vt.py to train_server_lfp.py 2026-04-10 14:27:44 +08:00
87owo b067591882 Add files via upload 2026-04-10 14:24:58 +08:00
87owo 7941d76fd7 Delete Engine/Properties/train.py 2026-04-10 14:13:24 +08:00
87owo 7bff601beb Add files via upload 2026-04-10 14:12:27 +08:00
87owo 7b4da32bee Update README.md 2026-04-10 14:00:42 +08:00
87owo bbf2974703 Update README.md 2026-04-10 13:50:28 +08:00
87owo f5abaf06de Add files via upload 2026-04-08 17:57:14 +08:00
87owo 88023dd09e Add files via upload 2026-04-08 01:20:52 +08:00
87owo eec2996fab Add files via upload 2026-04-07 23:53:35 +08:00
87owo 97ca200c29 Add files via upload 2026-04-07 23:52:55 +08:00
87owo f0600ea3a3 Add files via upload 2026-04-07 23:52:20 +08:00
87owo 19b3eb51d7 Add files via upload 2026-04-04 16:02:36 +08:00
87owo 871dabf142 Add files via upload 2026-04-02 01:30:02 +08:00
87owo 58795b9349 Add files via upload 2026-04-01 23:42:12 +08:00
87owo 1ef769842b Add files via upload 2026-04-01 22:45:57 +08:00
87owo 6051570414 Add files via upload 2026-04-01 22:45:18 +08:00
87owo da5d5d0dc7 Add files via upload 2026-03-31 19:39:18 +08:00
87owo 782aa22d4d Add files via upload 2026-03-31 19:14:08 +08:00
87owo 0084867f38 Add files via upload 2026-03-29 21:14:20 +08:00
87owo 5a27858f86 Add files via upload 2026-03-27 02:17:54 +08:00
87owo 7905d8375f Add files via upload 2026-03-25 15:59:26 +08:00
87owo ba8aa63d75 Add files via upload 2026-03-16 15:10:16 +08:00
87owo ac82778e26 Add files via upload 2026-03-11 17:55:19 +08:00
87owo 55d2661e38 Add files via upload 2026-03-11 17:37:54 +08:00
87owo 4803b89294 Update train.py 2026-03-11 16:05:26 +08:00
87owo e48adbd87d Add files via upload 2026-03-11 16:00:07 +08:00
87owo 227314d83c Add files via upload 2026-03-08 03:53:52 +08:00
87owo 3c0e21eb02 Add files via upload 2026-03-08 03:42:55 +08:00
87owo 86d6153ef1 Add files via upload 2026-03-08 02:56:01 +08:00
87owo 78cf8bded3 Add files via upload 2026-03-07 12:50:56 +08:00
87owo 26d12181cd Add files via upload 2026-03-07 12:49:07 +08:00
87owo 8d184b011c Add files via upload 2026-03-01 18:40:56 +08:00
87owo ed3a1444ec Add files via upload 2026-03-01 18:19:34 +08:00
87owo d3e70a47cd Add files via upload 2026-03-01 18:19:08 +08:00
87owo 3171151219 Add files via upload 2026-03-01 18:16:04 +08:00
87owo e407867635 Add files via upload 2026-03-01 17:46:39 +08:00
87owo 6d9cfab55f Add files via upload 2026-02-26 02:50:09 +08:00
87owo f0bce029f0 Add files via upload 2026-02-26 01:21:41 +08:00
87owo d47960a0cf Add files via upload 2026-02-26 01:20:03 +08:00
87owo 8416018afe Add files via upload 2026-02-23 17:48:40 +08:00
87owo e93fc70169 Add files via upload 2026-02-23 17:47:50 +08:00
87owo 5b3474c781 Add files via upload 2026-02-23 01:04:21 +08:00
87owo 8d2a9f3b2b Add files via upload 2026-02-20 14:14:19 +08:00
87owo 73d09f9b09 Add files via upload 2026-02-20 13:49:18 +08:00
87owo 4e7c6efa2a Add files via upload 2026-02-20 13:46:13 +08:00
87owo 81a884bc61 Update PYAS_Engine.py 2026-02-18 23:56:27 +08:00
87owo ac4f960352 Add files via upload 2026-02-10 17:45:23 +08:00
87owo e4b3e4e438 Add files via upload 2026-02-10 17:44:48 +08:00
87owo d6ee476296 Add files via upload 2026-02-10 17:44:15 +08:00
87owo c23741ba9a Add files via upload 2026-02-10 17:43:47 +08:00
87owo 7bac5b4740 Add files via upload 2026-02-10 17:43:04 +08:00
87owo 1fe440168e Add files via upload 2026-02-04 23:11:56 +08:00
87owo 26ad57138b Add files via upload 2026-02-04 23:11:14 +08:00
87owo 92e1fdaf0f Add files via upload 2026-02-04 23:09:59 +08:00
87owo 357540d0ad Update README.md 2026-01-24 01:19:33 +08:00
87owo 405622a91e Update README.md 2026-01-24 01:14:02 +08:00
87owo 5686c73c56 Update README.md 2026-01-24 01:11:38 +08:00
87owo 76e2f787ac Update README.md 2026-01-24 01:10:28 +08:00
87owo 02b67f4e6a Update README.md 2026-01-24 01:06:59 +08:00
87owo a2ab527761 Update README.md 2026-01-24 01:05:17 +08:00
87owo f1142ae742 Add files via upload 2026-01-23 14:48:01 +08:00
87owo decb222dac Add files via upload 2026-01-23 14:25:34 +08:00
87owo 00c598e6f7 Add files via upload 2026-01-23 14:25:11 +08:00
87owo e9843dd3a5 Add files via upload 2026-01-23 14:24:27 +08:00
87owo 37f390742b Add files via upload 2026-01-23 14:23:14 +08:00
87owo 533e7dfd15 Add files via upload 2026-01-23 13:49:06 +08:00
87owo ddcbe1cd51 Delete Engine directory 2026-01-23 13:46:15 +08:00
87owo 4eabd04bc6 Add files via upload 2026-01-23 13:44:24 +08:00
87owo c8f2da6ac9 Add files via upload 2026-01-23 13:43:17 +08:00
87owo 8820ac4bf3 Add files via upload 2026-01-23 13:42:37 +08:00
87owo 236b200f39 Add files via upload 2026-01-12 14:28:24 +08:00
87owo 6789e32674 Add files via upload 2026-01-12 14:27:37 +08:00
87owo 9eb55deedf Add files via upload 2026-01-12 13:29:30 +08:00
87owo 6e76b5b8eb Add files via upload 2026-01-12 13:28:04 +08:00
87owo 491b0da83d Add files via upload 2026-01-10 22:48:17 +08:00
87owo 5d2c17e940 Add files via upload 2026-01-10 22:47:35 +08:00
87owo 0497c4a9e7 Add files via upload 2026-01-10 20:05:44 +08:00
87owo 6d0765848b Add files via upload 2026-01-10 20:03:39 +08:00
87owo 40c4ae71bd Merge pull request #35 from secretlay3r/main
refactor: replace ifs with dicts/sets + simplify exception handling
2026-01-10 19:37:25 +08:00
secretlay3r 8edba10dff Update PYAS.py
backup_mbr():
- Shorten except blocks logic into one
- Add len(mbr) == 512 check  
- Add MBR_SIGNATURE instead of just b"\x55\xAA"

pipe_server_thread():
- Replace whole ifs chain with RULES dict
- Replace [4001, 5001] with KILL_CODES set (for readability)

get_window_info()  and  get_process_name():
- Extract process name logic into private _get_process_name()
2026-01-10 14:17:27 +03:00
87owo 85aa7bc652 Add files via upload 2026-01-09 14:05:47 +08:00
87owo 854ad1db07 Add files via upload 2026-01-09 00:11:30 +08:00
87owo 955600a1e1 Add files via upload 2026-01-07 22:19:13 +08:00
87owo b739134d85 Add files via upload 2026-01-07 22:18:36 +08:00
87owo 723152566d Add files via upload 2026-01-07 21:10:34 +08:00
87owo 678b045e0e Update README.md 2026-01-07 17:47:13 +08:00
87owo 681f4df49a Add files via upload 2026-01-07 17:44:23 +08:00
87owo b19f7d7098 Add files via upload 2026-01-06 15:11:42 +08:00
87owo daaae3ec10 Add files via upload 2026-01-06 14:43:06 +08:00
87owo c14957afff Update and rename convert_full.py to convert.py 2026-01-04 22:34:35 +08:00
87owo 843a4998f1 Delete Engine/Model/convert.py 2026-01-04 20:45:08 +08:00
87owo 9637e74edc Add files via upload 2026-01-04 20:17:23 +08:00
87owo b1bdf4f671 Add files via upload 2026-01-04 18:55:43 +08:00
87owo 238ed8e364 Add files via upload 2026-01-04 18:55:04 +08:00
87owo 8aa1509863 Add files via upload 2026-01-04 13:41:45 +08:00
87owo aac182e30b Add files via upload 2026-01-04 13:40:19 +08:00
87owo ac7e953acc Add files via upload 2026-01-04 12:28:25 +08:00
87owo 6ae0f27e05 Add files via upload 2026-01-04 11:46:45 +08:00
87owo f6e5a92400 Add files via upload 2026-01-02 22:27:59 +08:00
87owo 5e5ff3428c Add files via upload 2026-01-02 22:26:42 +08:00
87owo 1cdbb9c402 Add files via upload 2026-01-02 22:25:22 +08:00
87owo 8caacd1870 Update README.md 2026-01-01 21:38:30 +08:00
87owo cfbc4c9c20 Update README.md 2026-01-01 21:29:21 +08:00
87owo 76dbf1c5d0 Add files via upload 2026-01-01 20:38:03 +08:00
87owo c0e7c4afa5 Add files via upload 2026-01-01 18:31:39 +08:00
87owo 9da0970d85 Delete ProtectRules.cpp 2026-01-01 18:31:01 +08:00
87owo d6f2ad32a7 Delete ProtectRegistry.cpp 2026-01-01 18:30:54 +08:00
87owo 8dbc87a331 Delete ProtectProcess.cpp 2026-01-01 18:30:45 +08:00
87owo 77eb1ce44e Delete ProtectFile.cpp 2026-01-01 18:30:37 +08:00
87owo e12f4ae61a Delete ProtectBoot.cpp 2026-01-01 18:30:29 +08:00
87owo c23a73625f Delete DriverEntry.cpp 2026-01-01 18:30:20 +08:00
87owo 3a66946686 Delete DriverCommon.h 2026-01-01 18:30:13 +08:00
87owo 7fef43701f Add files via upload 2026-01-01 18:29:52 +08:00
87owo 7f5eb34ac6 Add files via upload 2026-01-01 17:41:40 +08:00
87owo ba4369f829 Add files via upload 2026-01-01 03:39:49 +08:00
87owo 81af2e51fc Delete Plugins/Filter/ProtectScreen.c 2026-01-01 03:37:53 +08:00
87owo dff09064c8 Delete Plugins/Filter/ProtectRules.h 2026-01-01 03:37:45 +08:00
87owo ee0bb32cce Delete Plugins/Filter/ProtectRules.c 2026-01-01 03:37:35 +08:00
87owo 4a215c308b Delete Plugins/Filter/ProtectRegistry.c 2026-01-01 03:37:18 +08:00
87owo 79493a96ea Delete Plugins/Filter/ProtectRemote.c 2026-01-01 03:37:07 +08:00
87owo 3cca1c4671 Delete Plugins/Filter/ProtectProcess.c 2026-01-01 03:36:54 +08:00
87owo 72e9923d08 Delete Plugins/Filter/ProtectMatch.h 2026-01-01 03:36:43 +08:00
87owo 406e152891 Delete Plugins/Filter/ProtectMatch.c 2026-01-01 03:36:27 +08:00
87owo e9eb569d50 Delete Plugins/Filter/ProtectInject.c 2026-01-01 03:36:17 +08:00
87owo 640b389e44 Delete Plugins/Filter/ProtectImage.c 2026-01-01 03:36:07 +08:00
87owo 314e3349d6 Delete Plugins/Filter/ProtectFile.c 2026-01-01 03:35:56 +08:00
87owo 0ae4d72bc9 Delete Plugins/Filter/ProtectBoot.c 2026-01-01 03:35:45 +08:00
87owo 8920a5fb21 Delete Plugins/Filter/DriverPipe.c 2026-01-01 03:35:34 +08:00
87owo b338ff5dd9 Delete Plugins/Filter/DriverEntry.h 2026-01-01 03:35:25 +08:00
87owo 87e2fcb37c Delete Plugins/Filter/DriverEntry.c 2026-01-01 03:35:05 +08:00
87owo bab43e3b17 Add files via upload 2026-01-01 03:34:44 +08:00
87owo e602088330 Add files via upload 2025-12-29 20:14:49 +08:00
87owo 2f6db92077 Add files via upload 2025-12-29 20:14:14 +08:00
87owo cee33c0f77 Add files via upload 2025-12-28 14:58:49 +08:00
87owo 4fcdaa10b6 Add files via upload 2025-12-28 14:54:52 +08:00
87owo 949f74ab04 Add files via upload 2025-12-28 14:21:07 +08:00
87owo ef68a89b45 Add files via upload 2025-12-28 14:20:35 +08:00
87owo 10ecb35cca Add files via upload 2025-12-28 14:12:29 +08:00
87owo 696ac22f77 Add files via upload 2025-12-27 15:17:13 +08:00
87owo 8d13f98030 Add files via upload 2025-12-27 02:09:29 +08:00
87owo 1dddf13a9d Add files via upload 2025-12-27 02:08:10 +08:00
87owo 855472239a Delete Engine/Model/train_torch.py 2025-12-27 01:42:33 +08:00
87owo dc5d317623 Delete Engine/Model/train_tensorflow.py 2025-12-27 01:42:24 +08:00
87owo 91011e9e2a Add files via upload 2025-12-27 01:42:07 +08:00
87owo bb09b75d3b Add files via upload 2025-12-27 01:41:45 +08:00
87owo b2f9adad66 Add files via upload 2025-12-27 01:41:03 +08:00
87owo 0c2c84d2a9 Add files via upload 2025-12-26 15:13:42 +08:00
87owo 1733e7cc86 Add files via upload 2025-12-25 23:49:05 +08:00
87owo 831d9a9895 Add files via upload 2025-12-25 18:53:53 +08:00
87owo 70ba3a629d Update README.md 2025-12-25 03:14:28 +08:00
87owo 29e9702d21 Update README.md 2025-12-25 03:12:28 +08:00
87owo f8ef756bd4 Add files via upload 2025-12-25 01:23:41 +08:00
87owo 233b28e8a5 Add files via upload 2025-12-24 22:34:19 +08:00
87owo da77c17be5 Add files via upload 2025-12-24 14:33:17 +08:00
87owo 8dfa76822e Delete Engine/Model/train.py 2025-12-24 14:32:38 +08:00
87owo 4163991b66 Add files via upload 2025-12-24 14:32:18 +08:00
87owo 78323c9a08 Add files via upload 2025-12-24 14:31:06 +08:00
87owo eb517e86f3 Add files via upload 2025-12-24 14:30:13 +08:00
87owo e24f3823cb Add files via upload 2025-12-24 11:15:31 +08:00
87owo fd3e8ee28a Update README.md 2025-12-21 23:27:08 +08:00
87owo a980ea7bd6 Update README.md 2025-12-21 23:26:00 +08:00
87owo 20ce73c54f Update README.md 2025-12-21 23:17:32 +08:00
87owo d8f22f7f28 Update README.md 2025-12-21 23:16:03 +08:00
87owo 591055edaf Update README.md 2025-12-21 23:13:09 +08:00
87owo fbf0e06c04 Update LICENSE.txt 2025-12-19 22:46:40 +08:00
87owo 9daf327e80 Update README.md 2025-12-19 22:42:21 +08:00
87owo 4441978e10 Update LICENSE.txt 2025-12-19 22:38:14 +08:00
87owo d8eb770735 Update LICENSE.txt 2025-12-18 20:12:03 +08:00
87owo cefbf79c6e Update LICENSE.txt 2025-12-11 20:01:08 +08:00
87owo fc8762094e Update LICENSE.txt 2025-12-11 20:00:42 +08:00
87owo 801c3aadcc Update LICENSE.txt 2025-12-09 11:43:08 +08:00
87owo 4296f1ec43 Add files via upload 2025-11-27 15:28:31 +08:00
87owo a7f469747c Add files via upload 2025-11-27 14:57:17 +08:00
87owo 68d0352343 Add files via upload 2025-11-27 14:56:17 +08:00
87owo 01e6d09f7c Update train.py 2025-11-26 17:56:08 +08:00
87owo 6582abfd4a Update train.py 2025-11-26 17:26:31 +08:00
87owo f8f4b303d7 Update LICENSE.txt 2025-11-01 17:08:11 +08:00
87owo 79f05a23a8 Add files via upload 2025-10-08 11:51:18 +08:00
87owo 95845c5c85 Add files via upload 2025-10-08 11:05:43 +08:00
87owo cd1a24290e Add files via upload 2025-10-07 23:08:14 +08:00
87owo 21261bfb17 Add files via upload 2025-10-07 22:48:17 +08:00
87owo 79abf51cb8 Add files via upload 2025-10-07 22:25:51 +08:00
87owo e538b837d5 Add files via upload 2025-10-07 21:53:12 +08:00
87owo 7b995e1223 Add files via upload 2025-09-16 20:12:31 +08:00
87owo c7826b58a3 Add files via upload 2025-09-16 20:04:32 +08:00
87owo 5786dbdb75 Add files via upload 2025-09-16 20:03:15 +08:00
87owo 0f42c19ec7 Delete README_zh_TW.md 2025-09-10 13:43:50 +08:00
87owo 87d44a64f3 Delete README_zh_CN.md 2025-09-10 13:43:40 +08:00
87owo 77dd4ace33 Update README.md 2025-09-10 13:43:14 +08:00
87owo 0907d71957 Update README.md 2025-09-10 13:36:40 +08:00
87owo e7a30646e3 Update README.md 2025-09-10 13:35:25 +08:00
87owo 98d21b3391 Update LICENSE.txt 2025-09-09 09:45:56 +08:00
87owo 35d9203b9c Update LICENSE.txt 2025-09-09 09:32:39 +08:00
87owo e6e384a7f7 Rename LICENSE.md to LICENSE.txt 2025-09-09 08:45:38 +08:00
87owo 7d954c14ae Rename LICENSE.txt to LICENSE.md 2025-09-09 08:45:19 +08:00
PYDT 41388962e2 Add files via upload 2025-08-29 17:59:44 +08:00
PYDT 6d51f6b6a9 Add files via upload 2025-08-29 16:42:14 +08:00
PYDT c7af9a3702 Add files via upload 2025-08-29 16:41:38 +08:00
PYDT da7c61202c Add files via upload 2025-08-28 13:36:16 +08:00
PYDT c24e872a33 Add files via upload 2025-08-28 10:28:15 +08:00
PYDT d0809ec313 Add files via upload 2025-08-28 08:58:42 +08:00
PYDT c1a796da38 Add files via upload 2025-08-27 17:53:10 +08:00
PYDT 98c27800e0 Add files via upload 2025-08-26 10:11:36 +08:00
PYDT 7a18eadd13 Add files via upload 2025-08-25 23:50:38 +08:00
PYDT b07adb7b30 Add files via upload 2025-08-25 23:23:42 +08:00
PYDT 4d7c3cce4d Add files via upload 2025-08-25 20:28:36 +08:00
PYDT 4ff0ab9cd8 Add files via upload 2025-08-25 09:42:51 +08:00
PYDT 264dd50969 Add files via upload 2025-08-25 08:49:53 +08:00
PYDT 26d0ad1a6e Add files via upload 2025-08-24 22:06:31 +08:00
PYDT 90284018e5 Add files via upload 2025-08-24 22:06:02 +08:00
PYDT 46eeec16d4 Add files via upload 2025-08-24 22:05:30 +08:00
PYDT 083fb0dccc Add files via upload 2025-08-23 22:07:39 +08:00
PYDT d46f145806 Delete Plugins/Filter/ProtectReg.c 2025-08-23 22:04:35 +08:00
PYDT 868eddfd2b Add files via upload 2025-08-23 22:04:11 +08:00
PYDT 8295e6bb5b Add files via upload 2025-08-22 23:13:46 +08:00
PYDT 424914b842 Add files via upload 2025-08-22 22:16:20 +08:00
PYDT 8c5027df0f Delete Plugins/Filter/ProtectBoot.c 2025-08-22 21:16:55 +08:00
PYDT 0b7817d992 Add files via upload 2025-08-22 21:16:36 +08:00
PYDT ca6c9bfd05 Add files via upload 2025-08-22 05:31:46 +08:00
PYDT 0a1abd8040 Add files via upload 2025-08-22 05:27:25 +08:00
PYDT ed69a4fdf6 Add files via upload 2025-08-22 05:20:50 +08:00
PYDT 2ae19a6d4e Add files via upload 2025-08-22 05:08:52 +08:00
PYDT 404bc50dd4 Add files via upload 2025-08-22 04:56:09 +08:00
PYDT cada5eeeaf Add files via upload 2025-08-22 04:16:55 +08:00
PYDT 5e9bd40e8b Add files via upload 2025-08-22 03:22:40 +08:00
PYDT 0788bab0dd Add files via upload 2025-08-22 03:21:51 +08:00
PYDT 4e8e0dbea7 Add files via upload 2025-08-19 08:27:20 +08:00
PYDT b8c5279137 Add files via upload 2025-08-19 07:52:24 +08:00
PYDT a3255b1681 Add files via upload 2025-08-19 07:43:35 +08:00
PYDT f151379f8f Add files via upload 2025-08-18 22:49:35 +08:00
PYDT 7784544583 Add files via upload 2025-08-18 15:34:45 +08:00
PYDT f742937296 Add files via upload 2025-08-18 00:29:36 +08:00
PYDT 5fd9242291 Add files via upload 2025-08-17 15:30:24 +08:00
PYDT 9f343196a9 Add files via upload 2025-08-17 00:04:25 +08:00
PYDT 5468eded04 Add files via upload 2025-08-17 00:01:22 +08:00
PYDT 1b97758fc9 Add files via upload 2025-08-16 23:57:22 +08:00
PYDT b2e8e49447 Add files via upload 2025-08-16 23:56:03 +08:00
PYDT 3eec781139 Add files via upload 2025-08-16 15:37:39 +08:00
PYDT b6f1977fa0 Add files via upload 2025-08-16 00:02:23 +08:00
PYDT e0aa080f00 Add files via upload 2025-08-15 23:56:43 +08:00
PYDT 66aa76c836 Add files via upload 2025-08-15 23:55:49 +08:00
PYDT bb9444e1ae Update README_zh_CN.md 2025-08-15 19:19:35 +08:00
PYDT 6c9bfa7755 Update README_zh_TW.md 2025-08-15 19:18:26 +08:00
PYDT c4fa849290 Update README_zh_TW.md 2025-08-15 19:17:58 +08:00
PYDT 4807e2c410 Update README.md 2025-08-15 19:15:51 +08:00
PYDT 5388efdebc Update README.md 2025-08-15 19:13:15 +08:00
PYDT 1d656de7ba Add files via upload 2025-08-15 18:31:42 +08:00
PYDT eaa1d725a9 Update README_zh_TW.md 2025-08-15 18:01:43 +08:00
PYDT dea2150d63 Update README_zh_CN.md 2025-08-15 18:00:55 +08:00
PYDT 80f9d6cf75 Update README.md 2025-08-15 17:56:38 +08:00
PYDT 7430d38594 Update README.md 2025-08-15 17:54:45 +08:00
PYDT 6804e4af9f Update README_zh_CN.md 2025-08-15 16:38:23 +08:00
PYDT 138756c31d Update README_zh_TW.md 2025-08-15 16:37:50 +08:00
PYDT 349bc293c6 Update README.md 2025-08-15 16:37:17 +08:00
PYDT 2f87cd10f2 Update README.md 2025-08-15 16:30:41 +08:00
PYDT fc50eafcca Add files via upload 2025-08-15 16:13:36 +08:00
PYDT b48e20a727 Update README_zh_CN.md 2025-08-15 15:58:20 +08:00
PYDT ce7ed2e6eb Update README_zh_TW.md 2025-08-15 15:58:04 +08:00
PYDT 043d71e0ff Update README.md 2025-08-15 15:57:32 +08:00
PYDT 1855ae0e1d Delete Plugins/Filter/PYAS_Driver.sys 2025-08-15 15:48:29 +08:00
PYDT 77323a50df Add files via upload 2025-08-15 15:48:14 +08:00
PYDT 1c2f6b85ca Add files via upload 2025-08-15 15:47:36 +08:00
PYDT 2b5c478e4b Update and rename LICENSE.md to LICENSE.txt 2025-08-15 15:39:17 +08:00
PYDT 90fd83a81f Rename LICENSE.proprietary to LICENSE.md 2025-08-15 15:38:29 +08:00
PYDT 8fa2a166f3 Delete LICENSE 2025-08-15 15:36:54 +08:00
PYDT e8cc45ebe7 Update LICENSE.proprietary 2025-08-15 15:36:00 +08:00
PYDT eb87117b91 Rename LICENSE.md to LICENSE 2025-08-15 14:51:50 +08:00
PYDT 3799dfa1e8 Rename LICENSE.proprietary.md to LICENSE.proprietary 2025-08-15 14:51:37 +08:00
PYDT 163c7fd680 Rename LICENSE.proprietary to LICENSE.proprietary.md 2025-08-15 14:51:22 +08:00
PYDT 44ca762f69 Create LICENSE.proprietary 2025-08-15 14:50:15 +08:00
PYDT 8db311ba33 Add files via upload 2025-08-15 14:21:22 +08:00
PYDT 99d8604db4 Add files via upload 2025-08-15 11:14:46 +08:00
PYDT 90aa88daeb Update README.md 2025-08-14 20:31:29 +08:00
PYDT ae6eebad4d Update README_zh_CN.md 2025-08-14 20:30:39 +08:00
PYDT cd31ce1c38 Update README_zh_TW.md 2025-08-14 20:30:00 +08:00
PYDT ed3846e451 Update README_zh_TW.md 2025-08-14 20:28:02 +08:00
PYDT 0c79cf8e37 Update README_zh_CN.md 2025-08-14 20:25:36 +08:00
PYDT 81c7e16c0e Update README_zh_CN.md 2025-08-14 20:23:44 +08:00
PYDT 16c03095b8 Update README.md 2025-08-14 20:22:36 +08:00
PYDT b5dab3aa22 Update README_zh_CN.md 2025-08-14 20:21:11 +08:00
PYDT e4a3c871f8 Update README.md 2025-08-14 20:15:46 +08:00
PYDT a2fe947b08 Update README.md 2025-08-14 20:13:26 +08:00
PYDT 8df49ecfc1 Update README.md 2025-08-14 20:03:11 +08:00
PYDT 526b9bd4c7 Update README.md 2025-08-14 20:00:42 +08:00
PYDT c67ff3d936 Add files via upload 2025-08-14 14:21:47 +08:00
PYDT 417b17da98 Add files via upload 2025-08-13 16:35:12 +08:00
PYDT 4ca19a4eb0 Update README_zh_CN.md 2025-08-13 16:00:20 +08:00
PYDT e834dfb7ee Update README_zh_TW.md 2025-08-13 16:00:05 +08:00
PYDT 5e1ff74fb3 Update README.md 2025-08-13 15:59:50 +08:00
PYDT 7a1d0f2ca7 Delete Engine/Model/PYAS_Model_A1.onnx 2025-08-13 15:53:33 +08:00
PYDT b305522106 Delete Engine/Model/PYAS_Model.json 2025-08-13 15:53:15 +08:00
PYDT ff3495645a Add files via upload 2025-08-13 15:52:58 +08:00
PYDT ddc000321f Add files via upload 2025-08-13 15:41:32 +08:00
PYDT fe4e6af3b9 Add files via upload 2025-08-13 15:40:43 +08:00
PYDT a1a83cc32c Add files via upload 2025-08-13 15:39:56 +08:00
PYDT e37665218b Update README_zh_CN.md 2025-08-12 17:25:31 +08:00
PYDT 2a876f4136 Update README_zh_TW.md 2025-08-12 17:20:27 +08:00
PYDT 290d8e8a64 Update README_zh_TW.md 2025-08-12 17:19:09 +08:00
PYDT 121bce529f Update README_zh_TW.md 2025-08-12 17:17:17 +08:00
PYDT 1232d98573 Update README.md 2025-08-12 17:16:46 +08:00
PYDT 208d9150b0 Update README.md 2025-08-12 17:10:23 +08:00
PYDT 351bf7725e Update README.md 2025-08-12 17:07:56 +08:00
PYDT a547776766 Add files via upload 2025-08-12 17:06:02 +08:00
PYDT 86a8d20757 Add files via upload 2025-08-11 11:26:26 +08:00
PYDT 760c420f95 Delete Plugins/Filter directory 2025-08-11 11:26:15 +08:00
PYDT 44c2edf58e Add files via upload 2025-08-10 21:14:30 +08:00
PYDT e88207c232 Update README.md 2025-08-10 05:02:16 +08:00
PYDT f6b2450fcd Update README.md 2025-08-10 04:58:10 +08:00
PYDT a124ecd3ed Update README.md 2025-08-10 04:54:52 +08:00
PYDT 34fcc3d29e Update README.md 2025-08-10 04:43:12 +08:00
PYDT 5f3011eebc Update README.md 2025-08-10 04:40:49 +08:00
PYDT d4464edb6c Update README.md 2025-08-10 04:34:13 +08:00
PYDT 1dc89a80db Update README.md 2025-08-10 04:33:27 +08:00
PYDT bd23599770 Add files via upload 2025-08-10 00:46:48 +08:00
PYDT bda6ff80da Delete PYAS.py 2025-08-10 00:42:33 +08:00
PYDT 16bee9825f Add files via upload 2025-08-10 00:41:16 +08:00
PYDT 5e4a4c4e8f Add files via upload 2025-08-09 23:50:31 +08:00
PYDT 0a03093333 Delete Plugins/Filter directory 2025-08-09 23:50:08 +08:00
PYDT 960b1d53f7 Add files via upload 2025-08-09 19:32:57 +08:00
PYDT f09dee6a52 Add files via upload 2025-08-09 19:32:08 +08:00
PYDT 301e1e56d1 Delete Plugins/Filter/PYAS_Driver.sys 2025-08-09 19:31:04 +08:00
PYDT 6b2dbd382d Add files via upload 2025-08-08 23:15:27 +08:00
PYDT e6f526c766 Update README_zh_CN.md 2025-08-06 01:09:35 +08:00
PYDT 06cca669a0 Update README_zh_CN.md 2025-08-06 01:09:18 +08:00
PYDT f89ccea208 Update README_zh_TW.md 2025-08-06 01:07:35 +08:00
PYDT 0728f2d995 Update README.md 2025-08-06 01:06:20 +08:00
PYDT c7a7a61c9a Delete PYAS_Suffixes.py 2025-08-06 00:43:52 +08:00
PYDT aca11e66a8 Delete PYAS_Language.py 2025-08-06 00:43:36 +08:00
PYDT 46c7a001c2 Delete Extens directory 2025-08-06 00:43:07 +08:00
PYDT d6aa3c50a3 Add files via upload 2025-08-06 00:42:43 +08:00
PYDT caaadc5cf3 Add files via upload 2025-08-06 00:41:52 +08:00
PYDT 14d703903c Delete Driver directory 2025-08-06 00:41:07 +08:00
PYDT 76fa14ab01 Add files via upload 2025-08-06 00:40:11 +08:00
PYDT d1afe255e5 Add files via upload 2025-05-06 17:28:11 +08:00
PYDT 8f27739331 Add files via upload 2025-04-25 17:09:33 +08:00
PYDT 7a6aba5a2a Add files via upload 2025-02-22 23:18:46 -08:00
PYDT ca0ec1f99d Add files via upload 2025-02-22 23:18:09 -08:00
PYDT 4e167486a1 Add files via upload 2025-02-16 14:51:54 -08:00
PYDT 503bbcd995 Add files via upload 2025-02-16 14:51:20 -08:00
PYDT b160d2f634 Add files via upload 2025-02-16 00:27:25 -08:00
PYDT 2e7628a837 Add files via upload 2025-02-15 03:40:02 -08:00
PYDT 1259948ed7 Update README_zh_TW.md 2025-02-15 15:49:09 +08:00
PYDT 81881ae1a4 Update README_zh_CN.md 2025-02-15 15:48:35 +08:00
PYDT 0b5c581aca Update README.md 2025-02-15 15:47:42 +08:00
PYDT eb3614ed0c Add files via upload 2025-02-14 09:01:50 -08:00
PYDT eb50513277 Add files via upload 2025-02-14 01:10:11 -08:00
PYDT c3af73b8cf Add files via upload 2025-02-13 08:41:54 -08:00
PYDT b552164a13 Add files via upload 2025-02-13 07:42:33 -08:00
PYDT b6dc9ecadb Add files via upload 2025-02-13 07:04:08 -08:00
PYDT 0723dc8dbb Add files via upload 2025-02-13 06:24:22 -08:00
PYDT 0b1fffb5bf Add files via upload 2025-02-13 06:03:33 -08:00
PYDT a39d87e5c5 Add files via upload 2025-02-13 05:52:51 -08:00
PYDT 0b0c3310cf Add files via upload 2025-02-13 05:36:46 -08:00
PYDT f75c3750a5 Add files via upload 2025-02-13 04:15:07 -08:00
PYDT 3da760721b Add files via upload 2025-02-13 03:15:23 -08:00
PYDT a9ad3feeec Add files via upload 2025-02-12 19:27:01 -08:00
PYDT 479c4ade67 Add files via upload 2025-02-12 18:32:50 -08:00
PYDT 84afa3e714 Add files via upload 2025-02-12 18:32:11 -08:00
PYDT 9a69665bab Add files via upload 2025-02-12 18:30:14 -08:00
PYDT fea34ee937 Add files via upload 2025-02-12 01:15:57 -08:00
PYDT ff2412c65d Add files via upload 2025-02-12 01:15:19 -08:00
PYDT 658953860a Add files via upload 2025-02-12 01:13:55 -08:00
PYDT b473783527 Add files via upload 2025-02-09 02:11:01 -08:00
PYDT 7e590d4925 Add files via upload 2025-02-08 17:37:01 -08:00
PYDT 232fd3e2f2 Add files via upload 2025-02-08 17:16:21 -08:00
PYDT 9ea25fb77c Add files via upload 2025-02-08 16:55:43 -08:00
PYDT 6c47136de3 Add files via upload 2025-02-08 16:33:55 -08:00
PYDT 6fae29b488 Add files via upload 2025-02-08 07:11:31 -08:00
PYDT 7ed8cc9380 Add files via upload 2025-02-06 23:38:20 -08:00
PYDT 142e9d1028 Add files via upload 2025-02-05 06:56:05 -08:00
PYDT c96c30ff9a Add files via upload 2025-02-04 19:22:57 -08:00
PYDT 337f1cc100 Add files via upload 2025-02-04 19:21:48 -08:00
PYDT c3cb89dbea Add files via upload 2025-02-02 08:53:39 -08:00
PYDT 445bd1f668 Add files via upload 2025-02-02 08:51:46 -08:00
PYDT 1bded908c1 Add files via upload 2025-01-13 13:28:19 +08:00
PYDT 8d9dea4b08 Add files via upload 2025-01-06 21:25:37 +08:00
PYDT 4e98d6d8ce Add files via upload 2025-01-02 19:41:57 +08:00
PYDT 55b5cd939e Add files via upload 2024-12-31 23:52:47 +08:00
PYDT d72f5a43c8 Update README_zh_TW.md 2024-12-31 20:05:29 +08:00
PYDT b406d8d30b Update README_zh_CN.md 2024-12-31 20:05:13 +08:00
PYDT f9c91c9ba0 Update README.md 2024-12-31 20:04:50 +08:00
PYDT 0213d7eeb4 Merge pull request #30 from ABCblock/main
Update PYAS_Language.py
2024-12-31 19:58:09 +08:00
ABCblock 048c5c0970 Update PYAS_Language.py 2024-12-31 19:29:18 +08:00
PYDT 728542fce8 Add files via upload 2024-12-31 09:11:01 +08:00
PYDT 81ca24c7a2 Update LICENSE.md 2024-12-31 09:09:33 +08:00
PYDT 32ec272253 Add files via upload 2024-12-31 08:09:25 +08:00
PYDT 758982b660 Add files via upload 2024-12-30 22:15:53 +08:00
PYDT a83bba10e3 Add files via upload 2024-12-27 10:10:59 +08:00
PYDT 4b9342fa8b Add files via upload 2024-11-25 15:45:23 +08:00
PYDT a48162cf4a Add files via upload 2024-11-22 14:17:44 +08:00
PYDT 3fa61e777c Add files via upload 2024-11-22 14:17:03 +08:00
PYDT 01a2c55207 Add files via upload 2024-11-22 14:16:43 +08:00
PYDT 1a2376e6b7 Add files via upload 2024-11-20 15:18:42 +08:00
PYDT dab0d6a47f Add files via upload 2024-11-20 15:15:12 +08:00
PYDT b5d90b5cb7 Add files via upload 2024-11-20 14:46:03 +08:00
PYDT 25fd0bd2af Update README.md 2024-11-07 13:52:41 +08:00
PYDT a4bb63fcd4 Update README_zh_TW.md 2024-11-07 13:52:24 +08:00
PYDT 9d85785c27 Update README_zh_CN.md 2024-11-07 13:51:54 +08:00
PYDT 4206242627 Update README_zh_TW.md 2024-11-07 13:46:30 +08:00
PYDT f0149be9ad Update README.md 2024-11-07 13:38:53 +08:00
PYDT 5d56a1f0e0 Add files via upload 2024-11-07 13:25:51 +08:00
PYDT ad06c75058 Add files via upload 2024-11-07 13:22:29 +08:00
PYDT d5b6e17e59 Add files via upload 2024-11-07 13:21:36 +08:00
PYDT ffe2514e11 Delete Rules directory 2024-11-07 13:20:42 +08:00
PYDT 8621bed5d4 Delete Model directory 2024-11-07 13:20:28 +08:00
PYDT 634031e6dc Delete Driver directory 2024-11-07 13:20:12 +08:00
PYDT 11fae36469 Add files via upload 2024-11-02 21:15:54 +08:00
PYDT 3d01e36a71 Add files via upload 2024-11-02 20:58:29 +08:00
PYDT c2082b1ac5 Add files via upload 2024-11-02 15:50:18 +08:00
PYDT c94bbf84fe Add files via upload 2024-11-01 10:26:53 +08:00
PYDT 930363cd3f Add files via upload 2024-11-01 09:19:24 +08:00
PYDT 085ca9eb58 Add files via upload 2024-10-29 12:47:54 +08:00
PYDT f486d44804 Add files via upload 2024-10-29 00:20:19 +08:00
PYDT 1b4fbd3449 Add files via upload 2024-10-28 19:29:55 +08:00
PYDT 43ad7bf646 Add files via upload 2024-10-28 19:29:20 +08:00
PYDT 64921c3308 Add files via upload 2024-10-27 10:17:41 +08:00
PYDT 7a0e6a00c5 Add files via upload 2024-10-27 10:16:53 +08:00
PYDT 1332dd2c0e Add files via upload 2024-10-27 10:16:16 +08:00
PYDT d52628bed2 Add files via upload 2024-10-19 17:38:44 +08:00
PYDT 981ec006b2 Add files via upload 2024-10-19 17:38:07 +08:00
PYDT 7da05cf678 Add files via upload 2024-10-19 17:37:39 +08:00
PYDT 316882bcd0 Add files via upload 2024-10-03 02:27:09 +08:00
PYDT b204e52297 Update README_zh_CN.md 2024-10-02 21:58:55 +08:00
PYDT f82a63f4c8 Update README_zh_TW.md 2024-10-02 21:58:40 +08:00
PYDT cb0f2108a4 Update README.md 2024-10-02 21:58:12 +08:00
PYDT 300b7a7a68 Add files via upload 2024-10-02 12:30:44 +08:00
PYDT c3852ca60d Add files via upload 2024-10-02 12:00:37 +08:00
PYDT a5fb735c93 Add files via upload 2024-09-28 11:15:53 +08:00
PYDT d0b04ba84f Add files via upload 2024-09-28 11:14:54 +08:00
PYDT 9552742a39 Add files via upload 2024-09-21 22:51:13 +08:00
PYDT 8e9bdf6c0c Add files via upload 2024-09-21 22:50:02 +08:00
PYDT 818cc48502 Add files via upload 2024-09-20 00:36:42 +08:00
PYDT adc4e28eb8 Add files via upload 2024-09-20 00:31:25 +08:00
PYDT 2e3a4d3bf1 Add files via upload 2024-09-14 15:41:49 +08:00
PYDT d9bcac78e7 Add files via upload 2024-09-14 15:12:14 +08:00
PYDT 2342947849 Add files via upload 2024-09-14 15:11:36 +08:00
PYDT 19204dee8d Add files via upload 2024-09-12 16:17:50 +08:00
PYDT 863fa90b80 Add files via upload 2024-09-12 16:08:26 +08:00
PYDT 6fdef4a8f1 Add files via upload 2024-09-12 16:08:10 +08:00
PYDT 9469ceaa02 Add files via upload 2024-09-12 15:25:07 +08:00
PYDT 857f184409 Add files via upload 2024-09-11 01:05:58 +08:00
PYDT a2f4a725f5 Add files via upload 2024-09-10 14:34:02 +08:00
PYDT d12449bbb9 Add files via upload 2024-09-10 13:35:57 +08:00
PYDT a41f4711dd Add files via upload 2024-09-10 13:34:16 +08:00
PYDT 3c2b018d49 Add files via upload 2024-09-07 10:49:46 +08:00
PYDT e221a09709 Add files via upload 2024-09-07 10:48:43 +08:00
PYDT 26ff4bd843 Update README_zh_TW.md 2024-08-26 07:42:37 +08:00
PYDT d8e28f384a Update README_zh_CN.md 2024-08-26 07:42:17 +08:00
PYDT 65e68c3cc4 Update README.md 2024-08-26 07:41:44 +08:00
PYDT 7b76ab2a59 Update README.md 2024-08-26 07:41:18 +08:00
PYDT ae2a01b463 Update README_zh_TW.md 2024-08-26 07:29:15 +08:00
PYDT cda022a9f4 Update README_zh_CN.md 2024-08-26 07:28:10 +08:00
PYDT 672e48c5f8 Update README.md 2024-08-26 07:26:34 +08:00
PYDT 6fbdb1354f Update README.md 2024-08-26 07:22:09 +08:00
PYDT 79bc7fd443 Update README_zh_TW.md 2024-08-20 10:57:17 +08:00
PYDT 5578dd3339 Update README_zh_CN.md 2024-08-20 10:57:03 +08:00
PYDT 0232dbd196 Update README.md 2024-08-20 10:56:46 +08:00
PYDT d44e192eaa Update README_zh_CN.md 2024-08-20 10:53:34 +08:00
PYDT 4f12b19cf8 Update README_zh_TW.md 2024-08-20 10:52:57 +08:00
PYDT 392ac1b1c7 Update README_zh_TW.md 2024-08-20 10:52:37 +08:00
PYDT 8ad175aca3 Update README.md 2024-08-20 10:51:48 +08:00
PYDT 6afa58c42b Delete PYAS_Extension.py 2024-08-18 12:48:43 +08:00
PYDT 8be03cf232 Add files via upload 2024-08-18 12:48:16 +08:00
PYDT 23ea53d3ff Add files via upload 2024-08-18 12:46:52 +08:00
PYDT 294f40e7ac Add files via upload 2024-08-18 12:46:11 +08:00
PYDT 4f5f706ee5 Delete Exten directory 2024-08-18 12:45:44 +08:00
PYDT 27c1a7b4e4 Add files via upload 2024-07-24 09:53:48 +08:00
PYDT cfaa5be6d7 Add files via upload 2024-07-20 18:11:08 +08:00
PYDT a6942280a0 Add files via upload 2024-07-20 17:51:33 +08:00
PYDT 159124e6a3 Add files via upload 2024-07-20 17:50:48 +08:00
PYDT 6e63293a3c Update README_zh_TW.md 2024-07-19 16:23:33 +08:00
PYDT 9a9dc0d788 Update README_zh_TW.md 2024-07-19 16:23:09 +08:00
PYDT e201cd074c Update README_zh_CN.md 2024-07-19 16:18:11 +08:00
PYDT 0fd49a6e1c Update README.md 2024-07-19 16:09:49 +08:00
PYDT 6169a85464 Update README.md 2024-07-19 16:08:28 +08:00
PYDT e583344fee Update README.md 2024-07-19 16:05:56 +08:00
PYDT dcee00394c Update README.md 2024-07-19 16:03:49 +08:00
PYDT e48dc99dc0 Update README.md 2024-07-19 15:59:20 +08:00
PYDT 3ba3dda384 Update README.md 2024-07-19 15:56:01 +08:00
PYDT bbf1ce993c Update README.md 2024-07-19 15:54:30 +08:00
PYDT 56245a8c9b Update README.md 2024-07-19 15:38:32 +08:00
PYDT 4f2e65094c Add files via upload 2024-07-19 15:31:08 +08:00
PYDT 0bf456cbc8 Delete Exten/hollows_hunter directory 2024-07-19 15:29:58 +08:00
PYDT 9213d0da16 Delete Exten/pe_sieve directory 2024-07-19 15:29:49 +08:00
PYDT 13f2ece0ff Delete Exten/Bitdefender directory 2024-07-19 15:16:22 +08:00
PYDT 45c2a74c94 Add files via upload 2024-07-19 15:15:47 +08:00
PYDT b1b3e90e9b Add files via upload 2024-07-19 15:14:41 +08:00
PYDT 90ef841dae Add files via upload 2024-07-17 11:31:20 +08:00
PYDT b46000e8eb Add files via upload 2024-07-17 11:30:35 +08:00
PYDT b24891355d Add files via upload 2024-07-16 20:42:42 +08:00
PYDT 14bde5a790 Add files via upload 2024-07-15 09:58:25 +08:00
PYDT d6445f17e3 Add files via upload 2024-07-15 09:57:20 +08:00
PYDT 6124c3fe40 Add files via upload 2024-07-15 09:55:10 +08:00
PYDT 5531a4b194 Add files via upload 2024-07-14 10:59:27 +08:00
PYDT 839a0bbd42 Add files via upload 2024-07-13 14:43:51 +08:00
PYDT 1ba6272e4e Add files via upload 2024-07-13 14:02:02 +08:00
PYDT fdd86815ef Add files via upload 2024-07-13 14:01:13 +08:00
PYDT c8091fdc84 Add files via upload 2024-07-11 15:40:46 +08:00
PYDT 9d569bd9e3 Add files via upload 2024-07-11 09:15:57 +08:00
PYDT 1991664cd1 Add files via upload 2024-07-10 07:16:38 +08:00
PYDT ee7064fafc Add files via upload 2024-07-10 07:14:15 +08:00
PYDT cdaf861485 Add files via upload 2024-07-10 07:13:32 +08:00
PYDT 3e962b1da9 Add files via upload 2024-07-10 07:04:41 +08:00
PYDT 8398f1706c Add files via upload 2024-06-27 20:36:41 +08:00
PYDT 24d2d441b4 Add files via upload 2024-06-22 20:01:01 +08:00
PYDT 5700039d42 Add files via upload 2024-06-21 18:09:06 +08:00
PYDT 22445c79d4 Add files via upload 2024-06-21 18:08:07 +08:00
PYDT 2be05ac76c Add files via upload 2024-06-20 21:06:48 +08:00
PYDT 84e397aeed Add files via upload 2024-06-20 19:45:53 +08:00
PYDT bb513b9115 Add files via upload 2024-06-20 19:45:03 +08:00
PYDT 01b680e278 Add files via upload 2024-06-19 23:15:16 +08:00
PYDT ef7c1cba2e Add files via upload 2024-06-19 22:17:23 +08:00
PYDT 40bbc57c82 Add files via upload 2024-06-19 21:51:41 +08:00
PYDT 457e5bebbb Add files via upload 2024-06-19 15:31:19 +08:00
PYDT 99abc56177 Add files via upload 2024-06-19 10:25:09 +08:00
PYDT 9eeb0b6376 Add files via upload 2024-06-19 10:23:10 +08:00
PYDT 0b2da187ee Add files via upload 2024-06-19 00:47:25 +08:00
PYDT 06f5410a4d Add files via upload 2024-06-18 22:41:34 +08:00
PYDT 2551ada3b7 Add files via upload 2024-06-18 16:00:15 +08:00
PYDT 56df08879e Delete Rules directory 2024-06-18 15:57:32 +08:00
PYDT d41685c86e Add files via upload 2024-06-17 21:08:46 +08:00
PYDT 14b942970e Add files via upload 2024-06-17 16:01:26 +08:00
PYDT b6103c845d Add files via upload 2024-06-17 10:24:41 +08:00
PYDT 7927f12e84 Add files via upload 2024-06-16 18:34:14 +08:00
PYDT 7774ff77b2 Add files via upload 2024-06-16 15:18:23 +08:00
PYDT aaa2ed7eef Add files via upload 2024-06-16 00:05:38 +08:00
PYDT b83674e9b7 Add files via upload 2024-06-15 21:42:39 +08:00
PYDT 017356780c Add files via upload 2024-06-15 21:42:02 +08:00
PYDT 45916004d2 Add files via upload 2024-06-14 12:24:23 +08:00
PYDT 388c8b615e Add files via upload 2024-06-14 09:22:05 +08:00
PYDT 4219473632 Add files via upload 2024-06-14 08:49:55 +08:00
PYDT f2283cdb7f Add files via upload 2024-06-13 22:36:25 +08:00
PYDT 72ce9cfd6b Add files via upload 2024-06-13 22:35:18 +08:00
PYDT b26375d25a Add files via upload 2024-06-12 15:40:07 +08:00
PYDT a2a823f358 Update README_zh_CN.md 2024-06-12 13:50:03 +08:00
PYDT 62164cf628 Update README_zh_TW.md 2024-06-12 13:48:43 +08:00
PYDT 0b5fc22181 Update README.md 2024-06-12 13:46:15 +08:00
PYDT 0df905f777 Update README.md 2024-06-12 13:44:28 +08:00
PYDT a539a948f6 Add files via upload 2024-06-11 19:48:57 +08:00
PYDT 6bd8364b5f Delete Driver/PYAS_Proc.sys 2024-06-11 19:48:25 +08:00
PYDT 70b70bc3e7 Add files via upload 2024-06-11 19:47:58 +08:00
PYDT ac50f8917e Add files via upload 2024-06-11 15:52:05 +08:00
PYDT f935b2c0b6 Update README_zh_CN.md 2024-06-11 15:35:46 +08:00
PYDT 245c9d1119 Update README_zh_TW.md 2024-06-11 15:35:12 +08:00
PYDT 9476313725 Update README.md 2024-06-11 15:34:25 +08:00
PYDT 2d27a74278 Add files via upload 2024-06-11 15:31:48 +08:00
PYDT 823a5115eb Add files via upload 2024-06-11 15:29:25 +08:00
PYDT 33ab1e1f5e Delete PYAS_Model.json 2024-06-11 15:25:23 +08:00
PYDT 8db984d1fd Update README_zh_TW.md 2024-06-05 15:27:55 +08:00
PYDT a00415657a Update README_zh_CN.md 2024-06-05 15:27:20 +08:00
PYDT 527837cc56 Add files via upload 2024-06-05 15:25:07 +08:00
PYDT ac9ddff8b1 Add files via upload 2024-06-05 06:46:18 +08:00
PYDT 4ebae2a167 Add files via upload 2024-06-03 18:06:13 +08:00
PYDT 11f1685f42 Add files via upload 2024-05-30 09:47:58 +08:00
PYDT 8199101891 Add files via upload 2024-05-29 14:40:48 +08:00
PYDT 4f3ce323ae Add files via upload 2024-05-29 14:09:52 +08:00
PYDT 76befc7c70 Add files via upload 2024-05-28 02:00:56 +08:00
PYDT 8b0ad06676 Update README_zh_TW.md 2024-05-24 10:43:20 +08:00
PYDT d7f091a3a9 Update README.md 2024-05-24 10:42:39 +08:00
PYDT 679b00229c Update README_zh_CN.md 2024-05-24 10:42:10 +08:00
PYDT 0cfc636fb6 Update README.md 2024-05-24 10:40:25 +08:00
PYDT bd3c31e150 Update README.md 2024-05-24 10:39:18 +08:00
PYDT 8e9547b75a Update README_zh_CN.md 2024-05-24 10:27:54 +08:00
PYDT d38ecc0f96 Update README_zh_CN.md 2024-05-24 10:26:26 +08:00
PYDT 85834497e0 Create README_zh_CN.md 2024-05-24 10:24:42 +08:00
PYDT 0d8997db02 Update README.md 2024-05-24 10:18:38 +08:00
PYDT cb53450ca5 Update and rename README_zh.md to README_zh_TW.md 2024-05-24 10:16:52 +08:00
PYDT f38ae36eb6 Update README_zh.md 2024-05-24 10:14:35 +08:00
PYDT 8218b0c8a6 Update README_zh.md 2024-05-24 10:12:48 +08:00
PYDT ea036d2d53 Update README.md 2024-05-24 10:10:21 +08:00
PYDT b163eb2cdb Update README_zh.md 2024-05-24 10:07:52 +08:00
PYDT ba3568f312 Add files via upload 2024-05-24 10:07:17 +08:00
PYDT 80c9976832 Add files via upload 2024-05-22 10:52:26 +08:00
PYDT b6326c25b9 Add files via upload 2024-05-22 10:43:38 +08:00
PYDT 35f591cf49 Add files via upload 2024-05-22 10:43:19 +08:00
PYDT 67e437bbd7 Add files via upload 2024-05-20 16:05:56 +08:00
PYDT 194dae8ce1 Add files via upload 2024-05-20 15:25:27 +08:00
PYDT a89442ceb0 Add files via upload 2024-05-15 10:02:53 +08:00
PYDT 24debf6062 Add files via upload 2024-04-17 15:00:15 +08:00
PYDT ff98846c99 Add files via upload 2024-04-17 13:35:21 +08:00
PYDT e3f5a0bca1 Add files via upload 2024-04-08 12:56:53 +08:00
PYDT 7278e4f051 Update README.md 2024-04-03 17:21:24 +08:00
PYDT 709a511c1d Add files via upload 2024-04-03 17:16:40 +08:00
PYDT 452027f085 Add files via upload 2024-04-01 23:59:25 +08:00
PYDT 8574802428 Add files via upload 2024-04-01 22:55:13 +08:00
PYDT 79fb044921 Add files via upload 2024-04-01 07:16:53 +08:00
PYDT 13ac634fea Delete Rules directory 2024-03-31 15:29:12 +08:00
PYDT 04a68bc262 Add files via upload 2024-03-29 13:43:15 +08:00
PYDT 47de15ab68 Add files via upload 2024-03-29 12:32:56 +08:00
PYDT 512af24a05 Delete Rules directory 2024-03-29 12:29:21 +08:00
PYDT e5ff46d3bb Delete Rules/Script.yar 2024-03-28 11:56:12 +08:00
PYDT c7a0979140 Delete Rules/Windows.yar 2024-03-28 11:55:58 +08:00
PYDT 7fd7245df2 Delete Rules/Linux.yar 2024-03-28 11:55:47 +08:00
PYDT 026301b011 Add files via upload 2024-03-28 11:55:25 +08:00
PYDT 5cc77f90ae Add files via upload 2024-03-28 10:21:13 +08:00
PYDT 0d4568ac8a Add files via upload 2024-03-28 10:20:08 +08:00
PYDT a6ed491a39 Add files via upload 2024-03-28 00:51:14 +08:00
PYDT 90dfc3f1ae Add files via upload 2024-03-28 00:49:12 +08:00
PYDT 36388fb0d7 Add files via upload 2024-03-27 00:11:46 +08:00
PYDT 043166d0c8 Add files via upload 2024-03-26 20:40:28 +08:00
PYDT b92d488851 Add files via upload 2024-03-26 04:09:19 +08:00
PYDT d841a04a89 Delete PYAS_Rules.json 2024-03-26 01:47:11 +08:00
PYDT d8553baa78 Add files via upload 2024-03-26 01:46:57 +08:00
PYDT 8521d5aee3 Add files via upload 2024-03-25 20:50:16 +08:00
PYDT ebe21d9c7f Add files via upload 2024-03-25 18:33:31 +08:00
PYDT 3b83abdbd3 Add files via upload 2024-03-25 16:41:37 +08:00
PYDT aead2463c9 Delete PYAS_Rules.py 2024-03-25 16:41:20 +08:00
PYDT 5cc5676672 Add files via upload 2024-03-25 14:56:41 +08:00
PYDT ecc32ca18d Add files via upload 2024-03-25 14:25:40 +08:00
PYDT 661640de79 Add files via upload 2024-03-24 23:19:46 +08:00
PYDT 96dfdab7ed Add files via upload 2024-03-24 23:19:09 +08:00
PYDT 56bed5fd3b Add files via upload 2024-03-24 16:45:19 +08:00
PYDT 3fd3b18406 Add files via upload 2024-03-23 23:10:47 +08:00
PYDT 45bac97a16 Add files via upload 2024-03-23 16:40:52 +08:00
PYDT 2c6eca4a92 Add files via upload 2024-03-23 01:41:29 +08:00
PYDT 8109d59655 Add files via upload 2024-03-22 16:35:59 +08:00
PYDT 8a15571cd2 Add files via upload 2024-03-22 12:03:29 +08:00
PYDT a15c8f2e60 Add files via upload 2024-03-22 00:01:26 +08:00
PYDT cec3d6c04d Add files via upload 2024-03-21 16:58:16 +08:00
PYDT d872604855 Add files via upload 2024-03-21 13:59:44 +08:00
PYDT 2b6fb933a4 Add files via upload 2024-03-21 12:43:38 +08:00
PYDT 1da892e863 Add files via upload 2024-03-21 12:43:19 +08:00
PYDT 19bfedd1a3 Add files via upload 2024-03-21 11:26:40 +08:00
PYDT cb87392d9d Add files via upload 2024-03-21 08:42:17 +08:00
PYDT 7cd5bc9ec3 Add files via upload 2024-03-21 00:38:14 +08:00
PYDT edcc1a30ab Add files via upload 2024-03-20 22:52:46 +08:00
PYDT 6f93f6ab06 Add files via upload 2024-03-14 08:49:33 +08:00
PYDT 9de1f44288 Add files via upload 2024-03-13 22:04:03 +08:00
PYDT 3d360b0881 Add files via upload 2024-03-12 21:23:09 +08:00
PYDT cf1c415846 Add files via upload 2024-03-12 14:52:45 +08:00
PYDT 90133e2444 Add files via upload 2024-03-11 11:15:55 +08:00
PYDT 81246046b8 Add files via upload 2024-03-10 13:05:03 +08:00
PYDT 20e037ab9e Add files via upload 2024-03-09 03:24:41 +08:00
PYDT bc27036ba7 Add files via upload 2024-03-07 16:35:31 +08:00
PYDT 1cd470b90b Add files via upload 2024-03-07 16:03:41 +08:00
PYDT 64471e34bc Add files via upload 2024-03-07 14:09:51 +08:00
PYDT f4c5d3de09 Add files via upload 2024-03-07 13:40:44 +08:00
PYDT 0dc59405e3 Update README.md 2024-03-06 15:34:29 +08:00
PYDT 7c775bdc9b Add files via upload 2024-03-06 15:19:10 +08:00
PYDT 61400ff4d4 Add files via upload 2024-03-02 17:33:31 +08:00
PYDT e119e34ebe Add files via upload 2024-03-01 15:48:26 +08:00
PYDT 6f059747bf Add files via upload 2024-03-01 09:32:59 +08:00
PYDT 24d72641fa Update README.md 2024-02-29 08:08:03 +08:00
PYDT b91fca3aa6 Update README.md 2024-02-29 08:06:59 +08:00
mtkiao a6f1947837 Merge pull request #18 from zackzheng1121/main
增加中文
2024-02-28 21:01:35 +08:00
zackzheng1121 6919131cef Update README_zh.md 2024-02-28 21:00:31 +08:00
PYDT 9186d801fc Add files via upload 2024-02-27 07:35:29 +08:00
PYDT 76e2f200bd Add files via upload 2024-02-26 23:21:40 +08:00
PYDT 1400bbd9ce Add files via upload 2024-02-26 15:02:04 +08:00
PYDT fd37628ac2 Add files via upload 2024-02-25 23:12:15 +08:00
PYDT 4396d5afc4 Add files via upload 2024-02-25 16:16:02 +08:00
PYDT f5faf80883 Add files via upload 2024-02-25 15:58:53 +08:00
PYDT ba32da97c8 Add files via upload 2024-02-25 10:42:07 +08:00
PYDT ec2de73d3a Update README.md 2024-02-25 02:34:20 +08:00
PYDT f4d032e5c7 Add files via upload 2024-02-25 02:17:22 +08:00
PYDT 4114aac6c3 Add files via upload 2024-02-25 01:45:23 +08:00
PYDT 0c43c6bb5f Add files via upload 2024-02-24 23:43:10 +08:00
PYDT 7b3c965b88 Add files via upload 2024-02-24 21:55:53 +08:00
zackzheng1121 d1035268f6 Update README_zh.md 2024-02-24 19:44:58 +08:00
zackzheng1121 8968f30bf9 Update README_zh.md 2024-02-24 19:43:45 +08:00
zackzheng1121 84c2c29600 Update README.md 2024-02-24 19:43:23 +08:00
zackzheng1121 b2a59f261c Update README.md 2024-02-24 19:40:42 +08:00
zackzheng1121 363a330f8e Create README.md 2024-02-24 19:39:20 +08:00
zackzheng1121 1d2aa059ee Update and rename README.md to README_zh.md 2024-02-24 19:38:16 +08:00
zackzheng1121 f2bfa908a1 add readme_zh 2024-02-24 19:32:40 +08:00
PYDT 02a8de4696 Add files via upload 2024-02-23 08:38:55 +08:00
PYDT 22fa3eff71 Add files via upload 2024-02-22 14:32:17 +08:00
PYDT 69361209c3 Add files via upload 2024-02-22 01:08:15 +08:00
PYDT ff0aeaa4ef Add files via upload 2024-02-21 10:21:38 +08:00
PYDT 3c461dfd4b Add files via upload 2024-02-21 10:13:11 +08:00
PYDT c6beda383e Add files via upload 2024-02-21 07:10:15 +08:00
PYDT 3d59f3befd Add files via upload 2024-02-21 00:42:59 +08:00
PYDT e54f0db239 Update README.md 2024-02-20 14:41:04 +08:00
PYDT 0f877f2749 Delete PYAS_Function.vdb 2024-02-20 14:02:47 +08:00
PYDT b69ba165d9 Add files via upload 2024-02-20 14:02:37 +08:00
PYDT 965076fe52 Delete PYAS_Compress.py 2024-02-20 13:43:32 +08:00
PYDT f4d6cb0430 Add files via upload 2024-02-19 10:39:21 +08:00
PYDT 19d412188c Add files via upload 2024-02-19 10:38:19 +08:00
PYDT 798d85978a Add files via upload 2024-02-11 19:53:57 +08:00
PYDT 819742d753 Add files via upload 2024-02-11 16:12:59 +08:00
PYDT 9b32fa6219 Add files via upload 2024-02-11 10:56:55 +08:00
PYDT 2c93661726 Add files via upload 2024-02-10 23:02:45 +08:00
PYDT bddaca2a1e Add files via upload 2024-02-10 22:08:39 +08:00
PYDT 2f06f2e051 Add files via upload 2024-02-10 20:52:38 +08:00
PYDT 1d26e46bd9 Add files via upload 2024-02-10 20:01:52 +08:00
PYDT fa0ff826a3 Add files via upload 2024-02-10 19:50:01 +08:00
PYDT e1b3114c83 Add files via upload 2024-02-10 19:41:34 +08:00
PYDT a655f075db Add files via upload 2024-02-10 19:40:54 +08:00
PYDT 13d4ebbf6b Add files via upload 2024-02-09 14:24:52 +08:00
PYDT 913d10b1ee Add files via upload 2024-02-09 14:18:30 +08:00
PYDT eb541a0104 Add files via upload 2024-01-30 19:03:05 +08:00
PYDT 2063186994 Add files via upload 2024-01-28 16:20:22 +08:00
PYDT 860d571039 Delete PYAS_Function.py 2024-01-28 15:41:03 +08:00
PYDT c6d79adf9a Add files via upload 2024-01-28 15:40:44 +08:00
PYDT 5453900ba1 Add files via upload 2024-01-28 03:29:28 +08:00
PYDT 5029ff1e37 Add files via upload 2024-01-28 03:13:40 +08:00
PYDT 47fb691339 Add files via upload 2024-01-28 03:12:42 +08:00
PYDT dff9dd17bf Add files via upload 2024-01-27 11:58:36 +08:00
PYDT 5bc4a16b90 Add files via upload 2024-01-26 10:14:32 +08:00
PYDT b1918953b0 Update README.md 2024-01-26 09:35:36 +08:00
PYDT 6e89ed7007 Add files via upload 2024-01-26 09:33:16 +08:00
PYDT 744e8bc941 Add files via upload 2024-01-25 20:21:35 +08:00
PYDT 0b98ce7ffd Add files via upload 2024-01-25 20:19:27 +08:00
PYDT ca8b293b06 Delete PYAS_Function.zip 2024-01-25 18:10:50 +08:00
PYDT e28d99a257 Add files via upload 2024-01-25 18:09:58 +08:00
PYDT 488feb6108 Add files via upload 2024-01-25 16:12:47 +08:00
PYDT 6cdb106f07 Add files via upload 2024-01-24 22:58:36 +08:00
PYDT a7c5ccd27a Add files via upload 2024-01-24 22:56:15 +08:00
PYDT 136f9dbf0a Add files via upload 2024-01-24 22:47:40 +08:00
PYDT 16b45c3450 Add files via upload 2024-01-24 15:13:42 +08:00
PYDT 68330fad52 Add files via upload 2024-01-24 12:57:03 +08:00
PYDT dca167518d Add files via upload 2024-01-24 12:18:50 +08:00
PYDT bcc44422ef Add files via upload 2024-01-24 08:18:06 +08:00
PYDT e080e03466 Add files via upload 2024-01-24 07:54:57 +08:00
PYDT b6e75490de Add files via upload 2024-01-23 22:19:24 +08:00
PYDT 196c014576 Add files via upload 2024-01-23 16:58:43 +08:00
PYDT 236110df5e Update README.md 2024-01-23 12:34:58 +08:00
PYDT b2ae192056 Update README.md 2024-01-23 11:56:05 +08:00
PYDT f080969a62 Update README.md 2024-01-23 11:52:38 +08:00
PYDT 69d969898d Update README.md 2024-01-23 11:44:26 +08:00
PYDT a21a766926 Update README.md 2024-01-23 11:41:44 +08:00
PYDT f11fdb6b96 Update README.md 2024-01-23 11:34:02 +08:00
PYDT c7445df4c6 Update README.md 2024-01-23 11:07:51 +08:00
PYDT 2c45c9bc5b Update README.md 2024-01-23 11:02:53 +08:00
PYDT ae5ed27cb6 Update README.md 2024-01-23 10:57:13 +08:00
PYDT 11f9fe3c8b Add files via upload 2024-01-23 10:55:05 +08:00
PYDT e93ad3bd33 Delete PYAS_Function.7z 2024-01-23 10:54:34 +08:00
PYDT 20c26ea0a8 Add files via upload 2024-01-23 10:45:31 +08:00
PYDT 5925a80d3b Add files via upload 2024-01-22 16:19:31 +08:00
PYDT 56cb95e523 Add files via upload 2024-01-22 16:11:56 +08:00
PYDT a6e101cc5d Add files via upload 2024-01-22 12:49:46 +08:00
PYDT e8292b6f81 Add files via upload 2024-01-21 23:35:59 +08:00
PYDT 37a4392c94 Add files via upload 2024-01-21 15:49:43 +08:00
PYDT a897f75ecf Add files via upload 2024-01-20 22:16:36 +08:00
PYDT 79055d3779 Add files via upload 2024-01-19 16:31:27 +08:00
PYDT 3d39aa7f97 Delete PYAS_Function_Virus.7z 2024-01-19 11:18:58 +08:00
PYDT 2c1d09affc Delete PYAS_Function_Safe.7z 2024-01-19 11:18:42 +08:00
PYDT 4775358a79 Add files via upload 2024-01-19 11:18:28 +08:00
PYDT cb5f8e8191 Add files via upload 2024-01-19 11:10:48 +08:00
PYDT 8209b4ff01 Add files via upload 2024-01-19 11:05:39 +08:00
PYDT e110134d24 Add files via upload 2024-01-19 07:30:45 +08:00
PYDT c2248fdd49 Add files via upload 2024-01-18 16:51:36 +08:00
PYDT 58fea5b0ca Add files via upload 2024-01-18 15:29:15 +08:00
PYDT 7a36946545 Add files via upload 2024-01-18 13:00:09 +08:00
PYDT 563d9a8a36 Add files via upload 2024-01-18 12:52:17 +08:00
PYDT bdbd0617b5 Add files via upload 2024-01-18 09:04:50 +08:00
PYDT 67006d88cb Add files via upload 2024-01-17 21:39:54 +08:00
PYDT ded2083462 Add files via upload 2024-01-17 16:18:32 +08:00
PYDT 87b7d044f8 Add files via upload 2024-01-17 14:37:47 +08:00
PYDT 9781cef29b Add files via upload 2024-01-17 13:45:19 +08:00
PYDT 52c393148b Add files via upload 2024-01-17 13:33:21 +08:00
PYDT b98d617d6f Add files via upload 2024-01-16 17:00:10 +08:00
PYDT b475573e0e Add files via upload 2024-01-16 15:37:53 +08:00
PYDT ba3c85d5b2 Add files via upload 2024-01-16 10:06:13 +08:00
PYDT 410777efb3 Add files via upload 2024-01-15 22:11:42 +08:00
PYDT 0b3fb452b4 Add files via upload 2024-01-15 19:26:37 +08:00
PYDT aaff565172 Add files via upload 2024-01-15 17:13:45 +08:00
PYDT dd0786648e Add files via upload 2024-01-15 16:46:10 +08:00
PYDT e145ffa111 Add files via upload 2024-01-15 11:31:14 +08:00
PYDT b322468c1c Add files via upload 2024-01-15 11:17:40 +08:00
PYDT 992d8b909c Add files via upload 2024-01-15 09:39:53 +08:00
PYDT d5327c6370 Delete How To Use.py 2024-01-15 09:39:35 +08:00
PYDT 0d13bb5f8f Add files via upload 2024-01-15 09:39:08 +08:00
PYDT 3ad08a33a9 Add files via upload 2024-01-15 09:35:25 +08:00
PYDT 533e0ed736 Add files via upload 2024-01-15 09:15:58 +08:00
PYDT e7ba77b600 Add files via upload 2024-01-15 00:12:33 +08:00
PYDT f3b84b04f7 Add files via upload 2024-01-14 21:17:04 +08:00
PYDT f4c948aca9 Add files via upload 2024-01-13 23:01:02 +08:00
PYDT 1507f5df5a Add files via upload 2024-01-13 18:32:48 +08:00
PYDT 0562d11a71 Add files via upload 2024-01-13 13:23:35 +08:00
PYDT b3a9f5cce0 Add files via upload 2024-01-13 13:17:56 +08:00
PYDT 5974a3c85a Add files via upload 2024-01-13 13:14:37 +08:00
PYDT 78c732d2b8 Add files via upload 2024-01-13 12:42:11 +08:00
PYDT d087b2dc16 Add files via upload 2024-01-12 19:08:57 +08:00
PYDT 16c5d014aa Add files via upload 2024-01-12 10:42:34 +08:00
PYDT e661ff400f Update README.md 2024-01-12 09:53:48 +08:00
PYDT b8c8e2d04d Update README.md 2024-01-12 09:42:24 +08:00
PYDT 8fc36f2b20 Update README.md 2024-01-12 09:37:35 +08:00
PYDT 4b73a09a09 Update README.md 2024-01-12 09:26:49 +08:00
PYDT 65c4d5d5b7 Update README.md 2024-01-12 09:25:45 +08:00
PYDT 19d0702aee Update LICENSE.md 2024-01-12 09:15:08 +08:00
PYDT b74e8330de Add files via upload 2024-01-12 08:24:21 +08:00
PYDT 334b837d43 Add files via upload 2024-01-11 18:57:45 +08:00
PYDT 169cb37f08 Add files via upload 2024-01-11 18:54:52 +08:00
PYDT 8f29c3f0da Add files via upload 2024-01-11 11:26:50 +08:00
PYDT bec5cc4a04 Delete PYAS_Function.7z 2024-01-11 11:25:28 +08:00
PYDT af627ee202 Delete PYAS_Compress.py 2024-01-11 11:25:17 +08:00
PYDT 1e091a3e7c Delete PYAS_Function_Virus.7z 2024-01-11 10:23:11 +08:00
PYDT 8840da91d7 Delete PYAS_Function_Safe.7z 2024-01-11 10:22:59 +08:00
PYDT 1f4ff04ed3 Add files via upload 2024-01-11 10:22:17 +08:00
PYDT 60974e8f72 Add files via upload 2024-01-11 09:31:52 +08:00
PYDT 86f68994c2 Add files via upload 2024-01-10 09:19:18 +08:00
PYDT 21c4918486 Add files via upload 2024-01-09 08:20:17 +08:00
PYDT c6a426ec25 Add files via upload 2024-01-08 21:22:54 +08:00
PYDT db75a22c1c Add files via upload 2024-01-08 19:31:04 +08:00
PYDT 7e85d22ecd Add files via upload 2024-01-08 18:53:53 +08:00
PYDT 67adadc0a4 Add files via upload 2024-01-08 17:46:19 +08:00
PYDT 6b78562454 Add files via upload 2024-01-08 08:33:37 +08:00
PYDT 4f13afc867 Add files via upload 2024-01-07 20:06:03 +08:00
PYDT c34e8f193f Add files via upload 2024-01-06 16:53:56 +08:00
PYDT 4bcb507eae Add files via upload 2024-01-06 12:45:32 +08:00
PYDT a50d457d75 Add files via upload 2024-01-05 10:51:12 +08:00
PYDT 9f119265a9 Add files via upload 2024-01-05 10:21:49 +08:00
PYDT 0b121a624b Add files via upload 2024-01-05 09:34:07 +08:00
PYDT 0f47f5ec8f Add files via upload 2024-01-05 08:12:45 +08:00
PYDT f89896d041 Add files via upload 2024-01-04 15:47:23 +08:00
PYDT 5e335fd5e8 Add files via upload 2024-01-04 15:47:06 +08:00
PYDT fd245dec14 Add files via upload 2024-01-04 14:56:46 +08:00
PYDT 774cdc5de3 Add files via upload 2024-01-04 13:28:02 +08:00
PYDT 633cfad1a8 Add files via upload 2024-01-04 11:39:51 +08:00
PYDT cb7875c320 Add files via upload 2024-01-04 10:08:12 +08:00
PYDT 7960a57fc0 Add files via upload 2024-01-03 23:08:28 +08:00
PYDT a23f693921 Delete PYAS_Function.zip 2024-01-03 22:55:51 +08:00
PYDT c49cb8bc4a Delete PYAS_Compress.py 2024-01-03 22:55:39 +08:00
PYDT 02c425cfc0 Add files via upload 2024-01-03 11:50:11 +08:00
PYDT be96ba0a0e Add files via upload 2024-01-02 11:19:37 +08:00
PYDT df5e00977a Add files via upload 2024-01-02 07:53:56 +08:00
PYDT f055650365 Add files via upload 2024-01-02 07:21:14 +08:00
PYDT b0baddda3b Delete PYAS_Function.7z 2024-01-02 07:20:32 +08:00
PYDT 69359cba05 Delete PYAS_Function_Virus.7z 2024-01-02 00:16:56 +08:00
PYDT 8b0b29e39b Delete PYAS_Function_Safe.7z 2024-01-02 00:16:45 +08:00
PYDT 21ac50667d Add files via upload 2024-01-02 00:16:07 +08:00
PYDT b843a438ba Add files via upload 2024-01-01 03:59:04 +08:00
PYDT 441cc30c0b Add files via upload 2024-01-01 03:42:15 +08:00
PYDT 85adf5dc80 Add files via upload 2023-12-31 20:55:32 +08:00
PYDT 0c48f0981d Delete PYML.py 2023-12-31 17:30:22 +08:00
PYDT 88b646e41c Delete PYAS_Database.7z 2023-12-31 17:30:03 +08:00
PYDT dc4c3e0a99 Add files via upload 2023-12-31 17:29:47 +08:00
PYDT 262f6d55a0 Add files via upload 2023-12-29 11:22:07 +08:00
PYDT 2d68400670 Delete PYAS_Function.7z 2023-12-29 09:42:48 +08:00
PYDT 8acaae3f0d Add files via upload 2023-12-29 09:42:10 +08:00
PYDT a5cb26528f Add files via upload 2023-12-15 08:58:39 +08:00
PYDT ac2520a03f Add files via upload 2023-12-15 08:43:04 +08:00
PYDT 9c15cc7b33 Add files via upload 2023-12-14 22:49:20 +08:00
PYDT c38f460163 Add files via upload 2023-12-14 22:25:15 +08:00
PYDT 9bda8c9e77 Add files via upload 2023-12-14 15:48:01 +08:00
PYDT 558be68bad Add files via upload 2023-12-14 15:25:36 +08:00
PYDT 6b9d27ce9b Add files via upload 2023-12-14 09:57:22 +08:00
PYDT 412745eede Add files via upload 2023-12-14 09:44:59 +08:00
PYDT 91ea771af1 Add files via upload 2023-12-14 07:17:45 +08:00
PYDT 238ab03db3 Add files via upload 2023-12-14 07:16:10 +08:00
PYDT 2d63da193d Add files via upload 2023-12-13 09:31:18 +08:00
PYDT fa4c20a241 Add files via upload 2023-12-12 18:00:47 +08:00
PYDT 6294fc33d1 Add files via upload 2023-12-11 18:17:39 +08:00
PYDT c4cf48a94b Add files via upload 2023-12-11 09:12:24 +08:00
PYDT 2934c7eb57 Add files via upload 2023-12-11 07:53:44 +08:00
PYDT 46ce454105 Add files via upload 2023-12-10 18:02:52 +08:00
PYDT 9ab06a0ea9 Add files via upload 2023-12-10 12:33:37 +08:00
PYDT e6f742380a Add files via upload 2023-12-09 17:43:10 +08:00
PYDT 2686812470 Add files via upload 2023-12-09 17:01:08 +08:00
PYDT cd11b5b7b2 Add files via upload 2023-12-08 21:28:06 +08:00
PYDT aae35dc640 Add files via upload 2023-12-08 18:21:31 +08:00
PYDT f0b669ff85 Add files via upload 2023-12-08 08:18:32 +08:00
PYDT 237605bb9f Add files via upload 2023-12-07 16:17:34 +08:00
PYDT 1778046581 Add files via upload 2023-12-07 09:45:20 +08:00
PYDT ff10adfabb Add files via upload 2023-12-06 14:35:52 +08:00
PYDT 1cb0f8d7ba Add files via upload 2023-12-06 14:29:34 +08:00
PYDT 5813bbdcd1 Add files via upload 2023-12-06 09:52:59 +08:00
PYDT b38e5b177e Add files via upload 2023-12-06 09:08:11 +08:00
PYDT 9d66cf248c Add files via upload 2023-12-06 06:37:25 +08:00
PYDT ebcf90d426 Add files via upload 2023-12-05 15:58:41 +08:00
PYDT 51904db187 Add files via upload 2023-12-05 15:15:21 +08:00
PYDT 4fc8755b8d Add files via upload 2023-12-05 11:27:36 +08:00
PYDT 7afcbfaa26 Add files via upload 2023-12-05 09:16:49 +08:00
PYDT 55cb96d978 Add files via upload 2023-12-05 08:44:24 +08:00
PYDT a1de099974 Add files via upload 2023-12-04 21:24:39 +08:00
PYDT a0238732fe Add files via upload 2023-12-04 19:59:48 +08:00
PYDT 6c100b0679 Add files via upload 2023-12-04 19:25:29 +08:00
PYDT e4d159840f Add files via upload 2023-12-04 19:25:10 +08:00
PYDT 0375b3ff02 Add files via upload 2023-12-04 17:01:02 +08:00
PYDT 746bae5103 Add files via upload 2023-12-04 14:10:23 +08:00
PYDT 70eb2c4500 Add files via upload 2023-12-03 23:18:21 +08:00
PYDT 69175f3ae1 Add files via upload 2023-12-02 20:21:07 +08:00
PYDT ed5fab2c54 Add files via upload 2023-12-01 22:26:39 +08:00
PYDT 1425ff8e6c Add files via upload 2023-12-01 19:43:30 +08:00
PYDT 832ab549a1 Add files via upload 2023-12-01 09:25:11 +08:00
PYDT 4ec1661c26 Add files via upload 2023-12-01 08:26:16 +08:00
PYDT ea27712b62 Add files via upload 2023-12-01 08:25:59 +08:00
PYDT 6f65efe2d8 Add files via upload 2023-11-30 21:11:48 +08:00
PYDT 8edcf60baf Add files via upload 2023-11-30 17:23:46 +08:00
PYDT 74f6aec367 Add files via upload 2023-11-30 16:02:10 +08:00
PYDT 62c65a766a Add files via upload 2023-11-30 15:09:35 +08:00
PYDT acbcaa337e Add files via upload 2023-11-30 08:21:54 +08:00
PYDT f4dbe57244 Add files via upload 2023-11-30 00:07:59 +08:00
PYDT b494c64a2f Add files via upload 2023-11-29 22:28:22 +08:00
PYDT 321e086b95 Add files via upload 2023-11-29 15:12:49 +08:00
PYDT fb60d6b867 Add files via upload 2023-11-29 13:08:38 +08:00
PYDT 8ff2e2074a Delete PYAS_Function_Safe.7z 2023-11-28 18:45:40 +08:00
PYDT 1151a1c43f Add files via upload 2023-11-28 18:45:16 +08:00
PYDT 13bc6cecc4 Add files via upload 2023-11-28 13:29:09 +08:00
PYDT a4ea572458 Add files via upload 2023-11-28 01:02:21 +08:00
PYDT 880df4dee9 Add files via upload 2023-11-27 19:31:39 +08:00
PYDT b75e86dd11 Add files via upload 2023-11-27 18:08:54 +08:00
PYDT 75c84092ae Add files via upload 2023-11-27 12:42:50 +08:00
PYDT c69db97da8 Add files via upload 2023-11-27 12:16:53 +08:00
PYDT 9c2a8892ae Add files via upload 2023-11-27 06:39:02 +08:00
PYDT f92111563c Add files via upload 2023-11-26 22:01:51 +08:00
PYDT 0abb3e78cb Add files via upload 2023-11-26 15:51:40 +08:00
PYDT fb83071419 Add files via upload 2023-11-26 12:56:33 +08:00
PYDT f593c6df8b Add files via upload 2023-11-26 12:51:13 +08:00
PYDT 9b452b25c2 Add files via upload 2023-11-25 21:47:21 +08:00
PYDT c835fcf99a Add files via upload 2023-11-25 20:23:47 +08:00
PYDT e4373edc54 Add files via upload 2023-11-25 19:59:51 +08:00
PYDT 686c05785f Add files via upload 2023-11-25 17:12:59 +08:00
PYDT 994358a793 Add files via upload 2023-11-25 16:58:41 +08:00
PYDT b02ca3757c Add files via upload 2023-11-25 16:14:41 +08:00
PYDT 164ec25415 Add files via upload 2023-11-25 14:58:27 +08:00
PYDT 8ee85cd9ca Add files via upload 2023-11-25 14:20:24 +08:00
PYDT c07bf05754 Add files via upload 2023-11-25 13:09:25 +08:00
PYDT 2e2a08a765 Add files via upload 2023-11-24 23:30:33 +08:00
PYDT 10be5f442f Add files via upload 2023-11-24 20:21:25 +08:00
PYDT 0fcd8565d8 Add files via upload 2023-11-24 12:08:55 +08:00
PYDT e07eee86dd Add files via upload 2023-11-24 09:09:49 +08:00
PYDT f25d5d73c6 Add files via upload 2023-11-23 23:31:26 +08:00
PYDT 28b4d00d3c Add files via upload 2023-11-23 22:48:46 +08:00
PYDT c75cf8a539 Add files via upload 2023-11-23 20:08:54 +08:00
PYDT ff7199b857 Add files via upload 2023-11-23 17:58:09 +08:00
PYDT 5613fd81b7 Update README.md 2023-11-23 16:00:46 +08:00
PYDT c1458502f7 Update README.md 2023-11-23 15:56:19 +08:00
PYDT b2f620bd3d Add files via upload 2023-11-23 15:07:41 +08:00
PYDT 0e1030f186 Add files via upload 2023-11-23 14:55:15 +08:00
PYDT ff4ffb8ec5 Add files via upload 2023-11-23 14:34:25 +08:00
PYDT 941458a381 Add files via upload 2023-11-22 14:49:09 +08:00
PYDT 560eb924b8 Add files via upload 2023-11-21 20:48:57 +08:00
PYDT c3fab9e48b Add files via upload 2023-11-21 20:31:50 +08:00
PYDT fc4dc74f9e Add files via upload 2023-11-21 20:16:16 +08:00
PYDT 35f0362910 Update README.md 2023-11-21 14:59:18 +08:00
PYDT 27dfaa5f06 Add files via upload 2023-11-21 14:52:06 +08:00
PYDT cf1866710a Delete PYAS_Function.zip 2023-11-21 14:51:37 +08:00
PYDT b3a5d06c4a Add files via upload 2023-11-21 14:40:38 +08:00
PYDT 7c904ff331 Add files via upload 2023-11-16 14:25:47 +08:00
PYDT c7855a9dd1 Add files via upload 2023-11-16 13:40:33 +08:00
PYDT 5faee6a05f Add files via upload 2023-11-16 11:41:33 +08:00
PYDT 9213f9f54f Add files via upload 2023-11-16 10:39:56 +08:00
PYDT c5e8351d76 Delete PYAS_Rules.py 2023-11-16 10:39:12 +08:00
PYDT e8e245ac0b Add files via upload 2023-11-15 12:49:31 +08:00
PYDT 2d8d6851d1 Add files via upload 2023-11-15 11:39:51 +08:00
PYDT 54f3e2ceda Add files via upload 2023-11-15 00:27:26 +08:00
PYDT 81d98917c3 Add files via upload 2023-11-14 21:10:40 +08:00
PYDT 8651f1e5d6 Add files via upload 2023-11-10 16:14:39 +08:00
PYDT db1a26424d Add files via upload 2023-11-10 15:20:38 +08:00
PYDT 16405810dd Add files via upload 2023-11-10 10:07:45 +08:00
PYDT f4f7fc1b0c Add files via upload 2023-11-09 22:02:06 +08:00
PYDT e1145a743a Add files via upload 2023-11-09 21:33:02 +08:00
PYDT 6e5b54bbfe Add files via upload 2023-11-09 21:21:20 +08:00
PYDT a948219e1a Add files via upload 2023-11-09 10:45:41 +08:00
PYDT 5675e926d5 Add files via upload 2023-11-09 09:19:56 +08:00
PYDT cb7f8bbaab Add files via upload 2023-11-09 09:14:14 +08:00
PYDT 61e7fd8f40 Add files via upload 2023-11-08 19:49:30 +08:00
PYDT 76fab2671a Add files via upload 2023-11-08 09:33:31 +08:00
PYDT dbc2bd2d62 Add files via upload 2023-11-07 23:48:08 +08:00
PYDT 73e62935ff Add files via upload 2023-11-07 14:35:09 +08:00
PYDT c9e28b5482 Add files via upload 2023-11-07 11:15:32 +08:00
PYDT 6bf58eae4a Add files via upload 2023-11-07 07:26:43 +08:00
PYDT 3e09574b3c Add files via upload 2023-11-06 16:23:59 +08:00
PYDT a7a00b9ca6 Add files via upload 2023-11-06 08:24:54 +08:00
PYDT 7a62e2df27 Add files via upload 2023-11-05 17:49:37 +08:00
PYDT 317f1ccae7 Add files via upload 2023-11-05 17:38:51 +08:00
PYDT 884631409a Add files via upload 2023-11-05 14:44:08 +08:00
PYDT 14dca5e2cb Add files via upload 2023-11-04 13:38:04 +08:00
PYDT 3a0b856d47 Add files via upload 2023-11-03 20:36:21 +08:00
PYDT e66f8af022 Add files via upload 2023-11-03 18:02:13 +08:00
PYDT 13e4560d86 Add files via upload 2023-11-03 08:20:39 +08:00
PYDT 5ea789df7f Add files via upload 2023-11-03 08:14:52 +08:00
PYDT debda9ec11 Add files via upload 2023-11-02 20:36:42 +08:00
PYDT b3f126181b Add files via upload 2023-11-02 14:35:57 +08:00
PYDT 6bd110cae7 Add files via upload 2023-11-02 14:30:26 +08:00
PYDT 635f4ccde3 Add files via upload 2023-11-02 10:52:47 +08:00
PYDT 01da2685a5 Add files via upload 2023-11-02 10:51:45 +08:00
PYDT b040aad8d1 Add files via upload 2023-11-02 08:47:53 +08:00
PYDT 84a0f08618 Add files via upload 2023-11-01 19:44:29 +08:00
PYDT 1f64c0d672 Add files via upload 2023-11-01 12:55:25 +08:00
PYDT 5bfff87e21 Add files via upload 2023-11-01 11:19:25 +08:00
PYDT 47db0e1c46 Delete PYAS_Scripts.py 2023-10-31 15:02:10 +08:00
PYDT 9a9fdc418f Delete PYAS_Function_Safe.zip 2023-10-31 15:01:31 +08:00
PYDT c30c89ed40 Add files via upload 2023-10-31 15:01:01 +08:00
PYDT d7bb89968f Add files via upload 2023-10-30 21:05:07 +08:00
PYDT f9b431d158 Add files via upload 2023-10-30 20:56:16 +08:00
PYDT a1364896af Add files via upload 2023-10-30 20:07:24 +08:00
PYDT 2870a999a2 Add files via upload 2023-10-30 20:05:04 +08:00
PYDT 98646a6bd9 Add files via upload 2023-10-29 15:47:10 +08:00
PYDT 8ec894f576 Add files via upload 2023-10-29 13:15:09 +08:00
PYDT 254a67b9a8 Add files via upload 2023-10-29 12:13:14 +08:00
PYDT eebfb79c27 Add files via upload 2023-10-29 11:56:02 +08:00
PYDT 1a1d7ec783 Add files via upload 2023-10-29 08:25:17 +08:00
PYDT 4482144b4d Add files via upload 2023-10-28 18:25:08 +08:00
PYDT 827279c9a8 Add files via upload 2023-10-28 15:32:10 +08:00
PYDT b1d3488842 Add files via upload 2023-10-27 18:57:00 +08:00
PYDT 90112ae1ae Add files via upload 2023-10-27 15:48:25 +08:00
PYDT 1f4b9390b9 Add files via upload 2023-10-27 10:53:02 +08:00
PYDT cc142aca40 Add files via upload 2023-10-27 08:28:38 +08:00
PYDT 89513b2c0d Add files via upload 2023-10-27 00:33:05 +08:00
PYDT bfcd00acec Add files via upload 2023-10-27 00:26:21 +08:00
PYDT 9833b28a50 Add files via upload 2023-10-27 00:03:41 +08:00
PYDT d0404dd29c Add files via upload 2023-10-26 20:52:20 +08:00
PYDT 9d3761e7f6 Add files via upload 2023-10-26 20:14:54 +08:00
PYDT 03515acc68 Add files via upload 2023-10-26 18:06:31 +08:00
PYDT f8413f4cfb Add files via upload 2023-10-26 17:50:39 +08:00
PYDT 24f7f67e63 Add files via upload 2023-10-26 14:29:49 +08:00
PYDT 85129cdfe1 Add files via upload 2023-10-25 15:58:42 +08:00
PYDT 6d4f8b2731 Add files via upload 2023-10-25 13:39:48 +08:00
PYDT 24a0efcce1 Add files via upload 2023-10-24 21:28:11 +08:00
PYDT ce6be1b4d5 Add files via upload 2023-10-24 19:53:41 +08:00
PYDT 723ac47c48 Add files via upload 2023-10-24 19:52:58 +08:00
PYDT 720d163bdb Add files via upload 2023-10-24 13:15:05 +08:00
PYDT a74047d4e5 Add files via upload 2023-10-24 13:12:21 +08:00
PYDT f6538f93c7 Add files via upload 2023-10-24 13:08:41 +08:00
PYDT 49cb0b3ef5 Add files via upload 2023-10-24 09:40:15 +08:00
PYDT c81845ba3a Add files via upload 2023-10-24 09:23:43 +08:00
PYDT 053ae64008 Add files via upload 2023-10-24 09:16:11 +08:00
PYDT 48989840b8 Add files via upload 2023-10-23 20:47:18 +08:00
PYDT 36c7bcd87f Add files via upload 2023-10-23 18:56:42 +08:00
PYDT a50eca1600 Add files via upload 2023-10-22 15:38:01 +08:00
PYDT f70dc8eb46 Add files via upload 2023-10-22 15:09:01 +08:00
PYDT f13d816c5b Add files via upload 2023-10-21 23:46:01 +08:00
PYDT 3429e658b6 Add files via upload 2023-10-21 10:46:45 +08:00
PYDT 0c6f9d6041 Add files via upload 2023-10-20 11:21:47 +08:00
PYDT 4a668499b0 Add files via upload 2023-10-20 07:29:21 +08:00
PYDT f1057252b3 Add files via upload 2023-10-19 19:56:21 +08:00
PYDT 4e3c866536 Add files via upload 2023-10-19 13:42:22 +08:00
PYDT c585cb370c Add files via upload 2023-10-19 12:04:53 +08:00
PYDT 2211a2b1d4 Add files via upload 2023-10-18 10:15:49 +08:00
PYDT 42069e2aac Add files via upload 2023-10-18 09:17:55 +08:00
PYDT fd499a17fe Add files via upload 2023-10-18 06:25:51 +08:00
PYDT 0cc56d3da7 Add files via upload 2023-10-17 16:08:49 +08:00
PYDT 2096f55ce8 Add files via upload 2023-10-17 15:56:09 +08:00
PYDT a4afe0ac10 Add files via upload 2023-10-17 15:24:15 +08:00
PYDT d523b66970 Add files via upload 2023-10-17 15:17:25 +08:00
PYDT 192335249c Add files via upload 2023-10-17 14:07:09 +08:00
PYDT e02879b3d7 Add files via upload 2023-10-17 13:01:37 +08:00
PYDT bf7157fb3e Add files via upload 2023-10-17 11:22:52 +08:00
PYDT 7c2ae87c73 Add files via upload 2023-10-17 10:14:09 +08:00
PYDT c1357bb2e1 Add files via upload 2023-10-16 08:32:32 +08:00
PYDT c298c3773e Add files via upload 2023-10-15 21:10:07 +08:00
PYDT 7d09c6501c Add files via upload 2023-10-15 21:00:37 +08:00
PYDT 1a051d42af Add files via upload 2023-10-15 18:25:43 +08:00
PYDT 22bbcc5217 Add files via upload 2023-10-15 18:23:10 +08:00
PYDT 017f153002 Add files via upload 2023-10-15 14:37:23 +08:00
PYDT cf4762ad04 Add files via upload 2023-10-15 09:17:04 +08:00
PYDT 6ba920e26a Add files via upload 2023-10-14 17:07:00 +08:00
PYDT a66acf0ef9 Delete requirements.txt 2023-10-14 17:01:56 +08:00
PYDT 8ab982ac38 Update README.md 2023-10-14 17:00:02 +08:00
PYDT 0c32a126a9 Update README.md 2023-10-14 16:56:45 +08:00
PYDT fd47881f88 Update README.md 2023-10-14 16:53:26 +08:00
PYDT 61298235fd Add files via upload 2023-10-14 12:24:43 +08:00
PYDT 4a38277c3e Add files via upload 2023-10-14 00:05:34 +08:00
PYDT fd7912f631 Add files via upload 2023-10-13 21:04:42 +08:00
mtkiao129 4f1b0e99e4 Add files via upload
add Python module list
2023-10-13 20:57:16 +08:00
PYDT 086e375cea Add files via upload 2023-10-13 20:00:57 +08:00
PYDT f90b132ccb Add files via upload 2023-10-13 18:42:29 +08:00
PYDT f4bd217445 Add files via upload 2023-10-13 18:28:58 +08:00
PYDT 5524e2f689 Add files via upload 2023-10-13 17:38:57 +08:00
PYDT 42b8201f37 Add files via upload 2023-10-13 15:15:19 +08:00
PYDT f71c821128 Add files via upload 2023-10-13 12:47:20 +08:00
PYDT 28330d3ad6 Add files via upload 2023-10-13 09:01:57 +08:00
PYDT 5afd576a3c Add files via upload 2023-10-12 11:39:03 +08:00
PYDT edcf82d139 Add files via upload 2023-10-12 09:50:21 +08:00
PYDT 69e5143a27 Add files via upload 2023-10-11 20:43:54 +08:00
PYDT 215d0faa53 Add files via upload 2023-10-11 20:11:28 +08:00
PYDT 470142a640 Add files via upload 2023-10-11 11:54:56 +08:00
PYDT 8e67a8d679 Add files via upload 2023-10-11 11:52:38 +08:00
PYDT be5baf9c87 Add files via upload 2023-10-11 11:04:42 +08:00
PYDT 7a05e42f3f Delete PYAS_Function_Full.zip 2023-10-11 11:04:19 +08:00
PYDT 34240ec01f Delete PYAS_Function.py 2023-10-11 11:03:55 +08:00
PYDT 0bf6eccb8b Add files via upload 2023-10-11 11:03:09 +08:00
PYDT 1f3b694231 Add files via upload 2023-10-10 14:17:48 +08:00
PYDT 470358585d Add files via upload 2023-10-10 00:44:40 +08:00
PYDT 4c69b555ae Add files via upload 2023-10-10 00:13:21 +08:00
PYDT aef60afcd8 Update README.md 2023-10-09 22:13:23 +08:00
PYDT ec753c50a5 Add files via upload 2023-10-09 22:07:11 +08:00
PYDT cbebe878aa Add files via upload 2023-10-09 21:41:34 +08:00
PYDT e9d930507e Add files via upload 2023-10-08 22:26:15 +08:00
PYDT 3eba768d06 Add files via upload 2023-10-08 02:00:53 +08:00
PYDT 76a5732997 Add files via upload 2023-10-08 01:54:58 +08:00
PYDT 32987c1274 Add files via upload 2023-10-07 14:10:49 +08:00
PYDT 8990b97a32 Add files via upload 2023-10-05 20:33:33 +08:00
PYDT 65b427121f Add files via upload 2023-10-05 06:57:23 +08:00
PYDT 81dd259672 Add files via upload 2023-10-05 01:35:34 +08:00
PYDT 05c2031d47 Add files via upload 2023-10-05 01:30:52 +08:00
PYDT 2b2de7550f Add files via upload 2023-10-05 00:48:22 +08:00
PYDT f9a8244086 Add files via upload 2023-10-05 00:47:28 +08:00
PYDT 86f3904b8a Add files via upload 2023-10-04 12:35:15 +08:00
PYDT 017aab4b0a Add files via upload 2023-10-04 10:55:51 +08:00
PYDT e33777c961 Add files via upload 2023-10-03 11:42:22 +08:00
PYDT ac14acd042 Add files via upload 2023-10-03 02:06:29 +08:00
PYDT e9f07df010 Add files via upload 2023-10-03 01:32:50 +08:00
PYDT 5d3855cdfa Add files via upload 2023-10-03 01:22:47 +08:00
PYDT 938e76fb4a Add files via upload 2023-10-02 17:49:09 +08:00
PYDT c0f6722c18 Add files via upload 2023-10-02 12:42:00 +08:00
PYDT 54e8922bc3 Add files via upload 2023-10-02 11:37:21 +08:00
PYDT 81b47dbf45 Add files via upload 2023-10-01 23:32:22 +08:00
PYDT 312401d80f Add files via upload 2023-09-26 19:27:47 +08:00
PYDT 8927ab7e36 Add files via upload 2023-09-26 17:50:21 +08:00
PYDT 6d99576e36 Add files via upload 2023-09-26 17:14:38 +08:00
PYDT 5618cd19cb Add files via upload 2023-09-26 06:41:25 +08:00
PYDT da11c6f5b6 Add files via upload 2023-09-25 10:00:56 +08:00
PYDT 6e370e776a Add files via upload 2023-09-24 21:06:50 +08:00
PYDT ab6b319738 Add files via upload 2023-09-23 11:48:32 +08:00
PYDT aca03cacf9 Add files via upload 2023-09-23 00:00:56 +08:00
PYDT 01b5e7ced0 Add files via upload 2023-09-22 18:51:41 +08:00
PYDT 6d8ef1d4a4 Add files via upload 2023-09-22 18:34:39 +08:00
PYDT f029636757 Add files via upload 2023-09-22 17:42:09 +08:00
PYDT 168b396daa Add files via upload 2023-09-22 12:06:19 +08:00
PYDT 0873a59392 Add files via upload 2023-09-22 08:25:11 +08:00
PYDT 3c646f57e6 Add files via upload 2023-09-22 06:54:08 +08:00
PYDT 940db64678 Add files via upload 2023-09-22 02:39:10 +08:00
PYDT da1c980743 Add files via upload 2023-09-21 07:50:58 +08:00
PYDT e3a4b636f7 Add files via upload 2023-09-20 20:17:05 +08:00
PYDT 9434898efa Add files via upload 2023-09-20 19:54:16 +08:00
PYDT 5d1c17e6ff Add files via upload 2023-09-20 19:53:33 +08:00
PYDT 4f736b352a Add files via upload 2023-09-20 19:52:54 +08:00
PYDT 037e2fbab1 Add files via upload 2023-09-20 15:18:39 +08:00
PYDT 4b24858631 Add files via upload 2023-09-20 14:59:41 +08:00
PYDT 81904a3a7b Add files via upload 2023-09-20 12:36:14 +08:00
PYDT 6e63a789cb Add files via upload 2023-09-20 11:18:00 +08:00
PYDT 4b977ec4df Add files via upload 2023-09-20 10:05:46 +08:00
PYDT fa692caaa8 Add files via upload 2023-09-19 22:52:52 +08:00
PYDT 7082003e4a Add files via upload 2023-09-19 21:26:02 +08:00
PYDT dec35d9b8a Add files via upload 2023-09-19 21:25:42 +08:00
PYDT 90711465ba Add files via upload 2023-09-19 21:23:17 +08:00
PYDT 1bb74f20b4 Add files via upload 2023-09-19 21:22:55 +08:00
PYDT b2cce37490 Add files via upload 2023-09-19 21:22:21 +08:00
PYDT 22e41eeacc Add files via upload 2023-09-19 07:59:27 +08:00
PYDT 600f2543a6 Add files via upload 2023-09-19 00:07:05 +08:00
PYDT 9e7185ae6d Add files via upload 2023-09-18 23:56:13 +08:00
PYDT 11725afa5a Add files via upload 2023-09-18 13:04:51 +08:00
PYDT 3bb94d05be Add files via upload 2023-09-17 18:47:30 +08:00
PYDT 7290db72e8 Add files via upload 2023-09-16 08:33:47 +08:00
PYDT 4dc92b081e Add files via upload 2023-09-15 20:14:15 +08:00
PYDT 68c614d9dd Add files via upload 2023-09-15 15:44:50 +08:00
PYDT efca8d0161 Add files via upload 2023-09-15 13:32:51 +08:00
PYDT 6d86b15800 Add files via upload 2023-09-15 11:44:45 +08:00
PYDT f43b2df6fc Add files via upload 2023-09-15 11:34:07 +08:00
PYDT 9f3eb593f8 Add files via upload 2023-09-15 11:23:36 +08:00
PYDT 9ca7c41fe7 Add files via upload 2023-09-15 11:01:46 +08:00
PYDT f39746c116 Add files via upload 2023-09-15 10:23:59 +08:00
PYDT 88f1dc2c01 Add files via upload 2023-09-15 10:22:12 +08:00
PYDT ee3daae665 Add files via upload 2023-09-14 23:20:07 +08:00
PYDT 9a47f06c2a Add files via upload 2023-09-14 22:46:09 +08:00
PYDT 6df173d30a Add files via upload 2023-09-13 23:49:26 +08:00
PYDT f992394f6f Add files via upload 2023-09-13 23:32:29 +08:00
PYDT 98c19fcd7e Add files via upload 2023-09-13 12:54:31 +08:00
PYDT 12cc2439af Add files via upload 2023-09-13 10:17:37 +08:00
PYDT 2341100397 Add files via upload 2023-09-12 21:52:33 +08:00
PYDT b15c9e4e39 Add files via upload 2023-09-11 22:55:32 +08:00
PYDT dbf860ca7a Add files via upload 2023-09-11 22:21:33 +08:00
PYDT aa481f415d Add files via upload 2023-09-11 19:47:01 +08:00
PYDT 59eeae791a Add files via upload 2023-09-09 12:51:44 +08:00
PYDT 0691a4420c Add files via upload 2023-09-08 18:02:46 +08:00
PYDT 66e744dd57 Add files via upload 2023-09-08 17:08:05 +08:00
PYDT 9f5eb72cec Add files via upload 2023-09-08 06:52:44 +08:00
PYDT a021ab6e42 Update README.md 2023-09-05 23:14:19 +08:00
PYDT 6a316e850c Add files via upload 2023-09-05 23:00:08 +08:00
PYDT 69413c1bed Add files via upload 2023-09-04 23:35:25 +08:00
PYDT c152cd944e Add files via upload 2023-09-04 23:15:31 +08:00
PYDT a055864676 Add files via upload 2023-09-04 21:07:05 +08:00
PYDT cb64da2d5f Add files via upload 2023-09-04 19:51:38 +08:00
PYDT 5633e70a11 Add files via upload 2023-09-02 10:38:25 +08:00
PYDT c1f6d0692b Add files via upload 2023-09-02 10:36:18 +08:00
PYDT fe527f1668 Add files via upload 2023-09-01 19:46:58 +08:00
PYAS 774a2313fb Add files via upload 2023-08-10 20:03:47 +08:00
PYDT a5f07706f5 Add files via upload 2023-08-01 12:24:21 +08:00
PYDT 2b6b8accf1 Add files via upload 2023-07-31 22:54:25 +08:00
PYDT e6aca5533b Add files via upload 2023-07-30 23:21:43 +08:00
PYDT dc60cc3ccb Add files via upload 2023-07-27 17:36:07 +08:00
PYDT 5613993019 Add files via upload 2023-07-27 01:18:45 +08:00
PYDT 1613101bd6 Add files via upload 2023-07-27 01:17:56 +08:00
PYDT cb3440494e Add files via upload 2023-07-26 22:12:46 +08:00
PYDT 78b979f397 Add files via upload 2023-07-26 19:22:42 +08:00
PYDT 6742b71208 Add files via upload 2023-07-26 18:03:47 +08:00
PYDT e0178ac2b5 Add files via upload 2023-07-25 20:08:30 +08:00
PYDT e2141decaa Add files via upload 2023-07-23 03:23:51 +08:00
PYDT 4a68c62e72 Add files via upload 2023-07-22 14:00:05 +08:00
PYDT bc7d5704f9 Add files via upload 2023-07-22 00:22:58 +08:00
PYDT a984be2535 Add files via upload 2023-07-16 16:36:37 +08:00
PYDT 026f96d473 Add files via upload 2023-07-16 15:02:32 +08:00
PYDT 0dbca7895e Add files via upload 2023-07-12 18:11:16 +08:00
PYDT 0f390668f7 Delete Library directory 2023-07-10 21:54:28 +08:00
PYDT f4ced70d8e Add files via upload 2023-07-10 21:52:36 +08:00
PYDT 7b805df433 Delete PYAS_UI_rc.py 2023-07-10 21:49:32 +08:00
PYDT 4b66171388 Delete PYAS_UI.py 2023-07-10 21:49:17 +08:00
PYDT 0cf80753ae Delete PYAS_Model.py 2023-07-10 21:43:35 +08:00
PYDT 6f3d315851 Add files via upload 2023-07-10 21:43:23 +08:00
PYDT 475d4b4a80 Add files via upload 2023-07-10 21:36:31 +08:00
PYDT bd8633de0d Add files via upload 2023-07-10 21:30:43 +08:00
PYDT 5d2937c896 Add files via upload 2023-07-10 21:30:00 +08:00
PYDT eb89284834 Add files via upload 2023-07-09 21:29:38 +08:00
PYDT f5777b2a68 Delete PYAS_Version_File.py 2023-07-09 21:29:30 +08:00
PYDT 9431a4dd6c Add files via upload 2023-07-09 21:26:44 +08:00
PYDT 82a4dfdfd5 Add files via upload 2023-07-07 03:49:48 +08:00
PYDT 9bd63d15e9 Add files via upload 2023-07-07 03:41:27 +08:00
PYDT f6e5c8e0b1 Add files via upload 2023-07-07 01:46:25 +08:00
PYDT 3b56f6dc6f Add files via upload 2023-07-07 00:53:36 +08:00
PYDT 2c24079552 Add files via upload 2023-07-05 17:24:25 +08:00
PYDT f58a846826 Add files via upload 2023-07-05 12:06:22 +08:00
PYDT 8bc74a8833 Add files via upload 2023-07-05 12:03:34 +08:00
PYDT 5bd0033ff0 Add files via upload 2023-07-04 23:48:20 +08:00
PYDT e45758be80 Add files via upload 2023-07-04 23:41:04 +08:00
PYDT 5033348eed Update README.md 2023-07-04 19:53:51 +08:00
PYDT 2327fd099c Add files via upload 2023-07-04 15:36:15 +08:00
PYDT 6afa02ea71 Add files via upload 2023-07-04 15:34:48 +08:00
PYDT 9cf1b38e56 Add files via upload 2023-07-04 15:32:44 +08:00
PYDT 241a9ffea5 Add files via upload 2023-07-04 11:14:55 +08:00
PYDT 3e0749ad60 Add files via upload 2023-07-03 15:43:42 +08:00
PYDT 0f55ff4295 Add files via upload 2023-07-03 13:50:02 +08:00
PYDT d8f8c34991 Add files via upload 2023-07-02 19:43:43 +08:00
PYDT 7ddd323b65 Add files via upload 2023-07-02 01:09:19 +08:00
PYDT 36bbb6e708 Add files via upload 2023-07-02 00:11:55 +08:00
PYDT 06638a8cdc Add files via upload 2023-06-30 20:32:24 +08:00
PYDT 42d8a8fde0 Add files via upload 2023-06-29 17:45:16 +08:00
PYDT e2997fbbce Add files via upload 2023-06-29 17:39:19 +08:00
PYDT 5dd671eb4a Add files via upload 2023-06-27 19:00:24 +08:00
PYDT 59aff0f196 Add files via upload 2023-06-27 18:37:06 +08:00
PYDT 548def29b3 Add files via upload 2023-06-26 14:59:40 +08:00
PYDT 84d59eb7d4 Add files via upload 2023-06-25 00:28:29 +08:00
PYDT 1cc3b599a9 Add files via upload 2023-06-18 00:03:44 +08:00
45 changed files with 32554 additions and 7244 deletions

No files matched your search

File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+309
View File
@@ -0,0 +1,309 @@
import os, sys, time, json, zlib, array, onnxmltools, multiprocessing
import numpy as np
import pandas as pd
import lightgbm as lgb
import scipy.sparse as sp
from collections import defaultdict
from onnxmltools.convert.common.data_types import FloatTensorType
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, roc_auc_score
try:
import orjson
JSON_LOADS = orjson.loads
except ImportError:
JSON_LOADS = json.loads
####################################################################################################
JSONL_PATH = "pe_features.jsonl"
MODEL_FILE = "Pefile_General_E1.txt"
ONNX_FILE = "Pefile_General_E1.onnx"
FEATURE_FILE = "features.json"
TEST_SIZE = 0.0001
RANDOM_SEED = 42
DLL_HASH_DIM = 512
API_HASH_DIM = 4096
EXCLUDE_FEATURES = {
'label', 'filehash',
}
LGBM_PARAMS = {
'objective': 'binary',
'metric': ['binary_logloss', 'auc'],
'boosting_type': 'gbdt',
'num_leaves': 256,
'feature_fraction': 0.8,
'bagging_fraction': 1.0,
'bagging_freq': 5,
'verbose': -1,
'seed': RANDOM_SEED,
'n_jobs': -1,
'max_depth': -1,
'min_data_in_leaf': 50,
}
####################################################################################################
def analyze_schema(jsonl_path):
print("[*] Stage 1: Scanning global schema...")
base_keys = set()
num_lines = 0
with open(jsonl_path, 'rb') as f:
for line in f:
num_lines += 1
try:
data = JSON_LOADS(line)
base_data = data.get('Base')
if base_data:
base_keys.update(base_data.keys())
except Exception:
pass
base_schema = sorted([k for k in base_keys if k.lower().strip() not in EXCLUDE_FEATURES])
dll_schema = [f"DllHash_{i:03d}" for i in range(DLL_HASH_DIM)]
api_schema = [f"ApiHash_{i:04d}" for i in range(API_HASH_DIM)]
return base_schema, dll_schema, api_schema, num_lines
####################################################################################################
def load_data_efficiently(jsonl_path, base_schema, dll_schema, api_schema, num_lines):
print(f"[*] Stage 2: Building sparse feature matrix dynamically via Multiprocessing...")
final_features = base_schema + dll_schema + api_schema
num_features = len(final_features)
offset_dll = len(base_schema)
offset_api = offset_dll + DLL_HASH_DIM
file_size = os.path.getsize(jsonl_path)
workers = min(os.cpu_count() or 4, 16)
chunk_size = file_size // workers
tasks = []
for i in range(workers):
start = i * chunk_size
end = file_size if i == workers - 1 else (i + 1) * chunk_size
tasks.append((jsonl_path, start, end, base_schema, num_features, offset_dll, offset_api))
with multiprocessing.Pool(workers) as pool:
results = pool.map(_chunk_worker, tasks)
Xs = [r[0] for r in results if r[0].shape[0] > 0]
ys = [r[1] for r in results if r[1].shape[0] > 0]
X_final = sp.vstack(Xs, format='csr') if Xs else sp.csr_matrix((0, num_features), dtype=np.float32)
y_final = np.concatenate(ys) if ys else np.array([], dtype=np.int8)
return X_final, pd.Series(y_final), final_features
def _chunk_worker(args):
filepath, start_byte, end_byte, base_schema, num_features, offset_dll, offset_api = args
base_idx = {feat: i for i, feat in enumerate(base_schema)}
base_idx_get = base_idx.get
rows = array.array('i')
cols = array.array('i')
vals = array.array('f')
y_list = array.array('b')
with open(filepath, 'rb') as f:
if start_byte > 0:
f.seek(start_byte - 1)
if f.read(1) != b'\n':
f.seek(start_byte)
f.readline()
else:
f.seek(start_byte)
else:
f.seek(0)
row_idx = 0
while f.tell() < end_byte:
line = f.readline()
if not line:
break
try:
data = JSON_LOADS(line)
y_list.append(data.get('Label', 0))
base_data = data.get('Base')
if base_data:
for k, v in base_data.items():
idx = base_idx_get(k)
if idx is not None:
val = float(v)
if val != 0.0:
rows.append(row_idx)
cols.append(idx)
vals.append(val)
dll_data = data.get('DLLs')
if dll_data:
for d in dll_data:
idx = zlib.crc32(d.encode('utf-8', 'ignore')) % DLL_HASH_DIM
rows.append(row_idx)
cols.append(offset_dll + idx)
vals.append(1.0)
api_data = data.get('APIs')
if api_data:
for a in api_data:
idx = zlib.crc32(a.encode('utf-8', 'ignore')) % API_HASH_DIM
rows.append(row_idx)
cols.append(offset_api + idx)
vals.append(1.0)
row_idx += 1
except Exception:
continue
y_arr = np.frombuffer(y_list, dtype=np.int8)
np_rows = np.frombuffer(rows, dtype=np.int32)
np_cols = np.frombuffer(cols, dtype=np.int32)
np_vals = np.frombuffer(vals, dtype=np.float32)
X_local = sp.csr_matrix((np_vals, (np_rows, np_cols)), shape=(row_idx, num_features), dtype=np.float32)
return X_local, y_arr
####################################################################################################
def _calculate_dynamic_lr(current_iter: int) -> float:
return max(0.01, 0.1 - (current_iter // 80) * 0.01)
def train_process(X, y, feature_names):
print(f"[*] Dataset shape: {X.shape}")
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=TEST_SIZE, random_state=RANDOM_SEED, stratify=y)
n_pos = (y_train == 1).sum()
n_neg = (y_train == 0).sum()
base_weight = n_neg / n_pos if n_pos > 0 else 1.0
weight_ratio_target = 1
final_pos_weight = base_weight * weight_ratio_target
print(f"[*] Sample distribution: Safe={n_neg}, Malware={n_pos}")
print(f"[*] Weight correction: Base={base_weight:.4f}, Final={final_pos_weight:.4f}")
train_data = lgb.Dataset(X_train, label=y_train, feature_name=feature_names)
valid_data = lgb.Dataset(X_test, label=y_test, reference=train_data, feature_name=feature_names)
params = LGBM_PARAMS.copy()
params['scale_pos_weight'] = final_pos_weight
print("\n[*] Starting LightGBM training...")
start_time = time.time()
model = lgb.train(
params,
train_data,
valid_sets=[valid_data],
num_boost_round=500,
callbacks=[
lgb.log_evaluation(period=50),
lgb.reset_parameter(learning_rate=_calculate_dynamic_lr)
]
)
elapsed = time.time() - start_time
print(f"\n[+] Training complete, time elapsed {elapsed:.2f} seconds")
return model, X_test, y_test
####################################################################################################
def export_onnx_model(model, feature_names):
print(f"[*] Exporting ONNX model to {ONNX_FILE}...")
try:
initial_type = [('float_input', FloatTensorType([None, len(feature_names)]))]
onnx_model = onnxmltools.convert_lightgbm(model, initial_types=initial_type)
onnxmltools.utils.save_model(onnx_model, ONNX_FILE)
with open(FEATURE_FILE, 'w') as f:
json.dump(feature_names, f)
print(f"[+] ONNX export successful. Feature order saved to {FEATURE_FILE}")
except Exception as e:
print(f"[-] ONNX export failed: {e}")
def evaluate_and_save(model, X_test, y_test):
print("\n------------------- Evaluation Report -------------------\n")
y_prob = model.predict(X_test, num_iteration=model.best_iteration)
y_pred = (y_prob > 0.5).astype(int)
acc = accuracy_score(y_test, y_pred)
auc = roc_auc_score(y_test, y_prob)
tp = np.sum((y_test == 1) & (y_pred == 1))
fn = np.sum((y_test == 1) & (y_pred == 0))
tn = np.sum((y_test == 0) & (y_pred == 0))
fp = np.sum((y_test == 0) & (y_pred == 1))
total_malware = tp + fn
total_safe = tn + fp
detection_rate = (tp / total_malware * 100) if total_malware > 0 else 0.0
fpr = (fp / total_safe * 100) if total_safe > 0 else 0.0
print(f"Accuracy : {acc:.6f}")
print(f"ROC AUC : {auc:.6f}\n")
print(f"True Positive (Class 1) : {detection_rate:.3f}% ({tp}/{total_malware})")
print(f"False Positive (Class 0) : {fpr:.3f}% ({fp}/{total_safe})")
print("\n---------------------------------------------------------\n")
print("[*] Top 20 Features:")
feature_names = model.feature_name()
importance = model.feature_importance(importance_type='gain')
feature_imp = pd.DataFrame(sorted(zip(importance, feature_names), reverse=True), columns=['Value', 'Feature'])
print(feature_imp.head(20).to_string(index=False))
print("\n---------------------------------------------------------\n")
model.save_model(MODEL_FILE)
print(f"[+] Native model saved to: {os.path.abspath(MODEL_FILE)}")
export_onnx_model(model, feature_names)
####################################################################################################
if __name__ == "__main__":
multiprocessing.freeze_support()
print("\n---------------- PE Malware Trainer v4.0 ----------------\n")
if not os.path.exists(JSONL_PATH):
print(f"[-] Error: Feature file {JSONL_PATH} not found.")
sys.exit(1)
base_schema, dll_schema, api_schema, num_lines = analyze_schema(JSONL_PATH)
if num_lines == 0:
print("[-] Error: Feature file is empty.")
sys.exit(1)
print(f"[*] Detected Base features: {len(base_schema)}")
print(f"[*] Hashing DLL features: {len(dll_schema)}")
print(f"[*] Hashing API features: {len(api_schema)}")
X, y, final_features = load_data_efficiently(JSONL_PATH, base_schema, dll_schema, api_schema, num_lines)
try:
model, X_test, y_test = train_process(X, y, final_features)
evaluate_and_save(model, X_test, y_test)
except KeyboardInterrupt:
print("\n\n[-] Training aborted.")
except Exception as e:
print(f"\n[-] System exception: {e}")
+309
View File
@@ -0,0 +1,309 @@
import os, sys, time, json, zlib, array, onnxmltools, multiprocessing
import numpy as np
import pandas as pd
import lightgbm as lgb
import scipy.sparse as sp
from collections import defaultdict
from onnxmltools.convert.common.data_types import FloatTensorType
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, roc_auc_score
try:
import orjson
JSON_LOADS = orjson.loads
except ImportError:
JSON_LOADS = json.loads
####################################################################################################
JSONL_PATH = "pe_features.jsonl"
MODEL_FILE = "Pefile_General_S1.txt"
ONNX_FILE = "Pefile_General_S1.onnx"
FEATURE_FILE = "features.json"
TEST_SIZE = 0.0001
RANDOM_SEED = 42
DLL_HASH_DIM = 512
API_HASH_DIM = 4096
EXCLUDE_FEATURES = {
'label', 'filehash',
}
LGBM_PARAMS = {
'objective': 'binary',
'metric': ['binary_logloss', 'auc'],
'boosting_type': 'gbdt',
'num_leaves': 256,
'feature_fraction': 0.8,
'bagging_fraction': 1.0,
'bagging_freq': 5,
'verbose': -1,
'seed': RANDOM_SEED,
'n_jobs': -1,
'max_depth': -1,
'min_data_in_leaf': 50,
}
####################################################################################################
def analyze_schema(jsonl_path):
print("[*] Stage 1: Scanning global schema...")
base_keys = set()
num_lines = 0
with open(jsonl_path, 'rb') as f:
for line in f:
num_lines += 1
try:
data = JSON_LOADS(line)
base_data = data.get('Base')
if base_data:
base_keys.update(base_data.keys())
except Exception:
pass
base_schema = sorted([k for k in base_keys if k.lower().strip() not in EXCLUDE_FEATURES])
dll_schema = [f"DllHash_{i:03d}" for i in range(DLL_HASH_DIM)]
api_schema = [f"ApiHash_{i:04d}" for i in range(API_HASH_DIM)]
return base_schema, dll_schema, api_schema, num_lines
####################################################################################################
def load_data_efficiently(jsonl_path, base_schema, dll_schema, api_schema, num_lines):
print(f"[*] Stage 2: Building sparse feature matrix dynamically via Multiprocessing...")
final_features = base_schema + dll_schema + api_schema
num_features = len(final_features)
offset_dll = len(base_schema)
offset_api = offset_dll + DLL_HASH_DIM
file_size = os.path.getsize(jsonl_path)
workers = min(os.cpu_count() or 4, 16)
chunk_size = file_size // workers
tasks = []
for i in range(workers):
start = i * chunk_size
end = file_size if i == workers - 1 else (i + 1) * chunk_size
tasks.append((jsonl_path, start, end, base_schema, num_features, offset_dll, offset_api))
with multiprocessing.Pool(workers) as pool:
results = pool.map(_chunk_worker, tasks)
Xs = [r[0] for r in results if r[0].shape[0] > 0]
ys = [r[1] for r in results if r[1].shape[0] > 0]
X_final = sp.vstack(Xs, format='csr') if Xs else sp.csr_matrix((0, num_features), dtype=np.float32)
y_final = np.concatenate(ys) if ys else np.array([], dtype=np.int8)
return X_final, pd.Series(y_final), final_features
def _chunk_worker(args):
filepath, start_byte, end_byte, base_schema, num_features, offset_dll, offset_api = args
base_idx = {feat: i for i, feat in enumerate(base_schema)}
base_idx_get = base_idx.get
rows = array.array('i')
cols = array.array('i')
vals = array.array('f')
y_list = array.array('b')
with open(filepath, 'rb') as f:
if start_byte > 0:
f.seek(start_byte - 1)
if f.read(1) != b'\n':
f.seek(start_byte)
f.readline()
else:
f.seek(start_byte)
else:
f.seek(0)
row_idx = 0
while f.tell() < end_byte:
line = f.readline()
if not line:
break
try:
data = JSON_LOADS(line)
y_list.append(data.get('Label', 0))
base_data = data.get('Base')
if base_data:
for k, v in base_data.items():
idx = base_idx_get(k)
if idx is not None:
val = float(v)
if val != 0.0:
rows.append(row_idx)
cols.append(idx)
vals.append(val)
dll_data = data.get('DLLs')
if dll_data:
for d in dll_data:
idx = zlib.crc32(d.encode('utf-8', 'ignore')) % DLL_HASH_DIM
rows.append(row_idx)
cols.append(offset_dll + idx)
vals.append(1.0)
api_data = data.get('APIs')
if api_data:
for a in api_data:
idx = zlib.crc32(a.encode('utf-8', 'ignore')) % API_HASH_DIM
rows.append(row_idx)
cols.append(offset_api + idx)
vals.append(1.0)
row_idx += 1
except Exception:
continue
y_arr = np.frombuffer(y_list, dtype=np.int8)
np_rows = np.frombuffer(rows, dtype=np.int32)
np_cols = np.frombuffer(cols, dtype=np.int32)
np_vals = np.frombuffer(vals, dtype=np.float32)
X_local = sp.csr_matrix((np_vals, (np_rows, np_cols)), shape=(row_idx, num_features), dtype=np.float32)
return X_local, y_arr
####################################################################################################
def _calculate_dynamic_lr(current_iter: int) -> float:
return max(0.01, 0.1 - (current_iter // 80) * 0.01)
def train_process(X, y, feature_names):
print(f"[*] Dataset shape: {X.shape}")
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=TEST_SIZE, random_state=RANDOM_SEED, stratify=y)
n_pos = (y_train == 1).sum()
n_neg = (y_train == 0).sum()
base_weight = n_neg / n_pos if n_pos > 0 else 1.0
weight_ratio_target = 0.01
final_pos_weight = base_weight * weight_ratio_target
print(f"[*] Sample distribution: Safe={n_neg}, Malware={n_pos}")
print(f"[*] Weight correction: Base={base_weight:.4f}, Final={final_pos_weight:.4f}")
train_data = lgb.Dataset(X_train, label=y_train, feature_name=feature_names)
valid_data = lgb.Dataset(X_test, label=y_test, reference=train_data, feature_name=feature_names)
params = LGBM_PARAMS.copy()
params['scale_pos_weight'] = final_pos_weight
print("\n[*] Starting LightGBM training...")
start_time = time.time()
model = lgb.train(
params,
train_data,
valid_sets=[valid_data],
num_boost_round=350,
callbacks=[
lgb.log_evaluation(period=50),
lgb.reset_parameter(learning_rate=_calculate_dynamic_lr)
]
)
elapsed = time.time() - start_time
print(f"\n[+] Training complete, time elapsed {elapsed:.2f} seconds")
return model, X_test, y_test
####################################################################################################
def export_onnx_model(model, feature_names):
print(f"[*] Exporting ONNX model to {ONNX_FILE}...")
try:
initial_type = [('float_input', FloatTensorType([None, len(feature_names)]))]
onnx_model = onnxmltools.convert_lightgbm(model, initial_types=initial_type)
onnxmltools.utils.save_model(onnx_model, ONNX_FILE)
with open(FEATURE_FILE, 'w') as f:
json.dump(feature_names, f)
print(f"[+] ONNX export successful. Feature order saved to {FEATURE_FILE}")
except Exception as e:
print(f"[-] ONNX export failed: {e}")
def evaluate_and_save(model, X_test, y_test):
print("\n------------------- Evaluation Report -------------------\n")
y_prob = model.predict(X_test, num_iteration=model.best_iteration)
y_pred = (y_prob > 0.5).astype(int)
acc = accuracy_score(y_test, y_pred)
auc = roc_auc_score(y_test, y_prob)
tp = np.sum((y_test == 1) & (y_pred == 1))
fn = np.sum((y_test == 1) & (y_pred == 0))
tn = np.sum((y_test == 0) & (y_pred == 0))
fp = np.sum((y_test == 0) & (y_pred == 1))
total_malware = tp + fn
total_safe = tn + fp
detection_rate = (tp / total_malware * 100) if total_malware > 0 else 0.0
fpr = (fp / total_safe * 100) if total_safe > 0 else 0.0
print(f"Accuracy : {acc:.6f}")
print(f"ROC AUC : {auc:.6f}\n")
print(f"True Positive (Class 1) : {detection_rate:.3f}% ({tp}/{total_malware})")
print(f"False Positive (Class 0) : {fpr:.3f}% ({fp}/{total_safe})")
print("\n---------------------------------------------------------\n")
print("[*] Top 20 Features:")
feature_names = model.feature_name()
importance = model.feature_importance(importance_type='gain')
feature_imp = pd.DataFrame(sorted(zip(importance, feature_names), reverse=True), columns=['Value', 'Feature'])
print(feature_imp.head(20).to_string(index=False))
print("\n---------------------------------------------------------\n")
model.save_model(MODEL_FILE)
print(f"[+] Native model saved to: {os.path.abspath(MODEL_FILE)}")
export_onnx_model(model, feature_names)
####################################################################################################
if __name__ == "__main__":
multiprocessing.freeze_support()
print("\n---------------- PE Malware Trainer v4.0 ----------------\n")
if not os.path.exists(JSONL_PATH):
print(f"[-] Error: Feature file {JSONL_PATH} not found.")
sys.exit(1)
base_schema, dll_schema, api_schema, num_lines = analyze_schema(JSONL_PATH)
if num_lines == 0:
print("[-] Error: Feature file is empty.")
sys.exit(1)
print(f"[*] Detected Base features: {len(base_schema)}")
print(f"[*] Hashing DLL features: {len(dll_schema)}")
print(f"[*] Hashing API features: {len(api_schema)}")
X, y, final_features = load_data_efficiently(JSONL_PATH, base_schema, dll_schema, api_schema, num_lines)
try:
model, X_test, y_test = train_process(X, y, final_features)
evaluate_and_save(model, X_test, y_test)
except KeyboardInterrupt:
print("\n\n[-] Training aborted.")
except Exception as e:
print(f"\n[-] System exception: {e}")
+309
View File
@@ -0,0 +1,309 @@
import os, sys, time, json, zlib, array, onnxmltools, multiprocessing
import numpy as np
import pandas as pd
import lightgbm as lgb
import scipy.sparse as sp
from collections import defaultdict
from onnxmltools.convert.common.data_types import FloatTensorType
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, roc_auc_score
try:
import orjson
JSON_LOADS = orjson.loads
except ImportError:
JSON_LOADS = json.loads
####################################################################################################
JSONL_PATH = "pe_features.jsonl"
MODEL_FILE = "Pefile_General_T1.txt"
ONNX_FILE = "Pefile_General_T1.onnx"
FEATURE_FILE = "features.json"
TEST_SIZE = 0.0001
RANDOM_SEED = 42
DLL_HASH_DIM = 512
API_HASH_DIM = 4096
EXCLUDE_FEATURES = {
'label', 'filehash',
}
LGBM_PARAMS = {
'objective': 'binary',
'metric': ['binary_logloss', 'auc'],
'boosting_type': 'gbdt',
'num_leaves': 256,
'feature_fraction': 0.8,
'bagging_fraction': 1.0,
'bagging_freq': 5,
'verbose': -1,
'seed': RANDOM_SEED,
'n_jobs': -1,
'max_depth': -1,
'min_data_in_leaf': 50,
}
####################################################################################################
def analyze_schema(jsonl_path):
print("[*] Stage 1: Scanning global schema...")
base_keys = set()
num_lines = 0
with open(jsonl_path, 'rb') as f:
for line in f:
num_lines += 1
try:
data = JSON_LOADS(line)
base_data = data.get('Base')
if base_data:
base_keys.update(base_data.keys())
except Exception:
pass
base_schema = sorted([k for k in base_keys if k.lower().strip() not in EXCLUDE_FEATURES])
dll_schema = [f"DllHash_{i:03d}" for i in range(DLL_HASH_DIM)]
api_schema = [f"ApiHash_{i:04d}" for i in range(API_HASH_DIM)]
return base_schema, dll_schema, api_schema, num_lines
####################################################################################################
def load_data_efficiently(jsonl_path, base_schema, dll_schema, api_schema, num_lines):
print(f"[*] Stage 2: Building sparse feature matrix dynamically via Multiprocessing...")
final_features = base_schema + dll_schema + api_schema
num_features = len(final_features)
offset_dll = len(base_schema)
offset_api = offset_dll + DLL_HASH_DIM
file_size = os.path.getsize(jsonl_path)
workers = min(os.cpu_count() or 4, 16)
chunk_size = file_size // workers
tasks = []
for i in range(workers):
start = i * chunk_size
end = file_size if i == workers - 1 else (i + 1) * chunk_size
tasks.append((jsonl_path, start, end, base_schema, num_features, offset_dll, offset_api))
with multiprocessing.Pool(workers) as pool:
results = pool.map(_chunk_worker, tasks)
Xs = [r[0] for r in results if r[0].shape[0] > 0]
ys = [r[1] for r in results if r[1].shape[0] > 0]
X_final = sp.vstack(Xs, format='csr') if Xs else sp.csr_matrix((0, num_features), dtype=np.float32)
y_final = np.concatenate(ys) if ys else np.array([], dtype=np.int8)
return X_final, pd.Series(y_final), final_features
def _chunk_worker(args):
filepath, start_byte, end_byte, base_schema, num_features, offset_dll, offset_api = args
base_idx = {feat: i for i, feat in enumerate(base_schema)}
base_idx_get = base_idx.get
rows = array.array('i')
cols = array.array('i')
vals = array.array('f')
y_list = array.array('b')
with open(filepath, 'rb') as f:
if start_byte > 0:
f.seek(start_byte - 1)
if f.read(1) != b'\n':
f.seek(start_byte)
f.readline()
else:
f.seek(start_byte)
else:
f.seek(0)
row_idx = 0
while f.tell() < end_byte:
line = f.readline()
if not line:
break
try:
data = JSON_LOADS(line)
y_list.append(data.get('Label', 0))
base_data = data.get('Base')
if base_data:
for k, v in base_data.items():
idx = base_idx_get(k)
if idx is not None:
val = float(v)
if val != 0.0:
rows.append(row_idx)
cols.append(idx)
vals.append(val)
dll_data = data.get('DLLs')
if dll_data:
for d in dll_data:
idx = zlib.crc32(d.encode('utf-8', 'ignore')) % DLL_HASH_DIM
rows.append(row_idx)
cols.append(offset_dll + idx)
vals.append(1.0)
api_data = data.get('APIs')
if api_data:
for a in api_data:
idx = zlib.crc32(a.encode('utf-8', 'ignore')) % API_HASH_DIM
rows.append(row_idx)
cols.append(offset_api + idx)
vals.append(1.0)
row_idx += 1
except Exception:
continue
y_arr = np.frombuffer(y_list, dtype=np.int8)
np_rows = np.frombuffer(rows, dtype=np.int32)
np_cols = np.frombuffer(cols, dtype=np.int32)
np_vals = np.frombuffer(vals, dtype=np.float32)
X_local = sp.csr_matrix((np_vals, (np_rows, np_cols)), shape=(row_idx, num_features), dtype=np.float32)
return X_local, y_arr
####################################################################################################
def _calculate_dynamic_lr(current_iter: int) -> float:
return max(0.01, 0.1 - (current_iter // 80) * 0.01)
def train_process(X, y, feature_names):
print(f"[*] Dataset shape: {X.shape}")
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=TEST_SIZE, random_state=RANDOM_SEED, stratify=y)
n_pos = (y_train == 1).sum()
n_neg = (y_train == 0).sum()
base_weight = n_neg / n_pos if n_pos > 0 else 1.0
weight_ratio_target = 0.0001
final_pos_weight = base_weight * weight_ratio_target
print(f"[*] Sample distribution: Safe={n_neg}, Malware={n_pos}")
print(f"[*] Weight correction: Base={base_weight:.4f}, Final={final_pos_weight:.4f}")
train_data = lgb.Dataset(X_train, label=y_train, feature_name=feature_names)
valid_data = lgb.Dataset(X_test, label=y_test, reference=train_data, feature_name=feature_names)
params = LGBM_PARAMS.copy()
params['scale_pos_weight'] = final_pos_weight
print("\n[*] Starting LightGBM training...")
start_time = time.time()
model = lgb.train(
params,
train_data,
valid_sets=[valid_data],
num_boost_round=350,
callbacks=[
lgb.log_evaluation(period=50),
lgb.reset_parameter(learning_rate=_calculate_dynamic_lr)
]
)
elapsed = time.time() - start_time
print(f"\n[+] Training complete, time elapsed {elapsed:.2f} seconds")
return model, X_test, y_test
####################################################################################################
def export_onnx_model(model, feature_names):
print(f"[*] Exporting ONNX model to {ONNX_FILE}...")
try:
initial_type = [('float_input', FloatTensorType([None, len(feature_names)]))]
onnx_model = onnxmltools.convert_lightgbm(model, initial_types=initial_type)
onnxmltools.utils.save_model(onnx_model, ONNX_FILE)
with open(FEATURE_FILE, 'w') as f:
json.dump(feature_names, f)
print(f"[+] ONNX export successful. Feature order saved to {FEATURE_FILE}")
except Exception as e:
print(f"[-] ONNX export failed: {e}")
def evaluate_and_save(model, X_test, y_test):
print("\n------------------- Evaluation Report -------------------\n")
y_prob = model.predict(X_test, num_iteration=model.best_iteration)
y_pred = (y_prob > 0.5).astype(int)
acc = accuracy_score(y_test, y_pred)
auc = roc_auc_score(y_test, y_prob)
tp = np.sum((y_test == 1) & (y_pred == 1))
fn = np.sum((y_test == 1) & (y_pred == 0))
tn = np.sum((y_test == 0) & (y_pred == 0))
fp = np.sum((y_test == 0) & (y_pred == 1))
total_malware = tp + fn
total_safe = tn + fp
detection_rate = (tp / total_malware * 100) if total_malware > 0 else 0.0
fpr = (fp / total_safe * 100) if total_safe > 0 else 0.0
print(f"Accuracy : {acc:.6f}")
print(f"ROC AUC : {auc:.6f}\n")
print(f"True Positive (Class 1) : {detection_rate:.3f}% ({tp}/{total_malware})")
print(f"False Positive (Class 0) : {fpr:.3f}% ({fp}/{total_safe})")
print("\n---------------------------------------------------------\n")
print("[*] Top 20 Features:")
feature_names = model.feature_name()
importance = model.feature_importance(importance_type='gain')
feature_imp = pd.DataFrame(sorted(zip(importance, feature_names), reverse=True), columns=['Value', 'Feature'])
print(feature_imp.head(20).to_string(index=False))
print("\n---------------------------------------------------------\n")
model.save_model(MODEL_FILE)
print(f"[+] Native model saved to: {os.path.abspath(MODEL_FILE)}")
export_onnx_model(model, feature_names)
####################################################################################################
if __name__ == "__main__":
multiprocessing.freeze_support()
print("\n---------------- PE Malware Trainer v4.0 ----------------\n")
if not os.path.exists(JSONL_PATH):
print(f"[-] Error: Feature file {JSONL_PATH} not found.")
sys.exit(1)
base_schema, dll_schema, api_schema, num_lines = analyze_schema(JSONL_PATH)
if num_lines == 0:
print("[-] Error: Feature file is empty.")
sys.exit(1)
print(f"[*] Detected Base features: {len(base_schema)}")
print(f"[*] Hashing DLL features: {len(dll_schema)}")
print(f"[*] Hashing API features: {len(api_schema)}")
X, y, final_features = load_data_efficiently(JSONL_PATH, base_schema, dll_schema, api_schema, num_lines)
try:
model, X_test, y_test = train_process(X, y, final_features)
evaluate_and_save(model, X_test, y_test)
except KeyboardInterrupt:
print("\n\n[-] Training aborted.")
except Exception as e:
print(f"\n[-] System exception: {e}")
+942
View File
@@ -0,0 +1,942 @@
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
-webkit-tap-highlight-color: transparent;
outline: none;
}
:root {
--bg-window: rgb(245, 245, 247);
--bg-nav: rgb(255, 255, 255);
--bg-panel: rgb(255, 255, 255);
--bg-hover: rgba(0, 0, 0, 0.05);
--text-primary: rgb(29, 29, 31);
--text-secondary: rgb(134, 134, 139);
--text-on-accent: rgb(255, 255, 255);
--border-color: rgb(210, 210, 215);
--accent-color: rgb(0, 122, 255);
--accent-alpha: rgba(0, 122, 255, 0.1);
--accent-shadow: rgba(0, 122, 255, 0.2);
--accent-hover: rgba(0, 122, 255, 0.3);
--shadow-sm: 0 2px 12px rgba(0, 0, 0, 0.04);
}
body {
background-color: transparent;
margin: 0;
padding: 0;
width: 100vw;
height: 100vh;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
color: var(--text-primary);
}
.app-container {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
overflow: hidden;
background-color: var(--bg-window);
}
.navigate-window {
height: 44px;
background-color: var(--bg-nav);
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 10px 0 20px;
border-bottom: 1px solid var(--border-color);
transition: background-color 0.3s;
}
.navigate-title {
font-size: 17px;
font-weight: 600;
letter-spacing: -0.2px;
}
.window-controls {
display: flex;
gap: 4px;
-webkit-app-region: no-drag;
}
.ctrl-btn {
width: 46px;
height: 32px;
border: none;
background: transparent;
border-radius: 6px;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
transition: background-color 0.15s;
color: var(--text-secondary);
}
.ctrl-btn:hover { background-color: var(--bg-hover); color: var(--text-primary); }
#close_button:hover { background-color: #ff3b30; color: var(--text-on-accent); }
.theme-svg {
width: 16px;
height: 16px;
}
.main-layout {
display: flex;
height: calc(100% - 44px);
}
.options-window {
width: 64px;
background-color: var(--bg-nav);
display: flex;
flex-direction: column;
align-items: center;
padding: 16px 0;
gap: 12px;
border-right: 1px solid var(--border-color);
transition: background-color 0.3s;
}
.nav-btn {
width: 44px;
height: 44px;
border: none;
background: transparent;
border-radius: 10px;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
color: var(--text-secondary);
transition: all 0.2s;
position: relative;
}
.nav-btn svg { width: 22px; height: 22px; }
.nav-btn:hover { background-color: var(--bg-hover); color: var(--text-primary); }
.nav-btn.active { background-color: var(--accent-alpha); color: var(--accent-color); }
.spacer { flex-grow: 1; }
.content-window {
flex-grow: 1;
position: relative;
overflow: hidden;
}
.page {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 28px 32px;
opacity: 0;
visibility: hidden;
transform: translateY(8px);
transition: opacity 0.25s ease, transform 0.25s ease;
display: flex;
flex-direction: column;
}
.page.active {
opacity: 1;
visibility: visible;
transform: translateY(0);
}
.state-widget {
flex: 1;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 16px;
color: var(--accent-color);
}
.state-title {
font-size: 24px;
font-weight: 600;
color: var(--text-primary);
letter-spacing: -0.5px;
}
.log-widget {
flex-grow: 1;
margin-top: 20px;
}
.license-widget {
flex-grow: 1;
}
.log-text, .license-text {
width: 100%;
height: 100%;
border: 1px solid var(--border-color);
border-radius: 12px;
background-color: var(--bg-panel);
color: var(--text-primary);
resize: none;
padding: 16px;
font-size: 13px;
line-height: 1.6;
white-space: pre;
overflow-x: auto;
}
.progress-widget {
height: 70px;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
gap: 16px;
}
.header-group {
flex: 1;
min-width: 0;
}
.header-group h2 {
font-size: 24px;
font-weight: 600;
letter-spacing: -0.5px;
white-space: nowrap;
}
.header-group p {
font-size: 14px;
color: var(--text-secondary);
margin-top: 4px;
white-space: nowrap;
overflow-x: auto;
padding-bottom: 4px;
}
.modern-action-group {
display: flex;
gap: 12px;
align-items: center;
flex-shrink: 0;
}
.modern-select {
appearance: none;
}
.modern-select:hover, .modern-select:focus {
border-color: var(--accent-color);
box-shadow: 0 0 0 2px rgba(0, 122, 255, 0.2);
}
.modern-btn {
padding: 8px 20px;
border: 1px solid var(--border-color);
border-radius: 10px;
background-color: transparent;
color: var(--text-primary);
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
}
.modern-btn:hover { background-color: var(--bg-hover); }
.primary-btn {
background-color: var(--accent-color);
color: var(--text-on-accent);
border: none;
box-shadow: 0 2px 4px var(--accent-shadow);
}
.primary-btn:hover {
box-shadow: 0 4px 8px var(--accent-hover);
transform: translateY(-1px);
background-color: var(--accent-color);
opacity: 0.95;
}
.primary-btn:active {
transform: translateY(0);
opacity: 0.8;
}
.danger-btn { color: #ff3b30; border-color: #ff3b30; }
.danger-btn:hover { background-color: rgba(255, 59, 48, 0.1); }
.hidden { display: none !important; }
.scan-content {
flex-grow: 1;
min-height: 0;
display: flex;
flex-direction: column;
}
.virus-widget {
width: 100%;
flex-grow: 1;
min-height: 0;
border: 1px solid var(--border-color);
border-radius: 12px;
background-color: var(--bg-panel);
overflow-y: auto;
overflow-x: auto;
}
.virus-list {
list-style: none;
padding: 0;
margin: 0;
min-width: max-content;
}
.list-widget {
display: flex;
flex-direction: column;
height: 100%;
overflow-y: auto;
padding-right: 12px;
gap: 12px;
}
.list-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 18px 24px;
border-radius: 16px;
background-color: var(--bg-panel);
border: 1px solid var(--border-color);
transition: background-color 0.2s;
gap: 16px;
}
.item-icon {
width: 40px;
height: 40px;
flex: 0 0 40px;
stroke-width: 1.5;
color: var(--accent-color);
pointer-events: none;
}
.item-icon-compact {
transform: scale(0.9);
}
.item-icon-repair {
transform: translateX(2px) scale(1.1);
}
.item-icon ~ :is(.toggle-switch, .icon-action-btn) {
flex-shrink: 0;
}
.item-info {
flex: 1;
min-width: 0;
overflow-x: auto;
padding-bottom: 2px;
}
.list-item[data-target]:hover, .list-item[data-action]:hover,
#about_window .list-item:is(:hover, :focus-within) {
background-color: var(--bg-hover);
}
.item-info h2 {
font-size: 16px;
font-weight: 600;
letter-spacing: -0.2px;
white-space: nowrap;
}
.item-info p {
font-size: 13px;
color: var(--text-secondary);
margin-top: 4px;
white-space: nowrap;
}
.toggle-switch {
position: relative;
display: inline-block;
width: 50px;
height: 28px;
}
.toggle-switch input { opacity: 0; width: 0; height: 0; }
.slider {
position: absolute;
cursor: pointer;
top: 0; left: 0; right: 0; bottom: 0;
background-color: var(--border-color);
transition: .3s;
border-radius: 28px;
}
.slider:before {
position: absolute;
content: "";
height: 24px; width: 24px;
left: 2px; bottom: 2px;
background-color: white;
transition: .3s;
border-radius: 50%;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
.toggle-switch input:checked + .slider {
background-color: var(--accent-color);
}
.toggle-switch input:checked + .slider:before {
transform: translateX(22px);
}
.icon-action-btn {
width: 32px; height: 32px;
border-radius: 8px;
border: none;
background-color: transparent;
color: var(--text-secondary);
cursor: pointer;
display: flex; justify-content: center; align-items: center;
transition: background-color 0.2s;
}
.icon-action-btn:hover { background-color: var(--bg-hover); color: var(--text-primary); }
.icon-action-btn svg { width: 20px; height: 20px; }
.sub-header-toolbar {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 16px;
width: 100%;
}
.sub-header-toolbar h2 {
font-size: 24px;
font-weight: 600;
letter-spacing: -0.5px;
white-space: nowrap;
}
.icon-btn {
background: transparent;
border: none;
color: var(--text-secondary);
cursor: pointer;
padding: 6px;
border-radius: 8px;
display: flex; align-items: center; justify-content: center;
transition: background-color 0.2s;
}
.icon-btn:hover { background-color: var(--bg-hover); color: var(--text-primary); }
.icon-btn svg { width: 24px; height: 24px; }
.search-box {
display: flex;
align-items: center;
background-color: var(--bg-panel);
border: 1px solid var(--border-color);
border-radius: 10px;
padding: 0 14px;
width: 200px;
transition: border-color 0.2s, box-shadow 0.2s;
}
.search-box:focus-within {
border-color: var(--accent-color);
box-shadow: 0 0 0 2px var(--accent-shadow);
}
.search-box svg {
width: 18px; height: 18px;
color: var(--text-secondary);
}
.search-box input {
border: none;
background: transparent;
color: var(--text-primary);
padding: 10px;
outline: none;
width: 100%;
font-size: 14px;
}
.flex-grow {
flex-grow: 1;
min-height: 0;
}
.manage-widget {
border: 1px solid var(--border-color);
border-radius: 12px;
background-color: var(--bg-panel);
overflow-y: auto;
overflow-x: auto;
}
.manage-list {
list-style: none;
padding: 0;
margin: 0;
min-width: max-content;
}
.manage-list-item {
display: flex;
align-items: center;
gap: 12px;
padding: 12px 16px;
border-bottom: 1px solid var(--border-color);
transition: background-color 0.2s;
}
.manage-list-item:last-child {
border-bottom: none;
}
.manage-list-item:hover {
background-color: var(--bg-hover);
}
.manage-list-item input[type="checkbox"] {
width: 16px;
height: 16px;
accent-color: var(--accent-color);
cursor: pointer;
flex-shrink: 0;
}
.manage-list-item-content {
flex-grow: 1;
min-width: 0;
font-size: 14px;
color: var(--text-primary);
white-space: nowrap;
}
.custom-select-wrapper {
position: relative;
min-width: 100px;
display: inline-grid;
vertical-align: middle;
user-select: none;
}
select.hidden + .custom-select-wrapper {
display: none !important;
}
.custom-select-trigger {
grid-area: 1 / 1;
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 16px;
border-radius: 10px;
border: 1px solid var(--border-color);
background-color: var(--bg-panel);
color: var(--text-primary);
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: border-color 0.2s, box-shadow 0.2s;
gap: 12px;
box-sizing: border-box;
}
.custom-select-phantom {
grid-area: 1 / 1;
visibility: hidden;
pointer-events: none;
display: grid;
padding: 8px 16px;
font-size: 14px;
font-weight: 500;
box-sizing: border-box;
}
.custom-select-phantom span {
grid-area: 1 / 1;
white-space: nowrap;
padding-right: 28px;
}
.custom-select-wrapper.open .custom-select-trigger,
.custom-select-trigger:hover {
border-color: var(--accent-color);
box-shadow: 0 0 0 2px var(--accent-shadow);
}
.custom-select-icon {
display: flex;
align-items: center;
color: var(--text-secondary);
transition: transform 0.3s ease;
}
.custom-select-wrapper.open .custom-select-icon {
transform: rotate(180deg);
}
.custom-select-icon svg { width: 16px; height: 16px; }
.custom-select-options {
position: fixed;
display: none;
width: max-content;
background-color: var(--bg-panel);
border: 1px solid var(--border-color);
border-radius: 10px;
box-shadow: var(--shadow-sm);
z-index: 1000;
list-style: none;
margin: 0;
padding: 6px;
overflow-y: auto;
overflow-x: hidden;
overscroll-behavior: contain;
overflow-wrap: anywhere;
}
.custom-select-options.open {
display: block;
}
@media (prefers-reduced-motion: no-preference) {
.custom-select-options.open {
animation: select-options-enter 160ms ease-out;
}
@keyframes select-options-enter {
from { opacity: 0; transform: translateY(var(--select-enter-offset)); }
to { opacity: 1; transform: translateY(0); }
}
}
.custom-select-option {
padding: 8px 12px;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
color: var(--text-primary);
transition: background-color 0.2s, color 0.2s;
text-align: center;
}
.custom-select-option:hover {
background-color: var(--bg-hover);
}
.custom-select-option.selected {
background-color: var(--accent-alpha);
color: var(--accent-color);
font-weight: 600;
}
.home-top-widget {
display: flex;
align-items: center;
height: 200px;
gap: 24px;
width: 100%;
}
.quick-actions {
flex: 0 0 calc(50% + 40px);
min-width: 0;
display: flex;
flex-direction: column;
gap: 12px;
height: 100%;
justify-content: center;
}
.quick-actions .list-item {
gap: 12px;
}
#loading_overlay {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: #e0e0e0;
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
transition: opacity 0.4s ease, visibility 0.4s ease;
}
#loading_overlay.fade-out {
opacity: 0;
visibility: hidden;
}
#loading_overlay.startup-error {
padding: 28px;
background-color: #f5f5f7;
color: #1d1d1f;
}
.startup-error-box {
max-width: 520px;
padding: 24px;
border: 1px solid rgba(0, 0, 0, 0.12);
border-radius: 8px;
background: #ffffff;
box-shadow: 0 16px 40px rgba(0, 0, 0, 0.12);
}
.startup-error-box h1 {
margin: 0 0 10px;
font-size: 18px;
font-weight: 700;
}
.startup-error-box p {
margin: 0;
font-size: 13px;
line-height: 1.6;
color: #515154;
word-break: break-word;
}
.spinner {
animation: rotate 2s linear infinite;
width: 50px;
height: 50px;
}
.spinner .path {
stroke: #86868b;
stroke-linecap: round;
animation: dash 1.5s ease-in-out infinite;
}
@keyframes rotate {
100% { transform: rotate(360deg); }
}
@keyframes dash {
0% { stroke-dasharray: 1, 150; stroke-dashoffset: 0; }
50% { stroke-dasharray: 90, 150; stroke-dashoffset: -35; }
100% { stroke-dasharray: 90, 150; stroke-dashoffset: -124; }
}
.app-container.fade-in {
opacity: 1 !important;
}
.manage-list-header {
display: flex;
align-items: center;
gap: 12px;
padding: 12px 16px;
border-bottom: 1px solid var(--border-color);
background-color: var(--bg-panel);
font-weight: 600;
font-size: 13px;
color: var(--text-secondary);
position: sticky;
top: 0;
z-index: 10;
}
.manage-list-header input[type="checkbox"] {
width: 16px;
height: 16px;
accent-color: var(--accent-color);
cursor: pointer;
flex-shrink: 0;
}
.header-cols-container, .manage-list-item-content {
display: flex;
flex-grow: 1;
min-width: 0;
gap: 16px;
align-items: center;
}
.col-header {
position: relative;
cursor: pointer;
display: flex;
align-items: center;
padding: 0 8px;
border-right: 1px solid var(--border-color);
background-color: var(--bg-panel);
user-select: none;
-webkit-user-select: none;
}
.col-header:last-child {
border-right: none;
}
.header-text {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex-grow: 1;
}
.manage-list-header, .col-header, .col-resizer {
user-select: none;
-webkit-user-select: none;
}
.col-resizer {
position: absolute;
right: -5px;
top: 0;
bottom: 0;
width: 10px;
cursor: col-resize;
z-index: 10;
background-color: transparent !important;
}
.col-resizer::after {
content: "";
position: absolute;
left: 50%;
top: 0;
bottom: 0;
width: 1px;
background-color: transparent;
transition: background-color 0.2s;
}
.col-resizer:hover::after,
.col-resizer.resizing::after {
background-color: var(--text-secondary) !important;
opacity: 0.6;
}
body.resizing-active,
body.resizing-active * {
user-select: none !important;
-webkit-user-select: none !important;
cursor: col-resize !important;
}
.col-resizer:hover {
background-color: var(--accent-color);
opacity: 0.5;
}
.col-header:hover {
color: var(--text-primary);
}
.sort-icon {
font-size: 10px;
margin-left: 4px;
color: var(--accent-color);
width: 12px;
}
.row-col {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 14px;
color: var(--text-primary);
}
.custom-context-menu {
position: absolute;
z-index: 10000;
background-color: var(--bg-panel);
border: 1px solid var(--border-color);
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
padding: 4px;
display: none;
min-width: 160px;
}
.custom-context-menu.show {
display: block;
}
.custom-context-menu-item {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 12px;
border-radius: 6px;
cursor: pointer;
font-size: 13px;
color: var(--text-primary);
transition: background-color 0.2s;
}
.custom-context-menu-item:hover {
background-color: var(--bg-hover);
}
.custom-context-menu-item svg {
width: 16px;
height: 16px;
color: var(--text-secondary);
}
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border-color); border-radius: 10px; }
::-webkit-scrollbar-thumb:hover { background: var(--text-secondary); }
@media (prefers-reduced-motion: no-preference) {
:is(.nav-btn, .icon-action-btn, .icon-btn, .ctrl-btn, .search-box) > svg {
transform-origin: center;
transition: transform 220ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
:is(.nav-btn, .icon-action-btn):not(:disabled):is(:hover, :focus-visible) > svg {
transform: scale(1.08);
}
.list-item:is(:hover, :focus-within)
> .icon-action-btn:not(:disabled) > svg {
transform: translateX(3px);
}
.icon-btn[data-target]:not(:disabled):is(:hover, :focus-visible) > svg {
transform: translateX(-3px);
}
.ctrl-btn:not(:disabled):is(:hover, :focus-visible) > svg {
transform: scale(1.1);
}
.search-box:focus-within > svg {
transform: rotate(-8deg) scale(1.08);
}
:is(.nav-btn, .ctrl-btn, .icon-action-btn):not(:disabled):active > svg,
.icon-btn[data-target]:not(:disabled):active > svg,
.list-item:active
> .icon-action-btn:not(:disabled) > svg {
transform: scale(0.92);
transition-duration: 100ms;
}
.app-container.fade-in #home_window.active .state-icon > polyline {
animation: pyas-check-draw 300ms ease-in backwards;
}
@keyframes pyas-check-draw {
from {
stroke-dasharray: 12 12;
stroke-dashoffset: 12;
}
to {
stroke-dasharray: 12 12;
stroke-dashoffset: 0;
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+624
View File
@@ -0,0 +1,624 @@
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PYAS Security</title>
<link rel="stylesheet" href="/static/css/style.css">
<script defer src="/static/js/i18n.js"></script>
<script defer src="/static/js/main.js"></script>
<script>
window.addEventListener('DOMContentLoaded', function () {
window.setTimeout(function () {
var overlay = document.getElementById('loading_overlay');
if (overlay && !overlay.classList.contains('fade-out') && !overlay.classList.contains('startup-error')) {
overlay.classList.add('startup-error');
overlay.innerHTML = '<div class="startup-error-box"><h1>PYAS failed to open</h1><p>WebView2 initialization timed out. PYAS will retry automatically.</p></div>';
}
}, 20000);
});
</script>
</head>
<body>
<div id="loading_overlay">
<svg class="spinner" viewBox="0 0 50 50">
<circle class="path" cx="25" cy="25" r="20" fill="none" stroke-width="5"></circle>
</svg>
</div>
<div class="app-container" style="opacity: 0; transition: opacity 0.5s ease;">
<header class="navigate-window pywebview-drag-region">
<div class="navigate-title" data-i18n>PYAS Security</div>
<div class="window-controls">
<button class="ctrl-btn" id="about_button" data-target="about_window">
<svg viewBox="0 0 24 24" class="theme-svg" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg>
</button>
<button class="ctrl-btn" id="minimize_button">
<svg viewBox="0 0 24 24" class="theme-svg" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="12" x2="19" y2="12"></line></svg>
</button>
<button class="ctrl-btn" id="close_button">
<svg viewBox="0 0 24 24" class="theme-svg" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
</button>
</div>
</header>
<div class="main-layout">
<aside class="options-window pywebview-drag-region">
<button class="nav-btn active" data-target="home_window">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg>
</button>
<button class="nav-btn" data-target="scan_window">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
</button>
<button class="nav-btn" data-target="tool_window">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7"></rect><rect x="14" y="3" width="7" height="7"></rect><rect x="14" y="14" width="7" height="7"></rect><rect x="3" y="14" width="7" height="7"></rect></svg>
</button>
<button class="nav-btn" data-target="protect_window">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path></svg>
</button>
<div class="spacer"></div>
<button class="nav-btn" data-target="setting_window">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
</button>
</aside>
<main class="content-window">
<section id="home_window" class="page active">
<div class="home-top-widget">
<div class="state-widget">
<svg viewBox="0 0 24 24" class="state-icon theme-svg" style="width: 120px; height: 120px;" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path><polyline points="9 12 11 14 15 10"></polyline></svg>
<h2 class="state-title" data-i18n>此裝置已受到防護</h2>
</div>
<div class="quick-actions">
<div class="list-item" style="cursor: pointer;" id="quick_scan_btn" data-action="scan">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="10" cy="10" r="6"/><path d="m14.5 14.5 5 5M8 10l1.5 1.5L12 8.5"/></svg>
<div class="item-info">
<h2 data-i18n>智能掃描</h2><p data-i18n>此選項可以快速掃描裝置安全性</p>
</div>
<button class="icon-action-btn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg></button>
</div>
<div class="list-item" style="cursor: pointer;" data-target="log_export_window">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9zM14 3v6h6"/><path d="M8 13h4m-4 4h3m5-5v6m-3-3 3 3 3-3"/></svg>
<div class="item-info">
<h2 data-i18n>日誌導出</h2><p data-i18n>此選項可以篩選日誌並匯出存檔</p>
</div>
<button class="icon-action-btn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg></button>
</div>
</div>
</div>
<div class="log-widget">
<textarea class="log-text" readonly></textarea>
</div>
</section>
<section id="scan_window" class="page">
<div class="progress-widget">
<div class="header-group">
<h2 class="section-title" data-i18n>病毒掃描</h2>
<p class="section-desc" id="progress_text" data-i18n>此選項可以選擇進階掃描方式</p>
</div>
<div class="action-group modern-action-group">
<select id="scan_method_select" class="modern-select">
<option value="none" selected disabled data-i18n>選擇</option>
<option value="smart" data-i18n>智能掃描</option>
<option value="file" data-i18n>檔案掃描</option>
<option value="path" data-i18n>路徑掃描</option>
<option value="full" data-i18n>全盤掃描</option>
</select>
<button class="action-btn modern-btn hidden" id="stop_btn" data-i18n>停止</button>
</div>
</div>
<div class="scan-content">
<div class="virus-widget">
<ul class="virus-list" id="virus_list"></ul>
</div>
</div>
</section>
<section id="protect_window" class="page">
<div class="list-widget">
<div class="list-item">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><path d="M8 12h2l1-3 2 6 1-3h2"/></svg>
<div class="item-info">
<h2 data-i18n>進程防護</h2><p data-i18n>此選項可以終止惡意進程運行</p>
</div>
<label class="toggle-switch"><input type="checkbox" checked><span class="slider"></span></label>
</div>
<div class="list-item">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="9"/><path d="M9 8v8m6-8v8"/></svg>
<div class="item-info">
<h2 data-i18n>進程暫停</h2><p data-i18n>此選項可以暫停進程等待掃描</p>
</div>
<label class="toggle-switch"><input type="checkbox" checked><span class="slider"></span></label>
</div>
<div class="list-item">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="m12 3 9 5-9 5-9-5 9-5zM3 12l9 5 9-5M3 16l9 5 9-5"/></svg>
<div class="item-info">
<h2 data-i18n>加載防護</h2><p data-i18n>此選項可以攔截惡意進程加載</p>
</div>
<label class="toggle-switch"><input type="checkbox" checked><span class="slider"></span></label>
</div>
<div class="list-item">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8zM14 2v6h6m-12 7 3 3 5-5"/></svg>
<div class="item-info">
<h2 data-i18n>檔案防護</h2><p data-i18n>此選項可以隔離惡意檔案建立</p>
</div>
<label class="toggle-switch"><input type="checkbox" checked><span class="slider"></span></label>
</div>
<div class="list-item">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><rect x="3" y="3" width="18" height="13" rx="2"/><path d="M8 21h8m-4-5v5M8 10l3 3 5-6"/></svg>
<div class="item-info">
<h2 data-i18n>系統防護</h2><p data-i18n>此選項可以實時修復系統異常</p>
</div>
<label class="toggle-switch"><input type="checkbox" checked><span class="slider"></span></label>
</div>
<div class="list-item">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10zM8 10a6 6 0 0 1 8 0m-6 3a3 3 0 0 1 4 0"/><circle cx="12" cy="16" r=".5"/></svg>
<div class="item-info">
<h2 data-i18n>網路防護</h2><p data-i18n>此選項可以攔截惡意網路連接</p>
</div>
<label class="toggle-switch"><input type="checkbox" checked><span class="slider"></span></label>
</div>
<div class="list-item">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><rect x="6" y="6" width="12" height="12" rx="2"/><path d="M9 2v4m6-4v4M9 18v4m6-4v4M2 9h4m-4 6h4m12-6h4m-4 6h4"/><polyline points="9 12 11 14 15 10"/></svg>
<div class="item-info">
<h2 data-i18n>驅動防護</h2><p data-i18n>此選項可以實時攔截惡意行為</p>
</div>
<label class="toggle-switch"><input type="checkbox" checked><span class="slider"></span></label>
</div>
<div class="list-item" style="cursor: pointer;" data-target="custom_protect_window">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M4 6h3m4 0h9M4 12h9m4 0h3M4 18h3m4 0h9"/><circle cx="9" cy="6" r="2"/><circle cx="15" cy="12" r="2"/><circle cx="9" cy="18" r="2"/></svg>
<div class="item-info">
<h2 data-i18n>自訂防護</h2><p data-i18n>此選項可以導入自訂防護規則</p>
</div>
<button class="icon-action-btn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg></button>
</div>
</div>
</section>
<section id="tool_window" class="page">
<div class="list-widget">
<div class="list-item" style="cursor: pointer;" data-target="taskmgr_window">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><rect x="3" y="3" width="18" height="14" rx="2"/><path d="M8 21h8m-4-4v4M6 11h3l2-4 3 7 2-3h2"/></svg>
<div class="item-info">
<h2 data-i18n>進程管理</h2><p data-i18n>此選項可以實時查看系統進程</p>
</div>
<button class="icon-action-btn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg></button>
</div>
<div class="list-item" style="cursor: pointer;" data-target="startup_window">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M12 3v9m-6.4-6.4a9 9 0 1 0 12.8 0"/></svg>
<div class="item-info">
<h2 data-i18n>啟動項管理</h2><p data-i18n>此選項可以管理各應用啟動項</p>
</div>
<button class="icon-action-btn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg></button>
</div>
<div class="list-item" style="cursor: pointer;" data-target="junk_window">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M3 6h18M9 6V3h6v3M5 6l1 15h12l1-15M10 10v7m4-7v7"/></svg>
<div class="item-info">
<h2 data-i18n>垃圾清理</h2><p data-i18n>此選項可以清理暫存垃圾檔案</p>
</div>
<button class="icon-action-btn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg></button>
</div>
<div class="list-item" style="cursor: pointer;" data-target="repair_window">
<svg class="item-icon item-icon-repair" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M14 6a5 5 0 0 0-6 6l-5 5a2.1 2.1 0 0 0 3 3l5-5a5 5 0 0 0 6-6l-3 3-3-3 3-3z"/></svg>
<div class="item-info">
<h2 data-i18n>系統修復</h2><p data-i18n>此選項可以修復系統登錄檔項目</p>
</div>
<button class="icon-action-btn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg></button>
</div>
<div class="list-item" style="cursor: pointer;" data-target="popup_window">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><rect x="3" y="4" width="18" height="16" rx="2"/><path d="M3 8h18m-12 3 6 6m0-6-6 6"/></svg>
<div class="item-info">
<h2 data-i18n>彈窗攔截</h2><p data-i18n>此選項可以選擇指定窗口攔截</p>
</div>
<button class="icon-action-btn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg></button>
</div>
<div class="list-item" style="cursor: pointer;" data-target="netmon_window">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M5 3v18h16M8 15l4-5 4 3 5-7"/></svg>
<div class="item-info">
<h2 data-i18n>流量監控</h2><p data-i18n>此選項可以實時監控網路流量</p>
</div>
<button class="icon-action-btn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg></button>
</div>
<div class="list-item" style="cursor: pointer;" data-target="whitelist_window">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><rect x="4" y="3" width="16" height="18" rx="2"/><path d="m7 8 1 1 2-2m3 1h4m-10 7 2 2 3-4m2 2h3"/></svg>
<div class="item-info">
<h2 data-i18n>白名單</h2><p data-i18n>此選項可以查看並管理白名單</p>
</div>
<button class="icon-action-btn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg></button>
</div>
<div class="list-item" style="cursor: pointer;" data-target="quarantine_window">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M3 9h18m-13 5h8m-4-4v8M8 5V3h8v2"/></svg>
<div class="item-info">
<h2 data-i18n>隔離區</h2><p data-i18n>此選項可以查看並管理隔離區</p>
</div>
<button class="icon-action-btn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg></button>
</div>
</div>
</section>
<section id="setting_window" class="page">
<div class="list-widget">
<div class="list-item">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="m13 2-9 12h7l-1 8 10-12h-7l1-8z"/></svg>
<div class="item-info">
<h2 data-i18n>增強模式</h2><p data-i18n>此選項可以增強靜態掃描引擎</p>
</div>
<label class="toggle-switch"><input type="checkbox"><span class="slider"></span></label>
</div>
<div class="list-item">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><rect x="4" y="4" width="16" height="16" rx="3"/><path d="M8 12h8m-4-4v8"/></svg>
<div class="item-info">
<h2 data-i18n>擴展引擎</h2><p data-i18n>此選項可以使用擴展規則引擎</p>
</div>
<label class="toggle-switch"><input type="checkbox"><span class="slider"></span></label>
</div>
<div class="list-item">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M7 18H6a4 4 0 0 1-.8-7.9A7 7 0 0 1 18.7 8a5 5 0 0 1-.7 10h-1m-5 3V11m-4 4 4-4 4 4"/></svg>
<div class="item-info">
<h2 data-i18n>雲端服務</h2><p data-i18n>此選項可以自動上報可疑檔案</p>
</div>
<label class="toggle-switch"><input type="checkbox" checked><span class="slider"></span></label>
</div>
<div class="list-item">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M3 4h18l-7 8v7l-4 2v-9L3 4z"/></svg>
<div class="item-info">
<h2 data-i18n>副檔名過濾</h2><p data-i18n>此選項僅掃描指定檔案副檔名</p>
</div>
<label class="toggle-switch"><input type="checkbox" checked><span class="slider"></span></label>
</div>
<div class="list-item">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><rect x="3" y="3" width="18" height="14" rx="2"/><path d="M8 21h8m-4-4v4M12 6v4m-2.5-2.5a3.5 3.5 0 1 0 5 0"/></svg>
<div class="item-info">
<h2 data-i18n>開機啟動</h2><p data-i18n>此選項可以設定開機自動執行</p>
</div>
<label class="toggle-switch"><input type="checkbox" checked><span class="slider"></span></label>
</div>
<div class="list-item">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M7 7h10M7 11h3"/><circle cx="13" cy="14" r="3"/><path d="m15.2 16.2 2.8 2.8"/></svg>
<div class="item-info">
<h2 data-i18n>選單掃描</h2><p data-i18n>此選項可以啟用右鍵掃描功能</p>
</div>
<label class="toggle-switch"><input type="checkbox"><span class="slider"></span></label>
</div>
<div class="list-item">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M12 3a9 9 0 1 0 0 18h1a2 2 0 0 0 1.4-3.4 1.5 1.5 0 0 1 1.1-2.6H18a3 3 0 0 0 3-3 9 9 0 0 0-9-9z"/><circle cx="7.5" cy="10" r=".7"/><circle cx="11" cy="7" r=".7"/><circle cx="15.5" cy="8" r=".7"/></svg>
<div class="item-info">
<h2 data-i18n>顯色主題</h2><p data-i18n>此選項可以選擇主題顏色</p>
</div>
<select id="theme_select" class="modern-select">
<option value="system_switch" selected data-i18n>跟隨系統</option>
<option value="white_switch" data-i18n>白色主題</option>
<option value="red_switch" data-i18n>紅色主題</option>
<option value="yellow_switch" data-i18n>黃色主題</option>
<option value="green_switch" data-i18n>綠色主題</option>
<option value="blue_switch" data-i18n>藍色主題</option>
<option value="black_switch" data-i18n>黑色主題</option>
</select>
</div>
<div class="list-item">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M3 5h12M9 2v3m3 0c-1 6-4 9-9 12M5 8c1.5 4 4 6 8 8m0 5 4-10 4 10m-6.5-4h5"/></svg>
<div class="item-info">
<h2 data-i18n>顯示語言</h2><p data-i18n>此選項可以選擇顯示語言</p>
</div>
<select id="lang_select" class="modern-select">
<option value="english_switch">English</option>
<option value="traditional_switch">繁體中文</option>
<option value="simplified_switch">简体中文</option>
<option value="japanese_switch">日本語</option>
<option value="korean_switch">한국어</option>
<option value="french_switch">Français</option>
<option value="spanish_switch">Español</option>
<option value="hindi_switch">हिन्दी</option>
<option value="arabic_switch">العربية</option>
<option value="russian_switch">Русский</option>
<option value="slovenian_switch">Slovenščina</option>
</select>
</div>
<div class="list-item">
<svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M3 10a9 9 0 1 1 2 8M3 4v6h6m3-3v5l3 2"/></svg>
<div class="item-info">
<h2 data-i18n>重置選項</h2><p data-i18n>此選項可以重置所有設定</p>
</div>
<button class="action-btn modern-btn danger-btn" data-i18n>執行</button>
</div>
</div>
</section>
<section id="about_window" class="page">
<div class="list-widget">
<div class="list-item">
<svg class="item-icon item-icon-compact" aria-hidden="true" focusable="false" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"></path></svg>
<div class="item-info">
<h2 data-i18n>產品金鑰</h2><p data-i18n>此選項可以啟用產品金鑰</p>
</div>
<button class="icon-action-btn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg></button>
</div>
<div class="list-item">
<svg class="item-icon item-icon-compact" aria-hidden="true" focusable="false" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="2" y1="12" x2="22" y2="12"></line><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path></svg>
<div class="item-info">
<h2 data-i18n>官方網站</h2><p data-i18n>此選項可以前往官方網站</p>
</div>
<button class="icon-action-btn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg></button>
</div>
<div class="list-item">
<svg class="item-icon" aria-hidden="true" focusable="false" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 10a9 9 0 1 0-2 8M21 4v6h-6"/></svg>
<div class="item-info">
<h2 data-i18n>檢查更新</h2><p data-i18n>此選項可以檢查可用更新</p>
</div>
<button class="icon-action-btn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg></button>
</div>
<div class="license-widget">
<textarea class="license-text" readonly>87owo Publicly Available Source Code License Agreement
Last Updated: 2026-07-18
IMPORTANT NOTICE: THIS LICENSE IS "SOURCE AVAILABLE" AND IS NOT AN OPEN SOURCE LICENSE APPROVED BY THE OPEN SOURCE INITIATIVE (OSI). BY DOWNLOADING, ACCESSING, OR USING THE SOFTWARE, YOU AGREE TO BE BOUND BY THESE TERMS.
1. Definitions and Interpretation
- 1.1. Author: Refers to 87owo (PYAS Security).
- 1.2. Software: Refers to the source code, binaries, project archives, assets, and documentation associated with this repository or distribution.
- 1.3. Personal Local Use: Means viewing, downloading, executing, and modifying the Software strictly on local hardware owned or directly controlled by an individual for private, non-commercial, non-production, and non-distribution purposes.
- 1.4. Enterprise Use: Includes enterprise internal deployment, multi-user institutional use, or utilization within any corporate environment, which is strictly excluded from Personal Local Use.
2. Intellectual Property and Ownership
- 2.1. Retention of Rights: The Author reserves all legal rights, titles, and interests in and to the Software, including but not limited to all copyrights, trademarks, patents, and trade secrets.
- 2.2. No Transfer: No intellectual property rights or ownership stakes are transferred under this Agreement. All project components remain fully proprietary.
- 2.3. Activation Keys: Access to or execution of certain premium features, modules, or binary distributions within the Software may require a valid, authorized activation key issued solely by the Author.
3. Grant of License and Permitted Use
Subject to your strict compliance with all terms of this Agreement, the Author hereby grants you a limited, non-exclusive, world-wide, royalty-free, revocable, and non-transferable license to:
- 3.1. Code Inspection: View and download the source code from official authorized repositories.
- 3.2. Local Modification: Modify the source code strictly for the purposes of Personal Local Use.
- 3.3. Local Execution: Execute the Software locally for personal evaluation and private deployment.
4. Prohibitions and Restrictions
Except as explicitly granted in Section 3, you shall not, and shall not permit any third party to:
- 4.1. Unauthorized Redistribution: Copy, redistribute, sublicense, republish, mirror, or publicly disclose any original or modified versions of the source code, binaries, or assets.
- 4.2. Commercial and SaaS Deployment: Host, deploy, embed, or utilize the Software for commercial purposes, including but not limited to Software-as-a-Service (SaaS), commercial web hosting, paid remote execution, cloud infrastructure integration, or enterprise internal utility.
- 4.3. Reverse Engineering: Reverse engineer, decompile, decrypt, or disassemble any binary components of the Software, except and only to the extent that such restriction is explicitly prohibited by applicable mandatory laws.
- 4.4. Notice Preservation: Remove, obscure, deface, or alter any copyright notices, trademarks, hyperlinked terms, or license files included within the Software distribution.
5. Prior Authorization and Application Channels
- 5.1. Authorization Requirement: Any activity exceeding the scope of Personal Local Use (including but not limited to public redistribution, independent forks not targeting upstream contributions, commercial deployment, or enterprise use) requires prior explicit written consent from the Author.
- 5.2. Official Application Channels: Users seeking such authorization must submit a formal request through one of the following official channels:
- Channel A (GitHub Fork): Initiating a standard Fork on the official GitHub repository for collaborative and upstream contributions.
- Channel B (GitHub Issues): Submitting a public issue utilizing the designated authorization request template.
- Channel C (Official Email): Sending a detailed inquiry to the official organizational email address associated with the PYAS Security project.
- 5.3. Request Content: Any application must explicitly state the specific use case, intended target audience, scope of deployment, and whether any commercial monetization is involved.
6. Updates, Amendments, and Scope of Terms
- 6.1. New Releases: The Author may deliver updates, critical security patches, feature enhancements, or user interface modifications. Continued use of the Software constitutes acceptance of the latest distributed version.
- 6.2. Non-Retroactivity: The Author reserves the right to amend this License Agreement at any time. Amendments apply strictly to subsequent versions or new downloads. Copies lawfully acquired prior to such modification remain governed by the exact version of the License under which they were originally obtained.
7. Telemetry, Data, and Privacy
- 7.1. Operational Data Collection: The Software may collect anonymized technical, operational, and usage data strictly for security analysis, performance optimization, and bug reporting.
- 7.2. Cloud Sample Submission: To enhance threat detection and malware analysis, the Software may automatically or manually transmit suspicious executable files and software samples to the Author's cloud infrastructure for deep analysis.
- 7.3. Scope of Collected Extensions: Sample collection targets potential executable and system binary formats, which explicitly include, but are not limited to, files with the following extensions: `.exe`, `.dll`, `.sys`, `.ocx`, `.scr`, `.efi`, `.acm`, `.ax`, `.cpl`, `.drv`, `.com`, `.mui`, `.pyd`, `.wfx`, `.api`, `.awx`, `.rll`, and `.winmd`.
- 7.4. Public Disclosure of Threat Intelligence: You explicitly acknowledge and agree that the metadata, behavioral reports, and threat intelligence data generated from the cloud analysis of submitted samples may be publicly disclosed, published, or shared with the cybersecurity community for collaborative defense purposes.
- 7.5. Opt-Out Mechanism: Cloud-based telemetry and sample submission are fully optional. Users who do not wish to participate in sample collection or cloud-assisted analysis may disable the corresponding cloud services at any time via the toggle switches provided within the Software’s settings interface.
- 7.6. Driver Signature: Certain kernel-mode drivers distributed with this software may be digitally signed using code signing methods that are not certified by Microsoft Windows Hardware Quality Labs (WHQL). By installing or using this software, you acknowledge this and decide for yourself whether to install and trust such drivers on your system.
8. Warranty Disclaimer and Limitation of Liability
- 8.1. Disclaimer of Warranty: TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE SOFTWARE AND ALL RELATED ASSETS ARE PROVIDED ON AN "AS IS" AND "AS AVAILABLE" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED.
- 8.2. Limitation of Liability: TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL THE AUTHOR, COPYRIGHT HOLDERS, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE. USERS ASSUME ALL RISKS REGARDING PERFORMANCE, DATA INTEGRITY, AND SYSTEM STABILITY.
© 2020-2026 87owo (PYAS Security). All rights reserved.</textarea>
</div>
</div>
</section>
<section id="taskmgr_window" class="page sub-page">
<div class="sub-header-toolbar">
<button class="icon-btn" data-target="tool_window"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"></polyline></svg></button>
<h2 data-i18n>進程管理</h2>
<div class="spacer"></div>
<div class="search-box">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
<input type="text" data-i18n-placeholder="搜尋進程..." placeholder="搜尋進程...">
</div>
<div class="action-group modern-action-group">
<select id="taskmgr_select" class="modern-select">
<option value="none" selected disabled data-i18n="btn_select">選擇</option>
<option value="view" data-i18n="btn_view_item">查看項目</option>
<option value="end" data-i18n="btn_end">結束進程</option>
<option value="quarantine" data-i18n="act_quarantine">加入隔離區</option>
<option value="whitelist" data-i18n="act_white">加入白名單</option>
</select>
</div>
</div>
<div class="manage-widget flex-grow"><ul class="manage-list"></ul></div>
</section>
<section id="startup_window" class="page sub-page">
<div class="sub-header-toolbar">
<button class="icon-btn" data-target="tool_window"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"></polyline></svg></button>
<h2 data-i18n>啟動項管理</h2>
<div class="spacer"></div>
<div class="search-box">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
<input type="text" data-i18n-placeholder="搜尋項目..." placeholder="搜尋項目...">
</div>
<div class="action-group modern-action-group">
<select id="startup_select" class="modern-select">
<option value="none" selected disabled data-i18n="btn_select">選擇</option>
<option value="enable" data-i18n="btn_enable_item">啟用項目</option>
<option value="disable" data-i18n="btn_disable_item">禁用項目</option>
<option value="delete" data-i18n="btn_delete_item">刪除項目</option>
</select>
</div>
</div>
<div class="manage-widget flex-grow"><ul class="manage-list"></ul></div>
</section>
<section id="whitelist_window" class="page sub-page">
<div class="sub-header-toolbar">
<button class="icon-btn" data-target="tool_window"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"></polyline></svg></button>
<h2 data-i18n>白名單管理</h2>
<div class="spacer"></div>
<div class="search-box">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
<input type="text" data-i18n-placeholder="搜尋檔案..." placeholder="搜尋檔案...">
</div>
<div class="action-group modern-action-group">
<select id="whitelist_select" class="modern-select">
<option value="none" selected disabled data-i18n="btn_select">選擇</option>
<option value="add_file" data-i18n="btn_add_file">新增檔案</option>
<option value="add_path" data-i18n="btn_add_path">新增路徑</option>
<option value="extract" data-i18n="btn_extract_item">提取項目</option>
<option value="remove" data-i18n="btn_remove_item">移除項目</option>
<option value="quarantine" data-i18n="act_quarantine">加入隔離區</option>
</select>
</div>
</div>
<div class="manage-widget flex-grow"><ul class="manage-list"></ul></div>
</section>
<section id="quarantine_window" class="page sub-page">
<div class="sub-header-toolbar">
<button class="icon-btn" data-target="tool_window"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"></polyline></svg></button>
<h2 data-i18n>隔離區管理</h2>
<div class="spacer"></div>
<div class="search-box">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
<input type="text" data-i18n-placeholder="搜尋檔案..." placeholder="搜尋檔案...">
</div>
<div class="action-group modern-action-group">
<select id="quarantine_select" class="modern-select">
<option value="none" selected disabled data-i18n="btn_select">選擇</option>
<option value="add_file" data-i18n="btn_add_file">新增檔案</option>
<option value="add_path" data-i18n="btn_add_path">新增路徑</option>
<option value="extract" data-i18n="btn_extract_item">提取項目</option>
<option value="remove" data-i18n="btn_remove_item">移除項目</option>
<option value="whitelist" data-i18n="act_white">加入白名單</option>
</select>
</div>
</div>
<div class="manage-widget flex-grow"><ul class="manage-list"></ul></div>
</section>
<section id="junk_window" class="page sub-page">
<div class="sub-header-toolbar">
<button class="icon-btn" data-target="tool_window"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"></polyline></svg></button>
<h2 data-i18n>垃圾清理</h2>
<div class="spacer"></div>
<div class="search-box">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
<input type="text" data-i18n-placeholder="搜尋檔案..." placeholder="搜尋檔案...">
</div>
<div class="action-group modern-action-group">
<select id="junk_select" class="modern-select">
<option value="none" selected disabled data-i18n="btn_select">選擇</option>
<option value="view" data-i18n="btn_view_item">查看項目</option>
<option value="delete" data-i18n="btn_delete_item">刪除項目</option>
</select>
</div>
</div>
<div class="manage-widget flex-grow"><ul class="manage-list"></ul></div>
</section>
<section id="repair_window" class="page sub-page">
<div class="sub-header-toolbar">
<button class="icon-btn" data-target="tool_window"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"></polyline></svg></button>
<h2 data-i18n>系統修復</h2>
<div class="spacer"></div>
<div class="action-group modern-action-group">
<select id="repair_select" class="modern-select">
<option value="none" selected disabled data-i18n="btn_select">選擇</option>
<option value="repair" data-i18n="btn_repair_item">修復項目</option>
</select>
</div>
</div>
<div class="manage-widget flex-grow"><ul class="manage-list"></ul></div>
</section>
<section id="popup_window" class="page sub-page">
<div class="sub-header-toolbar">
<button class="icon-btn" data-target="tool_window"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"></polyline></svg></button>
<h2 data-i18n>彈窗攔截</h2>
<div class="spacer"></div>
<div class="search-box">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
<input type="text" data-i18n-placeholder="搜尋窗口..." placeholder="搜尋窗口...">
</div>
<div class="action-group modern-action-group">
<select id="popup_select" class="modern-select">
<option value="none" selected disabled data-i18n="btn_select">選擇</option>
<option value="add" data-i18n="btn_add_item">新增項目</option>
<option value="remove" data-i18n="btn_remove_item">移除項目</option>
</select>
</div>
</div>
<div class="manage-widget flex-grow"><ul class="manage-list"></ul></div>
</section>
<section id="netmon_window" class="page sub-page">
<div class="sub-header-toolbar">
<button class="icon-btn" data-target="tool_window"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"></polyline></svg></button>
<h2 data-i18n>流量監控</h2>
<div class="spacer"></div>
<div class="search-box">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
<input type="text" data-i18n-placeholder="搜尋進程..." placeholder="搜尋進程...">
</div>
<div class="action-group modern-action-group">
<select id="netmon_select" class="modern-select">
<option value="none" selected disabled data-i18n="btn_select">選擇</option>
<option value="view" data-i18n="btn_view_item">查看項目</option>
<option value="end" data-i18n="btn_end">結束進程</option>
</select>
</div>
</div>
<div class="manage-widget flex-grow"><ul class="manage-list"></ul></div>
</section>
<section id="custom_protect_window" class="page sub-page">
<div class="sub-header-toolbar">
<button class="icon-btn" data-target="protect_window"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"></polyline></svg></button>
<h2 data-i18n>自訂防護</h2>
<div class="spacer"></div>
<div class="search-box">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
<input type="text" data-i18n-placeholder="搜尋規則..." placeholder="搜尋規則...">
</div>
<div class="action-group modern-action-group">
<select id="custom_protect_select" class="modern-select">
<option value="none" selected disabled data-i18n="btn_select">選擇</option>
<option value="add" data-i18n="btn_add_item">新增項目</option>
<option value="remove" data-i18n="btn_remove_item">移除項目</option>
</select>
</div>
</div>
<div class="manage-widget flex-grow"><ul class="manage-list"></ul></div>
</section>
<section id="log_export_window" class="page sub-page">
<div class="sub-header-toolbar">
<button class="icon-btn" data-target="home_window"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"></polyline></svg></button>
<h2 data-i18n>日誌導出</h2>
<div class="spacer"></div>
<div class="search-box">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
<input type="text" data-i18n-placeholder="搜尋日誌..." placeholder="搜尋日誌...">
</div>
<div class="action-group modern-action-group">
<select id="log_export_select" class="modern-select">
<option value="none" selected disabled data-i18n="btn_select">選擇</option>
<option value="export" data-i18n="btn_export">導出項目</option>
<option value="delete" data-i18n="btn_remove_item">移除項目</option>
</select>
</div>
</div>
<div class="manage-widget flex-grow"><ul class="manage-list"></ul></div>
</section>
</main>
</div>
</div>
</body>
</html>
-21
View File
@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2020-2023 87owo (PYAS Security)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+62
View File
@@ -0,0 +1,62 @@
87owo Publicly Available Source Code License Agreement
Last Updated: 2026-07-18
IMPORTANT NOTICE: THIS LICENSE IS "SOURCE AVAILABLE" AND IS NOT AN OPEN SOURCE LICENSE APPROVED BY THE OPEN SOURCE INITIATIVE (OSI). BY DOWNLOADING, ACCESSING, OR USING THE SOFTWARE, YOU AGREE TO BE BOUND BY THESE TERMS.
1. Definitions and Interpretation
- 1.1. Author: Refers to 87owo (PYAS Security).
- 1.2. Software: Refers to the source code, binaries, project archives, assets, and documentation associated with this repository or distribution.
- 1.3. Personal Local Use: Means viewing, downloading, executing, and modifying the Software strictly on local hardware owned or directly controlled by an individual for private, non-commercial, non-production, and non-distribution purposes.
- 1.4. Enterprise Use: Includes enterprise internal deployment, multi-user institutional use, or utilization within any corporate environment, which is strictly excluded from Personal Local Use.
2. Intellectual Property and Ownership
- 2.1. Retention of Rights: The Author reserves all legal rights, titles, and interests in and to the Software, including but not limited to all copyrights, trademarks, patents, and trade secrets.
- 2.2. No Transfer: No intellectual property rights or ownership stakes are transferred under this Agreement. All project components remain fully proprietary.
- 2.3. Activation Keys: Access to or execution of certain premium features, modules, or binary distributions within the Software may require a valid, authorized activation key issued solely by the Author.
3. Grant of License and Permitted Use
Subject to your strict compliance with all terms of this Agreement, the Author hereby grants you a limited, non-exclusive, world-wide, royalty-free, revocable, and non-transferable license to:
- 3.1. Code Inspection: View and download the source code from official authorized repositories.
- 3.2. Local Modification: Modify the source code strictly for the purposes of Personal Local Use.
- 3.3. Local Execution: Execute the Software locally for personal evaluation and private deployment.
4. Prohibitions and Restrictions
Except as explicitly granted in Section 3, you shall not, and shall not permit any third party to:
- 4.1. Unauthorized Redistribution: Copy, redistribute, sublicense, republish, mirror, or publicly disclose any original or modified versions of the source code, binaries, or assets.
- 4.2. Commercial and SaaS Deployment: Host, deploy, embed, or utilize the Software for commercial purposes, including but not limited to Software-as-a-Service (SaaS), commercial web hosting, paid remote execution, cloud infrastructure integration, or enterprise internal utility.
- 4.3. Reverse Engineering: Reverse engineer, decompile, decrypt, or disassemble any binary components of the Software, except and only to the extent that such restriction is explicitly prohibited by applicable mandatory laws.
- 4.4. Notice Preservation: Remove, obscure, deface, or alter any copyright notices, trademarks, hyperlinked terms, or license files included within the Software distribution.
5. Prior Authorization and Application Channels
- 5.1. Authorization Requirement: Any activity exceeding the scope of Personal Local Use (including but not limited to public redistribution, independent forks not targeting upstream contributions, commercial deployment, or enterprise use) requires prior explicit written consent from the Author.
- 5.2. Official Application Channels: Users seeking such authorization must submit a formal request through one of the following official channels:
- Channel A (GitHub Fork): Initiating a standard Fork on the official GitHub repository for collaborative and upstream contributions.
- Channel B (GitHub Issues): Submitting a public issue utilizing the designated authorization request template.
- Channel C (Official Email): Sending a detailed inquiry to the official organizational email address associated with the PYAS Security project.
- 5.3. Request Content: Any application must explicitly state the specific use case, intended target audience, scope of deployment, and whether any commercial monetization is involved.
6. Updates, Amendments, and Scope of Terms
- 6.1. New Releases: The Author may deliver updates, critical security patches, feature enhancements, or user interface modifications. Continued use of the Software constitutes acceptance of the latest distributed version.
- 6.2. Non-Retroactivity: The Author reserves the right to amend this License Agreement at any time. Amendments apply strictly to subsequent versions or new downloads. Copies lawfully acquired prior to such modification remain governed by the exact version of the License under which they were originally obtained.
7. Telemetry, Data, and Privacy
- 7.1. Operational Data Collection: The Software may collect anonymized technical, operational, and usage data strictly for security analysis, performance optimization, and bug reporting.
- 7.2. Cloud Sample Submission: To enhance threat detection and malware analysis, the Software may automatically or manually transmit suspicious executable files and software samples to the Author's cloud infrastructure for deep analysis.
- 7.3. Scope of Collected Extensions: Sample collection targets potential executable and system binary formats, which explicitly include, but are not limited to, files with the following extensions: `.exe`, `.dll`, `.sys`, `.ocx`, `.scr`, `.efi`, `.acm`, `.ax`, `.cpl`, `.drv`, `.com`, `.mui`, `.pyd`, `.wfx`, `.api`, `.awx`, `.rll`, and `.winmd`.
- 7.4. Public Disclosure of Threat Intelligence: You explicitly acknowledge and agree that the metadata, behavioral reports, and threat intelligence data generated from the cloud analysis of submitted samples may be publicly disclosed, published, or shared with the cybersecurity community for collaborative defense purposes.
- 7.5. Opt-Out Mechanism: Cloud-based telemetry and sample submission are fully optional. Users who do not wish to participate in sample collection or cloud-assisted analysis may disable the corresponding cloud services at any time via the toggle switches provided within the Software’s settings interface.
- 7.6. Driver Signature: Certain kernel-mode drivers distributed with this software may be digitally signed using code signing methods that are not certified by Microsoft Windows Hardware Quality Labs (WHQL). By installing or using this software, you acknowledge this and decide for yourself whether to install and trust such drivers on your system.
8. Warranty Disclaimer and Limitation of Liability
- 8.1. Disclaimer of Warranty: TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE SOFTWARE AND ALL RELATED ASSETS ARE PROVIDED ON AN "AS IS" AND "AS AVAILABLE" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED.
- 8.2. Limitation of Liability: TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL THE AUTHOR, COPYRIGHT HOLDERS, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE. USERS ASSUME ALL RISKS REGARDING PERFORMANCE, DATA INTEGRITY, AND SYSTEM STABILITY.
© 2020-2026 87owo (PYAS Security). All rights reserved.
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

-5
View File
@@ -1,5 +0,0 @@
{
"language": "en_US",
"high_sensitivity": 0,
"cloud_services": 1
}
+1427 -1198
View File
File diff suppressed because it is too large. Load diff
+248
View File
@@ -0,0 +1,248 @@
import os, time, uuid, logging, requests, hashlib
from pathlib import Path
from typing import Optional, List, Dict, Any, Union
from concurrent.futures import ThreadPoolExecutor
####################################################################################################
class PYAS_Client:
def __init__(self, api_key: str, hosts: Union[str, List[str]], timeout: int = 30):
self.timeout = timeout
self.logger = logging.getLogger("PYAS_API")
self.session = requests.Session()
self.session.headers.update({"X-API-Key": api_key, "User-Agent": "PYAS-API/1.1"})
if isinstance(hosts, str):
self.base_url = hosts.rstrip('/')
else:
self.base_url = self._get_fastest_host(hosts)
self.logger.info(f"Initialized PYAS API Client targeting {self.base_url}")
def _get_fastest_host(self, hosts: List[str]) -> str:
def ping(host: str):
url = host.rstrip('/')
try:
start = time.perf_counter()
r = self.session.head(url, timeout=3)
if r.status_code < 500:
return url, time.perf_counter() - start
except Exception:
pass
return url, float('inf')
self.logger.info("Testing host latencies...")
with ThreadPoolExecutor(max_workers=min(len(hosts), 10)) as executor:
results = list(executor.map(ping, hosts))
valid_results = []
for url, latency in results:
if latency != float('inf'):
self.logger.info(f"Host: {url} -> {latency:.4f}s")
valid_results.append((url, latency))
else:
self.logger.warning(f"Host: {url} -> Timeout/Error")
if not valid_results:
self.logger.warning("All host latency tests failed. Falling back to the first host.")
return hosts[0].rstrip('/')
best_host, best_time = min(valid_results, key=lambda x: x[1])
self.logger.info(f"Selected fastest host: {best_host} ({best_time:.4f}s)")
return best_host
def _request(self, method: str, endpoint: str, **kwargs) -> Optional[requests.Response]:
self.logger.debug(f"Request: {method} {endpoint}")
try:
r = self.session.request(method, f"{self.base_url}{endpoint}", timeout=self.timeout, **kwargs)
if r.status_code == 200:
return r
error_map = {401: "API Key invalid", 402: "Insufficient points", 404: "Not found", 413: "Payload too large", 500: "Server Error"}
self.logger.error(f"[{endpoint}] Failed: {error_map.get(r.status_code, f'HTTP {r.status_code}')}")
if 400 <= r.status_code < 500:
setattr(r, 'is_fatal', True)
return r
except Exception as e:
self.logger.error(f"Connection error: {e}")
return None
####################################################################################################
def _calculate_sha256(self, path: Path) -> str:
self.logger.debug(f"Calculating SHA256 for {path}")
sha256_hash = hashlib.sha256()
with open(path, "rb") as f:
for byte_block in iter(lambda: f.read(1048576), b""):
sha256_hash.update(byte_block)
return sha256_hash.hexdigest()
def upload_file(self, file_path: str, chunk_size: int = 4194304, max_retries: int = 3) -> Optional[str]:
path = Path(file_path)
if not path.exists():
self.logger.error(f"File not found: {file_path}")
return None
file_size = path.stat().st_size
self.logger.info(f"Initiating unified chunked upload for {path.name} ({file_size} bytes)")
if file_size > 268435456:
self.logger.error(f"File size exceeds 256MB limit: {file_size} bytes")
return None
local_sha256 = self._calculate_sha256(path)
status_req = self._request("GET", f"/api/processing_status/{local_sha256}")
if status_req and status_req.status_code == 200:
if status_req.json().get('status') in ['done', 'processing', 'queued']:
self.logger.info(f"File already exists or processing on server: {local_sha256}")
return local_sha256
return self._upload_chunked(path, chunk_size, file_size, max_retries)
####################################################################################################
def _upload_chunked(self, path: Path, chunk_size: int, file_size: int, max_retries: int = 3) -> Optional[str]:
total_chunks = max(1, (file_size + chunk_size - 1) // chunk_size)
upload_id = uuid.uuid4().hex
self.logger.info(f"Starting chunked upload for {path.name} (Chunks: {total_chunks}, ID: {upload_id})")
with open(path, 'rb') as f:
for i in range(total_chunks):
chunk_data = f.read(chunk_size)
headers = {
"X-Chunk-Index": str(i),
"X-Total-Chunks": str(total_chunks),
"X-Upload-ID": upload_id
}
chunk_success = False
for attempt in range(max_retries):
r = self._request("POST", "/api/upload", files={'file': (path.name, chunk_data)}, headers=headers)
if r and r.status_code == 200:
chunk_success = True
self.logger.debug(f"Uploaded chunk {i + 1}/{total_chunks}")
if i == total_chunks - 1:
try:
return r.json().get('url', '').split('/')[-1] or None
except Exception as e:
self.logger.error(f"Failed to parse final chunk response: {e}")
return None
break
if hasattr(r, 'is_fatal'):
self.logger.error(f"Fatal upload error encountered at chunk {i}. Aborting.")
return None
wait_time = 2 ** attempt
self.logger.warning(f"Chunk upload retry {attempt + 1}/{max_retries} for chunk {i}. Waiting {wait_time}s")
time.sleep(wait_time)
if not chunk_success:
self.logger.error(f"Failed to upload chunk {i + 1}/{total_chunks} after {max_retries} attempts")
return None
return None
####################################################################################################
def wait_for_analysis(self, sha256: str, interval: int = 5, max_retries: int = 60) -> bool:
self.logger.info(f"Waiting for analysis completion: {sha256}")
for attempt in range(max_retries):
r = self._request("GET", f"/api/processing_status/{sha256}")
if r and r.status_code == 200:
status = r.json().get('status')
self.logger.debug(f"Analysis status: {status}")
if status == 'done':
self.logger.info(f"Analysis completed: {sha256}")
return True
if status in ['missing', 'error', 'failed']:
self.logger.error(f"Analysis failed with status: {status}")
return False
time.sleep(interval)
self.logger.error(f"Analysis polling timed out for {sha256}")
return False
def get_report(self, sha256: str) -> Optional[Dict[str, Any]]:
self.logger.info(f"Fetching report for {sha256}")
r = self._request("GET", f"/api/report/{sha256}")
if r:
return r.json()
self.logger.error(f"Failed to fetch report for {sha256}")
return None
####################################################################################################
def rescan(self, sha256: str) -> bool:
self.logger.info(f"Triggering rescan for {sha256}")
r = self._request("POST", f"/api/rescan/{sha256}")
success = bool(r and r.json().get('status') == 'success')
if success:
self.logger.info(f"Rescan triggered successfully for {sha256}")
else:
self.logger.error(f"Rescan failed for {sha256}")
return success
def search_files(self, query: str, limit: int = 50, page: int = 0, snapshot: Optional[str] = None) -> List[Dict[str, Any]]:
self.logger.info(f"Searching files (Query: '{query}', Limit: {limit}, Page: {page})")
payload = {'query': query, 'page': page}
if snapshot:
payload['snapshot'] = snapshot
r = self._request("POST", "/api/search_more", data=payload)
results = r.json().get('results', [])[:limit] if r else []
self.logger.info(f"Search returned {len(results)} results")
return results
def download_sample(self, sha256: str, save_dir: str = "downloads") -> Optional[str]:
self.logger.info(f"Downloading sample {sha256}")
os.makedirs(save_dir, exist_ok=True)
path = os.path.join(save_dir, f"{sha256}.zip")
r = self._request("GET", f"/api/download/{sha256}", stream=True)
if r:
with open(path, 'wb') as f:
for chunk in r.iter_content(8192):
if chunk:
f.write(chunk)
self.logger.info(f"Sample downloaded successfully to {path}")
return path
self.logger.error(f"Failed to download sample {sha256}")
return None
####################################################################################################
if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG, format='[%(asctime)s] %(levelname)s [%(name)s] - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
API_KEY = "" # https://pyas-security.com/setting?tab=application
HOSTS = [
"https://pyas-security.com/",
"https://cn.pyas-security.com/"
]
client = PYAS_Client(API_KEY, HOSTS)
target_file = r"C:/Windows/explorer.exe"
sha = client.upload_file(target_file)
if sha and client.wait_for_analysis(sha):
report = client.get_report(sha)
if report:
meta = report.get('data', {}).get('metadata', {})
logging.info(f"Result: {meta.get('label')} ({meta.get('score')}%)")
for item in client.search_files('date>=2020; ext=exe | dll', limit=3):
client.download_sample(item['sha256'])
+1322
View File
File diff suppressed because it is too large. Load diff
+315
View File
@@ -0,0 +1,315 @@
#define AppId "{{a7d7bac3-93b8-4630-8308-c7a56bf7fdf4}"
#define AppName "PYAS"
#define AppVersion "3.7.0.0"
#define AppPublisher "PYAS Security"
#define AppURL "https://github.com/87owo/PYAS"
#define AppExeName "PYAS.exe"
[Setup]
AppId={#AppId}
AppName={#AppName}
AppVersion={#AppVersion}
AppVerName={#AppName} {#AppVersion}
AppPublisher={#AppPublisher}
AppPublisherURL={#AppURL}
AppSupportURL={#AppURL}
AppUpdatesURL={#AppURL}
VersionInfoVersion={#AppVersion}
VersionInfoCompany={#AppPublisher}
VersionInfoDescription={#AppName} Setup
VersionInfoProductName={#AppName} Setup
VersionInfoProductVersion={#AppVersion}
DefaultDirName={autopf}\{#AppName}
DefaultGroupName={#AppPublisher}\{#AppName}
AllowNoIcons=yes
LicenseFile=SetupResources\licence.rtf
ShowLanguageDialog=yes
WizardStyle=modern
WizardImageFile=SetupResources\wizardImage.bmp
WizardSmallImageFile=SetupResources\headerImage.png
SetupIconFile=Payload\Interface\static\img\icon.ico
UninstallDisplayIcon={app}\{#AppExeName}
PrivilegesRequired=admin
ArchitecturesAllowed=x64compatible
ArchitecturesInstallIn64BitMode=x64compatible
MinVersion=10.0
Compression=lzma2/max
SolidCompression=yes
OutputDir=Output
OutputBaseFilename=PYAS_Setup
UsePreviousTasks=no
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
Name: "chinesesimplified"; MessagesFile: "SetupResources\ChineseSimplified.isl"
Name: "chinesetraditional"; MessagesFile: "SetupResources\ChineseTraditional.isl"
Name: "japanese"; MessagesFile: "SetupResources\Japanese.isl"
Name: "korean"; MessagesFile: "SetupResources\Korean.isl"
Name: "french"; MessagesFile: "SetupResources\French.isl"
Name: "spanish"; MessagesFile: "SetupResources\Spanish.isl"
Name: "hindi"; MessagesFile: "SetupResources\Hindi.isl"
Name: "arabic"; MessagesFile: "SetupResources\Arabic.isl"
Name: "russian"; MessagesFile: "SetupResources\Russian.isl"
Name: "slovenian"; MessagesFile: "SetupResources\Slovenian.isl"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"
[Files]
Source: "Redist\VC_redist.x64.exe"; DestDir: "{tmp}\PYAS_Redist"; Flags: deleteafterinstall ignoreversion; AfterInstall: EnsureVCRedist
Source: "Redist\MicrosoftEdgeWebview2Setup.exe"; DestDir: "{tmp}\PYAS_Redist"; Flags: deleteafterinstall ignoreversion; AfterInstall: EnsureWebView2
Source: "Payload\Engine\*"; DestDir: "{app}\Engine"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "Payload\Interface\*"; DestDir: "{app}\Interface"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "Payload\License\*"; DestDir: "{app}\License"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "Payload\PYAS.exe"; DestDir: "{app}"; Flags: ignoreversion; AfterInstall: FinalizeDriverRemoval
Source: "Payload\Plugins\*"; DestDir: "{app}\Plugins"; Flags: ignoreversion recursesubdirs createallsubdirs
[Registry]
Root: HKCU; Subkey: "Software\Classes\*\shell\PYAS_Scan"; Flags: uninsdeletekey dontcreatekey
Root: HKCU; Subkey: "Software\Classes\Directory\shell\PYAS_Scan"; Flags: uninsdeletekey dontcreatekey
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Run"; ValueName: "PYAS_Security"; Flags: uninsdeletevalue dontcreatekey
[UninstallDelete]
Type: filesandordirs; Name: "{commonappdata}\PYAS"
[Icons]
Name: "{autodesktop}\{#AppName}"; Filename: "{app}\{#AppExeName}"; Tasks: desktopicon
Name: "{group}\{#AppName}"; Filename: "{app}\{#AppExeName}"
Name: "{group}\Uninstall {#AppName}"; Filename: "{uninstallexe}"
[Run]
Filename: "{app}\{#AppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(AppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent runascurrentuser; Check: CanLaunchApp
[CustomMessages]
english.InstallingVCRuntime=Installing Microsoft Visual C++ Runtime...
chinesesimplified.InstallingVCRuntime=正在安装 Microsoft Visual C++ 运行库...
chinesetraditional.InstallingVCRuntime=正在安裝 Microsoft Visual C++ 執行庫...
english.InstallingWebView2Runtime=Installing Microsoft Edge WebView2 Runtime...
chinesesimplified.InstallingWebView2Runtime=正在安装 Microsoft Edge WebView2 Runtime...
chinesetraditional.InstallingWebView2Runtime=正在安裝 Microsoft Edge WebView2 Runtime...
english.Dependencies=Dependencies:
chinesesimplified.Dependencies=运行环境:
chinesetraditional.Dependencies=執行環境:
english.InstallWebView2=Install Microsoft Edge WebView2 Runtime
chinesesimplified.InstallWebView2=安装 Microsoft Edge WebView2 运行环境
chinesetraditional.InstallWebView2=安裝 Microsoft Edge WebView2 執行環境
english.InstallVCRedist=Install Microsoft Visual C++ Runtime
chinesesimplified.InstallVCRedist=安装 Microsoft Visual C++ 运行库
chinesetraditional.InstallVCRedist=安裝 Microsoft Visual C++ 執行庫
english.LegacyVersionDetected=An older version of PYAS was detected. Please uninstall it manually before installing.
english.QuitFailed=PYAS or its driver could not be stopped safely. Restart Windows and run Setup again.
english.DependencyInstallFailed=Required Microsoft runtime installation failed. Setup cannot continue.
chinesesimplified.LegacyVersionDetected=检测到存在旧版 PYAS。请先手动卸载旧版后,再运行本安装程序。
chinesetraditional.LegacyVersionDetected=檢測到存在舊版 PYAS。請先手動卸載舊版後,再執行本安裝程式。
[Code]
var
DependencyRestartRequired: Boolean;
DependenciesReady: Boolean;
function FindWindow(lpClassName: LongWord; lpWindowName: string): HWND;
external '[email protected] stdcall';
function GetTickCount: Cardinal;
external '[email protected] stdcall';
function IsValidRuntimeVersion(Version: string): Boolean;
begin
Result := (Length(Trim(Version)) > 0) and (Trim(Version) <> '0.0.0.0');
end;
function IsWebView2Installed: Boolean;
var
Version: string;
begin
Result := False;
if RegQueryStringValue(HKLM, 'SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}', 'pv', Version) then
Result := IsValidRuntimeVersion(Version);
if not Result and RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}', 'pv', Version) then
Result := IsValidRuntimeVersion(Version);
if not Result and RegQueryStringValue(HKCU, 'SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}', 'pv', Version) then
Result := IsValidRuntimeVersion(Version);
end;
function IsVCRedistInstalled: Boolean;
var
Installed: Cardinal;
Version: string;
begin
Result := False;
if RegQueryDWordValue(HKLM64, 'SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64', 'Installed', Installed) and (Installed = 1) then
begin
if RegQueryStringValue(HKLM64, 'SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64', 'Version', Version) then
Result := IsValidRuntimeVersion(Version)
else
Result := True;
end;
end;
function DependencyExitCodeSucceeded(ResultCode: Integer): Boolean;
begin
Result := (ResultCode = 0) or (ResultCode = 1641) or (ResultCode = 3010);
if (ResultCode = 1641) or (ResultCode = 3010) then
DependencyRestartRequired := True;
end;
procedure EnsureVCRedist;
var
ResultCode: Integer;
InstallerPath: string;
begin
if IsVCRedistInstalled then Exit;
InstallerPath := ExpandConstant('{tmp}\PYAS_Redist\VC_redist.x64.exe');
WizardForm.StatusLabel.Caption := CustomMessage('InstallingVCRuntime');
if not Exec(InstallerPath, '/quiet /norestart', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) or
not DependencyExitCodeSucceeded(ResultCode) or not IsVCRedistInstalled then
begin
DependenciesReady := False;
RaiseException(CustomMessage('DependencyInstallFailed'));
end;
end;
procedure EnsureWebView2;
var
ResultCode: Integer;
InstallerPath: string;
begin
if IsWebView2Installed then Exit;
InstallerPath := ExpandConstant('{tmp}\PYAS_Redist\MicrosoftEdgeWebview2Setup.exe');
WizardForm.StatusLabel.Caption := CustomMessage('InstallingWebView2Runtime');
if not Exec(InstallerPath, '/silent /install', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) or
not DependencyExitCodeSucceeded(ResultCode) or not IsWebView2Installed then
begin
DependenciesReady := False;
RaiseException(CustomMessage('DependencyInstallFailed'));
end;
end;
function WaitForMainWindowToClose(TimeoutMs: Cardinal): Boolean;
var
Deadline: Cardinal;
begin
Deadline := GetTickCount + TimeoutMs;
repeat
if FindWindow(0, 'PYAS Security') = 0 then
begin
Result := True;
Exit;
end;
Sleep(100);
until GetTickCount >= Deadline;
Result := False;
end;
function QuitOldInstance(InstallPath: string): Boolean;
var
ResultCode: Integer;
ExePath: string;
begin
Result := True;
ExePath := InstallPath + '\{#AppExeName}';
if not FileExists(ExePath) then Exit;
if not Exec(ExePath, '-quit', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
begin
Result := False;
Exit;
end;
Result := (ResultCode = 0) and WaitForMainWindowToClose(30000);
end;
procedure FinalizeDriverRemoval;
var
ResultCode: Integer;
ExePath: string;
begin
ExePath := ExpandConstant('{app}\{#AppExeName}');
if not Exec(ExePath, '-quit', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) or (ResultCode <> 0) then
RaiseException(CustomMessage('QuitFailed'));
end;
function InitializeSetup(): Boolean;
var
OldInstallPath: string;
LegacyPath: string;
begin
DependencyRestartRequired := False;
DependenciesReady := True;
LegacyPath := ExpandConstant('{pf32}\{#AppName}');
if DirExists(LegacyPath) and FileExists(LegacyPath + '\{#AppExeName}') then
begin
MsgBox(CustomMessage('LegacyVersionDetected'), mbCriticalError, MB_OK);
Result := False;
Exit;
end;
if RegQueryStringValue(HKLM, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\' + ExpandConstant('{#AppId}') + '_is1', 'InstallLocation', OldInstallPath) or
RegQueryStringValue(HKCU, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\' + ExpandConstant('{#AppId}') + '_is1', 'InstallLocation', OldInstallPath) then
begin
if not QuitOldInstance(OldInstallPath) then
begin
MsgBox(CustomMessage('QuitFailed'), mbCriticalError, MB_OK);
Result := False;
Exit;
end;
end;
Result := True;
end;
function InitializeUninstall(): Boolean;
begin
Result := QuitOldInstance(ExpandConstant('{app}'));
if not Result then
MsgBox(CustomMessage('QuitFailed'), mbCriticalError, MB_OK);
end;
function CanLaunchApp: Boolean;
begin
Result := DependenciesReady and not DependencyRestartRequired;
end;
function NeedRestart: Boolean;
begin
Result := DependencyRestartRequired;
end;
procedure RemoveLegacyStartupTask;
var
TaskService: Variant;
RootFolder: Variant;
begin
try
TaskService := CreateOleObject('Schedule.Service');
TaskService.Connect();
RootFolder := TaskService.GetFolder('\');
try
RootFolder.DeleteTask('PYAS_Security_ATS', 0);
Log('Removed legacy PYAS scheduled startup task');
except
Log('Legacy PYAS scheduled startup task was not present or could not be removed');
end;
except
Log('Task Scheduler COM was unavailable while cleaning the legacy startup task');
end;
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall then
begin
RemoveLegacyStartupTask;
end;
end;
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
if CurUninstallStep = usUninstall then
begin
RemoveLegacyStartupTask;
end
else if CurUninstallStep = usPostUninstall then
begin
DelTree(ExpandConstant('{app}'), True, True, True);
end;
end;
-47
View File
@@ -1,47 +0,0 @@
translations = {"zh_TW": {"已开启":"已開啟","已关闭":"已關閉","On":"已開啟","Off":"已關閉"},
"zh_CN": {"已開啟":"已开启","已關閉":"已关闭","On":"已开启","Off":"已关闭",
"軟體":"软件","檔案":"文件","確定":"确认","設定":"设置","關於":"关于",
"錯誤":"错误","實時":"实时","發現":"发现","關閉":"关闭","裝置":"设备",
"總數":"总数","註冊":"注册","圖標":"图标","路徑":"路径","網路":"网络",
"位元":"字节","增":"增","單":"单","簽":"签","無":"无","關":"关",
"項":"项","掃":"扫","試":"试","黃":"黄","嗎":"吗","防":"保","鑰":"钥",
"當":"当","後":"后","護":"护","導":"导","區":"区","復":"复","攔":"拦",
"請":"请","統":"统","刪":"删","進":"进","個":"个","選":"选","啟":"启",
"監":"监","並":"并","徑":"径","盤":"盘","隱":"隐","動":"动","狀":"状",
"誌":"志","靈":"灵","這":"这","會":"会","題":"题","擇":"择","語":"语",
"顯":"显","變":"变","戶":"户","碼":"码","雲":"云","訂":"订","稱":"称",
"類":"类","輸":"输","執":"执","數":"数","尋":"寻","網":"网","詢":"询",
"製":"制","員":"员","許":"许","條":"条","藍":"蓝","紅":"红","綠":"绿",
"態":"态","務":"务","連":"连","檢":"检","測":"测","強":"强"},
"en_US": {"已開啟":"On","已關閉":"Off","已开启":"On","已关闭":"Off",",":", ",
"立即刪除":"Delete Now","安全模式":"Safe Mode","官方網站":"Website",
"許可條款":"License Terms","可疑":"Suspicious ","惡意軟體":"Malware ",
"啟用":"Enable ","禁用":"Disable ","正在初始化中":"Initializing ",
"正在掃描":"Scanning ","正在刪除":"Deleting ","最小化到":"Minimize To ",
"確定要":"Sure Want To ","靈敏度":"Sensitivity ","更新":"Update",
"白色主題":"White","黑色主題":"Black","黃色主題":"Yellow","紅色主題":"Red",
"藍色主題":"Blue","綠色主題":"Green","語言":"Language ","製作":"Make",
"測試人員":"Testers","版本資訊":"Information","無效簽名":"Unsign ",
"註冊表":"Registry ","退出":"Quit ","檔案":"File ","當前":"Currently ",
"狀態":"State ","掃描":"Scan ","工具":"Tools ","防護":"Protect ",
"失敗":"Failed ","請":"Please ","路徑":"Path ","方式":"Method ",
"需要":"Need ","病毒":"Virus ","選擇":"Select ","返回":"Back",
"受到":"Been ","錯誤":"Error","完成":"Complete ","引擎":"Engine ",
"托盤":"Tray ","圖標":"Icon ","不安全":"Unsafe","增強":"Enhanced ",
"系統":"System ","雲端":"Cloud ","重啟":"Reboot ","修復":"Repair ",
"裝置":"Device ","發現":"Found ","成功":"Success ","清理":"Cleanup ",
"確定":"OK","執行":"Execute ","警告":"Warning ","使用":"Use ",
"網路":"Network ","變更":"Change ","總數":"Total","結束":"End ",
"選項":"Options ","監控":"Monitor ","連接":"Connect ","可以":"To ",
"進程":"Process ","攔截":"Block ","引導":"Boot ","刪除":"Delete ",
"分區":"Partition ","設定":"Settings","關於":"About","模式":"Mode ",
"提高":"Improve ","安全":"Security ","顯色":"Color ","主題":"Themes ",
"風險":"Risk ","介面":"GUI ","核心":"Core ","服務":"Services ",
"管理":"Manage","所有":"All ","全盤":"Full ","日誌":"Log",
"垃圾":"Junk ","位元":"byte ","本機":"Computer ","停止":"Stop ",
"增加到":"Add File To ","白名單":"White List ","軟體":"Software ",
"增加":"Add","移除":"Delete","項目":"Items ","生成":"Create ",
"開啟":"Open ","您":"You ","此":"This ","並":"And ","未":"Not ",
"高":"High ","新":"New ","和":"And ","會":"Can ","密鑰":"Key ",
"已":"Has ","立即":"","顯示":"","個":"","的":"","嗎":"","中":"",
"了":"","行":"","稱":""," ":" "}}
-1
View File
@@ -1 +0,0 @@
function_list = [['_CorExeMain'], ['GetProcessHeap', 'RtlUnwind', 'RaiseException', 'HeapSize', 'TerminateProcess', 'UnhandledExceptionFilter', 'SetUnhandledExceptionFilter', 'IsDebuggerPresent', 'HeapDestroy', 'HeapCreate', 'VirtualFree', 'Sleep', 'GetStdHandle', 'GetTimeZoneInformation', 'GetACP', 'SetHandleCount', 'GetFileType', 'GetStartupInfoA', 'GetCommandLineA', 'GetEnvironmentStrings', 'FreeEnvironmentStringsW', 'GetEnvironmentStringsW', 'QueryPerformanceCounter', 'GetSystemTimeAsFileTime', 'LCMapStringA', 'LCMapStringW', 'GetConsoleCP', 'GetConsoleMode', 'GetStringTypeA', 'GetStringTypeW', 'SetStdHandle', 'WriteConsoleA', 'GetConsoleOutputCP', 'WriteConsoleW', 'GetDateFormatA', 'GetTimeFormatA', 'GetDriveTypeA', 'SetEnvironmentVariableA', 'HeapReAlloc', 'VirtualAlloc', 'SetCurrentDirectoryA', 'HeapAlloc', 'HeapFree', 'GetTickCount', 'GetCurrentDirectoryA', 'LocalFileTimeToFileTime', 'CreateFileA', 'GetShortPathNameA', 'GetVolumeInformationA', 'GetCurrentProcess', 'DuplicateHandle', 'GetFileSize', 'SetEndOfFile', 'UnlockFile', 'LockFile', 'FlushFileBuffers', 'SetFilePointer', 'WriteFile', 'ReadFile', 'DeleteFileA', 'MoveFileA', 'GetOEMCP', 'GetCPInfo', 'InterlockedIncrement', 'SystemTimeToFileTime', 'GetThreadLocale', 'GlobalFlags', 'TlsFree', 'DeleteCriticalSection', 'LocalReAlloc', 'TlsSetValue', 'TlsAlloc', 'InitializeCriticalSection', 'GlobalHandle', 'GlobalReAlloc', 'EnterCriticalSection', 'TlsGetValue', 'LeaveCriticalSection', 'LocalAlloc', 'CloseHandle', 'GetPrivateProfileStringA', 'WritePrivateProfileStringA', 'GetPrivateProfileIntA', 'GetCurrentProcessId', 'GetCurrentThread', 'ConvertDefaultLocale', 'GetModuleFileNameA', 'EnumResourceLanguagesA', 'GetLocaleInfoA', 'lstrcmpA', 'GetDiskFreeSpaceA', 'GetFullPathNameA', 'GetTempFileNameA', 'GetFileTime', 'SetFileTime', 'GetFileAttributesA', 'FreeResource', 'GetCurrentThreadId', 'GlobalGetAtomNameA', 'GlobalAddAtomA', 'GlobalFindAtomA', 'GlobalDeleteAtom', 'lstrcmpW', 'GetVersionExA', 'GlobalFree', 'GlobalAlloc', 'FormatMessageA', 'LocalFree', 'GlobalLock', 'GlobalUnlock', 'MulDiv', 'FindFirstFileA', 'FileTimeToLocalFileTime', 'FileTimeToSystemTime', 'FindNextFileA', 'FindClose', 'FreeLibrary', 'InterlockedDecrement', 'LockResource', 'SizeofResource', 'LoadResource', 'FindResourceA', 'ExitProcess', 'GetVersion', 'CompareStringA', 'GetModuleHandleA', 'LoadLibraryA', 'GetProcAddress', 'lstrcmpiA', 'SetLastError', 'GetLastError', 'InterlockedExchange', 'GetStringTypeExA', 'MultiByteToWideChar', 'CompareStringW', 'WideCharToMultiByte', 'lstrlenA', 'FreeEnvironmentStringsA', 'GetComputerNameA', 'CopyAcceleratorTableA', 'CreateMenu', 'PostThreadMessageA', 'GetTabbedTextExtentA', 'RegisterClipboardFormatA', 'GetSysColorBrush', 'UnregisterClassA', 'LoadCursorA', 'DestroyCursor', 'SetCursorPos', 'SetCapture', 'RedrawWindow', 'InflateRect', 'UnpackDDElParam', 'ReuseDDElParam', 'LoadMenuA', 'DestroyMenu', 'ReleaseCapture', 'LoadAcceleratorsA', 'InsertMenuItemA', 'CreatePopupMenu', 'BringWindowToTop', 'SetMenu', 'TranslateAcceleratorA', 'IsZoomed', 'WindowFromPoint', 'KillTimer', 'SetTimer', 'SetRect', 'SetParent', 'GetSystemMenu', 'DeleteMenu', 'SetRectEmpty', 'IsRectEmpty', 'GetDesktopWindow', 'CreateDialogIndirectParamA', 'GetNextDlgTabItem', 'EndDialog', 'GetMessageA', 'TranslateMessage', 'GetActiveWindow', 'GetCursorPos', 'ValidateRect', 'GetWindowThreadProcessId', 'ShowOwnedPopups', 'SetCursor', 'PostQuitMessage', 'IsWindowEnabled', 'SetWindowTextA', 'IsDialogMessageA', 'SetDlgItemTextA', 'RegisterWindowMessageA', 'LoadIconA', 'SendDlgItemMessageA', 'WinHelpA', 'GetCapture', 'SetWindowsHookExA', 'CallNextHookEx', 'GetClassNameA', 'SetPropA', 'GetPropA', 'RemovePropA', 'SetFocus', 'GetWindowTextLengthA', 'GetWindowTextA', 'GetLastActivePopup', 'SetActiveWindow', 'DispatchMessageA', 'BeginDeferWindowPos', 'EndDeferWindowPos', 'GetDlgItem', 'GetTopWindow', 'DestroyWindow', 'GetMessageTime', 'GetMessagePos', 'PeekMessageA', 'MapWindowPoints', 'ScrollWindow', 'TrackPopupMenu', 'GetKeyState', 'SetScrollRange', 'GetScrollRange', 'SetScrollPos', 'GetScrollPos', 'SetForegroundWindow', 'ShowScrollBar', 'IsWindowVisible', 'GetMenu', 'PostMessageA', 'MessageBoxA', 'CreateWindowExA', 'GetClassInfoExA', 'GetClassInfoA', 'RegisterClassA', 'EqualRect', 'DeferWindowPos', 'GetScrollInfo', 'SetScrollInfo', 'PtInRect', 'DefWindowProcA', 'CallWindowProcA', 'SetWindowPos', 'OffsetRect', 'IntersectRect', 'SystemParametersInfoA', 'GetWindowPlacement', 'GetWindowRect', 'GetSystemMetrics', 'GetWindow', 'GetMenuStringA', 'AppendMenuA', 'GetMenuItemID', 'InsertMenuA', 'GetMenuItemCount', 'GetSubMenu', 'RemoveMenu', 'GetSysColor', 'EndPaint', 'BeginPaint', 'GetWindowDC', 'ClientToScreen', 'ScreenToClient', 'GrayStringA', 'DrawTextExA', 'DrawTextA', 'TabbedTextOutA', 'FillRect', 'SetWindowRgn', 'DrawIcon', 'FindWindowA', 'LockWindowUpdate', 'GetDCEx', 'DestroyIcon', 'GetClassLongA', 'GetMenuItemInfoA', 'GetDlgCtrlID', 'IsChild', 'InvalidateRect', 'IsIconic', 'AdjustWindowRectEx',Line truncated
+2129
View File
File diff suppressed because it is too large. Load diff
+642
View File
@@ -0,0 +1,642 @@
import os, gc, json, time, stat, threading
import ctypes, ctypes.wintypes
from PYAS_Tools import MEMORY_BASIC_INFORMATION
####################################################################################################
class ScannerMixin:
def init_engine_thread(self):
try:
self.start_daemon_thread(self.backup_mbr)
self.start_daemon_thread(self.relock_file)
self.start_daemon_thread(self.init_whitelist)
self.start_daemon_thread(self.popup_intercept_thread)
def log_callback(x):
self.write_log("INFO", "Load Engine", source=os.path.basename(x))
self.heuristic.load_path(self.path_heuristic, callback=log_callback)
self.properties.load_path(self.path_properties, callback=log_callback)
self.write_log("INFO", "System", detail="Engine Initialization Complete")
if "-scan" in self.args_pyas:
try:
idx = self.args_pyas.index("-scan")
self.trigger_context_scan(self.args_pyas[idx+1])
except Exception:
pass
with self.lock_config:
first_launch = self.pyas_config.get("first_launch", True)
driver_enabled = self.pyas_config.get("driver_switch", False)
context_enabled = self.pyas_config.get("context_switch", True)
autostart_enabled = self.pyas_config.get("autostart_switch", True)
self.register_context_menu(context_enabled)
self.manage_autostart(autostart_enabled)
if not first_launch:
with self.lock_config:
if self.pyas_config.get("process_switch"):
self.start_daemon_thread(self.protect_proc_thread)
if self.pyas_config.get("document_switch"):
self.start_daemon_thread(self.protect_file_thread)
if self.pyas_config.get("system_switch"):
self.start_daemon_thread(self.protect_system_thread)
if self.pyas_config.get("network_switch"):
self.start_daemon_thread(self.protect_net_thread)
if driver_enabled:
if self.install_system_driver() and self.start_driver_listener(wait_ready=True):
pass
else:
self.stop_system_driver()
with self.lock_config:
self.pyas_config["driver_switch"] = False
self.save_config()
self.write_log("WARN", "System", detail="Driver Protection Failed to Start", success=False)
except Exception as e:
self.write_log("WARN", "init_engine_thread", detail=str(e), success=False)
####################################################################################################
def yield_files(self, targets):
if isinstance(targets, str):
if os.path.isdir(targets):
for root, dirs, files in os.walk(targets):
dirs[:] = [d for d in dirs if not self._is_reparse_point(os.path.join(root, d))]
for f in files:
yield self.norm_path(os.path.join(root, f)), False
elif os.path.isfile(targets):
yield self.norm_path(targets), True
elif isinstance(targets, (list, tuple, set)):
for t in targets:
yield from self.yield_files(t)
def _is_reparse_point(self, path):
try:
if os.path.islink(path):
return True
if hasattr(os.path, 'isjunction') and os.path.isjunction(path):
return True
st = os.lstat(path)
return bool(getattr(st, 'st_file_attributes', 0) & 0x400)
except OSError:
return False
####################################################################################################
def scan_engine(self, file_path):
with self.lock_config:
ext_switch = self.pyas_config.get("extension_switch", False)
sen_switch = self.pyas_config.get("sensitive_switch", False)
try:
pe_label, _ = self.properties.pe_scan(file_path, enhanced_mode=sen_switch)
if pe_label:
return pe_label
except Exception:
pass
try:
if ext_switch:
yara_label, _ = self.heuristic.yara_scan(file_path)
if yara_label:
return yara_label
except Exception:
pass
return False
def safe_scan_engine(self, file_path):
norm_path = self.norm_path(file_path)
if not norm_path:
return False
file_hash = self.calc_file_hash(norm_path)
cache_key = file_hash if file_hash else os.path.normcase(norm_path)
with self.lock_file_ops:
if cache_key in self.hash_cache:
return self.hash_cache[cache_key]
if cache_key in self.scan_events:
event = self.scan_events[cache_key]
needs_scan = False
else:
event = threading.Event()
self.scan_events[cache_key] = event
needs_scan = True
if not needs_scan:
event.wait(timeout=60)
with self.lock_file_ops:
return self.hash_cache.get(cache_key, False)
try:
result = self.scan_engine(norm_path)
with self.lock_file_ops:
if len(self.hash_cache) > 10000:
for k in list(self.hash_cache.keys())[:1000]:
del self.hash_cache[k]
self.hash_cache[cache_key] = result
return result
finally:
with self.lock_file_ops:
if cache_key in self.scan_events:
self.scan_events[cache_key].set()
del self.scan_events[cache_key]
gc.collect()
####################################################################################################
def _scan_result_messages(self, count=None, scanned=None, elapsed=None):
if count is None or scanned is None or elapsed is None:
with self.lock_virus:
count = len(getattr(self, 'virus_results', [])) if count is None else count
scanned = getattr(self, 'scan_count', 0) if scanned is None else scanned
scan_start = getattr(self, 'scan_start', time.time())
elapsed = int(time.time() - scan_start) if elapsed is None else elapsed
return {
"traditional_switch": f"發現 {count} 個病毒,掃描 {scanned} 個檔案,耗時 {elapsed} 秒",
"simplified_switch": f"发现 {count} 个病毒,扫描 {scanned} 个文件,耗时 {elapsed} 秒",
"english_switch": f"Found {count} viruses, scanned {scanned} files, time {elapsed}s",
"japanese_switch": f"{count} 個のウイルスを発見し、{scanned} 個のファイルをスキャンしました(所要時間 {elapsed} 秒)",
"korean_switch": f"바이러스 {count}개 발견, 파일 {scanned}개 검사, 소요 시간 {elapsed}초",
"french_switch": f"{count} virus trouvés, {scanned} fichiers analysés, temps {elapsed}s",
"spanish_switch": f"Se encontraron {count} virus, {scanned} archivos escaneados, tiempo {elapsed}s",
"hindi_switch": f"{count} वायरस मिले, {scanned} फ़ाइलें स्कैन की गईं, समय {elapsed}s",
"arabic_switch": f"تم العثور على {count} فيروسات، تم فحص {scanned} ملفات، الوقت {elapsed} ثانية",
"russian_switch": f"Найдено {count} вирусов, проверено {scanned} файлов, время {elapsed}с",
"slovenian_switch": f"Najdenih {count} virusov, skeniranih {scanned} datotek, čas {elapsed}s"
}
def _is_scan_cancel_requested(self):
with self.lock_virus:
return getattr(self, 'scan_stop_requested', False)
def _finish_scan_cancelled(self, messages=None):
with self.lock_virus:
count = len(getattr(self, 'virus_results', []))
scanned = getattr(self, 'scan_count', 0)
scan_start = getattr(self, 'scan_start', time.time())
elapsed = int(time.time() - scan_start)
self.scan_running = False
self.scan_preparing = False
self.scan_finished = True
self.scan_stop_requested = False
messages = messages or self._scan_result_messages(count, scanned, elapsed)
if self._window:
js_cmd = f"if(window.finishScan) window.finishScan({json.dumps(messages)}, {count});"
self.ui_queue.put(js_cmd)
return False
def _begin_scan_preparation(self):
with self.lock_virus:
if getattr(self, 'scan_running', False) or getattr(self, 'scan_preparing', False):
return False
self.scan_preparing = True
self.scan_stop_requested = False
self.scan_finished = False
self.virus_results = []
self.scan_count = 0
self.scan_start = time.time()
return True
def start_scan(self, targets, from_preparing=False):
with self.lock_virus:
if getattr(self, 'scan_running', False) or (getattr(self, 'scan_preparing', False) and not from_preparing):
return False
if getattr(self, 'scan_stop_requested', False):
self.scan_running = False
self.scan_preparing = False
self.scan_finished = True
return False
self.scan_preparing = False
self.scan_running = True
self.scan_finished = False
self.scan_stop_requested = False
self.virus_results = []
self.scan_count = 0
self.scan_start = time.time()
self.scan_pool.submit(self.scan_worker, targets)
return True
def scan_worker(self, targets):
last_update = 0.0
try:
for file_path, is_explicit in self.yield_files(targets):
with self.lock_virus:
if not self.scan_running or getattr(self, 'scan_stop_requested', False):
break
norm_path = self.norm_path(file_path)
if not norm_path:
continue
current_time = time.time()
if current_time - last_update >= 0.05:
if self._window:
js_cmd = f"if(window.updateScanProgress) window.updateScanProgress({json.dumps(norm_path.replace(os.sep, '/'))});"
self.ui_queue.put(js_cmd)
last_update = current_time
was_locked = False
try:
with self.lock_file_ops:
if norm_path in self.virus_lock:
self.lock_file(norm_path, False)
was_locked = True
if self.is_in_whitelist(norm_path):
continue
with self.lock_virus:
if not self.scan_running or getattr(self, 'scan_stop_requested', False):
break
self.scan_count += 1
with self.lock_config:
ext_filter = self.pyas_config.get("suffix_switch", True)
suffix = self.pyas_config.get("suffix", [])
if not is_explicit and ext_filter and os.path.splitext(norm_path)[-1].lower() not in suffix:
continue
result = self.safe_scan_engine(norm_path)
with self.lock_virus:
if not self.scan_running or getattr(self, 'scan_stop_requested', False):
break
if result:
with self.lock_virus:
self.virus_results.append(norm_path)
if self._window:
js_cmd = f"if(window.addVirusResult) window.addVirusResult({json.dumps(result)}, {json.dumps(norm_path.replace(os.sep, '/'))});"
self.ui_queue.put(js_cmd)
self.write_log("SCAN", "Virus Detected", source=norm_path, file_hash=self.calc_file_hash(norm_path))
self.cloud_check(norm_path)
except Exception as e:
self.write_log("WARN", "Scan Engine", source=norm_path, detail=str(e), success=False)
finally:
if was_locked:
self.lock_file(norm_path, True)
finally:
with self.lock_virus:
cancelled = getattr(self, 'scan_stop_requested', False)
self.scan_running = False
self.scan_preparing = False
self.scan_finished = True
self.scan_stop_requested = False
count, scanned, elapsed = len(self.virus_results), self.scan_count, int(time.time() - self.scan_start)
messages = self._scan_result_messages(count, scanned, elapsed)
log_detail = f"Found {count} viruses, scanned {scanned} files, time {elapsed}s"
if self._window:
js_cmd = f"if(window.finishScan) window.finishScan({json.dumps(messages)}, {count});"
self.ui_queue.put(js_cmd)
self.write_log("INFO", "Scan Completed", detail=log_detail)
####################################################################################################
def stop_scan(self):
with self.lock_virus:
active = getattr(self, 'scan_running', False) or getattr(self, 'scan_preparing', False)
if active:
self.scan_stop_requested = True
self.scan_running = False
return active
def trigger_scan(self, method):
targets = []
if not self._begin_scan_preparation():
return False
try:
if method == "smart":
for folder in ["Desktop", "Downloads", "AppData"]:
if self._is_scan_cancel_requested():
return self._finish_scan_cancelled()
fp = os.path.join(self.path_user, folder)
if os.path.exists(fp):
targets.append(fp)
if self._is_scan_cancel_requested():
return self._finish_scan_cancelled()
if os.path.exists(self.path_config):
targets.append(self.path_config)
buf = ctypes.create_unicode_buffer(1024)
max_address = 0x7FFFFFFFFFFF if ctypes.sizeof(ctypes.c_void_p) == 8 else 0x7FFFFFFF
system_dir = self.path_system.lower()
for proc in self.get_process_list():
if self._is_scan_cancel_requested():
return self._finish_scan_cancelled()
if proc["path"] and proc["path"] != "None":
targets.append(proc["path"])
pid = proc["pid"]
if pid <= 4:
continue
h_process = self.kernel32.OpenProcess(0x1000, False, pid)
if h_process:
try:
address = 0
mbi = MEMORY_BASIC_INFORMATION()
while address < max_address and not self._is_scan_cancel_requested() and self.kernel32.VirtualQueryEx(h_process, ctypes.c_void_p(address), ctypes.byref(mbi), ctypes.sizeof(mbi)):
if mbi.State == 0x1000 and mbi.Type == 0x1000000:
if self.psapi.GetMappedFileNameW(h_process, ctypes.c_void_p(address), buf, 1024):
raw_path = buf.value
if raw_path.startswith("\\"):
raw_path = self.device_path_to_drive(raw_path)
file_path = self.norm_path(raw_path)
if file_path and not file_path.lower().startswith(system_dir):
targets.append(file_path)
if mbi.RegionSize == 0:
break
address += mbi.RegionSize
finally:
self.kernel32.CloseHandle(h_process)
if self._is_scan_cancel_requested():
return self._finish_scan_cancelled()
if not self.start_scan(list(set(targets)), from_preparing=True):
return self._finish_scan_cancelled()
return True
elif method == "file":
targets = self.select_files()
if self._is_scan_cancel_requested():
return self._finish_scan_cancelled()
if targets:
if not self.start_scan(targets, from_preparing=True):
return self._finish_scan_cancelled()
return True
return self._finish_scan_cancelled()
elif method == "path":
targets = self.select_folder()
if self._is_scan_cancel_requested():
return self._finish_scan_cancelled()
if targets:
if not self.start_scan(targets, from_preparing=True):
return self._finish_scan_cancelled()
return True
return self._finish_scan_cancelled()
elif method == "full":
targets = [f"{chr(d)}:/" for d in range(65, 91) if os.path.exists(f"{chr(d)}:/")]
if self._is_scan_cancel_requested() or not self.start_scan(targets, from_preparing=True):
return self._finish_scan_cancelled()
return True
return self._finish_scan_cancelled()
except Exception as e:
self.write_log("WARN", "trigger_scan", detail=str(e), success=False)
return self._finish_scan_cancelled()
####################################################################################################
def _queue_virus_delete(self, file_path):
self._schedule_file_task("delete", file_path, self._retry_virus_delete, 0.5)
def _retry_virus_delete(self, file_path):
file_hash = self.calc_file_hash(file_path)
try:
with self.lock_file_ops:
if file_path in self.virus_lock:
self.lock_file(file_path, False)
target_key = os.path.normcase(self.norm_path(file_path, must_exist=False) or file_path)
for proc in self.get_process_list():
proc_path = proc.get("path")
if not proc_path or proc_path == "None":
continue
proc_key = os.path.normcase(self.norm_path(proc_path, must_exist=False) or proc_path)
if proc_key == target_key:
self.kill_process(proc["pid"])
try:
os.chmod(file_path, stat.S_IWRITE)
except Exception:
pass
os.remove(file_path)
except FileNotFoundError:
pass
except Exception as e:
self.lock_file(file_path, True, quiet=True)
self._queue_virus_delete(file_path)
self.write_log("INFO", "Virus Delete Deferred", source=file_path, detail=str(e))
return
self.remove_list_items("quarantine", [file_path])
with self.lock_virus:
target_key = os.path.normcase(self.norm_path(file_path, must_exist=False) or file_path)
self.virus_results = [
result for result in self.virus_results
if os.path.normcase(self.norm_path(result, must_exist=False) or result) != target_key
]
self.write_log("INFO", "Virus Delete", source=file_path, file_hash=file_hash, operate=True, success=True)
def solve_scan(self, file_paths):
deleted_paths = []
proc_map = {}
for proc in self.get_process_list():
if proc["path"] and proc["path"] != "None":
norm_p = self.norm_path(proc["path"], must_exist=False)
if norm_p:
proc_map.setdefault(os.path.normcase(norm_p), []).append(proc["pid"])
last_update = 0.0
with self.lock_virus:
deleted_set = set()
for raw_path in file_paths:
path = self.norm_path(raw_path, must_exist=False)
if not path:
continue
current_time = time.time()
if current_time - last_update >= 0.05:
if self._window:
self._window.evaluate_js(f"if(window.updateDeleteProgress) window.updateDeleteProgress({json.dumps(path.replace(os.sep, '/'))});")
last_update = current_time
try:
if path in self.virus_lock:
self.lock_file(path, False)
path_key = os.path.normcase(path)
if path_key in proc_map:
for pid in proc_map[path_key]:
self.kill_process(pid)
try:
os.chmod(path, stat.S_IWRITE)
except Exception:
pass
file_hash = self.calc_file_hash(path)
try:
os.remove(path)
except Exception as e:
self.lock_file(path, True, quiet=True)
self._queue_virus_delete(path)
self.write_log("INFO", "Virus Delete Deferred", source=path, detail=str(e))
continue
self.remove_list_items("quarantine", [path])
deleted_paths.append(raw_path)
deleted_set.add(path)
self.write_log("INFO", "Virus Delete", source=path, file_hash=file_hash, operate=True, success=True)
except Exception as e:
self.lock_file(path, True)
self.write_log("SCAN", "Virus Delete", source=path, file_hash=self.calc_file_hash(path), detail=str(e), operate=True, success=False)
if deleted_set:
self.virus_results = [p for p in self.virus_results if p not in deleted_set]
remaining = len(self.virus_results)
messages = {
"traditional_switch": f"剩餘 {remaining} 個病毒,已刪除 {len(deleted_paths)} 個檔案。",
"simplified_switch": f"剩余 {remaining} 个病毒,已删除 {len(deleted_paths)} 个文件。",
"english_switch": f"Remaining {remaining} viruses, deleted {len(deleted_paths)} files.",
"japanese_switch": f"残りのウイルス {remaining} 個、削除されたファイル {len(deleted_paths)} 個。",
"korean_switch": f"남은 바이러스 {remaining}개, 삭제된 파일 {len(deleted_paths)}개.",
"french_switch": f"Virus restants : {remaining}, fichiers supprimés : {len(deleted_paths)}.",
"spanish_switch": f"Virus restantes: {remaining}, archivos eliminados: {len(deleted_paths)}.",
"hindi_switch": f"शेष वायरस {remaining}, हटाए गए फ़ाइलें {len(deleted_paths)}.",
"arabic_switch": f"الفيروسات المتبقية {remaining}، تم حذف {len(deleted_paths)} ملفات.",
"russian_switch": f"Осталось вирусов: {remaining}, удалено файлов: {len(deleted_paths)}.",
"slovenian_switch": f"Preostalih virusov: {remaining}, izbrisanih datotek: {len(deleted_paths)}."
}
if self._window:
self._window.evaluate_js(f"if(window.finishScan) window.finishScan({json.dumps(messages)}, {remaining});")
return deleted_paths
def remove_virus_result(self, paths):
with self.lock_virus:
norm_paths = set(self.norm_path(p, must_exist=False) for p in paths)
self.virus_results = [p for p in self.virus_results if p not in norm_paths]
return len(self.virus_results)
####################################################################################################
def cloud_check(self, file_path):
norm_path = self.norm_path(file_path)
if not norm_path:
return
cache_key = os.path.normcase(norm_path)
with self.lock_file_ops:
if cache_key in self.cloud_pending:
return
self.cloud_pending.add(cache_key)
self.cloud_queue.put(norm_path)
def cloud_worker(self):
while True:
try:
file_path = self.cloud_queue.get()
cache_key = os.path.normcase(file_path)
try:
self.perform_cloud_scan(file_path)
finally:
with self.lock_file_ops:
self.cloud_pending.discard(cache_key)
self.cloud_queue.task_done()
except Exception:
pass
def perform_cloud_scan(self, file_path):
was_locked = False
try:
with self.lock_config:
if not self.pyas_config.get("cloud_switch", True):
return False
api_host, api_key, max_size = self.pyas_config.get("api_host"), self.pyas_config.get("api_key"), self.pyas_config.get("size", 256 * 1024 * 1024)
if not os.path.exists(file_path) or not os.path.isfile(file_path):
return False
with self.lock_file_ops:
if file_path in self.virus_lock:
self.lock_file(file_path, False)
was_locked = True
if os.path.getsize(file_path) > max_size:
if was_locked:
self.lock_file(file_path, True)
return False
file_hash = self.calc_file_hash(file_path)
success, sha256 = self.cloud.upload_file(file_path, api_host, api_key, file_hash=file_hash)
if was_locked:
self.lock_file(file_path, True)
was_locked = False
if not success:
self.write_log("WARN", "Cloud API", source=file_path, detail="Failed", success=False)
except Exception as e:
self.write_log("WARN", "perform_cloud_scan", detail=str(e), success=False)
finally:
if was_locked:
try:
self.lock_file(file_path, True)
except Exception:
pass
return False
+1407
View File
File diff suppressed because it is too large. Load diff
-1839
View File
File diff suppressed because it is too large. Load diff
-4109
View File
File diff suppressed because it is too large. Load diff
+12
View File
@@ -0,0 +1,12 @@
import pyinstaller_versionfile
pyinstaller_versionfile.create_versionfile(
output_file="versionfile.txt",
version='3.7.0.0',
company_name="PYAS Security",
file_description="PYAS Security Antivirus",
internal_name="PYAS",
legal_copyright="PYAS Security",
original_filename="PYAS.exe",
product_name="PYAS"
)
-10
View File
@@ -1,10 +0,0 @@
import pyinstaller_versionfile
pyinstaller_versionfile.create_versionfile(
output_file="versionfile.txt",
version='2.7.3',
company_name="PYAS Security",
file_description="Python Antivirus Software",
internal_name="PYAS",
legal_copyright="© PYAS Security",
original_filename="PYAS.exe",
product_name="PYAS")
+360
View File
@@ -0,0 +1,360 @@
#pragma once
#include <fltKernel.h>
#include <ntddk.h>
#include <ntdddisk.h>
#include <ntddscsi.h>
#include <ntstrsafe.h>
constexpr auto PYAS_PORT_NAME = L"\\PYAS_Output_Pipe";
constexpr auto MAX_PATH_LEN = 1024;
constexpr auto PYAS_POOL_TAG = 'SAYP';
constexpr auto PYAS_OB_ALTITUDE = L"320000.4101";
constexpr auto PYAS_CONNECTION_MAGIC = 0x53415950;
constexpr auto PYAS_CONNECTION_VERSION = 1;
#ifndef PROCESS_TERMINATE
#define PROCESS_TERMINATE (0x0001)
#endif
#ifndef PROCESS_CREATE_THREAD
#define PROCESS_CREATE_THREAD (0x0002)
#endif
#ifndef PROCESS_VM_OPERATION
#define PROCESS_VM_OPERATION (0x0008)
#endif
#ifndef PROCESS_VM_READ
#define PROCESS_VM_READ (0x0010)
#endif
#ifndef PROCESS_VM_WRITE
#define PROCESS_VM_WRITE (0x0020)
#endif
#ifndef PROCESS_DUP_HANDLE
#define PROCESS_DUP_HANDLE (0x0040)
#endif
#ifndef PROCESS_CREATE_PROCESS
#define PROCESS_CREATE_PROCESS (0x0080)
#endif
#ifndef PROCESS_SET_INFORMATION
#define PROCESS_SET_INFORMATION (0x0200)
#endif
#ifndef PROCESS_QUERY_INFORMATION
#define PROCESS_QUERY_INFORMATION (0x0400)
#endif
#ifndef PROCESS_SUSPEND_RESUME
#define PROCESS_SUSPEND_RESUME (0x0800)
#endif
#ifndef PROCESS_QUERY_LIMITED_INFORMATION
#define PROCESS_QUERY_LIMITED_INFORMATION (0x1000)
#endif
#ifndef PROCESS_SET_QUOTA
#define PROCESS_SET_QUOTA (0x0100)
#endif
#ifndef THREAD_TERMINATE
#define THREAD_TERMINATE (0x0001)
#endif
#ifndef THREAD_SUSPEND_RESUME
#define THREAD_SUSPEND_RESUME (0x0002)
#endif
#ifndef THREAD_SET_CONTEXT
#define THREAD_SET_CONTEXT (0x0010)
#endif
#ifndef THREAD_SET_INFORMATION
#define THREAD_SET_INFORMATION (0x0020)
#endif
#ifndef THREAD_SET_THREAD_TOKEN
#define THREAD_SET_THREAD_TOKEN (0x0080)
#endif
#ifndef THREAD_IMPERSONATE
#define THREAD_IMPERSONATE (0x0100)
#endif
#ifndef THREAD_DIRECT_IMPERSONATION
#define THREAD_DIRECT_IMPERSONATION (0x0200)
#endif
#ifndef POOL_FLAG_NON_PAGED
#define POOL_FLAG_NON_PAGED 0x0000000000000040UI64
#endif
#ifndef FSCTL_MANAGE_BYPASS_IO
#define FSCTL_MANAGE_BYPASS_IO CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 188, METHOD_NEITHER, FILE_ANY_ACCESS)
typedef enum _FS_BPIO_OPERATIONS {
FS_BPIO_OP_ENABLE = 1,
FS_BPIO_OP_DISABLE = 2,
FS_BPIO_OP_QUERY = 3,
FS_BPIO_OP_VOLUME_STACK_PAUSE = 4,
FS_BPIO_OP_VOLUME_STACK_RESUME = 5,
FS_BPIO_OP_STREAM_PAUSE = 6,
FS_BPIO_OP_STREAM_RESUME = 7,
FS_BPIO_OP_GET_INFO = 8
} FS_BPIO_OPERATIONS;
typedef struct _FS_BPIO_INPUT {
FS_BPIO_OPERATIONS Operation;
ULONG InFlags;
ULONGLONG Reserved1;
ULONGLONG Reserved2;
} FS_BPIO_INPUT, * PFS_BPIO_INPUT;
typedef struct _FS_BPIO_OUTPUT {
FS_BPIO_OPERATIONS Operation;
ULONG OutFlags;
ULONGLONG Reserved1;
ULONGLONG Reserved2;
NTSTATUS Status;
} FS_BPIO_OUTPUT, * PFS_BPIO_OUTPUT;
#endif
typedef enum _PYAS_DRIVER_STATE {
PyasDriverStateCold = 0,
PyasDriverStateStarting = 1,
PyasDriverStateRunning = 2,
PyasDriverStateStopping = 3,
PyasDriverStateStopRetry = 4,
PyasDriverStateStopped = 5
} PYAS_DRIVER_STATE;
typedef struct _PYAS_MESSAGE {
ULONG MessageCode;
ULONG ProcessId;
WCHAR Path[MAX_PATH_LEN];
} PYAS_MESSAGE, * PPYAS_MESSAGE;
typedef enum _PYAS_COMMAND {
PyasCommandAddWhitelist = 1,
PyasCommandRemoveWhitelist = 2,
PyasCommandLoadRuleFile = 3,
PyasCommandClearRules = 4,
PyasCommandAuthorizeUnload = 5,
PyasCommandRevokeUnload = 6,
PyasCommandQueryState = 7
} PYAS_COMMAND;
typedef struct _PYAS_USER_MESSAGE {
ULONG Command;
WCHAR Path[MAX_PATH_LEN];
} PYAS_USER_MESSAGE, * PPYAS_USER_MESSAGE;
typedef struct _PYAS_CONNECTION_CONTEXT {
ULONG Size;
ULONG Version;
ULONG Magic;
ULONG ProcessId;
} PYAS_CONNECTION_CONTEXT, * PPYAS_CONNECTION_CONTEXT;
typedef struct _DRIVER_DATA {
PDRIVER_OBJECT DriverObject;
PFLT_FILTER FilterHandle;
PFLT_PORT ServerPort;
PFLT_PORT ClientPort;
PEPROCESS PyasProcess;
ULONG PyasPid;
LARGE_INTEGER Cookie;
KSPIN_LOCK PortMutex;
KSPIN_LOCK TrackerMutex;
KSPIN_LOCK PidLock;
BOOLEAN Initialized;
volatile LONG DriverState;
volatile LONG UnloadAuthorized;
volatile LONG PortStopping;
volatile LONG ClientCloseActive;
EX_RUNDOWN_REF PortRundown;
KEVENT CleanupCompleteEvent;
PVOID ObRegistrationHandle;
UNICODE_STRING ClientImagePath;
WCHAR ClientImagePathBuffer[MAX_PATH_LEN];
} DRIVER_DATA, * PDRIVER_DATA;
typedef struct _RULE_NODE {
struct _RULE_NODE* Next;
UNICODE_STRING Pattern;
} RULE_NODE, * PRULE_NODE;
typedef enum _RULE_CATEGORY {
RuleCategoryProcess,
RuleCategoryFile,
RuleCategoryRegistry,
RuleCategoryDevice,
RuleCategoryMemory,
RuleCategoryThread,
RuleCategoryUnknown
} RULE_CATEGORY;
#define OP_WRITE 0x00000001
#define OP_DELETE 0x00000002
#define OP_CREATE 0x00000004
#define OP_EXECUTE 0x00000008
#define OP_RENAME 0x00000010
#define OP_IOCTL 0x00000020
#define OP_VM_READ 0x00000040
#define OP_VM_WRITE 0x00000080
#define OP_TERMINATE 0x00000100
#define OP_SUSPEND_RESUME 0x00000200
#define OP_DUP_HANDLE 0x00000400
#define OP_SET_INFORMATION 0x00000800
#define OP_VM_OPERATION 0x00001000
#define OP_CREATE_THREAD 0x00002000
#define OP_THREAD_SET_CONTEXT 0x00004000
#define OP_THREAD_SET_TOKEN 0x00008000
#define OP_CREATE_PROCESS 0x00010000
#define OP_IMAGE_LOAD 0x00020000
#define OP_IMPERSONATE 0x00040000
#define PYAS_HANDLE_CREATE 0x00000001
#define PYAS_HANDLE_DUPLICATE 0x00000002
#define PYAS_OBJECT_PROCESS 0x00000001
#define PYAS_OBJECT_THREAD 0x00000002
#define PYAS_MEMORY_PRIVATE 0x00000001
#define PYAS_MEMORY_MAPPED 0x00000002
#define PYAS_MEMORY_IMAGE 0x00000004
#define PYAS_PROTECT_EXECUTE 0x00000001
#define PYAS_PROTECT_EXECUTE_WRITE 0x00000002
typedef enum _RULE_TRI_STATE {
RuleTriAny = 0,
RuleTriTrue = 1,
RuleTriFalse = 2
} RULE_TRI_STATE;
typedef enum _RULE_OPERATION_MATCH {
RuleOperationAny = 0,
RuleOperationAll = 1
} RULE_OPERATION_MATCH;
typedef struct _DYNAMIC_RULE {
ULONG Code;
BOOLEAN Kill;
ULONG Priority;
RULE_CATEGORY Category;
ULONG Operations;
RULE_OPERATION_MATCH OperationMatch;
BOOLEAN Invalid;
PRULE_NODE Initiator;
PRULE_NODE InitiatorExclude;
PRULE_NODE InitiatorParent;
PRULE_NODE InitiatorParentExclude;
PRULE_NODE InitiatorProcessTree;
PRULE_NODE InitiatorProcessTreeExclude;
PRULE_NODE Target;
PRULE_NODE TargetExclude;
PRULE_NODE TargetProcessTree;
PRULE_NODE TargetProcessTreeExclude;
PRULE_NODE Creator;
PRULE_NODE CreatorExclude;
PRULE_NODE Parent;
PRULE_NODE ParentExclude;
PRULE_NODE CommandLine;
PRULE_NODE CommandLineExclude;
PRULE_NODE Extensions;
ULONG HandleTypes;
ULONG ObjectTypes;
ULONG MinimumRiskScore;
ULONG MaximumRiskScore;
ULONG ThreadMemoryTypes;
ULONG ThreadMemoryProtections;
ULONGLONG MinimumRegionSize;
ULONGLONG MaximumRegionSize;
RULE_TRI_STATE ParentMismatch;
RULE_TRI_STATE FileOpenNameAvailable;
RULE_TRI_STATE SubsystemProcess;
ULONG Threshold;
ULONG TimeWindow;
struct _DYNAMIC_RULE* Next;
} DYNAMIC_RULE, * PDYNAMIC_RULE;
BOOLEAN EvaluateDeviceRule(HANDLE ProcessId, PULONG OutCode, PBOOLEAN OutKill);
extern DRIVER_DATA GlobalData;
FLT_PREOP_CALLBACK_STATUS ProtectFile_PreCreate(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext);
FLT_PREOP_CALLBACK_STATUS ProtectFile_PreWrite(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext);
FLT_PREOP_CALLBACK_STATUS ProtectFile_PreSetInfo(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext);
FLT_PREOP_CALLBACK_STATUS ProtectFile_FileSystemControl(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext);
FLT_PREOP_CALLBACK_STATUS ProtectFile_SetSecurity(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext);
FLT_PREOP_CALLBACK_STATUS ProtectBoot_PreDeviceControl(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext);
NTSTATUS InitializeRegistryProtection(PDRIVER_OBJECT DriverObject);
NTSTATUS UninitializeRegistryProtection();
NTSTATUS InitializeProcessProtection();
NTSTATUS UninitializeProcessProtection();
BOOLEAN GetProcessRelation(HANDLE ProcessId, PHANDLE ParentProcessId, PHANDLE CreatorProcessId);
NTSTATUS InitializeMemoryProtection(PDRIVER_OBJECT DriverObject);
NTSTATUS UninitializeMemoryProtection(BOOLEAN WaitWithoutTimeout);
NTSTATUS LoadRulesFromDisk(PUNICODE_STRING RegistryPath);
VOID UnloadRules();
NTSTATUS InitializeRulesEngine();
VOID UninitializeRulesEngine();
VOID AddDynamicWhitelist(PUNICODE_STRING RuleStr);
VOID RemoveDynamicWhitelist(PUNICODE_STRING RuleStr);
NTSTATUS LoadRuleFile(PCUNICODE_STRING FilePath);
VOID ClearDynamicRules();
VOID ProcessNotifyCallbackEx(PEPROCESS Process, HANDLE ProcessId, PPS_CREATE_NOTIFY_INFO CreateInfo);
NTSTATUS GetProcessImageName(HANDLE ProcessId, PUNICODE_STRING* ImageName);
ULONG SafeGetPyasPid();
VOID SafeSetPyasPid(ULONG Pid);
BOOLEAN IsProcessTrusted(HANDLE ProcessId);
BOOLEAN WildcardMatch(PCWSTR Pattern, PCWSTR String, USHORT StringLengthBytes);
BOOLEAN EvaluateProcessCreateRule(
HANDLE CreatorPid,
HANDLE ParentPid,
HANDLE ProcessId,
PCUNICODE_STRING TargetPath,
PCUNICODE_STRING CommandLine,
BOOLEAN FileOpenNameAvailable,
BOOLEAN IsSubsystemProcess,
PULONG OutCode,
PBOOLEAN OutKill
);
BOOLEAN EvaluateProcessAccessRule(
HANDLE SourcePid,
HANDLE TargetPid,
ULONG RequestedOperations,
ULONG HandleType,
ULONG ObjectType,
PULONG DeniedOperations,
PULONG OutCode,
PBOOLEAN OutKill
);
BOOLEAN EvaluateThreadRule(
HANDLE SourcePid,
HANDLE TargetPid,
PVOID StartAddress,
ULONG MemoryType,
ULONG MemoryProtection,
SIZE_T RegionSize,
PULONG OutCode,
PBOOLEAN OutKill
);
BOOLEAN EvaluateImageLoadRule(HANDLE ProcessId, PCUNICODE_STRING ImagePath, PIMAGE_INFO ImageInfo, PULONG OutCode, PBOOLEAN OutKill);
BOOLEAN EvaluateProcessRule(HANDLE ProcessId, PCUNICODE_STRING TargetPath, PCUNICODE_STRING CommandLine, PULONG OutCode, PBOOLEAN OutKill);
BOOLEAN EvaluateFileRule(HANDLE ProcessId, PCUNICODE_STRING TargetPath, ULONG Operation, PVOID WriteBuffer, ULONG WriteLength, PULONG OutCode, PBOOLEAN OutKill);
BOOLEAN EvaluateRegistryRule(HANDLE ProcessId, PCUNICODE_STRING KeyName, ULONG Operation, PULONG OutCode, PBOOLEAN OutKill);
BOOLEAN EvaluateMemoryRule(HANDLE SourcePid, HANDLE TargetPid, ULONG Operation, PULONG OutCode, PBOOLEAN OutKill);
BOOLEAN EvaluateProcessHandleRule(HANDLE SourcePid, HANDLE TargetPid, ULONG Operation, PULONG OutCode, PBOOLEAN OutKill);
VOID QueueRuleProcessTermination(HANDLE ProcessId, BOOLEAN Kill);
NTSTATUS SendMessageToUser(ULONG Code, ULONG Pid, PWCHAR Path, USHORT PathSize);
FORCEINLINE PVOID PyasAllocate(SIZE_T Size) {
return ExAllocatePool2(POOL_FLAG_NON_PAGED, Size, PYAS_POOL_TAG);
}
FORCEINLINE VOID PyasFree(PVOID Ptr) {
if (Ptr) ExFreePoolWithTag(Ptr, PYAS_POOL_TAG);
}
+728
View File
@@ -0,0 +1,728 @@
#include "DriverCommon.h"
DRIVER_DATA GlobalData;
static BOOLEAN g_ProcessNotifyRegistered = FALSE;
static BOOLEAN g_ProcessProtectionInitialized = FALSE;
static BOOLEAN g_RegistryProtectionInitialized = FALSE;
static BOOLEAN g_RulesEngineInitialized = FALSE;
static NTSTATUS InstanceSetup(
PCFLT_RELATED_OBJECTS FltObjects,
FLT_INSTANCE_SETUP_FLAGS Flags,
DEVICE_TYPE VolumeDeviceType,
FLT_FILESYSTEM_TYPE VolumeFilesystemType
) {
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(Flags);
UNREFERENCED_PARAMETER(VolumeDeviceType);
UNREFERENCED_PARAMETER(VolumeFilesystemType);
return STATUS_SUCCESS;
}
static NTSTATUS InstanceQueryTeardown(
PCFLT_RELATED_OBJECTS FltObjects,
FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
) {
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(Flags);
return STATUS_SUCCESS;
}
static VOID InstanceTeardownStart(
PCFLT_RELATED_OBJECTS FltObjects,
FLT_INSTANCE_TEARDOWN_FLAGS Flags
) {
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(Flags);
}
static VOID InstanceTeardownComplete(
PCFLT_RELATED_OBJECTS FltObjects,
FLT_INSTANCE_TEARDOWN_FLAGS Flags
) {
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(Flags);
}
static NTSTATUS SelectFailure(NTSTATUS CurrentStatus, NTSTATUS CandidateStatus) {
if (!NT_SUCCESS(CurrentStatus)) return CurrentStatus;
return CandidateStatus;
}
static NTSTATUS LoadClientIdentityFromRegistry(PUNICODE_STRING RegistryPath) {
if (!RegistryPath || !RegistryPath->Buffer || !GlobalData.ClientImagePath.Buffer) return STATUS_INVALID_PARAMETER;
UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"ClientImagePath");
OBJECT_ATTRIBUTES ObjectAttributes;
InitializeObjectAttributes(&ObjectAttributes, RegistryPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
HANDLE KeyHandle = NULL;
NTSTATUS Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
if (!NT_SUCCESS(Status)) return Status;
ULONG ResultLength = 0;
Status = ZwQueryValueKey(KeyHandle, &ValueName, KeyValuePartialInformation, NULL, 0, &ResultLength);
if (Status != STATUS_BUFFER_TOO_SMALL && Status != STATUS_BUFFER_OVERFLOW) {
ZwClose(KeyHandle);
return Status;
}
if (ResultLength == 0 || ResultLength > FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + GlobalData.ClientImagePath.MaximumLength) {
ZwClose(KeyHandle);
return STATUS_NAME_TOO_LONG;
}
PKEY_VALUE_PARTIAL_INFORMATION Information = (PKEY_VALUE_PARTIAL_INFORMATION)PyasAllocate(ResultLength);
if (!Information) {
ZwClose(KeyHandle);
return STATUS_INSUFFICIENT_RESOURCES;
}
Status = ZwQueryValueKey(KeyHandle, &ValueName, KeyValuePartialInformation, Information, ResultLength, &ResultLength);
ZwClose(KeyHandle);
if (NT_SUCCESS(Status)) {
if ((Information->Type != REG_SZ && Information->Type != REG_EXPAND_SZ) ||
Information->DataLength < sizeof(WCHAR) ||
(Information->DataLength % sizeof(WCHAR)) != 0 ||
Information->DataLength > GlobalData.ClientImagePath.MaximumLength - sizeof(WCHAR)) {
Status = STATUS_INVALID_PARAMETER;
}
else {
RtlZeroMemory(GlobalData.ClientImagePath.Buffer, GlobalData.ClientImagePath.MaximumLength);
RtlCopyMemory(GlobalData.ClientImagePath.Buffer, Information->Data, Information->DataLength);
USHORT CharacterCount = (USHORT)(Information->DataLength / sizeof(WCHAR));
while (CharacterCount > 0 && GlobalData.ClientImagePath.Buffer[CharacterCount - 1] == L'\0') {
CharacterCount--;
}
if (CharacterCount == 0) {
Status = STATUS_INVALID_PARAMETER;
}
else {
GlobalData.ClientImagePath.Buffer[CharacterCount] = L'\0';
GlobalData.ClientImagePath.Length = CharacterCount * sizeof(WCHAR);
Status = STATUS_SUCCESS;
}
}
}
PyasFree(Information);
return Status;
}
static BOOLEAN IsAuthorizedClientConnection(PVOID ConnectionContext, ULONG SizeOfContext) {
if (!ConnectionContext || SizeOfContext < sizeof(PYAS_CONNECTION_CONTEXT)) return FALSE;
if (!GlobalData.ClientImagePath.Buffer || GlobalData.ClientImagePath.Length == 0) return FALSE;
if (KeGetCurrentIrql() != PASSIVE_LEVEL) return FALSE;
PYAS_CONNECTION_CONTEXT Context = { 0 };
__try {
RtlCopyMemory(&Context, ConnectionContext, sizeof(Context));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return FALSE;
}
if (Context.Size < sizeof(PYAS_CONNECTION_CONTEXT)) return FALSE;
if (Context.Version != PYAS_CONNECTION_VERSION) return FALSE;
if (Context.Magic != PYAS_CONNECTION_MAGIC) return FALSE;
if (Context.ProcessId != (ULONG)(ULONG_PTR)PsGetCurrentProcessId()) return FALSE;
PUNICODE_STRING ImagePath = NULL;
NTSTATUS Status = SeLocateProcessImageName(PsGetCurrentProcess(), &ImagePath);
if (!NT_SUCCESS(Status) || !ImagePath || !ImagePath->Buffer) {
if (ImagePath) ExFreePool(ImagePath);
return FALSE;
}
BOOLEAN Authorized = RtlEqualUnicodeString(ImagePath, &GlobalData.ClientImagePath, TRUE);
ExFreePool(ImagePath);
return Authorized;
}
static NTSTATUS UnregisterRuntimeCallbacksPass(BOOLEAN WaitWithoutTimeout) {
NTSTATUS Status = STATUS_SUCCESS;
NTSTATUS MemoryStatus = UninitializeMemoryProtection(WaitWithoutTimeout);
if (!NT_SUCCESS(MemoryStatus)) {
Status = SelectFailure(Status, MemoryStatus);
}
if (g_ProcessNotifyRegistered) {
NTSTATUS ProcessNotifyStatus = PsSetCreateProcessNotifyRoutineEx(
ProcessNotifyCallbackEx,
TRUE
);
if (NT_SUCCESS(ProcessNotifyStatus) || ProcessNotifyStatus == STATUS_INVALID_PARAMETER) {
g_ProcessNotifyRegistered = FALSE;
}
else {
Status = SelectFailure(Status, ProcessNotifyStatus);
}
}
if (!g_ProcessNotifyRegistered && g_ProcessProtectionInitialized) {
NTSTATUS ProcessStatus = UninitializeProcessProtection();
if (NT_SUCCESS(ProcessStatus)) {
g_ProcessProtectionInitialized = FALSE;
}
else {
Status = SelectFailure(Status, ProcessStatus);
}
}
if (g_RegistryProtectionInitialized) {
NTSTATUS RegistryStatus = UninitializeRegistryProtection();
if (NT_SUCCESS(RegistryStatus)) {
g_RegistryProtectionInitialized = FALSE;
}
else {
Status = SelectFailure(Status, RegistryStatus);
}
}
return Status;
}
static NTSTATUS UnregisterRuntimeCallbacks(BOOLEAN WaitWithoutTimeout) {
for (;;) {
NTSTATUS Status = UnregisterRuntimeCallbacksPass(WaitWithoutTimeout);
if (NT_SUCCESS(Status) || !WaitWithoutTimeout) return Status;
LARGE_INTEGER Delay;
Delay.QuadPart = -(10LL * 10 * 1000);
KeDelayExecutionThread(KernelMode, FALSE, &Delay);
}
}
static PEPROCESS DetachConnectedProcessReference(PEPROCESS ExpectedProcess) {
PEPROCESS Process = NULL;
KIRQL OldIrql;
KeAcquireSpinLock(&GlobalData.PortMutex, &OldIrql);
if (!ExpectedProcess || GlobalData.PyasProcess == ExpectedProcess) {
Process = GlobalData.PyasProcess;
GlobalData.PyasProcess = NULL;
}
KeReleaseSpinLock(&GlobalData.PortMutex, OldIrql);
return Process;
}
static VOID ReleaseConnectedProcessReference() {
PEPROCESS Process = DetachConnectedProcessReference(NULL);
SafeSetPyasPid(0);
InterlockedExchange(&GlobalData.UnloadAuthorized, 0);
if (Process) {
ObDereferenceObject(Process);
}
}
static VOID CloseCurrentClientPort() {
if (InterlockedCompareExchange(&GlobalData.ClientCloseActive, 1, 0) != 0) return;
PFLT_FILTER FilterHandle = NULL;
PFLT_PORT ClientPort = NULL;
KIRQL OldIrql;
KeAcquireSpinLock(&GlobalData.PortMutex, &OldIrql);
FilterHandle = GlobalData.FilterHandle;
ClientPort = GlobalData.ClientPort;
GlobalData.ClientPort = NULL;
KeReleaseSpinLock(&GlobalData.PortMutex, OldIrql);
if (FilterHandle && ClientPort) {
FltCloseClientPort(FilterHandle, &ClientPort);
}
InterlockedExchange(&GlobalData.ClientCloseActive, 0);
}
static VOID WaitForClientPortClose() {
LARGE_INTEGER Delay;
Delay.QuadPart = -(10LL * 1000);
while (InterlockedCompareExchange(&GlobalData.ClientCloseActive, 0, 0) != 0) {
KeDelayExecutionThread(KernelMode, FALSE, &Delay);
}
}
static VOID ReleaseFilterResources() {
InterlockedExchange(&GlobalData.PortStopping, 1);
if (GlobalData.ServerPort) {
PFLT_PORT ServerPort = GlobalData.ServerPort;
GlobalData.ServerPort = NULL;
FltCloseCommunicationPort(ServerPort);
}
CloseCurrentClientPort();
WaitForClientPortClose();
ExWaitForRundownProtectionRelease(&GlobalData.PortRundown);
if (GlobalData.FilterHandle) {
PFLT_FILTER FilterHandle = GlobalData.FilterHandle;
FltUnregisterFilter(FilterHandle);
GlobalData.FilterHandle = NULL;
}
ReleaseConnectedProcessReference();
}
static NTSTATUS CleanupDriverState(BOOLEAN WaitWithoutTimeout) {
NTSTATUS Status = UnregisterRuntimeCallbacks(WaitWithoutTimeout);
if (!NT_SUCCESS(Status)) return Status;
GlobalData.Initialized = FALSE;
ReleaseFilterResources();
if (g_RulesEngineInitialized) {
UnloadRules();
UninitializeRulesEngine();
g_RulesEngineInitialized = FALSE;
}
return STATUS_SUCCESS;
}
static NTSTATUS BeginUnload(BOOLEAN MandatoryUnload) {
for (;;) {
LONG State = InterlockedCompareExchange(
&GlobalData.DriverState,
PyasDriverStateCold,
PyasDriverStateCold
);
if (State == PyasDriverStateStopped) return STATUS_SUCCESS;
if (State == PyasDriverStateStopping) {
LARGE_INTEGER Timeout;
PLARGE_INTEGER TimeoutPointer = NULL;
if (!MandatoryUnload) {
Timeout.QuadPart = -(2LL * 10 * 1000 * 1000);
TimeoutPointer = &Timeout;
}
NTSTATUS WaitStatus = KeWaitForSingleObject(
&GlobalData.CleanupCompleteEvent,
Executive,
KernelMode,
FALSE,
TimeoutPointer
);
if (!MandatoryUnload && WaitStatus == STATUS_TIMEOUT) {
return STATUS_DEVICE_BUSY;
}
if (!NT_SUCCESS(WaitStatus)) return WaitStatus;
continue;
}
if (State != PyasDriverStateRunning && State != PyasDriverStateStopRetry) {
return STATUS_DEVICE_NOT_READY;
}
if (!MandatoryUnload && InterlockedCompareExchange(&GlobalData.UnloadAuthorized, 0, 1) != 1) {
return STATUS_ACCESS_DENIED;
}
if (MandatoryUnload) {
InterlockedExchange(&GlobalData.UnloadAuthorized, 0);
}
if (InterlockedCompareExchange(
&GlobalData.DriverState,
PyasDriverStateStopping,
State
) != State) {
if (!MandatoryUnload) return STATUS_DEVICE_BUSY;
continue;
}
KeClearEvent(&GlobalData.CleanupCompleteEvent);
return STATUS_SUCCESS;
}
}
static NTSTATUS DriverUnload(FLT_FILTER_UNLOAD_FLAGS Flags) {
BOOLEAN MandatoryUnload = FlagOn(Flags, FLTFL_FILTER_UNLOAD_MANDATORY) ? TRUE : FALSE;
NTSTATUS Status = BeginUnload(MandatoryUnload);
if (!NT_SUCCESS(Status)) return Status;
LONG State = InterlockedCompareExchange(
&GlobalData.DriverState,
PyasDriverStateCold,
PyasDriverStateCold
);
if (State == PyasDriverStateStopped) return STATUS_SUCCESS;
Status = CleanupDriverState(MandatoryUnload);
InterlockedExchange(
&GlobalData.DriverState,
NT_SUCCESS(Status) ? PyasDriverStateStopped : PyasDriverStateStopRetry
);
KeSetEvent(&GlobalData.CleanupCompleteEvent, IO_NO_INCREMENT, FALSE);
return Status;
}
static NTSTATUS PortMessage(
PVOID PortCookie,
PVOID InputBuffer,
ULONG InputBufferLength,
PVOID OutputBuffer,
ULONG OutputBufferLength,
PULONG ReturnOutputBufferLength
) {
if (ReturnOutputBufferLength) *ReturnOutputBufferLength = 0;
if (InterlockedCompareExchange(&GlobalData.PortStopping, 0, 0) != 0) {
return STATUS_DELETE_PENDING;
}
if (!ExAcquireRundownProtection(&GlobalData.PortRundown)) {
return STATUS_DELETE_PENDING;
}
NTSTATUS Status = STATUS_SUCCESS;
PYAS_USER_MESSAGE Message = { 0 };
UNICODE_STRING Path = { 0 };
LONG DriverState = PyasDriverStateCold;
ULONG StateValue = PyasDriverStateCold;
if (!PortCookie || PortCookie != GlobalData.PyasProcess) {
Status = STATUS_ACCESS_DENIED;
goto Exit;
}
if (!InputBuffer || InputBufferLength < sizeof(PYAS_USER_MESSAGE)) {
Status = STATUS_INVALID_PARAMETER;
goto Exit;
}
__try {
RtlCopyMemory(&Message, InputBuffer, sizeof(Message));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
Status = GetExceptionCode();
goto Exit;
}
Message.Path[MAX_PATH_LEN - 1] = L'\0';
if (Message.Command == PyasCommandQueryState) {
if (!OutputBuffer || OutputBufferLength < sizeof(ULONG) || !ReturnOutputBufferLength) {
Status = STATUS_BUFFER_TOO_SMALL;
goto Exit;
}
StateValue = (ULONG)InterlockedCompareExchange(
&GlobalData.DriverState,
PyasDriverStateCold,
PyasDriverStateCold
);
__try {
*(PULONG)OutputBuffer = StateValue;
*ReturnOutputBufferLength = sizeof(ULONG);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
Status = GetExceptionCode();
}
goto Exit;
}
if (Message.Command == PyasCommandAuthorizeUnload) {
DriverState = InterlockedCompareExchange(
&GlobalData.DriverState,
PyasDriverStateCold,
PyasDriverStateCold
);
if (DriverState != PyasDriverStateRunning && DriverState != PyasDriverStateStopRetry) {
Status = STATUS_DEVICE_NOT_READY;
goto Exit;
}
InterlockedExchange(&GlobalData.UnloadAuthorized, 1);
goto Exit;
}
if (Message.Command == PyasCommandRevokeUnload) {
InterlockedExchange(&GlobalData.UnloadAuthorized, 0);
goto Exit;
}
if (Message.Command < PyasCommandAddWhitelist || Message.Command > PyasCommandClearRules) {
Status = STATUS_INVALID_DEVICE_REQUEST;
goto Exit;
}
DriverState = InterlockedCompareExchange(
&GlobalData.DriverState,
PyasDriverStateCold,
PyasDriverStateCold
);
if (DriverState != PyasDriverStateRunning) {
Status = STATUS_DEVICE_NOT_READY;
goto Exit;
}
RtlInitUnicodeString(&Path, Message.Path);
if (Message.Command == PyasCommandAddWhitelist) {
if (Path.Length == 0) {
Status = STATUS_INVALID_PARAMETER;
goto Exit;
}
AddDynamicWhitelist(&Path);
goto Exit;
}
if (Message.Command == PyasCommandRemoveWhitelist) {
if (Path.Length == 0) {
Status = STATUS_INVALID_PARAMETER;
goto Exit;
}
RemoveDynamicWhitelist(&Path);
goto Exit;
}
if (Message.Command == PyasCommandLoadRuleFile) {
if (Path.Length == 0) {
Status = STATUS_INVALID_PARAMETER;
goto Exit;
}
Status = LoadRuleFile(&Path);
goto Exit;
}
ClearDynamicRules();
Exit:
ExReleaseRundownProtection(&GlobalData.PortRundown);
return Status;
}
static NTSTATUS PortConnect(
PFLT_PORT ClientPort,
PVOID ServerPortCookie,
PVOID ConnectionContext,
ULONG SizeOfContext,
PVOID* ConnectionPortCookie
) {
UNREFERENCED_PARAMETER(ServerPortCookie);
if (!ConnectionPortCookie) return STATUS_INVALID_PARAMETER;
if (!IsAuthorizedClientConnection(ConnectionContext, SizeOfContext)) return STATUS_ACCESS_DENIED;
*ConnectionPortCookie = NULL;
if (InterlockedCompareExchange(&GlobalData.PortStopping, 0, 0) != 0) {
return STATUS_DELETE_PENDING;
}
LONG DriverState = InterlockedCompareExchange(
&GlobalData.DriverState,
PyasDriverStateCold,
PyasDriverStateCold
);
if (DriverState != PyasDriverStateRunning && DriverState != PyasDriverStateStopRetry) {
return STATUS_DEVICE_NOT_READY;
}
if (!ExAcquireRundownProtection(&GlobalData.PortRundown)) {
return STATUS_DELETE_PENDING;
}
PEPROCESS ConnectingProcess = PsGetCurrentProcess();
ObReferenceObject(ConnectingProcess);
NTSTATUS Status = STATUS_SUCCESS;
KIRQL OldIrql;
KeAcquireSpinLock(&GlobalData.PortMutex, &OldIrql);
DriverState = InterlockedCompareExchange(
&GlobalData.DriverState,
PyasDriverStateCold,
PyasDriverStateCold
);
if (InterlockedCompareExchange(&GlobalData.PortStopping, 0, 0) != 0) {
Status = STATUS_DELETE_PENDING;
}
else if (DriverState != PyasDriverStateRunning && DriverState != PyasDriverStateStopRetry) {
Status = STATUS_DEVICE_NOT_READY;
}
else if (GlobalData.ClientPort || GlobalData.PyasProcess) {
Status = STATUS_DEVICE_BUSY;
}
else {
GlobalData.ClientPort = ClientPort;
GlobalData.PyasProcess = ConnectingProcess;
*ConnectionPortCookie = ConnectingProcess;
}
KeReleaseSpinLock(&GlobalData.PortMutex, OldIrql);
if (!NT_SUCCESS(Status)) {
ObDereferenceObject(ConnectingProcess);
ExReleaseRundownProtection(&GlobalData.PortRundown);
return Status;
}
SafeSetPyasPid((ULONG)(ULONG_PTR)PsGetCurrentProcessId());
InterlockedExchange(&GlobalData.UnloadAuthorized, 0);
ExReleaseRundownProtection(&GlobalData.PortRundown);
return STATUS_SUCCESS;
}
static VOID PortDisconnect(PVOID ConnectionCookie) {
if (!ConnectionCookie) return;
PEPROCESS Process = DetachConnectedProcessReference((PEPROCESS)ConnectionCookie);
if (!Process) return;
CloseCurrentClientPort();
InterlockedExchange(&GlobalData.UnloadAuthorized, 0);
SafeSetPyasPid(0);
ObDereferenceObject(Process);
}
CONST FLT_OPERATION_REGISTRATION Callbacks[] = {
{ IRP_MJ_CREATE, 0, ProtectFile_PreCreate, NULL },
{ IRP_MJ_WRITE, 0, ProtectFile_PreWrite, NULL },
{ IRP_MJ_SET_INFORMATION, 0, ProtectFile_PreSetInfo, NULL },
{ IRP_MJ_SET_SECURITY, 0, ProtectFile_SetSecurity, NULL },
{ IRP_MJ_FILE_SYSTEM_CONTROL, 0, ProtectFile_FileSystemControl, NULL },
{ IRP_MJ_DEVICE_CONTROL, 0, ProtectBoot_PreDeviceControl, NULL },
{ IRP_MJ_OPERATION_END }
};
CONST FLT_REGISTRATION FilterRegistration = {
sizeof(FLT_REGISTRATION),
FLT_REGISTRATION_VERSION,
0,
NULL,
Callbacks,
DriverUnload,
InstanceSetup,
InstanceQueryTeardown,
InstanceTeardownStart,
InstanceTeardownComplete,
NULL,
NULL,
NULL
};
extern "C" NTSTATUS DriverEntry(
PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath
) {
RtlZeroMemory(&GlobalData, sizeof(GlobalData));
GlobalData.DriverObject = DriverObject;
GlobalData.ClientImagePath.Buffer = GlobalData.ClientImagePathBuffer;
GlobalData.ClientImagePath.MaximumLength = sizeof(GlobalData.ClientImagePathBuffer);
KeInitializeSpinLock(&GlobalData.PortMutex);
KeInitializeSpinLock(&GlobalData.TrackerMutex);
KeInitializeSpinLock(&GlobalData.PidLock);
ExInitializeRundownProtection(&GlobalData.PortRundown);
KeInitializeEvent(&GlobalData.CleanupCompleteEvent, NotificationEvent, FALSE);
InterlockedExchange(&GlobalData.PortStopping, 0);
InterlockedExchange(&GlobalData.ClientCloseActive, 0);
InterlockedExchange(&GlobalData.DriverState, PyasDriverStateStarting);
NTSTATUS Status = STATUS_SUCCESS;
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
Status = InitializeRulesEngine();
if (!NT_SUCCESS(Status)) {
InterlockedExchange(&GlobalData.DriverState, PyasDriverStateStopped);
KeSetEvent(&GlobalData.CleanupCompleteEvent, IO_NO_INCREMENT, FALSE);
return Status;
}
g_RulesEngineInitialized = TRUE;
Status = LoadRulesFromDisk(RegistryPath);
if (!NT_SUCCESS(Status)) goto Failure;
Status = LoadClientIdentityFromRegistry(RegistryPath);
if (!NT_SUCCESS(Status)) goto Failure;
Status = FltRegisterFilter(DriverObject, &FilterRegistration, &GlobalData.FilterHandle);
if (!NT_SUCCESS(Status)) goto Failure;
Status = FltBuildDefaultSecurityDescriptor(&SecurityDescriptor, FLT_PORT_ALL_ACCESS);
if (!NT_SUCCESS(Status)) goto Failure;
{
UNICODE_STRING PortName;
RtlInitUnicodeString(&PortName, PYAS_PORT_NAME);
OBJECT_ATTRIBUTES ObjectAttributes;
InitializeObjectAttributes(
&ObjectAttributes,
&PortName,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
NULL,
SecurityDescriptor
);
Status = FltCreateCommunicationPort(
GlobalData.FilterHandle,
&GlobalData.ServerPort,
&ObjectAttributes,
NULL,
PortConnect,
PortDisconnect,
PortMessage,
1
);
}
FltFreeSecurityDescriptor(SecurityDescriptor);
if (!NT_SUCCESS(Status)) goto Failure;
Status = InitializeRegistryProtection(DriverObject);
if (!NT_SUCCESS(Status)) goto Failure;
g_RegistryProtectionInitialized = TRUE;
Status = InitializeProcessProtection();
if (!NT_SUCCESS(Status)) goto Failure;
g_ProcessProtectionInitialized = TRUE;
Status = PsSetCreateProcessNotifyRoutineEx(ProcessNotifyCallbackEx, FALSE);
if (!NT_SUCCESS(Status)) goto Failure;
g_ProcessNotifyRegistered = TRUE;
Status = InitializeMemoryProtection(DriverObject);
if (!NT_SUCCESS(Status)) goto Failure;
Status = FltStartFiltering(GlobalData.FilterHandle);
if (!NT_SUCCESS(Status)) goto Failure;
GlobalData.Initialized = TRUE;
InterlockedExchange(&GlobalData.DriverState, PyasDriverStateRunning);
return STATUS_SUCCESS;
Failure:
CleanupDriverState(TRUE);
InterlockedExchange(&GlobalData.DriverState, PyasDriverStateStopped);
KeSetEvent(&GlobalData.CleanupCompleteEvent, IO_NO_INCREMENT, FALSE);
return Status;
}
+52
View File
@@ -0,0 +1,52 @@
[Version]
Signature = "$WINDOWS NT$"
Class = ActivityMonitor
ClassGuid = {b86dff51-a31e-4bac-b3cf-e8cfe75c9fc2}
Provider = %ManufacturerName%
DriverVer = 04/26/2026,3.5.1.0
CatalogFile = PYAS_Driver.cat
PnpLockdown = 1
[DestinationDirs]
DefaultDestDir = 12
PYAS_Driver.DriverFiles = 12
[SourceDisksNames]
1 = %DiskName%,,,""
[SourceDisksFiles]
PYAS_Driver.sys = 1,,
[DefaultInstall.NTamd64]
OptionDesc = %ServiceDescription%
CopyFiles = PYAS_Driver.DriverFiles
[DefaultInstall.NTamd64.Services]
AddService = %ServiceName%,,PYAS_Driver.Service
[PYAS_Driver.DriverFiles]
PYAS_Driver.sys
[PYAS_Driver.Service]
DisplayName = %ServiceName%
Description = %ServiceDescription%
ServiceBinary = %12%\PYAS_Driver.sys
Dependencies = FltMgr
ServiceType = 2
StartType = 3
ErrorControl = 1
LoadOrderGroup = "FSFilter Activity Monitor"
AddReg = PYAS_Driver.AddReg
[PYAS_Driver.AddReg]
HKR,"Parameters","DebugFlags",0x00010001,0x0
HKR,"Parameters","SupportedFeatures",0x00010001,0x3
HKR,"Parameters\Instances","DefaultInstance",0x00000000,"PYAS Instance"
HKR,"Parameters\Instances\PYAS Instance","Altitude",0x00000000,"320000"
HKR,"Parameters\Instances\PYAS Instance","Flags",0x00010001,0x0
[Strings]
ManufacturerName = "PYAS Security"
DiskName = "PYAS_Driver Source Disk"
ServiceName = "PYAS_Driver"
ServiceDescription = "PYAS Security Driver"
+35
View File
@@ -0,0 +1,35 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.14.36518.9 d17.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PYAS_Driver", "PYAS_Driver.vcxproj", "{699C79A8-A904-1976-F72A-CDD7E811CFD2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{699C79A8-A904-1976-F72A-CDD7E811CFD2}.Debug|ARM64.ActiveCfg = Debug|ARM64
{699C79A8-A904-1976-F72A-CDD7E811CFD2}.Debug|ARM64.Build.0 = Debug|ARM64
{699C79A8-A904-1976-F72A-CDD7E811CFD2}.Debug|ARM64.Deploy.0 = Debug|ARM64
{699C79A8-A904-1976-F72A-CDD7E811CFD2}.Debug|x64.ActiveCfg = Debug|x64
{699C79A8-A904-1976-F72A-CDD7E811CFD2}.Debug|x64.Build.0 = Debug|x64
{699C79A8-A904-1976-F72A-CDD7E811CFD2}.Debug|x64.Deploy.0 = Debug|x64
{699C79A8-A904-1976-F72A-CDD7E811CFD2}.Release|ARM64.ActiveCfg = Release|ARM64
{699C79A8-A904-1976-F72A-CDD7E811CFD2}.Release|ARM64.Build.0 = Release|ARM64
{699C79A8-A904-1976-F72A-CDD7E811CFD2}.Release|ARM64.Deploy.0 = Release|ARM64
{699C79A8-A904-1976-F72A-CDD7E811CFD2}.Release|x64.ActiveCfg = Release|x64
{699C79A8-A904-1976-F72A-CDD7E811CFD2}.Release|x64.Build.0 = Release|x64
{699C79A8-A904-1976-F72A-CDD7E811CFD2}.Release|x64.Deploy.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D166699A-50D5-470E-9559-39B8E842528D}
EndGlobalSection
EndGlobal
+131
View File
@@ -0,0 +1,131 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{699C79A8-A904-1976-F72A-CDD7E811CFD2}</ProjectGuid>
<TemplateGuid>{dd38f7fc-d7bd-488b-9242-7d8754cde80d}</TemplateGuid>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
<Configuration>Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">x64</Platform>
<RootNamespace>PYAS_Driver</RootNamespace>
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>WDM</DriverType>
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>WDM</DriverType>
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>WDM</DriverType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>WDM</DriverType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<EnableInf2cat>false</EnableInf2cat>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DriverSign>
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
<ClCompile>
<LanguageStandard>stdcpp20</LanguageStandard>
<TreatWarningAsError>false</TreatWarningAsError>
</ClCompile>
<Link>
<AdditionalDependencies>$(DDK_LIB_PATH)fltmgr.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>/INTEGRITYCHECK %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DriverSign>
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
<ClCompile>
<TreatWarningAsError>false</TreatWarningAsError>
</ClCompile>
<Link>
<AdditionalDependencies>$(DDK_LIB_PATH)fltmgr.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>/INTEGRITYCHECK %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<Inf Include="PYAS_Driver.inf" />
</ItemGroup>
<ItemGroup>
<FilesToPackage Include="$(TargetPath)" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="DriverCommon.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="DriverEntry.cpp" />
<ClCompile Include="ProtectBoot.cpp" />
<ClCompile Include="ProtectFile.cpp" />
<ClCompile Include="ProtectMemory.cpp" />
<ClCompile Include="ProtectProcess.cpp" />
<ClCompile Include="ProtectRegistry.cpp" />
<ClCompile Include="ProtectRules.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,54 @@
<?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="Driver Files">
<UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier>
<Extensions>inf;inv;inx;mof;mc;</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<Inf Include="PYAS_Driver.inf">
<Filter>Driver Files</Filter>
</Inf>
</ItemGroup>
<ItemGroup>
<ClInclude Include="DriverCommon.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="ProtectRules.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ProtectFile.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ProtectBoot.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ProtectRegistry.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ProtectProcess.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DriverEntry.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ProtectMemory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
+37
View File
@@ -0,0 +1,37 @@
#include "DriverCommon.h"
#ifndef IOCTL_DISK_FORMAT_TRACKS
#define IOCTL_DISK_FORMAT_TRACKS CTL_CODE(IOCTL_DISK_BASE, 0x0006, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#endif
#ifndef IOCTL_DISK_FORMAT_TRACKS_EX
#define IOCTL_DISK_FORMAT_TRACKS_EX CTL_CODE(IOCTL_DISK_BASE, 0x000b, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#endif
FLT_PREOP_CALLBACK_STATUS ProtectBoot_PreDeviceControl(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext) {
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(CompletionContext);
if (Data->RequestorMode == KernelMode) return FLT_PREOP_SUCCESS_NO_CALLBACK;
if (KeGetCurrentIrql() > APC_LEVEL) return FLT_PREOP_SUCCESS_NO_CALLBACK;
ULONG IoControlCode = Data->Iopb->Parameters.DeviceIoControl.Common.IoControlCode;
if (IoControlCode == IOCTL_DISK_SET_DRIVE_LAYOUT_EX ||
IoControlCode == IOCTL_SCSI_PASS_THROUGH_DIRECT ||
IoControlCode == IOCTL_DISK_FORMAT_TRACKS ||
IoControlCode == IOCTL_DISK_FORMAT_TRACKS_EX) {
HANDLE Pid = PsGetCurrentProcessId();
ULONG RuleCode = 0;
BOOLEAN Kill = FALSE;
if (EvaluateDeviceRule(Pid, &RuleCode, &Kill)) {
UNICODE_STRING MsgStr = RTL_CONSTANT_STRING(L"Disk_Wiper_Attempt");
SendMessageToUser(RuleCode, (ULONG)(ULONG_PTR)Pid, MsgStr.Buffer, MsgStr.Length);
QueueRuleProcessTermination(Pid, Kill);
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
return FLT_PREOP_COMPLETE;
}
}
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
+143
View File
@@ -0,0 +1,143 @@
#include "DriverCommon.h"
FLT_PREOP_CALLBACK_STATUS ProtectFile_PreCreate(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext) {
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(CompletionContext);
if (Data->RequestorMode == KernelMode) return FLT_PREOP_SUCCESS_NO_CALLBACK;
if (KeGetCurrentIrql() > APC_LEVEL) return FLT_PREOP_SUCCESS_NO_CALLBACK;
PFLT_FILE_NAME_INFORMATION nameInfo = NULL;
NTSTATUS status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &nameInfo);
if (!NT_SUCCESS(status) || !nameInfo) return FLT_PREOP_SUCCESS_NO_CALLBACK;
status = FltParseFileNameInformation(nameInfo);
if (!NT_SUCCESS(status) || !nameInfo->Name.Buffer || nameInfo->Name.Length == 0) {
FltReleaseFileNameInformation(nameInfo);
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
HANDLE Pid = PsGetCurrentProcessId();
FLT_PREOP_CALLBACK_STATUS callbackStatus = FLT_PREOP_SUCCESS_NO_CALLBACK;
ULONG CreateDisposition = (Data->Iopb->Parameters.Create.Options >> 24) & 0xFF;
BOOLEAN IsCreateAction = (CreateDisposition == FILE_CREATE || CreateDisposition == FILE_SUPERSEDE || CreateDisposition == FILE_OVERWRITE || CreateDisposition == FILE_OVERWRITE_IF || CreateDisposition == FILE_OPEN_IF);
ULONG DesiredAccess = Data->Iopb->Parameters.Create.SecurityContext->DesiredAccess;
ULONG Operation = 0;
if (IsCreateAction) Operation |= OP_CREATE;
if (DesiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES | WRITE_DAC | WRITE_OWNER | GENERIC_WRITE)) Operation |= OP_WRITE;
if (DesiredAccess & (DELETE | FILE_DELETE_CHILD)) Operation |= OP_DELETE;
if (Operation != 0) {
ULONG RuleCode = 0;
BOOLEAN Kill = FALSE;
if (EvaluateFileRule(Pid, &nameInfo->Name, Operation, NULL, 0, &RuleCode, &Kill)) {
SendMessageToUser(RuleCode, (ULONG)(ULONG_PTR)Pid, nameInfo->Name.Buffer, nameInfo->Name.Length);
QueueRuleProcessTermination(Pid, Kill);
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
callbackStatus = FLT_PREOP_COMPLETE;
}
}
FltReleaseFileNameInformation(nameInfo);
return callbackStatus;
}
FLT_PREOP_CALLBACK_STATUS ProtectFile_PreSetInfo(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext) {
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(CompletionContext);
if (Data->RequestorMode == KernelMode) return FLT_PREOP_SUCCESS_NO_CALLBACK;
if (KeGetCurrentIrql() > APC_LEVEL) return FLT_PREOP_SUCCESS_NO_CALLBACK;
FILE_INFORMATION_CLASS infoClass = Data->Iopb->Parameters.SetFileInformation.FileInformationClass;
if (infoClass != FileDispositionInformation && infoClass != FileRenameInformation && infoClass != FileRenameInformationEx) {
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
PFLT_FILE_NAME_INFORMATION nameInfo = NULL;
if (!NT_SUCCESS(FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &nameInfo)) || !nameInfo) return FLT_PREOP_SUCCESS_NO_CALLBACK;
if (!NT_SUCCESS(FltParseFileNameInformation(nameInfo)) || !nameInfo->Name.Buffer) {
FltReleaseFileNameInformation(nameInfo);
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
HANDLE Pid = PsGetCurrentProcessId();
FLT_PREOP_CALLBACK_STATUS callbackStatus = FLT_PREOP_SUCCESS_NO_CALLBACK;
ULONG Operation = 0;
if (infoClass == FileDispositionInformation) {
Operation = OP_DELETE;
}
else {
Operation = OP_RENAME;
}
ULONG RuleCode = 0;
BOOLEAN Kill = FALSE;
if (EvaluateFileRule(Pid, &nameInfo->Name, Operation, NULL, 0, &RuleCode, &Kill)) {
SendMessageToUser(RuleCode, (ULONG)(ULONG_PTR)Pid, nameInfo->Name.Buffer, nameInfo->Name.Length);
QueueRuleProcessTermination(Pid, Kill);
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
callbackStatus = FLT_PREOP_COMPLETE;
}
FltReleaseFileNameInformation(nameInfo);
return callbackStatus;
}
FLT_PREOP_CALLBACK_STATUS ProtectFile_PreWrite(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext) {
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(CompletionContext);
if (Data->RequestorMode == KernelMode) return FLT_PREOP_SUCCESS_NO_CALLBACK;
if (KeGetCurrentIrql() > APC_LEVEL) return FLT_PREOP_SUCCESS_NO_CALLBACK;
if (Data->Iopb->IrpFlags & (IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO | IRP_NOCACHE)) return FLT_PREOP_SUCCESS_NO_CALLBACK;
ULONG WriteLength = Data->Iopb->Parameters.Write.Length;
if (WriteLength == 0) return FLT_PREOP_SUCCESS_NO_CALLBACK;
PFLT_FILE_NAME_INFORMATION nameInfo = NULL;
if (!NT_SUCCESS(FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &nameInfo)) || !nameInfo) return FLT_PREOP_SUCCESS_NO_CALLBACK;
if (!NT_SUCCESS(FltParseFileNameInformation(nameInfo)) || !nameInfo->Name.Buffer) {
FltReleaseFileNameInformation(nameInfo);
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
HANDLE Pid = PsGetCurrentProcessId();
FLT_PREOP_CALLBACK_STATUS callbackStatus = FLT_PREOP_SUCCESS_NO_CALLBACK;
PVOID SystemBuffer = NULL;
PMDL Mdl = Data->Iopb->Parameters.Write.MdlAddress;
if (!Mdl && Data->Iopb->Parameters.Write.WriteBuffer && KeGetCurrentIrql() <= APC_LEVEL) {
if (NT_SUCCESS(FltLockUserBuffer(Data))) Mdl = Data->Iopb->Parameters.Write.MdlAddress;
}
if (Mdl) SystemBuffer = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority | MdlMappingNoExecute);
ULONG RuleCode = 0;
BOOLEAN Kill = FALSE;
if (EvaluateFileRule(Pid, &nameInfo->Name, OP_WRITE, SystemBuffer, WriteLength, &RuleCode, &Kill)) {
SendMessageToUser(RuleCode, (ULONG)(ULONG_PTR)Pid, nameInfo->Name.Buffer, nameInfo->Name.Length);
QueueRuleProcessTermination(Pid, Kill);
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
callbackStatus = FLT_PREOP_COMPLETE;
}
FltReleaseFileNameInformation(nameInfo);
return callbackStatus;
}
FLT_PREOP_CALLBACK_STATUS ProtectFile_SetSecurity(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext) {
UNREFERENCED_PARAMETER(Data);
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(CompletionContext);
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
FLT_PREOP_CALLBACK_STATUS ProtectFile_FileSystemControl(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext) {
UNREFERENCED_PARAMETER(Data);
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(CompletionContext);
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
+818
View File
@@ -0,0 +1,818 @@
#include "DriverCommon.h"
extern "C" {
NTSTATUS ZwOpenThread(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PCLIENT_ID ClientId
);
NTSTATUS ZwQueryInformationThread(
HANDLE ThreadHandle,
THREADINFOCLASS ThreadInformationClass,
PVOID ThreadInformation,
ULONG ThreadInformationLength,
PULONG ReturnLength
);
}
#ifndef THREAD_QUERY_INFORMATION
#define THREAD_QUERY_INFORMATION 0x0040
#endif
#define THREAD_QUERY_SET_WIN32_START_ADDRESS 9
constexpr ULONG PYAS_MEM_IMAGE_TYPE = 0x01000000UL;
typedef enum _MEMORY_WORK_TYPE {
MemoryWorkThreadAnalysis = 1,
MemoryWorkViolationReport = 2
} MEMORY_WORK_TYPE;
typedef struct _MEMORY_WORK_ITEM {
LIST_ENTRY Entry;
MEMORY_WORK_TYPE Type;
PEPROCESS SourceProcess;
PEPROCESS TargetProcess;
HANDLE SourcePid;
HANDLE TargetPid;
HANDLE ThreadId;
ULONG RuleCode;
BOOLEAN Kill;
WCHAR FallbackMessage[64];
} MEMORY_WORK_ITEM, * PMEMORY_WORK_ITEM;
typedef struct _THREAD_MEMORY_REGION {
PVOID StartAddress;
ULONG MemoryType;
ULONG MemoryProtection;
SIZE_T RegionSize;
} THREAD_MEMORY_REGION, * PTHREAD_MEMORY_REGION;
static BOOLEAN g_ThreadNotifyRegistered = FALSE;
static BOOLEAN g_LoadImageNotifyRegistered = FALSE;
static BOOLEAN g_MemoryProtectionInitialized = FALSE;
static BOOLEAN g_MemoryRundownCompleted = FALSE;
static EX_RUNDOWN_REF g_MemoryRundown;
static volatile LONG g_MemoryStopping = 1;
static volatile LONG g_PendingMemoryWork = 0;
static LIST_ENTRY g_MemoryWorkQueue;
static KSPIN_LOCK g_MemoryWorkLock;
static KSEMAPHORE g_MemoryWorkSemaphore;
static HANDLE g_MemoryWorkerHandle = NULL;
constexpr auto MAX_PENDING_MEMORY_WORK = 256;
constexpr auto MEMORY_WORKER_STOP_TIMEOUT_MS = 2000;
static PACCESS_MASK GetDesiredAccessPointer(POB_PRE_OPERATION_INFORMATION OperationInformation) {
if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE) {
return &OperationInformation->Parameters->CreateHandleInformation.DesiredAccess;
}
if (OperationInformation->Operation == OB_OPERATION_HANDLE_DUPLICATE) {
return &OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess;
}
return NULL;
}
static ULONG GetHandleType(POB_PRE_OPERATION_INFORMATION OperationInformation) {
if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE) {
return PYAS_HANDLE_CREATE;
}
if (OperationInformation->Operation == OB_OPERATION_HANDLE_DUPLICATE) {
return PYAS_HANDLE_DUPLICATE;
}
return 0;
}
static ULONG GetProcessOperations(ACCESS_MASK Access) {
ULONG Operations = 0;
if (Access & PROCESS_VM_READ) Operations |= OP_VM_READ;
if (Access & PROCESS_VM_WRITE) Operations |= OP_VM_WRITE;
if (Access & PROCESS_VM_OPERATION) Operations |= OP_VM_OPERATION;
if (Access & PROCESS_CREATE_THREAD) Operations |= OP_CREATE_THREAD;
if (Access & PROCESS_TERMINATE) Operations |= OP_TERMINATE;
if (Access & PROCESS_SUSPEND_RESUME) Operations |= OP_SUSPEND_RESUME;
if (Access & PROCESS_DUP_HANDLE) Operations |= OP_DUP_HANDLE;
if (Access & (PROCESS_SET_INFORMATION | PROCESS_SET_QUOTA)) Operations |= OP_SET_INFORMATION;
if (Access & PROCESS_CREATE_PROCESS) Operations |= OP_CREATE_PROCESS;
return Operations;
}
static ULONG GetThreadOperations(ACCESS_MASK Access) {
ULONG Operations = 0;
if (Access & THREAD_SET_CONTEXT) Operations |= OP_THREAD_SET_CONTEXT;
if (Access & THREAD_TERMINATE) Operations |= OP_TERMINATE;
if (Access & THREAD_SUSPEND_RESUME) Operations |= OP_SUSPEND_RESUME;
if (Access & THREAD_SET_INFORMATION) Operations |= OP_SET_INFORMATION;
if (Access & THREAD_SET_THREAD_TOKEN) Operations |= OP_THREAD_SET_TOKEN;
if (Access & (THREAD_IMPERSONATE | THREAD_DIRECT_IMPERSONATION)) Operations |= OP_IMPERSONATE;
return Operations;
}
static ACCESS_MASK GetProcessDeniedAccess(ULONG Operations) {
ACCESS_MASK DeniedAccess = 0;
if (Operations & OP_VM_READ) DeniedAccess |= PROCESS_VM_READ;
if (Operations & OP_VM_WRITE) DeniedAccess |= PROCESS_VM_WRITE;
if (Operations & OP_VM_OPERATION) DeniedAccess |= PROCESS_VM_OPERATION;
if (Operations & OP_CREATE_THREAD) DeniedAccess |= PROCESS_CREATE_THREAD;
if (Operations & OP_TERMINATE) DeniedAccess |= PROCESS_TERMINATE;
if (Operations & OP_SUSPEND_RESUME) DeniedAccess |= PROCESS_SUSPEND_RESUME;
if (Operations & OP_DUP_HANDLE) DeniedAccess |= PROCESS_DUP_HANDLE;
if (Operations & OP_SET_INFORMATION) DeniedAccess |= PROCESS_SET_INFORMATION | PROCESS_SET_QUOTA;
if (Operations & OP_CREATE_PROCESS) DeniedAccess |= PROCESS_CREATE_PROCESS;
return DeniedAccess;
}
static ACCESS_MASK GetThreadDeniedAccess(ULONG Operations) {
ACCESS_MASK DeniedAccess = 0;
if (Operations & OP_THREAD_SET_CONTEXT) DeniedAccess |= THREAD_SET_CONTEXT;
if (Operations & OP_TERMINATE) DeniedAccess |= THREAD_TERMINATE;
if (Operations & OP_SUSPEND_RESUME) DeniedAccess |= THREAD_SUSPEND_RESUME;
if (Operations & OP_SET_INFORMATION) DeniedAccess |= THREAD_SET_INFORMATION;
if (Operations & OP_THREAD_SET_TOKEN) DeniedAccess |= THREAD_SET_THREAD_TOKEN;
if (Operations & OP_IMPERSONATE) DeniedAccess |= THREAD_IMPERSONATE | THREAD_DIRECT_IMPERSONATION;
return DeniedAccess;
}
static BOOLEAN IsProcessIdentityCurrent(HANDLE ProcessId, PEPROCESS ExpectedProcess);
static VOID ReleaseMemoryWork(PMEMORY_WORK_ITEM Work) {
if (!Work) return;
if (Work->TargetProcess) ObDereferenceObject(Work->TargetProcess);
if (Work->SourceProcess) ObDereferenceObject(Work->SourceProcess);
InterlockedDecrement(&g_PendingMemoryWork);
PyasFree(Work);
}
static PMEMORY_WORK_ITEM PopMemoryWork() {
PMEMORY_WORK_ITEM Work = NULL;
KIRQL OldIrql;
KeAcquireSpinLock(&g_MemoryWorkLock, &OldIrql);
if (!IsListEmpty(&g_MemoryWorkQueue)) {
PLIST_ENTRY Entry = RemoveHeadList(&g_MemoryWorkQueue);
Work = CONTAINING_RECORD(Entry, MEMORY_WORK_ITEM, Entry);
}
KeReleaseSpinLock(&g_MemoryWorkLock, OldIrql);
return Work;
}
static VOID CancelQueuedMemoryWork() {
for (;;) {
PMEMORY_WORK_ITEM Work = PopMemoryWork();
if (!Work) return;
ReleaseMemoryWork(Work);
}
}
static BOOLEAN QueueMemoryWork(PMEMORY_WORK_ITEM Work) {
if (!Work) return FALSE;
LONG Pending = InterlockedIncrement(&g_PendingMemoryWork);
if (Pending > MAX_PENDING_MEMORY_WORK) {
InterlockedDecrement(&g_PendingMemoryWork);
return FALSE;
}
KIRQL OldIrql;
KeAcquireSpinLock(&g_MemoryWorkLock, &OldIrql);
if (InterlockedCompareExchange(&g_MemoryStopping, 0, 0) != 0) {
KeReleaseSpinLock(&g_MemoryWorkLock, OldIrql);
InterlockedDecrement(&g_PendingMemoryWork);
return FALSE;
}
InsertTailList(&g_MemoryWorkQueue, &Work->Entry);
KeReleaseSpinLock(&g_MemoryWorkLock, OldIrql);
KeReleaseSemaphore(&g_MemoryWorkSemaphore, IO_NO_INCREMENT, 1, FALSE);
return TRUE;
}
static VOID DeliverViolation(PMEMORY_WORK_ITEM Work) {
if (!Work) return;
if (InterlockedCompareExchange(&g_MemoryStopping, 0, 0) != 0) return;
BOOLEAN SourceMatches = IsProcessIdentityCurrent(Work->SourcePid, Work->SourceProcess);
BOOLEAN TargetMatches = IsProcessIdentityCurrent(Work->TargetPid, Work->TargetProcess);
if (!SourceMatches || !TargetMatches) return;
PUNICODE_STRING TargetPath = NULL;
if (NT_SUCCESS(GetProcessImageName(Work->TargetPid, &TargetPath)) && TargetPath && TargetPath->Buffer) {
SendMessageToUser(
Work->RuleCode,
(ULONG)(ULONG_PTR)Work->SourcePid,
TargetPath->Buffer,
TargetPath->Length
);
}
else {
UNICODE_STRING MessageString;
RtlInitUnicodeString(&MessageString, Work->FallbackMessage);
SendMessageToUser(
Work->RuleCode,
(ULONG)(ULONG_PTR)Work->SourcePid,
MessageString.Buffer,
MessageString.Length
);
}
if (TargetPath) ExFreePool(TargetPath);
QueueRuleProcessTermination(Work->SourcePid, Work->Kill);
}
static VOID ReportViolation(
ULONG RuleCode,
BOOLEAN Kill,
HANDLE SourcePid,
HANDLE TargetPid,
PCWSTR FallbackMessage
) {
if (!RuleCode || !SourcePid || !TargetPid || !FallbackMessage) return;
if (InterlockedCompareExchange(&g_MemoryStopping, 0, 0) != 0) return;
PEPROCESS SourceProcess = NULL;
PEPROCESS TargetProcess = NULL;
NTSTATUS Status = PsLookupProcessByProcessId(SourcePid, &SourceProcess);
if (NT_SUCCESS(Status)) {
Status = PsLookupProcessByProcessId(TargetPid, &TargetProcess);
}
if (!NT_SUCCESS(Status)) {
if (SourceProcess) ObDereferenceObject(SourceProcess);
return;
}
PMEMORY_WORK_ITEM Work = (PMEMORY_WORK_ITEM)PyasAllocate(sizeof(MEMORY_WORK_ITEM));
if (!Work) {
ObDereferenceObject(TargetProcess);
ObDereferenceObject(SourceProcess);
return;
}
RtlZeroMemory(Work, sizeof(*Work));
Work->Type = MemoryWorkViolationReport;
Work->SourceProcess = SourceProcess;
Work->TargetProcess = TargetProcess;
Work->SourcePid = SourcePid;
Work->TargetPid = TargetPid;
Work->RuleCode = RuleCode;
Work->Kill = Kill;
RtlStringCchCopyW(Work->FallbackMessage, RTL_NUMBER_OF(Work->FallbackMessage), FallbackMessage);
if (!QueueMemoryWork(Work)) {
ObDereferenceObject(TargetProcess);
ObDereferenceObject(SourceProcess);
PyasFree(Work);
}
}
static BOOLEAN IsExecuteProtection(ULONG Protect) {
ULONG BaseProtect = Protect & 0xFF;
return BaseProtect == PAGE_EXECUTE ||
BaseProtect == PAGE_EXECUTE_READ ||
BaseProtect == PAGE_EXECUTE_READWRITE ||
BaseProtect == PAGE_EXECUTE_WRITECOPY;
}
static BOOLEAN IsExecuteWriteProtection(ULONG Protect) {
ULONG BaseProtect = Protect & 0xFF;
return BaseProtect == PAGE_EXECUTE_READWRITE ||
BaseProtect == PAGE_EXECUTE_WRITECOPY;
}
static BOOLEAN QueryThreadMemoryRegionForProcess(
PEPROCESS Process,
PVOID Address,
PTHREAD_MEMORY_REGION Region
) {
if (!Process || !Region || !Address || KeGetCurrentIrql() != PASSIVE_LEVEL) return FALSE;
RtlZeroMemory(Region, sizeof(*Region));
KAPC_STATE ApcState;
KeStackAttachProcess(Process, &ApcState);
MEMORY_BASIC_INFORMATION MemoryInformation = { 0 };
SIZE_T ReturnLength = 0;
NTSTATUS Status = ZwQueryVirtualMemory(
ZwCurrentProcess(),
Address,
MemoryBasicInformation,
&MemoryInformation,
sizeof(MemoryInformation),
&ReturnLength
);
KeUnstackDetachProcess(&ApcState);
if (!NT_SUCCESS(Status)) return FALSE;
if (MemoryInformation.State != MEM_COMMIT) return FALSE;
if (!IsExecuteProtection(MemoryInformation.Protect)) return FALSE;
Region->StartAddress = Address;
Region->RegionSize = MemoryInformation.RegionSize;
if (MemoryInformation.Type == MEM_PRIVATE) Region->MemoryType = PYAS_MEMORY_PRIVATE;
else if (MemoryInformation.Type == MEM_MAPPED) Region->MemoryType = PYAS_MEMORY_MAPPED;
else if (MemoryInformation.Type == PYAS_MEM_IMAGE_TYPE) Region->MemoryType = PYAS_MEMORY_IMAGE;
else return FALSE;
Region->MemoryProtection = PYAS_PROTECT_EXECUTE;
if (IsExecuteWriteProtection(MemoryInformation.Protect)) {
Region->MemoryProtection |= PYAS_PROTECT_EXECUTE_WRITE;
}
return TRUE;
}
static BOOLEAN QueryThreadMemoryRegion(
HANDLE ProcessId,
PVOID Address,
PTHREAD_MEMORY_REGION Region
) {
if (!ProcessId) return FALSE;
PEPROCESS Process = NULL;
NTSTATUS Status = PsLookupProcessByProcessId(ProcessId, &Process);
if (!NT_SUCCESS(Status)) return FALSE;
BOOLEAN Result = QueryThreadMemoryRegionForProcess(Process, Address, Region);
ObDereferenceObject(Process);
return Result;
}
BOOLEAN IsAddressInUnmappedMemory(HANDLE ProcessId, PVOID Address) {
THREAD_MEMORY_REGION Region = { 0 };
if (!QueryThreadMemoryRegion(ProcessId, Address, &Region)) return FALSE;
return Region.MemoryType == PYAS_MEMORY_PRIVATE;
}
static BOOLEAN IsProcessIdentityCurrent(HANDLE ProcessId, PEPROCESS ExpectedProcess) {
if (!ProcessId || !ExpectedProcess) return FALSE;
PEPROCESS CurrentProcess = NULL;
NTSTATUS Status = PsLookupProcessByProcessId(ProcessId, &CurrentProcess);
if (!NT_SUCCESS(Status)) return FALSE;
BOOLEAN Matches = CurrentProcess == ExpectedProcess;
ObDereferenceObject(CurrentProcess);
return Matches;
}
static OB_PREOP_CALLBACK_STATUS ObjectPreCallbackCore(
POB_PRE_OPERATION_INFORMATION OperationInformation
) {
if (!OperationInformation || OperationInformation->KernelHandle) {
return OB_PREOP_SUCCESS;
}
PACCESS_MASK DesiredAccess = GetDesiredAccessPointer(OperationInformation);
ULONG HandleType = GetHandleType(OperationInformation);
if (!DesiredAccess || *DesiredAccess == 0 || HandleType == 0) {
return OB_PREOP_SUCCESS;
}
HANDLE SourcePid = PsGetCurrentProcessId();
if (!SourcePid || IsProcessTrusted(SourcePid)) {
return OB_PREOP_SUCCESS;
}
HANDLE TargetPid = NULL;
ULONG ObjectType = 0;
ULONG RequestedOperations = 0;
ACCESS_MASK OriginalAccess = *DesiredAccess;
if (OperationInformation->ObjectType == *PsProcessType) {
TargetPid = PsGetProcessId((PEPROCESS)OperationInformation->Object);
ObjectType = PYAS_OBJECT_PROCESS;
RequestedOperations = GetProcessOperations(OriginalAccess);
}
else if (OperationInformation->ObjectType == *PsThreadType) {
TargetPid = PsGetThreadProcessId((PETHREAD)OperationInformation->Object);
ObjectType = PYAS_OBJECT_THREAD;
RequestedOperations = GetThreadOperations(OriginalAccess);
}
else {
return OB_PREOP_SUCCESS;
}
if (!TargetPid || SourcePid == TargetPid || RequestedOperations == 0) {
return OB_PREOP_SUCCESS;
}
ULONG DeniedOperations = 0;
ULONG RuleCode = 0;
BOOLEAN Kill = FALSE;
if (!EvaluateProcessAccessRule(
SourcePid,
TargetPid,
RequestedOperations,
HandleType,
ObjectType,
&DeniedOperations,
&RuleCode,
&Kill
)) {
return OB_PREOP_SUCCESS;
}
ACCESS_MASK DeniedAccess = ObjectType == PYAS_OBJECT_PROCESS
? GetProcessDeniedAccess(DeniedOperations)
: GetThreadDeniedAccess(DeniedOperations);
ACCESS_MASK EffectiveDeniedAccess = OriginalAccess & DeniedAccess;
if (EffectiveDeniedAccess == 0) return OB_PREOP_SUCCESS;
*DesiredAccess = OriginalAccess & ~EffectiveDeniedAccess;
ReportViolation(
RuleCode,
Kill,
SourcePid,
TargetPid,
ObjectType == PYAS_OBJECT_PROCESS
? L"Process_Handle_Access_Denied"
: L"Thread_Handle_Access_Denied"
);
return OB_PREOP_SUCCESS;
}
static OB_PREOP_CALLBACK_STATUS ObjectPreCallback(
PVOID RegistrationContext,
POB_PRE_OPERATION_INFORMATION OperationInformation
) {
UNREFERENCED_PARAMETER(RegistrationContext);
if (!g_MemoryProtectionInitialized) return OB_PREOP_SUCCESS;
if (InterlockedCompareExchange(&g_MemoryStopping, 0, 0) != 0) return OB_PREOP_SUCCESS;
if (!ExAcquireRundownProtection(&g_MemoryRundown)) return OB_PREOP_SUCCESS;
OB_PREOP_CALLBACK_STATUS Result = ObjectPreCallbackCore(OperationInformation);
ExReleaseRundownProtection(&g_MemoryRundown);
return Result;
}
static VOID ProcessThreadAnalysis(PMEMORY_WORK_ITEM Work) {
if (!Work) return;
if (InterlockedCompareExchange(&g_MemoryStopping, 0, 0) != 0) return;
PVOID StartAddress = NULL;
HANDLE ThreadHandle = NULL;
BOOLEAN IdentityValid =
IsProcessIdentityCurrent(Work->SourcePid, Work->SourceProcess) &&
IsProcessIdentityCurrent(Work->TargetPid, Work->TargetProcess);
CLIENT_ID ClientId = { Work->TargetPid, Work->ThreadId };
OBJECT_ATTRIBUTES ObjectAttributes;
InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
NTSTATUS Status = STATUS_PROCESS_IS_TERMINATING;
if (IdentityValid) {
Status = ZwOpenThread(
&ThreadHandle,
THREAD_QUERY_INFORMATION,
&ObjectAttributes,
&ClientId
);
}
if (NT_SUCCESS(Status)) {
Status = ZwQueryInformationThread(
ThreadHandle,
(THREADINFOCLASS)THREAD_QUERY_SET_WIN32_START_ADDRESS,
&StartAddress,
sizeof(StartAddress),
NULL
);
ZwClose(ThreadHandle);
}
if (!NT_SUCCESS(Status) || !StartAddress) return;
if (InterlockedCompareExchange(&g_MemoryStopping, 0, 0) != 0) return;
THREAD_MEMORY_REGION Region = { 0 };
if (!QueryThreadMemoryRegionForProcess(Work->TargetProcess, StartAddress, &Region)) return;
ULONG RuleCode = 0;
BOOLEAN Kill = FALSE;
if (!EvaluateThreadRule(
Work->SourcePid,
Work->TargetPid,
StartAddress,
Region.MemoryType,
Region.MemoryProtection,
Region.RegionSize,
&RuleCode,
&Kill
)) {
return;
}
Work->RuleCode = RuleCode;
Work->Kill = Kill;
RtlStringCchCopyW(
Work->FallbackMessage,
RTL_NUMBER_OF(Work->FallbackMessage),
L"Remote_Executable_Thread_Detected"
);
DeliverViolation(Work);
}
static VOID MemoryWorkerThread(PVOID Parameter) {
UNREFERENCED_PARAMETER(Parameter);
for (;;) {
KeWaitForSingleObject(
&g_MemoryWorkSemaphore,
Executive,
KernelMode,
FALSE,
NULL
);
if (InterlockedCompareExchange(&g_MemoryStopping, 0, 0) != 0) {
CancelQueuedMemoryWork();
break;
}
PMEMORY_WORK_ITEM Work = PopMemoryWork();
if (!Work) continue;
if (Work->Type == MemoryWorkThreadAnalysis) {
ProcessThreadAnalysis(Work);
}
else if (Work->Type == MemoryWorkViolationReport) {
DeliverViolation(Work);
}
ReleaseMemoryWork(Work);
}
PsTerminateSystemThread(STATUS_SUCCESS);
}
static VOID ThreadNotifyCallback(
HANDLE ProcessId,
HANDLE ThreadId,
BOOLEAN IsCreated
) {
if (!IsCreated || !g_MemoryProtectionInitialized) return;
if (InterlockedCompareExchange(&g_MemoryStopping, 0, 0) != 0) return;
HANDLE SourcePid = PsGetCurrentProcessId();
if (!SourcePid || SourcePid == ProcessId || IsProcessTrusted(SourcePid)) return;
PEPROCESS SourceProcess = PsGetCurrentProcess();
PEPROCESS TargetProcess = NULL;
ObReferenceObject(SourceProcess);
NTSTATUS Status = PsLookupProcessByProcessId(ProcessId, &TargetProcess);
if (!NT_SUCCESS(Status)) {
ObDereferenceObject(SourceProcess);
return;
}
PMEMORY_WORK_ITEM Work = (PMEMORY_WORK_ITEM)PyasAllocate(sizeof(MEMORY_WORK_ITEM));
if (!Work) {
ObDereferenceObject(TargetProcess);
ObDereferenceObject(SourceProcess);
return;
}
RtlZeroMemory(Work, sizeof(*Work));
Work->Type = MemoryWorkThreadAnalysis;
Work->SourceProcess = SourceProcess;
Work->TargetProcess = TargetProcess;
Work->SourcePid = SourcePid;
Work->TargetPid = ProcessId;
Work->ThreadId = ThreadId;
if (!QueueMemoryWork(Work)) {
ObDereferenceObject(TargetProcess);
ObDereferenceObject(SourceProcess);
PyasFree(Work);
}
}
static VOID LoadImageNotifyCallback(
PUNICODE_STRING FullImageName,
HANDLE ProcessId,
PIMAGE_INFO ImageInfo
) {
if (!g_MemoryProtectionInitialized) return;
if (InterlockedCompareExchange(&g_MemoryStopping, 0, 0) != 0) return;
if (!FullImageName || !FullImageName->Buffer || !ImageInfo || ImageInfo->SystemModeImage) return;
if (!ProcessId || !ExAcquireRundownProtection(&g_MemoryRundown)) return;
ULONG RuleCode = 0;
BOOLEAN Kill = FALSE;
if (EvaluateImageLoadRule(ProcessId, FullImageName, ImageInfo, &RuleCode, &Kill)) {
SendMessageToUser(
RuleCode,
(ULONG)(ULONG_PTR)ProcessId,
FullImageName->Buffer,
FullImageName->Length
);
QueueRuleProcessTermination(ProcessId, Kill);
}
ExReleaseRundownProtection(&g_MemoryRundown);
}
static NTSTATUS RemoveMemoryCallbacks() {
NTSTATUS FirstFailure = STATUS_SUCCESS;
if (GlobalData.ObRegistrationHandle) {
ObUnRegisterCallbacks(GlobalData.ObRegistrationHandle);
GlobalData.ObRegistrationHandle = NULL;
}
if (g_ThreadNotifyRegistered) {
NTSTATUS Status = PsRemoveCreateThreadNotifyRoutine(ThreadNotifyCallback);
if (NT_SUCCESS(Status) || Status == STATUS_PROCEDURE_NOT_FOUND) {
g_ThreadNotifyRegistered = FALSE;
}
else if (NT_SUCCESS(FirstFailure)) {
FirstFailure = Status;
}
}
if (g_LoadImageNotifyRegistered) {
NTSTATUS Status = PsRemoveLoadImageNotifyRoutine(LoadImageNotifyCallback);
if (NT_SUCCESS(Status) || Status == STATUS_PROCEDURE_NOT_FOUND) {
g_LoadImageNotifyRegistered = FALSE;
}
else if (NT_SUCCESS(FirstFailure)) {
FirstFailure = Status;
}
}
return FirstFailure;
}
static NTSTATUS StartMemoryWorker() {
if (g_MemoryWorkerHandle) return STATUS_SUCCESS;
OBJECT_ATTRIBUTES ObjectAttributes;
InitializeObjectAttributes(
&ObjectAttributes,
NULL,
OBJ_KERNEL_HANDLE,
NULL,
NULL
);
return PsCreateSystemThread(
&g_MemoryWorkerHandle,
SYNCHRONIZE,
&ObjectAttributes,
NULL,
NULL,
MemoryWorkerThread,
NULL
);
}
static NTSTATUS StopMemoryWorker(BOOLEAN WaitWithoutTimeout) {
CancelQueuedMemoryWork();
if (!g_MemoryWorkerHandle) return STATUS_SUCCESS;
KeReleaseSemaphore(&g_MemoryWorkSemaphore, IO_NO_INCREMENT, 1, FALSE);
LARGE_INTEGER Timeout;
PLARGE_INTEGER TimeoutPointer = NULL;
if (!WaitWithoutTimeout) {
Timeout.QuadPart = -((LONGLONG)MEMORY_WORKER_STOP_TIMEOUT_MS * 10 * 1000);
TimeoutPointer = &Timeout;
}
NTSTATUS Status = ZwWaitForSingleObject(
g_MemoryWorkerHandle,
FALSE,
TimeoutPointer
);
if (Status == STATUS_TIMEOUT) return STATUS_DEVICE_BUSY;
if (!NT_SUCCESS(Status)) return Status;
ZwClose(g_MemoryWorkerHandle);
g_MemoryWorkerHandle = NULL;
return STATUS_SUCCESS;
}
NTSTATUS InitializeMemoryProtection(PDRIVER_OBJECT DriverObject) {
UNREFERENCED_PARAMETER(DriverObject);
if (g_MemoryProtectionInitialized) return STATUS_SUCCESS;
InitializeListHead(&g_MemoryWorkQueue);
KeInitializeSpinLock(&g_MemoryWorkLock);
KeInitializeSemaphore(&g_MemoryWorkSemaphore, 0, MAXLONG);
ExInitializeRundownProtection(&g_MemoryRundown);
g_MemoryRundownCompleted = FALSE;
InterlockedExchange(&g_PendingMemoryWork, 0);
InterlockedExchange(&g_MemoryStopping, 0);
g_MemoryProtectionInitialized = TRUE;
NTSTATUS Status = StartMemoryWorker();
if (!NT_SUCCESS(Status)) {
InterlockedExchange(&g_MemoryStopping, 1);
g_MemoryProtectionInitialized = FALSE;
return Status;
}
Status = PsSetCreateThreadNotifyRoutine(ThreadNotifyCallback);
if (!NT_SUCCESS(Status)) {
InterlockedExchange(&g_MemoryStopping, 1);
StopMemoryWorker(TRUE);
g_MemoryProtectionInitialized = FALSE;
return Status;
}
g_ThreadNotifyRegistered = TRUE;
Status = PsSetLoadImageNotifyRoutine(LoadImageNotifyCallback);
if (!NT_SUCCESS(Status)) {
InterlockedExchange(&g_MemoryStopping, 1);
RemoveMemoryCallbacks();
ExWaitForRundownProtectionRelease(&g_MemoryRundown);
g_MemoryRundownCompleted = TRUE;
StopMemoryWorker(TRUE);
g_MemoryProtectionInitialized = FALSE;
return Status;
}
g_LoadImageNotifyRegistered = TRUE;
OB_OPERATION_REGISTRATION OperationRegistration[2] = { 0 };
OperationRegistration[0].ObjectType = PsProcessType;
OperationRegistration[0].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
OperationRegistration[0].PreOperation = ObjectPreCallback;
OperationRegistration[1].ObjectType = PsThreadType;
OperationRegistration[1].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
OperationRegistration[1].PreOperation = ObjectPreCallback;
OB_CALLBACK_REGISTRATION CallbackRegistration = { 0 };
CallbackRegistration.Version = OB_FLT_REGISTRATION_VERSION;
CallbackRegistration.OperationRegistrationCount = RTL_NUMBER_OF(OperationRegistration);
CallbackRegistration.OperationRegistration = OperationRegistration;
RtlInitUnicodeString(&CallbackRegistration.Altitude, PYAS_OB_ALTITUDE);
Status = ObRegisterCallbacks(&CallbackRegistration, &GlobalData.ObRegistrationHandle);
if (NT_SUCCESS(Status)) return STATUS_SUCCESS;
InterlockedExchange(&g_MemoryStopping, 1);
RemoveMemoryCallbacks();
ExWaitForRundownProtectionRelease(&g_MemoryRundown);
g_MemoryRundownCompleted = TRUE;
StopMemoryWorker(TRUE);
g_MemoryProtectionInitialized = FALSE;
return Status;
}
NTSTATUS UninitializeMemoryProtection(BOOLEAN WaitWithoutTimeout) {
if (!g_MemoryProtectionInitialized) return STATUS_SUCCESS;
InterlockedExchange(&g_MemoryStopping, 1);
NTSTATUS CallbackStatus = RemoveMemoryCallbacks();
if (!g_MemoryRundownCompleted) {
ExWaitForRundownProtectionRelease(&g_MemoryRundown);
g_MemoryRundownCompleted = TRUE;
}
NTSTATUS WorkerStatus = StopMemoryWorker(WaitWithoutTimeout);
if (!NT_SUCCESS(CallbackStatus)) return CallbackStatus;
if (!NT_SUCCESS(WorkerStatus)) return WorkerStatus;
if (g_ThreadNotifyRegistered || g_LoadImageNotifyRegistered || GlobalData.ObRegistrationHandle) {
return STATUS_DEVICE_BUSY;
}
g_MemoryProtectionInitialized = FALSE;
return STATUS_SUCCESS;
}
+285
View File
@@ -0,0 +1,285 @@
#include "DriverCommon.h"
constexpr auto PROCESS_RELATION_BUCKET_COUNT = 1024;
constexpr auto PROCESS_RELATION_BUCKET_WAYS = 4;
typedef HANDLE(NTAPI* PPS_GET_PROCESS_INHERITED_FROM_UNIQUE_PROCESS_ID)(PEPROCESS Process);
typedef struct _PROCESS_RELATION_ENTRY {
HANDLE ProcessId;
HANDLE ParentProcessId;
HANDLE CreatorProcessId;
LARGE_INTEGER CreateTime;
LARGE_INTEGER ParentCreateTime;
ULONGLONG Sequence;
} PROCESS_RELATION_ENTRY, * PPROCESS_RELATION_ENTRY;
static PROCESS_RELATION_ENTRY g_ProcessRelations[PROCESS_RELATION_BUCKET_COUNT][PROCESS_RELATION_BUCKET_WAYS];
static KSPIN_LOCK g_ProcessRelationLock;
static EX_RUNDOWN_REF g_ProcessRundown;
static volatile LONG g_ProcessStopping = 1;
static volatile LONG64 g_ProcessRelationSequence = 0;
static BOOLEAN g_ProcessProtectionInitialized = FALSE;
static PPS_GET_PROCESS_INHERITED_FROM_UNIQUE_PROCESS_ID g_GetInheritedProcessId = NULL;
static ULONG GetProcessRelationBucket(HANDLE ProcessId) {
return ((ULONG)(ULONG_PTR)ProcessId >> 2) & (PROCESS_RELATION_BUCKET_COUNT - 1);
}
static BOOLEAN QueryProcessCreateTime(HANDLE ProcessId, PLARGE_INTEGER CreateTime) {
if (CreateTime) CreateTime->QuadPart = 0;
if (!ProcessId || !CreateTime || KeGetCurrentIrql() > APC_LEVEL) return FALSE;
PEPROCESS Process = NULL;
NTSTATUS Status = PsLookupProcessByProcessId(ProcessId, &Process);
if (!NT_SUCCESS(Status)) return FALSE;
CreateTime->QuadPart = PsGetProcessCreateTimeQuadPart(Process);
ObDereferenceObject(Process);
return TRUE;
}
static VOID StoreProcessRelation(
PEPROCESS Process,
HANDLE ProcessId,
HANDLE ParentProcessId,
HANDLE CreatorProcessId,
PLARGE_INTEGER KnownParentCreateTime
) {
if (!Process || !ProcessId) return;
PROCESS_RELATION_ENTRY NewEntry = { 0 };
NewEntry.ProcessId = ProcessId;
NewEntry.ParentProcessId = ParentProcessId;
NewEntry.CreatorProcessId = CreatorProcessId;
NewEntry.CreateTime.QuadPart = PsGetProcessCreateTimeQuadPart(Process);
if (KnownParentCreateTime) {
NewEntry.ParentCreateTime = *KnownParentCreateTime;
}
else if (ParentProcessId) {
QueryProcessCreateTime(ParentProcessId, &NewEntry.ParentCreateTime);
}
NewEntry.Sequence = (ULONGLONG)InterlockedIncrement64(&g_ProcessRelationSequence);
ULONG Bucket = GetProcessRelationBucket(ProcessId);
ULONG Selected = 0;
KIRQL OldIrql;
KeAcquireSpinLock(&g_ProcessRelationLock, &OldIrql);
for (ULONG Index = 0; Index < PROCESS_RELATION_BUCKET_WAYS; Index++) {
PPROCESS_RELATION_ENTRY Entry = &g_ProcessRelations[Bucket][Index];
if (Entry->ProcessId == ProcessId || Entry->ProcessId == NULL) {
Selected = Index;
break;
}
if (Entry->Sequence < g_ProcessRelations[Bucket][Selected].Sequence) {
Selected = Index;
}
}
g_ProcessRelations[Bucket][Selected] = NewEntry;
KeReleaseSpinLock(&g_ProcessRelationLock, OldIrql);
}
static VOID RemoveProcessRelation(HANDLE ProcessId) {
if (!ProcessId) return;
ULONG Bucket = GetProcessRelationBucket(ProcessId);
KIRQL OldIrql;
KeAcquireSpinLock(&g_ProcessRelationLock, &OldIrql);
for (ULONG Index = 0; Index < PROCESS_RELATION_BUCKET_WAYS; Index++) {
PPROCESS_RELATION_ENTRY Entry = &g_ProcessRelations[Bucket][Index];
if (Entry->ProcessId == ProcessId) {
RtlZeroMemory(Entry, sizeof(*Entry));
break;
}
}
KeReleaseSpinLock(&g_ProcessRelationLock, OldIrql);
}
BOOLEAN GetProcessRelation(
HANDLE ProcessId,
PHANDLE ParentProcessId,
PHANDLE CreatorProcessId
) {
if (ParentProcessId) *ParentProcessId = NULL;
if (CreatorProcessId) *CreatorProcessId = NULL;
if (!ProcessId || !g_ProcessProtectionInitialized || KeGetCurrentIrql() > APC_LEVEL) return FALSE;
PEPROCESS Process = NULL;
NTSTATUS Status = PsLookupProcessByProcessId(ProcessId, &Process);
if (!NT_SUCCESS(Status)) return FALSE;
LARGE_INTEGER CurrentCreateTime = { 0 };
CurrentCreateTime.QuadPart = PsGetProcessCreateTimeQuadPart(Process);
PROCESS_RELATION_ENTRY Snapshot = { 0 };
ULONG Bucket = GetProcessRelationBucket(ProcessId);
KIRQL OldIrql;
KeAcquireSpinLock(&g_ProcessRelationLock, &OldIrql);
for (ULONG Index = 0; Index < PROCESS_RELATION_BUCKET_WAYS; Index++) {
PPROCESS_RELATION_ENTRY Entry = &g_ProcessRelations[Bucket][Index];
if (Entry->ProcessId == ProcessId) {
Snapshot = *Entry;
break;
}
}
KeReleaseSpinLock(&g_ProcessRelationLock, OldIrql);
BOOLEAN CacheValid = Snapshot.ProcessId == ProcessId &&
Snapshot.CreateTime.QuadPart == CurrentCreateTime.QuadPart;
if (CacheValid && Snapshot.ParentProcessId && Snapshot.ParentCreateTime.QuadPart != 0) {
LARGE_INTEGER LiveParentCreateTime = { 0 };
if (QueryProcessCreateTime(Snapshot.ParentProcessId, &LiveParentCreateTime) &&
LiveParentCreateTime.QuadPart != Snapshot.ParentCreateTime.QuadPart) {
CacheValid = FALSE;
}
}
if (CacheValid) {
if (ParentProcessId) *ParentProcessId = Snapshot.ParentProcessId;
if (CreatorProcessId) *CreatorProcessId = Snapshot.CreatorProcessId;
ObDereferenceObject(Process);
return Snapshot.ParentProcessId != NULL || Snapshot.CreatorProcessId != NULL;
}
if (Snapshot.ProcessId == ProcessId) {
RemoveProcessRelation(ProcessId);
}
HANDLE LiveParentProcessId = NULL;
LARGE_INTEGER LiveParentCreateTime = { 0 };
if (g_GetInheritedProcessId) {
LiveParentProcessId = g_GetInheritedProcessId(Process);
}
if (!LiveParentProcessId || LiveParentProcessId == ProcessId) {
ObDereferenceObject(Process);
return FALSE;
}
if (!QueryProcessCreateTime(LiveParentProcessId, &LiveParentCreateTime) ||
LiveParentCreateTime.QuadPart > CurrentCreateTime.QuadPart) {
ObDereferenceObject(Process);
return FALSE;
}
StoreProcessRelation(
Process,
ProcessId,
LiveParentProcessId,
NULL,
&LiveParentCreateTime
);
if (ParentProcessId) *ParentProcessId = LiveParentProcessId;
if (CreatorProcessId) *CreatorProcessId = NULL;
ObDereferenceObject(Process);
return TRUE;
}
NTSTATUS InitializeProcessProtection() {
if (g_ProcessProtectionInitialized) return STATUS_SUCCESS;
KeInitializeSpinLock(&g_ProcessRelationLock);
RtlZeroMemory(g_ProcessRelations, sizeof(g_ProcessRelations));
InterlockedExchange64(&g_ProcessRelationSequence, 0);
ExInitializeRundownProtection(&g_ProcessRundown);
UNICODE_STRING RoutineName = RTL_CONSTANT_STRING(L"PsGetProcessInheritedFromUniqueProcessId");
g_GetInheritedProcessId = reinterpret_cast<PPS_GET_PROCESS_INHERITED_FROM_UNIQUE_PROCESS_ID>(
MmGetSystemRoutineAddress(&RoutineName)
);
InterlockedExchange(&g_ProcessStopping, 0);
g_ProcessProtectionInitialized = TRUE;
return STATUS_SUCCESS;
}
NTSTATUS UninitializeProcessProtection() {
if (!g_ProcessProtectionInitialized) return STATUS_SUCCESS;
InterlockedExchange(&g_ProcessStopping, 1);
ExWaitForRundownProtectionRelease(&g_ProcessRundown);
KIRQL OldIrql;
KeAcquireSpinLock(&g_ProcessRelationLock, &OldIrql);
RtlZeroMemory(g_ProcessRelations, sizeof(g_ProcessRelations));
KeReleaseSpinLock(&g_ProcessRelationLock, OldIrql);
g_GetInheritedProcessId = NULL;
g_ProcessProtectionInitialized = FALSE;
return STATUS_SUCCESS;
}
VOID ProcessNotifyCallbackEx(
PEPROCESS Process,
HANDLE ProcessId,
PPS_CREATE_NOTIFY_INFO CreateInfo
) {
if (!g_ProcessProtectionInitialized) return;
if (InterlockedCompareExchange(&g_ProcessStopping, 0, 0) != 0) return;
if (!ExAcquireRundownProtection(&g_ProcessRundown)) return;
if (!CreateInfo) {
RemoveProcessRelation(ProcessId);
ExReleaseRundownProtection(&g_ProcessRundown);
return;
}
if (!NT_SUCCESS(CreateInfo->CreationStatus)) {
ExReleaseRundownProtection(&g_ProcessRundown);
return;
}
HANDLE CreatorPid = CreateInfo->CreatingThreadId.UniqueProcess;
HANDLE ParentPid = CreateInfo->ParentProcessId;
ULONG RuleCode = 0;
BOOLEAN Kill = FALSE;
BOOLEAN Blocked = EvaluateProcessCreateRule(
CreatorPid,
ParentPid,
ProcessId,
CreateInfo->ImageFileName,
CreateInfo->CommandLine,
CreateInfo->FileOpenNameAvailable ? TRUE : FALSE,
CreateInfo->IsSubsystemProcess ? TRUE : FALSE,
&RuleCode,
&Kill
);
if (Blocked) {
CreateInfo->CreationStatus = STATUS_ACCESS_DENIED;
if (CreateInfo->ImageFileName && CreateInfo->ImageFileName->Buffer) {
SendMessageToUser(
RuleCode,
(ULONG)(ULONG_PTR)CreatorPid,
CreateInfo->ImageFileName->Buffer,
CreateInfo->ImageFileName->Length
);
}
QueueRuleProcessTermination(CreatorPid, Kill);
}
else {
StoreProcessRelation(Process, ProcessId, ParentPid, CreatorPid, NULL);
}
ExReleaseRundownProtection(&g_ProcessRundown);
}
+242
View File
@@ -0,0 +1,242 @@
#include "DriverCommon.h"
static LARGE_INTEGER Cookie;
static BOOLEAN IsWriteAccess(ACCESS_MASK Access) {
if (Access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK |
DELETE | WRITE_DAC | WRITE_OWNER | GENERIC_WRITE)) {
return TRUE;
}
return FALSE;
}
static PWCHAR GetFullPath(PVOID RootObject, PUNICODE_STRING CompleteName, PULONG OutLength) {
PWCHAR Buffer = NULL;
ULONG TotalSize = 0;
PCUNICODE_STRING RootName = NULL;
BOOLEAN NeedFreeRootName = FALSE;
if (RootObject) {
NTSTATUS status = CmCallbackGetKeyObjectIDEx(&Cookie, RootObject, NULL, &RootName, 0);
if (NT_SUCCESS(status) && RootName) {
NeedFreeRootName = TRUE;
}
}
ULONG RootLen = (RootName && RootName->Buffer) ? RootName->Length : 0;
ULONG RelLen = (CompleteName && CompleteName->Buffer) ? CompleteName->Length : 0;
TotalSize = RootLen + sizeof(WCHAR) + RelLen + sizeof(WCHAR);
Buffer = (PWCHAR)PyasAllocate(TotalSize);
if (!Buffer) {
if (NeedFreeRootName) CmCallbackReleaseKeyObjectIDEx(RootName);
return NULL;
}
RtlZeroMemory(Buffer, TotalSize);
PWCHAR Current = Buffer;
if (RootLen > 0) {
RtlCopyMemory(Current, RootName->Buffer, RootLen);
Current += (RootLen / sizeof(WCHAR));
if (Current > Buffer && *(Current - 1) != L'\\') {
*Current = L'\\';
Current++;
}
}
if (RelLen > 0) {
if (RootLen > 0 && CompleteName->Buffer[0] == L'\\') {
RtlCopyMemory(Current, CompleteName->Buffer + 1, RelLen - sizeof(WCHAR));
}
else {
RtlCopyMemory(Current, CompleteName->Buffer, RelLen);
}
}
if (NeedFreeRootName) CmCallbackReleaseKeyObjectIDEx(RootName);
if (OutLength) *OutLength = (ULONG)wcslen(Buffer) * sizeof(WCHAR);
return Buffer;
}
static NTSTATUS RegistryCallback(PVOID CallbackContext, PVOID Argument1, PVOID Argument2) {
UNREFERENCED_PARAMETER(CallbackContext);
if (KeGetCurrentIrql() > APC_LEVEL) return STATUS_SUCCESS;
REG_NOTIFY_CLASS Class = (REG_NOTIFY_CLASS)(ULONG_PTR)Argument1;
NTSTATUS status = STATUS_SUCCESS;
if (Class == RegNtPreCreateKey || Class == RegNtPreOpenKey || Class == RegNtPreOpenKeyEx) {
PVOID RootObject = NULL;
PUNICODE_STRING CompleteName = NULL;
ACCESS_MASK DesiredAccess = 0;
if (Class == RegNtPreCreateKey) {
REG_CREATE_KEY_INFORMATION* Info = (REG_CREATE_KEY_INFORMATION*)Argument2;
RootObject = Info->RootObject;
CompleteName = Info->CompleteName;
DesiredAccess = Info->DesiredAccess;
}
else {
REG_OPEN_KEY_INFORMATION* Info = (REG_OPEN_KEY_INFORMATION*)Argument2;
RootObject = Info->RootObject;
CompleteName = Info->CompleteName;
DesiredAccess = Info->DesiredAccess;
}
if (!IsWriteAccess(DesiredAccess)) {
return STATUS_SUCCESS;
}
ULONG PathLen = 0;
PWCHAR FullPathBuffer = GetFullPath(RootObject, CompleteName, &PathLen);
if (FullPathBuffer) {
UNICODE_STRING FullPath;
RtlInitUnicodeString(&FullPath, FullPathBuffer);
HANDLE Pid = PsGetCurrentProcessId();
ULONG RuleCode = 0;
BOOLEAN Kill = FALSE;
if (EvaluateRegistryRule(Pid, &FullPath, OP_CREATE | OP_WRITE, &RuleCode, &Kill)) {
SendMessageToUser(RuleCode, (ULONG)(ULONG_PTR)Pid, FullPath.Buffer, FullPath.Length);
QueueRuleProcessTermination(Pid, Kill);
status = STATUS_ACCESS_DENIED;
}
PyasFree(FullPathBuffer);
}
return status;
}
if (Class == RegNtPreDeleteKey) {
REG_DELETE_KEY_INFORMATION* Info = (REG_DELETE_KEY_INFORMATION*)Argument2;
PCUNICODE_STRING KeyName = NULL;
if (NT_SUCCESS(CmCallbackGetKeyObjectIDEx(&Cookie, Info->Object, NULL, &KeyName, 0))) {
if (KeyName) {
HANDLE Pid = PsGetCurrentProcessId();
ULONG RuleCode = 0;
BOOLEAN Kill = FALSE;
if (EvaluateRegistryRule(Pid, KeyName, OP_DELETE, &RuleCode, &Kill)) {
SendMessageToUser(RuleCode, (ULONG)(ULONG_PTR)Pid, KeyName->Buffer, KeyName->Length);
QueueRuleProcessTermination(Pid, Kill);
status = STATUS_ACCESS_DENIED;
}
CmCallbackReleaseKeyObjectIDEx(KeyName);
}
}
return status;
}
if (Class == RegNtPreSetValueKey) {
REG_SET_VALUE_KEY_INFORMATION* Info = (REG_SET_VALUE_KEY_INFORMATION*)Argument2;
PCUNICODE_STRING KeyName = NULL;
if (NT_SUCCESS(CmCallbackGetKeyObjectIDEx(&Cookie, Info->Object, NULL, &KeyName, 0))) {
if (KeyName && KeyName->Buffer) {
ULONG FullSize = KeyName->Length + sizeof(WCHAR) +
(Info->ValueName ? Info->ValueName->Length : 0) +
sizeof(WCHAR);
if (FullSize <= 0xFFFF) {
PWCHAR Buffer = (PWCHAR)PyasAllocate(FullSize);
if (Buffer) {
UNICODE_STRING FullPath;
FullPath.Buffer = Buffer;
FullPath.Length = 0;
FullPath.MaximumLength = (USHORT)FullSize;
RtlCopyUnicodeString(&FullPath, KeyName);
if (Info->ValueName && Info->ValueName->Length > 0) {
if (FullPath.Length > 0 && FullPath.Buffer[(FullPath.Length / sizeof(WCHAR)) - 1] != L'\\') {
RtlAppendUnicodeToString(&FullPath, L"\\");
}
RtlAppendUnicodeStringToString(&FullPath, Info->ValueName);
}
HANDLE Pid = PsGetCurrentProcessId();
ULONG RuleCode = 0;
BOOLEAN Kill = FALSE;
if (EvaluateRegistryRule(Pid, &FullPath, OP_WRITE, &RuleCode, &Kill)) {
SendMessageToUser(RuleCode, (ULONG)(ULONG_PTR)Pid, FullPath.Buffer, FullPath.Length);
QueueRuleProcessTermination(Pid, Kill);
status = STATUS_ACCESS_DENIED;
}
PyasFree(Buffer);
}
}
}
if (KeyName) CmCallbackReleaseKeyObjectIDEx(KeyName);
}
return status;
}
if (Class == RegNtPreDeleteValueKey) {
REG_DELETE_VALUE_KEY_INFORMATION* Info = (REG_DELETE_VALUE_KEY_INFORMATION*)Argument2;
PCUNICODE_STRING KeyName = NULL;
if (NT_SUCCESS(CmCallbackGetKeyObjectIDEx(&Cookie, Info->Object, NULL, &KeyName, 0))) {
if (KeyName && KeyName->Buffer) {
ULONG FullSize = KeyName->Length + sizeof(WCHAR) +
(Info->ValueName ? Info->ValueName->Length : 0) +
sizeof(WCHAR);
if (FullSize <= 0xFFFF) {
PWCHAR Buffer = (PWCHAR)PyasAllocate(FullSize);
if (Buffer) {
UNICODE_STRING FullPath;
FullPath.Buffer = Buffer;
FullPath.Length = 0;
FullPath.MaximumLength = (USHORT)FullSize;
RtlCopyUnicodeString(&FullPath, KeyName);
if (Info->ValueName && Info->ValueName->Length > 0) {
if (FullPath.Length > 0 && FullPath.Buffer[(FullPath.Length / sizeof(WCHAR)) - 1] != L'\\') {
RtlAppendUnicodeToString(&FullPath, L"\\");
}
RtlAppendUnicodeStringToString(&FullPath, Info->ValueName);
}
HANDLE Pid = PsGetCurrentProcessId();
ULONG RuleCode = 0;
BOOLEAN Kill = FALSE;
if (EvaluateRegistryRule(Pid, &FullPath, OP_DELETE, &RuleCode, &Kill)) {
SendMessageToUser(RuleCode, (ULONG)(ULONG_PTR)Pid, FullPath.Buffer, FullPath.Length);
QueueRuleProcessTermination(Pid, Kill);
status = STATUS_ACCESS_DENIED;
}
PyasFree(Buffer);
}
}
}
if (KeyName) CmCallbackReleaseKeyObjectIDEx(KeyName);
}
return status;
}
return STATUS_SUCCESS;
}
NTSTATUS InitializeRegistryProtection(PDRIVER_OBJECT DriverObject) {
if (Cookie.QuadPart != 0) return STATUS_SUCCESS;
UNICODE_STRING Altitude;
RtlInitUnicodeString(&Altitude, L"320000.4201");
return CmRegisterCallbackEx(RegistryCallback, &Altitude, DriverObject, NULL, &Cookie, NULL);
}
NTSTATUS UninitializeRegistryProtection() {
if (Cookie.QuadPart == 0) return STATUS_SUCCESS;
NTSTATUS Status = CmUnRegisterCallback(Cookie);
if (NT_SUCCESS(Status)) {
Cookie.QuadPart = 0;
}
return Status;
}
File diff suppressed because it is too large. Load diff
+20
View File
@@ -0,0 +1,20 @@
#include <windows.h>
#include <ntverp.h>
#define VER_FILETYPE VFT_DRV
#define VER_FILESUBTYPE VFT2_DRV_SYSTEM
#define VER_FILEDESCRIPTION_STR "PYAS Security Driver Protect"
#define VER_INTERNALNAME_STR "PYAS"
#define VER_LEGALCOPYRIGHT_STR "PYAS Security"
#define VER_ORIGINALFILENAME_STR "PYAS_Driver.sys"
#define VER_PRODUCTNAME_STR "PYAS"
#define VER_FILEVERSION 3,5,1,0
#define VER_FILEVERSION_STR "3,5,1,0"
#define VER_PRODUCTVERSION 3,5,1,0
#define VER_PRODUCTVERSION_STR "3,5,1,0"
#define VER_COMPANYNAME_STR "PYAS Security"
#include "common.ver"
+727
View File
@@ -0,0 +1,727 @@
{
"DynamicRules": [
{
"Name": "Self_Antivirus_Protect_Command",
"Code": 1001,
"Kill": false,
"Category": "Process",
"Initiator": [
"\\Device\\HarddiskVolume*\\Windows\\System32\\cmd.exe",
"\\Device\\HarddiskVolume*\\Windows\\SysWOW64\\cmd.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\WindowsPowerShell\\*\\powershell.exe",
"\\Device\\HarddiskVolume*\\Windows\\SysWOW64\\WindowsPowerShell\\*\\powershell.exe",
"\\Device\\HarddiskVolume*\\Program Files\\PowerShell\\*\\pwsh.exe",
"\\Device\\HarddiskVolume*\\Program Files (x86)\\PowerShell\\*\\pwsh.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\wscript.exe",
"\\Device\\HarddiskVolume*\\Windows\\SysWOW64\\wscript.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\cscript.exe",
"\\Device\\HarddiskVolume*\\Windows\\SysWOW64\\cscript.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\mshta.exe",
"\\Device\\HarddiskVolume*\\Windows\\SysWOW64\\mshta.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\wsl.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\bash.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\rundll32.exe",
"\\Device\\HarddiskVolume*\\Windows\\SysWOW64\\rundll32.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\regsvr32.exe",
"\\Device\\HarddiskVolume*\\Windows\\SysWOW64\\regsvr32.exe",
],
"InitiatorExclude": [
"*\\PYAS.exe",
],
"CommandLine": [
"*taskkill*PYAS.exe*",
"*taskkill*msedgewebview2.exe*",
"*Stop-Process*PYAS*",
"*Stop-Process*msedgewebview2*",
"*Get-Process*PYAS*Stop-Process*",
"*Get-Process*msedgewebview2*Stop-Process*",
"*wmic*PYAS.exe*call terminate*",
"*wmic*PYAS.exe*delete*",
"*wmic*msedgewebview2.exe*call terminate*",
"*wmic*msedgewebview2.exe*delete*",
],
"Operations": [
"Execute",
],
"Target": [
"*\\taskkill.exe",
"*\\cmd.exe",
"*\\powershell.exe",
"*\\pwsh.exe",
"*\\wmic.exe",
],
"Priority": 110,
"FileOpenNameAvailable": true,
"SubsystemProcess": false,
},
{
"Name": "Self_Antivirus_Protect_Handle",
"Code": 1002,
"Kill": false,
"Category": "Process",
"InitiatorExclude": [
"*\\PYAS.exe",
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\Local\\Temp\\*\\PYAS_Setup.tmp",
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\Local\\Temp\\*\\_unins.tmp",
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\Local\\sogoupdf\\pdfpopcl.exe",
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\Local\\WeGame\\*\\tiny_dl\\TinyDL.exe",
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\Local\\Microsoft\\OneDrive\\OneDrive.exe",
"\\Device\\HarddiskVolume*\\Windows\\explorer.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\csrss.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\lsass.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\services.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\svchost.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\msiexec.exe",
"\\Device\\HarddiskVolume*\\Windows\\SystemApps\\*\\SearchHost.exe",
"\\Device\\HarddiskVolume*\\Program Files\\*",
"\\Device\\HarddiskVolume*\\Program Files (x86)\\*",
"*\\games\\Arknights Game\\Arknights.exe",
"*\\games\\EndField Game\\EndField.exe",
"*\\cm\\FeverGames\\*\\FeverGamesInstaller.exe",
"*\\Davinci\\Resolve.exe",
],
"Target": [
"*\\PYAS.exe",
"*\\msedgewebview2.exe",
],
"TargetProcessTree": [
"*\\PYAS.exe",
],
"Operations": [
"Terminate",
"SuspendResume",
"DuplicateHandle",
"CreateProcess",
"SetThreadToken",
"Impersonate",
],
"Priority": 130,
"InitiatorProcessTreeExclude": [
"*\\PYAS.exe",
],
"HandleTypes": [
"Create",
"Duplicate",
],
"OperationMatch": "Any",
"MinimumRiskScore": 20,
"ObjectTypes": [
"Process",
"Thread",
]
},
{
"Name": "Attack_Command_Block_EFI_Mount",
"Code": 1003,
"Kill": false,
"Category": "Process",
"Target": [
"*\\mountvol.exe",
],
"CommandLine": [
"*mountvol* /S*",
],
"Operations": [
"Execute",
],
"Priority": 170,
"FileOpenNameAvailable": true,
},
{
"Name": "Attack_Command_Block_Destructive_Cmd_Delete",
"Code": 1004,
"Kill": true,
"Category": "Process",
"Target": [
"*\\cmd.exe",
],
"CommandLine": [
"*rd /s /q C:\\*",
"*rmdir /s /q C:\\*",
"*del X:\\* /s /f /q*",
"*rd /s /q X:\\EFI*",
],
"Operations": [
"Execute",
],
"Priority": 190,
"FileOpenNameAvailable": true,
},
{
"Name": "Attack_Command_Block_Forced_OOBE_Sysprep",
"Code": 1005,
"Kill": false,
"Category": "Process",
"Target": [
"*\\sysprep.exe",
],
"CommandLine": [
"*sysprep* /oobe*",
"*sysprep*/oobe*",
"* /oobe* /reboot*",
"* /generalize* /oobe*",
],
"Operations": [
"Execute",
],
"Priority": 185,
"FileOpenNameAvailable": true,
},
{
"Name": "Process_Protect_UserWritable_SystemName_Dll_Load",
"Code": 1006,
"Kill": false,
"Category": "Process",
"Initiator": [
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\*\\svchost.exe",
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\*\\rundll32.exe",
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\*\\regsvr32.exe",
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\*\\dllhost.exe",
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\*\\msiexec.exe",
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\*\\taskhostw.exe",
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\*\\spoolsv.exe",
"\\Device\\HarddiskVolume*\\Users\\*\\Downloads\\*\\svchost.exe",
"\\Device\\HarddiskVolume*\\Users\\*\\Downloads\\*\\rundll32.exe",
"\\Device\\HarddiskVolume*\\Users\\*\\Downloads\\*\\regsvr32.exe",
"\\Device\\HarddiskVolume*\\Users\\*\\Desktop\\*\\svchost.exe",
"\\Device\\HarddiskVolume*\\Users\\*\\Desktop\\*\\rundll32.exe",
"\\Device\\HarddiskVolume*\\Users\\*\\Desktop\\*\\regsvr32.exe",
"\\Device\\HarddiskVolume*\\ProgramData\\*\\svchost.exe",
"\\Device\\HarddiskVolume*\\ProgramData\\*\\rundll32.exe",
"\\Device\\HarddiskVolume*\\ProgramData\\*\\regsvr32.exe",
],
"Target": [
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\*\\*.dll",
"\\Device\\HarddiskVolume*\\Users\\*\\Downloads\\*\\*.dll",
"\\Device\\HarddiskVolume*\\Users\\*\\Desktop\\*\\*.dll",
"\\Device\\HarddiskVolume*\\ProgramData\\*\\*.dll",
],
"Operations": [
"ImageLoad",
],
"Priority": 160,
},
{
"Name": "Self_Antivirus_Protect_File",
"Code": 2001,
"Kill": false,
"Category": "File",
"InitiatorExclude": [
"*\\PYAS.exe",
"*\\notepad*.exe",
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\Local\\Temp\\*\\PYAS_Setup.tmp",
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\Local\\Temp\\*\\_unins.tmp",
"\\Device\\HarddiskVolume*\\Windows\\explorer.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\cleanmgr.exe",
],
"Target": [
"*\\PYAS.exe",
"*\\ProgramData\\PYAS\\*.json",
"*\\Engine\\Heuristic\\*.yar",
"*\\Engine\\Heuristic\\*.yara",
"*\\Engine\\Heuristic\\*.yc",
"*\\Engine\\Heuristic\\*.yrc",
"*\\Engine\\Heuristic\\*.ip",
"*\\Engine\\Heuristic\\*.txt",
"*\\Engine\\Pattern\\*.onnx",
"*\\Engine\\Properties\\*.json",
"*\\Engine\\Properties\\*.onnx",
"*\\Interface\\static\\css\\*.css",
"*\\Interface\\static\\img\\*.ico",
"*\\Interface\\static\\js\\*.js",
"*\\Interface\\templates\\*.html",
"*\\Plugins\\Filter\\*.sys",
"*\\Plugins\\Rules\\*.json",
],
"Operations": [
"Write",
"Delete",
]
},
{
"Name": "System_Boot_Protect_File",
"Code": 2002,
"Kill": true,
"Category": "File",
"InitiatorExclude": [
"*\\PYAS.exe",
"*\\Huorong\\Sysdiag\\bin\\sysclean.exe",
"*\\Dell\\SARemediation\\agent\\DellSupportAssistRemedationService.exe",
"\\Device\\HarddiskVolume*\\Windows\\explorer.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\SearchIndexer.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\lsass.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\svchost.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\services.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\taskhostw.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\TrustedInstaller.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\ReAgentc.exe",
"\\Device\\HarddiskVolume*\\Windows\\WinSxS\\*\\TiWorker.exe",
"\\Device\\HarddiskVolume*\\Windows\\UUS\\amd64\\wuaucltcore.exe",
"\\Device\\HarddiskVolume*\\$WinREAgent\\Scratch\\*\\DismHost.exe",
],
"Target": [
"\\Device\\HarddiskVolume*\\bootmgr",
"\\Device\\HarddiskVolume*\\boot.ini",
"\\Device\\HarddiskVolume*\\BOOTNXT",
"\\Device\\HarddiskVolume*\\EFI\\*",
"\\Device\\HarddiskVolume*\\Boot\\*",
"\\Device\\HarddiskVolume*\\Recovery\\*",
],
"TargetExclude": [
"\\Device\\HarddiskVolume*\\Windows\\System32\\Recovery\\ReAgent.xml",
"\\Device\\HarddiskVolume*\\Recovery\\OEM\\Logs\\Versions.ini",
],
"Operations": [
"Write",
"Delete",
]
},
{
"Name": "Illegal_Characters_Protect_File",
"Code": 2003,
"Kill": false,
"Category": "File",
"InitiatorExclude": [
"*\\PYAS.exe",
],
"Target": [
"*\\CON",
"*\\CON\\*",
"*\\PRN",
"*\\PRN\\*",
"*\\AUX",
"*\\AUX\\*",
"*\\NUL",
"*\\NUL\\*",
"*\\COM?",
"*\\COM?\\*",
"*\\LPT?",
"*\\LPT?\\*",
"*\\OSDATA",
"*\\OSDATA\\*",
"*\\*<*",
"*\\*>*",
],
"Operations": [
"Create",
"Write",
"Rename",
]
},
{
"Name": "System_Ransom_Protect_File",
"Code": 2004,
"Kill": true,
"Category": "File",
"Initiator": [
"\\Device\\HarddiskVolume*\\Windows\\System32\\cmd.exe",
"\\Device\\HarddiskVolume*\\Windows\\SysWOW64\\cmd.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\WindowsPowerShell\\*\\powershell.exe",
"\\Device\\HarddiskVolume*\\Windows\\SysWOW64\\WindowsPowerShell\\*\\powershell.exe",
"\\Device\\HarddiskVolume*\\Program Files\\PowerShell\\*\\pwsh.exe",
"\\Device\\HarddiskVolume*\\Program Files (x86)\\PowerShell\\*\\pwsh.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\wscript.exe",
"\\Device\\HarddiskVolume*\\Windows\\SysWOW64\\wscript.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\cscript.exe",
"\\Device\\HarddiskVolume*\\Windows\\SysWOW64\\cscript.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\mshta.exe",
"\\Device\\HarddiskVolume*\\Windows\\SysWOW64\\mshta.exe",
],
"Target": [
"\\Device\\HarddiskVolume*\\Windows\\*",
],
"TargetExclude": [
"\\Device\\HarddiskVolume*\\Windows\\Temp\\*",
"\\Device\\HarddiskVolume*\\Windows\\SystemTemp\\*",
"\\Device\\HarddiskVolume*\\Windows\\Prefetch\\*",
"\\Device\\HarddiskVolume*\\Windows\\Logs\\*",
"\\Device\\HarddiskVolume*\\Windows\\WinSxS\\*",
"\\Device\\HarddiskVolume*\\Windows\\servicing\\*",
],
"Operations": [
"Delete",
"Rename",
],
"Threshold": 50,
"TimeWindow": 3000,
},
{
"Name": "User_Ransom_Protect_File",
"Code": 2005,
"Kill": true,
"Category": "File",
"InitiatorExclude": [
"\\Device\\HarddiskVolume*\\Windows\\*",
"\\Device\\HarddiskVolume*\\Program Files\\*",
"\\Device\\HarddiskVolume*\\Program Files (x86)\\*",
"*\\Google\\Chrome\\Application\\chrome.exe",
"*\\Microsoft\\Edge\\Application\\msedge.exe",
"*\\Microsoft\\Edge*\\Application\\*\\msedgewebview2.exe",
"*\\Microsoft\\Edge*\\Install\\*\\setup.exe",
"*\\Microsoft\\Edge*\\Application\\*\\Installer\\setup.exe",
"*\\Mozilla Firefox\\firefox.exe",
"*\\Thorium\\Application\\thorium.exe",
"*\\Steam\\steam.exe",
"*\\steam\\*\\steam.exe",
"*\\Steam\\steamapps\\common\\*",
"*\\Battle.net\\*\\Battle.net.exe",
"*\\Epic Games\\Launcher\\Portal\\Binaries\\*\\EpicGamesLauncher.exe",
"*\\PC4399_WPFLauncher.exe",
"*\\Neverness To Everness\\NTELauncher.exe",
"*\\ThunderEv.exe",
"*\\ThunderStart.exe",
"*\\bin\\APlayer.exe",
"*\\bilibili\\bilibili.exe",
"*\\KuGou.exe",
"*\\XLGame.exe",
"*\\XLLiveUD.exe",
"*\\hrkill-*.exe",
"*\\Huorong\\Sysdiag\\bin\\HipsDaemon.exe",
"*\\360Safe.exe",
"*\\PYAS.exe",
"*\\WPS Office\\ksolaunch.exe",
"*\\WPS Office\\*\\wps.exe",
"*\\Application\\AndrowsLauncher.exe",
"*\\resources\\bin\\SDK\\DownloadSDKServer.exe",
"*\\bin\\*\\codex.exe",
"*\\bin\\codex.exe",
"*\\Weixin\\Weixin.exe",
"*\\Audacity\\Audacity.exe",
],
"Target": [
"\\Device\\HarddiskVolume*\\Users\\*",
],
"TargetExclude": [
"*\\Documents\\My Games\\*",
"*\\Documents\\Tencent Files\\*",
"*\\Documents\\WeChat Files\\*",
"*\\Documents\\WPS Cloud Files\\*",
"*\\Users\\*\\steam\\*",
"\\Device\\HarddiskVolume*\\Users\\*\\User Data\\*",
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\*",
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\Local\\*",
"\\Device\\HarddiskVolume*\\Users\\*\\Temp\\*",
"\\Device\\HarddiskVolume*\\Users\\*\\Local\\Temp\\*",
"\\Device\\HarddiskVolume*\\Users\\*\\cache\\*",
"\\Device\\HarddiskVolume*\\Users\\*\\.cache\\*",
"\\Device\\HarddiskVolume*\\Users\\*\\.aws\\*",
"\\Device\\HarddiskVolume*\\Users\\*\\.codex\\*",
"\\Device\\HarddiskVolume*\\Users\\*\\.designer\\*",
"\\Device\\HarddiskVolume*\\Users\\*\\.idlerc\\*",
"\\Device\\HarddiskVolume*\\Users\\*\\.keras\\*",
"\\Device\\HarddiskVolume*\\Users\\*\\.matplotlib\\*",
"\\Device\\HarddiskVolume*\\Users\\*\\.ssh\\*",
"*\\ventoy\\Boot\\*",
"*\\AdminRegionConfig.*",
"*\\nt_qq\\nt_*\\*",
"*\\nt_qq\\global\\nt_*\\*",
"\\Device\\HarddiskVolume*\\Users\\*\\Documents\\Tencent Files\\*",
],
"Extensions": [
".zip",
".7z",
".rar",
".tar",
".gz",
".ppt",
".pptx",
".wps",
".txt",
".rtf",
".pdf",
".xls",
".xlsx",
".doc",
".docx",
".jpg",
".jpeg",
".png",
".webp",
".gif",
".mp3",
".wav",
".aac",
".ogg",
".flac",
".mp4",
".avi",
".mov",
".wmv",
".mkv",
],
"Operations": [
"Write",
"Delete",
"Rename",
],
"Threshold": 10,
"TimeWindow": 3000,
},
{
"Name": "System_Boot_Protect_Disk_Wiper",
"Code": 2006,
"Kill": false,
"Category": "Device",
"InitiatorExclude": [
"*\\PYAS.exe",
"*\\rufus-*.exe",
"*\\DiskInfo*.exe",
"\\Device\\HarddiskVolume*\\Program Files\\*\\launcher\\ca_launcher.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\diskpart.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\diskmgmt.msc",
"\\Device\\HarddiskVolume*\\Windows\\System32\\taskhostw.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\vds.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\format.com",
"\\Device\\HarddiskVolume*\\Windows\\System32\\WinSAT.exe",
],
"Operations": [
"Ioctl",
]
},
{
"Name": "Registry_Protect_System_Suspicious",
"Code": 3001,
"Kill": false,
"Category": "Registry",
"InitiatorExclude": [
"\\Device\\HarddiskVolume*\\Windows\\*",
"\\Device\\HarddiskVolume*\\Program Files\\*",
"\\Device\\HarddiskVolume*\\Program Files (x86)\\*",
"\\Device\\HarddiskVolume*\\ProgramData\\Microsoft\\Windows Defender\\*",
"\\Device\\HarddiskVolume*\\ProgramData\\Microsoft\\Windows Defender Advanced Threat Protection\\*",
"*\\hrkill-*.exe",
"*\\Huorong\\Sysdiag\\bin\\HipsDaemon.exe",
"*\\360Safe.exe",
"*\\PYAS.exe",
],
"Target": [
"*\\mouclass",
"*\\kbdclass",
"*\\DisableAntiSpyware",
"*\\DisableWindowsUpdateAccess",
"*\\NoWindowsUpdate",
"*\\AutoAdminLogon",
"*\\DefaultUserName",
"*\\DefaultPassword",
"*\\AltDefaultUserName",
"*\\AltDefaultPassword",
"*\\AutoReboot",
"*\\DisableAutomaticRestartOnFailure",
"*\\SystemBiosVersion",
"*\\ClearRecentDocsOnExit",
"*\\HideClock",
"*\\HideFastUserSwitching",
"*\\ShutdownWithoutLogon",
"*\\DisableCAD",
],
"Operations": [
"Write",
"Delete",
"Create",
],
"Priority": 130,
},
{
"Name": "Registry_Protect_Open_With_Suspicious",
"Code": 3002,
"Kill": false,
"Category": "Registry",
"InitiatorExclude": [
"\\Device\\HarddiskVolume*\\Windows\\*",
"\\Device\\HarddiskVolume*\\Program Files\\*",
"\\Device\\HarddiskVolume*\\Program Files (x86)\\*",
"*\\PYAS.exe",
],
"Target": [
"*\\Classes\\.exe",
"*\\Classes\\.com",
"*\\Classes\\.bat",
"*\\Classes\\.cmd",
"*\\Classes\\exefile\\*",
"*\\Classes\\comfile\\*",
"*\\Classes\\batfile\\*",
"*\\Classes\\cmdfile\\*",
],
"Operations": [
"Write",
"Delete",
"Create",
],
"Priority": 150,
},
{
"Name": "Registry_Protect_BCD_Suspicious",
"Code": 3003,
"Kill": false,
"Category": "Registry",
"InitiatorExclude": [
"\\Device\\HarddiskVolume*\\Windows\\*",
"\\Device\\HarddiskVolume*\\ProgramData\\Microsoft\\Windows Defender\\*",
"\\Device\\HarddiskVolume*\\ProgramData\\Microsoft\\Windows Defender Advanced Threat Protection\\*",
"*\\PYAS.exe",
],
"Target": [
"\\REGISTRY\\MACHINE\\BCD00000000",
"\\REGISTRY\\MACHINE\\BCD00000000\\*",
],
"Operations": [
"Write",
"Delete",
"Create",
],
"Priority": 140,
},
{
"Name": "Registry_Protect_System_Critical",
"Code": 3004,
"Kill": true,
"Category": "Registry",
"InitiatorExclude": [
"\\Device\\HarddiskVolume*\\Windows\\*",
"*\\PYAS.exe",
],
"Target": [
"*\\EnableLUA",
"*\\ConsentPromptBehaviorAdmin",
"*\\ConsentPromptBehaviorUser",
"*\\EnableSecureUIAPaths",
"*\\BootExecute",
"*\\SubSystems",
"*\\FirmwareBootDevice",
"*\\BootDriverFlags",
"*\\SystemStartOptions",
"*\\Userinit",
"*\\UIHost",
"*\\NoControlPanel",
"*\\NoDrives",
"*\\NoFileMenu",
"*\\NoFind",
"*\\NoStartMenuPinnedList",
"*\\NoSetFolders",
"*\\NoSetFolderOptions",
"*\\NoViewOnDrive",
"*\\NoClose",
"*\\NoDesktop",
"*\\NoLogoff",
"*\\NoFolderOptions",
"*\\RestrictRun",
"*\\NoViewContextMenu",
"*\\NoStartMenuMyGames",
"*\\NoStartMenuMyMusic",
"*\\DisableCMD",
"*\\NoAddingComponents",
"*\\NoWinKeys",
"*\\NoStartMenuLogOff",
"*\\NoSimpleNetIDList",
"*\\NoLowDiskSpaceChecks",
"*\\DisableLockWorkstation",
"*\\Restrict_Run",
"*\\DisableTaskMgr",
"*\\DisableRegistryTools",
"*\\DisableChangePassword",
"*\\NoComponents",
"*\\NoStartMenuMorePrograms",
"*\\NoActiveDesktop",
"*\\NoSetActiveDesktop",
"*\\NoRecentDocsMenu",
"*\\NoChangeStartMenu",
"*\\NoFavoritesMenu",
"*\\NoRecentDocsHistory",
"*\\NoSetTaskbar",
"*\\NoSMHelp",
"*\\NoTrayContextMenu",
"*\\NoManageMyComputerVerb",
"*\\NoRealMode",
"*\\NoRun",
"*\\NoActiveDesktopChanges",
"*\\NoStartMenuNetworkPlaces",
"*\\NoLockScreen",
"*\\NoSRM",
"*\\NoInteractiveServices",
"*\\NoTheme",
],
"Operations": [
"Write",
"Delete",
"Create",
],
"Priority": 180,
},
{
"Name": "Registry_Protect_SafeMode_Autostart",
"Code": 3005,
"Kill": true,
"Category": "Registry",
"InitiatorExclude": [
"\\Device\\HarddiskVolume*\\Windows\\*",
"\\Device\\HarddiskVolume*\\ProgramData\\Microsoft\\Windows Defender\\*",
"\\Device\\HarddiskVolume*\\ProgramData\\Microsoft\\Windows Defender Advanced Threat Protection\\*",
"*\\Sources\\SetupHost.exe",
"*\\Work\\*\\DismHost.exe",
"*\\Huorong\\Sysdiag\\bin\\HipsDaemon.exe",
"*\\Huorong\\Sysdiag\\bin\\HRUpdate.exe",
"*\\360Safe.exe",
"*\\PYAS.exe",
],
"Target": [
"\\REGISTRY\\MACHINE\\SYSTEM\\*ControlSet*\\Control\\SafeBoot\\Minimal\\*",
"\\REGISTRY\\MACHINE\\SYSTEM\\*ControlSet*\\Control\\SafeBoot\\Network\\*",
"\\REGISTRY\\MACHINE\\SYSTEM\\*ControlSet*\\Control\\SafeBoot\\AlternateShell",
"\\REGISTRY\\MACHINE\\SYSTEM\\*ControlSet*\\Control\\SafeBoot\\AlternateShell\\*",
"\\REGISTRY\\MACHINE\\SYSTEM\\*ControlSet*\\Control\\SafeBoot\\Option",
"\\REGISTRY\\MACHINE\\SYSTEM\\*ControlSet*\\Control\\SafeBoot\\Option\\*",
],
"TargetExclude": [
"\\REGISTRY\\MACHINE\\SYSTEM\\ControlSet001\\Control\\SafeBoot\\Network\\HipsDaemon",
],
"Operations": [
"Write",
"Delete",
"Create",
],
"Priority": 170,
},
{
"Name": "Registry_Protect_OOBE_Reset",
"Code": 3006,
"Kill": false,
"Category": "Registry",
"InitiatorExclude": [
"*\\PYAS.exe",
"*\\Sources\\SetupHost.exe",
"*\\Work\\*\\DismHost.exe",
"\\Device\\HarddiskVolume*\\Windows\\UUS\\amd64\\MoUsoCoreWorker.exe",
"\\Device\\HarddiskVolume*\\Windows\\UUS\\Packages\\Preview\\amd64\\MoUsoCoreWorker.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\MoUsoCoreWorker.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\Sysprep\\sysprep.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\oobe\\*",
"\\Device\\HarddiskVolume*\\Windows\\System32\\svchost.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\taskhostw.exe",
"\\Device\\HarddiskVolume*\\Windows\\explorer.exe",
],
"Target": [
"\\REGISTRY\\MACHINE\\SYSTEM\\Setup\\OOBEInProgress",
"\\REGISTRY\\MACHINE\\SYSTEM\\Setup\\SystemSetupInProgress",
"\\REGISTRY\\MACHINE\\SYSTEM\\Setup\\SetupType",
"\\REGISTRY\\MACHINE\\SYSTEM\\Setup\\CmdLine",
"\\REGISTRY\\MACHINE\\SYSTEM\\Setup\\AuditInProgress",
"\\REGISTRY\\MACHINE\\SYSTEM\\Setup\\MiniSetupInProgress",
"\\REGISTRY\\MACHINE\\SYSTEM\\Setup\\SetupPhase",
"\\REGISTRY\\MACHINE\\SYSTEM\\Setup\\Status\\SysprepStatus\\*",
"\\REGISTRY\\MACHINE\\SYSTEM\\Setup\\Status\\ChildCompletion\\*",
"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State\\ImageState",
"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\OOBE\\*",
"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\OOBE\\*",
],
"TargetExclude": [
"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\OOBE\\TelemetryCorrelation",
],
"Operations": [
"Write",
"Delete",
"Create",
],
"Priority": 175,
},
]
}
+360 -14
View File
@@ -1,20 +1,366 @@
# PYAS (Python Antivirus Software)
![PYAS](https://github.com/87owo/PYAS/assets/85057800/e49a0aef-6ef6-4485-8f93-e7a73f9571ea)
# PYAS Security
## Official Website
https://pyantivirus.wixsite.com/pyas ,
https://github.com/87owo/PYAS
<div align="center">
## MIT License
https://github.com/87owo/PYAS/blob/main/LICENSE.md
**A hybrid Windows endpoint security platform powered by machine learning, YARA rules, cloud analysis, and kernel-level behavioral protection.**
## Support System
Windows 8.1, 10, 11 (64-bit), Ram 1GB, Rom 1GB or higher
[![Latest Release](https://img.shields.io/github/v/release/87owo/PYAS?display_name=tag&style=flat-square)](https://github.com/87owo/PYAS/releases/latest)
[![GitHub Stars](https://img.shields.io/github/stars/87owo/PYAS?style=flat-square)](https://github.com/87owo/PYAS/stargazers)
[![GitHub Forks](https://img.shields.io/github/forks/87owo/PYAS?style=flat-square)](https://github.com/87owo/PYAS/network/members)
[![Platform](https://img.shields.io/badge/platform-Windows%2010%2F11-0078D4?style=flat-square&logo=windows)](https://github.com/87owo/PYAS)
[![Python](https://img.shields.io/badge/Python-3.10-3776AB?style=flat-square&logo=python&logoColor=white)](https://www.python.org/)
[![C++](https://img.shields.io/badge/kernel-C%2B%2B-00599C?style=flat-square&logo=cplusplus)](https://github.com/87owo/PYAS/tree/main/Plugins/Filter)
## Import Module
os, sys, time, json, psutil, ctypes, requests, subprocess, win32file, win32api, win32con, elementpath, hashlib, pefile, threading, PyQt5, PYAS_Language, PYAS_Model, PYAS_UI
[Website](https://pyas-security.com/antivirus) · [Online Analysis](https://pyas-security.com/analyze) · [Download](https://github.com/87owo/PYAS/releases) · [Report an Issue](https://github.com/87owo/PYAS/issues)
## Special Thanks
360, Wix, VirusShare, mtkiao129, LenStevens
</div>
Copyright© 2020~2023 PYAS Security By 87owo
![PYAS Security interface](https://github.com/user-attachments/assets/4a7e6b52-7001-4726-96fe-a2d6ccc8e6a4)
## Overview
PYAS Security is a source-available Windows endpoint security project that combines multiple detection and protection layers in one desktop application. It brings together local PE-file machine-learning inference, YARA-based matching, digital-signature inspection, optional cloud analysis, real-time user-mode monitoring, and a native Windows minifilter driver.
The project is designed both as a usable security application and as an engineering platform for studying malware detection, Windows internals, rule-driven prevention, model training, and online file analysis.
> [!IMPORTANT]
> PYAS is an independent security project. No antivirus product can guarantee detection of every threat. Evaluate it in a controlled environment before production use, keep backups, and review alerts before deleting files.
## Why PYAS
- **Layered detection** — combines YARA, PE feature analysis, ONNX models, signature verification, and cloud-assisted analysis.
- **Behavior-oriented protection** — monitors processes, files, memory, network activity, system settings, and sensitive operations.
- **Kernel integration** — includes a C++ minifilter driver with configurable protection rules and user-mode communication.
- **Local-first scanning** — performs core static analysis on the endpoint; cloud submission is separately configurable.
- **Operational tooling** — adds quarantine, allow/block lists, system repair, startup management, cleanup, and activity reporting.
- **Research-ready codebase** — includes model-training utilities, an online analysis service, an API client, experimental engines, and a visual rule editor.
## Protection capabilities
| Layer | Capability | Implementation |
|---|---|---|
| Static rules | File and process-memory matching | YARA rules compiled and loaded by `rule_scanner` |
| PE machine learning | Feature extraction and local classification | `pefile`, NumPy, ONNX Runtime |
| Signature trust | Authenticode verification | Windows WinVerifyTrust APIs |
| Cloud analysis | Upload, polling, rescan, and result retrieval | HTTPS API with chunked upload support |
| Process protection | New-process inspection, optional suspension, termination controls | Win32/NT APIs and worker pools |
| File protection | Directory change monitoring, debounced real-time scans, file locking | Windows file notification APIs |
| Memory protection | Process-memory YARA scanning and kernel callbacks | User-mode scanner plus driver rules |
| Network visibility | Process-aware TCP connection monitoring | Windows IP Helper APIs |
| Kernel enforcement | File, process/thread, registry, memory, image-load, and boot/disk controls | Native C++ minifilter driver |
| Recovery and maintenance | Quarantine, system repair, startup management, cleanup, MBR backup/check | Python application services |
Protection modules are individually configurable. Several active-protection switches are disabled by default so users can enable only the controls appropriate for their environment.
## Detection pipeline
```mermaid
flowchart LR
A[File or process event] --> B{Scope and policy checks}
B -->|Allowed| C[Hash and metadata]
B -->|Excluded| Z[Skip]
C --> D[Digital signature verification]
C --> E[YARA rule scan]
C --> F[PE feature extraction]
F --> G[ONNX model inference]
D --> H[Local verdict aggregation]
E --> H
G --> H
H --> I{Cloud analysis enabled?}
I -->|Yes| J[Hash lookup / chunked upload]
J --> K[Cloud report]
I -->|No| L[Local result]
K --> M[Alert and response]
L --> M
M --> N[Quarantine / delete / allow]
```
## System architecture
```mermaid
flowchart TB
subgraph UI[Presentation layer]
WEB[HTML / CSS / JavaScript]
WV[WebView2 desktop shell]
TRAY[System tray and Windows shell integration]
end
subgraph APP[Python application layer]
CORE[PYAS.py orchestration]
SCAN[ScannerMixin]
PROTECT[ProtectMixin]
TOOLS[ToolsMixin]
ENGINE[PYAS_Engine.py]
end
subgraph DETECT[Detection engines]
YARA[YARA rules]
PE[PE feature extractor]
ONNX[ONNX Runtime models]
SIGN[Authenticode verification]
CLOUD[PYAS Cloud API]
end
subgraph KERNEL[Windows kernel layer]
PORT[Filter Manager communication port]
RULES[Dynamic rule engine and trust cache]
FILE[File-system minifilter]
PROC[Process and thread callbacks]
REG[Registry callbacks]
MEM[Memory and image-load controls]
BOOT[Boot and disk I/O controls]
end
subgraph ONLINE[Online analysis platform]
API[Flask application and REST API]
QUEUE[Priority analysis workers]
DB[(PostgreSQL)]
STORAGE[(Sample and report storage)]
end
WEB <--> WV
WV <--> CORE
TRAY <--> CORE
CORE --> SCAN
CORE --> PROTECT
CORE --> TOOLS
SCAN --> ENGINE
PROTECT --> ENGINE
ENGINE --> YARA
ENGINE --> PE
PE --> ONNX
ENGINE --> SIGN
ENGINE -. optional HTTPS .-> CLOUD
PROTECT <--> PORT
PORT <--> RULES
RULES --> FILE
RULES --> PROC
RULES --> REG
RULES --> MEM
RULES --> BOOT
CLOUD --> API
API --> QUEUE
QUEUE --> DB
QUEUE --> STORAGE
```
## Repository layout
```text
PYAS/
├── PYAS.py # Desktop entry point, UI bridge, configuration and lifecycle
├── PYAS_Engine.py # YARA, PE/ML, signature and cloud scanning engines
├── PYAS_Scanner.py # Scan scheduling, workers, results and remediation
├── PYAS_Protect.py # Real-time protection and driver lifecycle/communication
├── PYAS_Tools.py # Windows utilities, startup, process, network and cleanup tools
├── PYAS_Version.py # Windows executable version metadata
├── Engine/
│ ├── Heuristic/ # YARA signatures and rule assets
│ └── Properties/ # PE feature models and training/inference utilities
├── Interface/ # WebView2 HTML, CSS, JavaScript and icons
└── Plugins/
├── Filter/ # Native Windows minifilter driver source
└── Rules/ # Driver protection policies
```
## Getting started
### Option 1 — Install a packaged release
For most users, download the latest installer from [GitHub Releases](https://github.com/87owo/PYAS/releases).
1. Confirm that the installer comes from the official `87owo/PYAS` repository.
2. Ensure Microsoft Visual C++ 2015–2022 Redistributable and Microsoft Edge WebView2 Runtime are installed.
3. Run the installer as an administrator.
4. Open PYAS and review the protection switches before enabling kernel-level controls.
The current source tree may be ahead of the latest packaged release. Consult the version shown in the application and the release notes when reporting issues.
### Option 2 — Run from source
Python 3.10 is the recommended development runtime.
```powershell
git clone https://github.com/87owo/PYAS.git
cd PYAS
py -3.10 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
pip install pystray pefile requests pywebview Pillow yara-python numpy onnxruntime
python PYAS.py
```
Administrator privileges are required for features that interact with protected processes, system configuration, services, physical disks, or the kernel driver. Running the desktop UI without elevation may leave those capabilities unavailable.
### Optional training dependencies
The following packages are used by model-training or data-preparation utilities and are not required for the normal desktop runtime:
```powershell
pip install pandas scikit-learn lightgbm onnxmltools orjson
```
## Runtime requirements
| Profile | Operating system | Privileges | CPU | Memory | Free storage |
|---|---|---:|---:|---:|---:|
| Minimum | Windows 10 20H1 or newer | Administrator for full protection | 1 GHz | 300 MB | 100 MB |
| Recommended | Windows 10 21H2 / Windows 11 | Administrator | 3 GHz | 500 MB+ | 200 MB+ |
Required platform components:
- Microsoft Visual C++ 2015–2022 Redistributable
- Microsoft Edge WebView2 Runtime
- 64-bit Windows for the included x64 driver build
Actual resource usage depends on the selected scan scope, file sizes, enabled models, number of active workers, and real-time protection settings.
## Command-line integration
The application supports Windows shell and maintenance workflows through command-line arguments:
```text
PYAS.exe -scan <path> Scan a file or directory, forwarding to an existing instance
PYAS.exe -hide Start with the main window hidden
PYAS.exe -quit Request the running instance to exit
PYAS.exe -driver-unload Unload the active filter driver
PYAS.exe -driver-uninstall Stop and remove the driver service
```
These commands are primarily intended for installer, shell-menu, and maintenance integration. Administrative rights may be required.
## Configuration and local data
PYAS stores machine-wide configuration and reports under:
```text
%ProgramData%\PYAS\Config.json
%ProgramData%\PYAS\Report.json
```
WebView2 user data and its diagnostic log are stored under the current user's local application-data directory. Configuration includes scan limits, enabled protection layers, language and theme preferences, custom rule references, allow/block lists, and quarantine metadata.
Before reporting a configuration issue, reproduce it with default settings when safe to do so and remove sensitive paths or file information from logs.
## Online analysis service
The `Analyze/` component is a separate Flask and PostgreSQL application that provides:
- regular and chunked file uploads;
- asynchronous priority-based analysis tasks;
- SHA-256 report lookup and rescanning;
- structured PE metadata and similarity analysis;
- authenticated API access;
- search, statistics, comments, votes, and report export;
- encrypted sample packaging and controlled download workflows.
The service can be containerized with Docker Compose, but the checked-in deployment configuration must be treated as a development example. Replace all credentials and tokens with environment-managed secrets before deployment, restrict sample access, terminate TLS at a trusted reverse proxy, and isolate the analysis workers from production networks.
## Python API example
`PYAS_Cloud.py` provides a client for the online analysis API:
```python
from PYAS_Cloud import PYAS_Client
client = PYAS_Client(
api_key="YOUR_API_KEY",
hosts="https://pyas-security.com",
)
sha256 = client.upload_file(r"C:\samples\candidate.exe")
if sha256 and client.wait_for_analysis(sha256):
report = client.get_report(sha256)
print(report)
```
Only submit files that you are authorized to upload. Samples may contain confidential or personal information.
## Building the driver
The driver source is located in `Plugins/Filter/` and includes a Visual Studio solution and project.
Typical prerequisites:
- Visual Studio with Desktop development with C++;
- a compatible Windows Driver Kit (WDK);
- an x64 build environment;
- an appropriate test-signing or production code-signing workflow.
Build and test kernel components only in an isolated virtual machine with snapshots. Windows driver loading policies apply, and production distribution requires appropriate signing. Do not disable platform security controls on a primary workstation merely to load a development build.
## Rule editor
PYAS includes a Blockly-based visual editor for creating driver protection rules. The packaged editor is distributed through project releases.
![PYAS rule editor](https://github.com/user-attachments/assets/29a816a8-3bf9-4e1c-b881-7336676ad7f9)
Driver rules support matching across categories such as file, process, thread, registry, memory, device, and image-load activity, with allow/deny behavior, priority, operation masks, path relationships, thresholds, and other contextual constraints.
## Machine-learning engine
The local PE engine extracts structural and statistical characteristics from Windows executables, including headers, sections, data directories, imports, exports, resources, strings, byte distributions, entropy windows, overlay data, Rich headers, load configuration, certificates, and entry-point anomalies. Features are ordered according to the model metadata and evaluated through ONNX Runtime.
![Model training result](https://github.com/user-attachments/assets/fa7cf0e2-01a1-4234-9358-718c2b8a2c9a)
Model performance shown by training output should not be interpreted as a universal real-world detection rate. Reproducible evaluation requires a documented dataset split, class balance, deduplication strategy, temporal holdout, false-positive analysis, and testing against previously unseen malware families.
## Development and verification
Run the Windows-focused unit tests with:
```powershell
python -m unittest discover -s tests -v
```
Before submitting a change:
1. Keep modifications scoped to the affected protection layer.
2. Test both successful and denied Windows API paths.
3. Verify cleanup of handles, services, threads, temporary files, and driver ports.
4. Exercise the UI flow in both English and Traditional Chinese.
5. Test driver changes in a disposable VM, including unload and recovery behavior.
6. Record the Windows build, Python version, driver-signing mode, and enabled switches.
## Security and privacy
- Cloud scanning is optional; review the active configuration before analyzing confidential files.
- Kernel drivers and remediation features can affect system stability and data availability.
- Quarantine, deletion, startup changes, system repair, and MBR operations should be tested with recoverable data.
- Never deploy the example online-analysis stack with repository-default credentials or tokens.
- Treat uploaded malware samples as hostile. Use isolated storage, least privilege, network segmentation, and strict download authorization.
- If you discover a vulnerability, avoid publishing exploit details before the maintainer has had a reasonable opportunity to respond.
## Project status
PYAS is actively developed. The source tree can contain features intended for a future release, experimental modules, generated artifacts, and research data that are not part of the stable desktop package. For end-user installation, prefer signed artifacts from [Releases](https://github.com/87owo/PYAS/releases); for development, pin dependencies and validate the exact revision you build.
## Contributing
Issues and focused pull requests are welcome.
- Search [existing issues](https://github.com/87owo/PYAS/issues) before opening a new report.
- Include reproducible steps, expected and actual behavior, logs with sensitive data removed, and environment details.
- Keep unrelated refactors out of bug-fix pull requests.
- Do not commit malware samples, credentials, tokens, private certificates, or machine-specific build output.
## License and third-party components
The repository contains component-specific license files and bundled third-party assets. GitHub does not currently identify a repository-wide SPDX license. Review the applicable license files and obtain clarification from the maintainer before redistribution, commercial use, or incorporation into another product.
## Links and contact
- Source: [github.com/87owo/PYAS](https://github.com/87owo/PYAS)
- Releases: [github.com/87owo/PYAS/releases](https://github.com/87owo/PYAS/releases)
- Official website: [pyas-security.com/antivirus](https://pyas-security.com/antivirus)
- Online analysis: [pyas-security.com/analyze](https://pyas-security.com/analyze)
- Issue tracker: [github.com/87owo/PYAS/issues](https://github.com/87owo/PYAS/issues)
- Email: [[email protected]](mailto:[email protected])
---
<div align="center">
Built for Windows security research, layered endpoint defense, and transparent experimentation.
</div>