Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9eb55deedf | ||
|
|
6e76b5b8eb | ||
|
|
491b0da83d | ||
|
|
5d2c17e940 | ||
|
|
0497c4a9e7 | ||
|
|
6d0765848b | ||
|
|
40c4ae71bd | ||
|
|
8edba10dff | ||
|
|
85aa7bc652 | ||
|
|
854ad1db07 | ||
|
|
955600a1e1 | ||
|
|
b739134d85 | ||
|
|
723152566d | ||
|
|
678b045e0e | ||
|
|
681f4df49a | ||
|
|
b19f7d7098 | ||
|
|
daaae3ec10 | ||
|
|
c14957afff | ||
|
|
843a4998f1 | ||
|
|
9637e74edc | ||
|
|
b1bdf4f671 | ||
|
|
238ed8e364 | ||
|
|
8aa1509863 | ||
|
|
aac182e30b | ||
|
|
ac7e953acc | ||
|
|
6ae0f27e05 | ||
|
|
f6e5a92400 | ||
|
|
5e5ff3428c | ||
|
|
1cdbb9c402 | ||
|
|
8caacd1870 | ||
|
|
cfbc4c9c20 | ||
|
|
76dbf1c5d0 | ||
|
|
c0e7c4afa5 | ||
|
|
9da0970d85 | ||
|
|
d6f2ad32a7 | ||
|
|
8dbc87a331 | ||
|
|
77eb1ce44e | ||
|
|
e12f4ae61a | ||
|
|
c23a73625f | ||
|
|
3a66946686 | ||
|
|
7fef43701f | ||
|
|
7f5eb34ac6 | ||
|
|
ba4369f829 | ||
|
|
81af2e51fc | ||
|
|
dff09064c8 | ||
|
|
ee0bb32cce | ||
|
|
4a215c308b | ||
|
|
79493a96ea | ||
|
|
3cca1c4671 | ||
|
|
72e9923d08 | ||
|
|
406e152891 | ||
|
|
e9eb569d50 | ||
|
|
640b389e44 | ||
|
|
314e3349d6 | ||
|
|
0ae4d72bc9 | ||
|
|
8920a5fb21 | ||
|
|
b338ff5dd9 | ||
|
|
87e2fcb37c | ||
|
|
bab43e3b17 | ||
|
|
e602088330 | ||
|
|
2f6db92077 | ||
|
|
cee33c0f77 | ||
|
|
4fcdaa10b6 | ||
|
|
949f74ab04 | ||
|
|
ef68a89b45 | ||
|
|
10ecb35cca | ||
|
|
696ac22f77 | ||
|
|
8d13f98030 | ||
|
|
1dddf13a9d | ||
|
|
855472239a | ||
|
|
dc5d317623 | ||
|
|
91011e9e2a | ||
|
|
bb09b75d3b | ||
|
|
b2f9adad66 | ||
|
|
0c2c84d2a9 | ||
|
|
1733e7cc86 | ||
|
|
831d9a9895 | ||
|
|
70ba3a629d | ||
|
|
29e9702d21 | ||
|
|
f8ef756bd4 | ||
|
|
233b28e8a5 | ||
|
|
da77c17be5 | ||
|
|
8dfa76822e | ||
|
|
4163991b66 | ||
|
|
78323c9a08 | ||
|
|
eb517e86f3 | ||
|
|
e24f3823cb | ||
|
|
fd3e8ee28a | ||
|
|
a980ea7bd6 | ||
|
|
20ce73c54f | ||
|
|
d8f22f7f28 | ||
|
|
591055edaf | ||
|
|
fbf0e06c04 | ||
|
|
9daf327e80 | ||
|
|
4441978e10 | ||
|
|
d8eb770735 | ||
|
|
cefbf79c6e | ||
|
|
fc8762094e | ||
|
|
801c3aadcc | ||
|
|
4296f1ec43 | ||
|
|
a7f469747c | ||
|
|
68d0352343 | ||
|
|
01e6d09f7c | ||
|
|
6582abfd4a | ||
|
|
f8f4b303d7 | ||
|
|
79f05a23a8 | ||
|
|
95845c5c85 | ||
|
|
cd1a24290e | ||
|
|
21261bfb17 | ||
|
|
79abf51cb8 | ||
|
|
e538b837d5 | ||
|
|
7b995e1223 | ||
|
|
c7826b58a3 | ||
|
|
5786dbdb75 | ||
|
|
0f42c19ec7 | ||
|
|
87d44a64f3 | ||
|
|
77dd4ace33 | ||
|
|
0907d71957 | ||
|
|
e7a30646e3 | ||
|
|
98d21b3391 | ||
|
|
35d9203b9c | ||
|
|
e6e384a7f7 | ||
|
|
7d954c14ae | ||
|
|
41388962e2 | ||
|
|
6d51f6b6a9 | ||
|
|
c7af9a3702 | ||
|
|
da7c61202c | ||
|
|
c24e872a33 | ||
|
|
d0809ec313 | ||
|
|
c1a796da38 | ||
|
|
98c27800e0 | ||
|
|
7a18eadd13 | ||
|
|
b07adb7b30 | ||
|
|
4d7c3cce4d | ||
|
|
4ff0ab9cd8 | ||
|
|
264dd50969 | ||
|
|
26d0ad1a6e | ||
|
|
90284018e5 | ||
|
|
46eeec16d4 | ||
|
|
083fb0dccc | ||
|
|
d46f145806 | ||
|
|
868eddfd2b | ||
|
|
8295e6bb5b | ||
|
|
424914b842 | ||
|
|
8c5027df0f | ||
|
|
0b7817d992 | ||
|
|
ca6c9bfd05 | ||
|
|
0a1abd8040 | ||
|
|
ed69a4fdf6 | ||
|
|
2ae19a6d4e | ||
|
|
404bc50dd4 | ||
|
|
cada5eeeaf | ||
|
|
5e9bd40e8b | ||
|
|
0788bab0dd | ||
|
|
4e8e0dbea7 | ||
|
|
b8c5279137 | ||
|
|
a3255b1681 | ||
|
|
f151379f8f | ||
|
|
7784544583 | ||
|
|
f742937296 | ||
|
|
5fd9242291 | ||
|
|
9f343196a9 | ||
|
|
5468eded04 | ||
|
|
1b97758fc9 | ||
|
|
b2e8e49447 | ||
|
|
3eec781139 | ||
|
|
b6f1977fa0 | ||
|
|
e0aa080f00 | ||
|
|
66aa76c836 | ||
|
|
bb9444e1ae | ||
|
|
6c9bfa7755 | ||
|
|
c4fa849290 | ||
|
|
4807e2c410 | ||
|
|
5388efdebc | ||
|
|
1d656de7ba | ||
|
|
eaa1d725a9 | ||
|
|
dea2150d63 | ||
|
|
80f9d6cf75 | ||
|
|
7430d38594 | ||
|
|
6804e4af9f | ||
|
|
138756c31d | ||
|
|
349bc293c6 | ||
|
|
2f87cd10f2 | ||
|
|
fc50eafcca | ||
|
|
b48e20a727 | ||
|
|
ce7ed2e6eb | ||
|
|
043d71e0ff | ||
|
|
1855ae0e1d | ||
|
|
77323a50df | ||
|
|
1c2f6b85ca | ||
|
|
2b5c478e4b | ||
|
|
90fd83a81f | ||
|
|
8fa2a166f3 | ||
|
|
e8cc45ebe7 | ||
|
|
eb87117b91 | ||
|
|
3799dfa1e8 | ||
|
|
163c7fd680 | ||
|
|
44ca762f69 | ||
|
|
8db311ba33 | ||
|
|
99d8604db4 | ||
|
|
90aa88daeb | ||
|
|
ae6eebad4d | ||
|
|
cd31ce1c38 | ||
|
|
ed3846e451 | ||
|
|
0c79cf8e37 | ||
|
|
81c7e16c0e | ||
|
|
16c03095b8 | ||
|
|
b5dab3aa22 | ||
|
|
e4a3c871f8 | ||
|
|
a2fe947b08 | ||
|
|
8df49ecfc1 | ||
|
|
526b9bd4c7 | ||
|
|
c67ff3d936 | ||
|
|
417b17da98 | ||
|
|
4ca19a4eb0 | ||
|
|
e834dfb7ee | ||
|
|
5e1ff74fb3 | ||
|
|
7a1d0f2ca7 | ||
|
|
b305522106 | ||
|
|
ff3495645a | ||
|
|
ddc000321f | ||
|
|
fe4e6af3b9 | ||
|
|
a1a83cc32c | ||
|
|
e37665218b | ||
|
|
2a876f4136 | ||
|
|
290d8e8a64 | ||
|
|
121bce529f | ||
|
|
1232d98573 | ||
|
|
208d9150b0 | ||
|
|
351bf7725e | ||
|
|
a547776766 | ||
|
|
86a8d20757 | ||
|
|
760c420f95 | ||
|
|
44c2edf58e | ||
|
|
e88207c232 | ||
|
|
f6b2450fcd | ||
|
|
a124ecd3ed | ||
|
|
34fcc3d29e | ||
|
|
5f3011eebc | ||
|
|
d4464edb6c | ||
|
|
1dc89a80db | ||
|
|
bd23599770 | ||
|
|
bda6ff80da | ||
|
|
16bee9825f | ||
|
|
5e4a4c4e8f | ||
|
|
0a03093333 | ||
|
|
960b1d53f7 | ||
|
|
f09dee6a52 | ||
|
|
301e1e56d1 | ||
|
|
6b2dbd382d | ||
|
|
e6f526c766 | ||
|
|
06cca669a0 | ||
|
|
f89ccea208 | ||
|
|
0728f2d995 | ||
|
|
c7a7a61c9a | ||
|
|
aca11e66a8 | ||
|
|
46c7a001c2 | ||
|
|
d6aa3c50a3 | ||
|
|
caaadc5cf3 | ||
|
|
14d703903c | ||
|
|
76fa14ab01 | ||
|
|
d1afe255e5 | ||
|
|
8f27739331 | ||
|
|
7a6aba5a2a | ||
|
|
ca0ec1f99d | ||
|
|
4e167486a1 | ||
|
|
503bbcd995 | ||
|
|
b160d2f634 | ||
|
|
2e7628a837 | ||
|
|
1259948ed7 | ||
|
|
81881ae1a4 | ||
|
|
0b5c581aca | ||
|
|
eb3614ed0c | ||
|
|
eb50513277 | ||
|
|
c3af73b8cf | ||
|
|
b552164a13 | ||
|
|
b6dc9ecadb | ||
|
|
0723dc8dbb | ||
|
|
0b1fffb5bf | ||
|
|
a39d87e5c5 | ||
|
|
0b0c3310cf | ||
|
|
f75c3750a5 | ||
|
|
3da760721b | ||
|
|
a9ad3feeec | ||
|
|
479c4ade67 | ||
|
|
84afa3e714 | ||
|
|
9a69665bab | ||
|
|
fea34ee937 | ||
|
|
ff2412c65d | ||
|
|
658953860a | ||
|
|
b473783527 | ||
|
|
7e590d4925 | ||
|
|
232fd3e2f2 | ||
|
|
9ea25fb77c | ||
|
|
6c47136de3 | ||
|
|
6fae29b488 | ||
|
|
7ed8cc9380 | ||
|
|
142e9d1028 | ||
|
|
c96c30ff9a | ||
|
|
337f1cc100 | ||
|
|
c3cb89dbea | ||
|
|
445bd1f668 | ||
|
|
1bded908c1 | ||
|
|
8d9dea4b08 | ||
|
|
4e98d6d8ce | ||
|
|
55b5cd939e | ||
|
|
d72f5a43c8 | ||
|
|
b406d8d30b | ||
|
|
f9c91c9ba0 | ||
|
|
0213d7eeb4 | ||
|
|
048c5c0970 | ||
|
|
728542fce8 | ||
|
|
81ca24c7a2 | ||
|
|
32ec272253 | ||
|
|
758982b660 | ||
|
|
a83bba10e3 | ||
|
|
4b9342fa8b | ||
|
|
a48162cf4a | ||
|
|
3fa61e777c | ||
|
|
01a2c55207 | ||
|
|
1a2376e6b7 | ||
|
|
dab0d6a47f | ||
|
|
b5d90b5cb7 | ||
|
|
25fd0bd2af | ||
|
|
a4bb63fcd4 | ||
|
|
9d85785c27 | ||
|
|
4206242627 | ||
|
|
f0149be9ad | ||
|
|
5d56a1f0e0 | ||
|
|
ad06c75058 | ||
|
|
d5b6e17e59 | ||
|
|
ffe2514e11 | ||
|
|
8621bed5d4 | ||
|
|
634031e6dc | ||
|
|
11fae36469 | ||
|
|
3d01e36a71 | ||
|
|
c2082b1ac5 | ||
|
|
c94bbf84fe | ||
|
|
930363cd3f | ||
|
|
085ca9eb58 | ||
|
|
f486d44804 | ||
|
|
1b4fbd3449 | ||
|
|
43ad7bf646 | ||
|
|
64921c3308 | ||
|
|
7a0e6a00c5 | ||
|
|
1332dd2c0e | ||
|
|
d52628bed2 | ||
|
|
981ec006b2 | ||
|
|
7da05cf678 | ||
|
|
316882bcd0 | ||
|
|
b204e52297 | ||
|
|
f82a63f4c8 | ||
|
|
cb0f2108a4 | ||
|
|
300b7a7a68 | ||
|
|
c3852ca60d | ||
|
|
a5fb735c93 | ||
|
|
d0b04ba84f | ||
|
|
9552742a39 | ||
|
|
8e9bdf6c0c | ||
|
|
818cc48502 | ||
|
|
adc4e28eb8 | ||
|
|
2e3a4d3bf1 | ||
|
|
d9bcac78e7 | ||
|
|
2342947849 | ||
|
|
19204dee8d | ||
|
|
863fa90b80 | ||
|
|
6fdef4a8f1 | ||
|
|
9469ceaa02 | ||
|
|
857f184409 | ||
|
|
a2f4a725f5 | ||
|
|
d12449bbb9 | ||
|
|
a41f4711dd | ||
|
|
3c2b018d49 | ||
|
|
e221a09709 | ||
|
|
26ff4bd843 | ||
|
|
d8e28f384a | ||
|
|
65e68c3cc4 | ||
|
|
7b76ab2a59 | ||
|
|
ae2a01b463 | ||
|
|
cda022a9f4 | ||
|
|
672e48c5f8 | ||
|
|
6fbdb1354f | ||
|
|
79bc7fd443 | ||
|
|
5578dd3339 | ||
|
|
0232dbd196 | ||
|
|
d44e192eaa | ||
|
|
4f12b19cf8 | ||
|
|
392ac1b1c7 | ||
|
|
8ad175aca3 | ||
|
|
6afa58c42b | ||
|
|
8be03cf232 | ||
|
|
23ea53d3ff | ||
|
|
294f40e7ac | ||
|
|
4f5f706ee5 | ||
|
|
27c1a7b4e4 | ||
|
|
cfaa5be6d7 | ||
|
|
a6942280a0 | ||
|
|
159124e6a3 | ||
|
|
6e63293a3c | ||
|
|
9a9dc0d788 | ||
|
|
e201cd074c | ||
|
|
0fd49a6e1c | ||
|
|
6169a85464 | ||
|
|
e583344fee | ||
|
|
dcee00394c | ||
|
|
e48dc99dc0 | ||
|
|
3ba3dda384 | ||
|
|
bbf1ce993c | ||
|
|
56245a8c9b | ||
|
|
4f2e65094c | ||
|
|
0bf456cbc8 | ||
|
|
9213d0da16 | ||
|
|
13f2ece0ff | ||
|
|
45c2a74c94 | ||
|
|
b1b3e90e9b | ||
|
|
90ef841dae | ||
|
|
b46000e8eb | ||
|
|
b24891355d | ||
|
|
14bde5a790 | ||
|
|
d6445f17e3 | ||
|
|
6124c3fe40 | ||
|
|
5531a4b194 | ||
|
|
839a0bbd42 | ||
|
|
1ba6272e4e | ||
|
|
fdd86815ef | ||
|
|
c8091fdc84 | ||
|
|
9d569bd9e3 | ||
|
|
1991664cd1 | ||
|
|
ee7064fafc | ||
|
|
cdaf861485 | ||
|
|
3e962b1da9 | ||
|
|
8398f1706c | ||
|
|
24d2d441b4 | ||
|
|
5700039d42 | ||
|
|
22445c79d4 | ||
|
|
2be05ac76c | ||
|
|
84e397aeed | ||
|
|
bb513b9115 | ||
|
|
01b680e278 | ||
|
|
ef7c1cba2e | ||
|
|
40bbc57c82 | ||
|
|
457e5bebbb | ||
|
|
99abc56177 | ||
|
|
9eeb0b6376 | ||
|
|
0b2da187ee | ||
|
|
06f5410a4d | ||
|
|
2551ada3b7 | ||
|
|
56df08879e | ||
|
|
d41685c86e | ||
|
|
14b942970e | ||
|
|
b6103c845d | ||
|
|
7927f12e84 | ||
|
|
7774ff77b2 | ||
|
|
aaa2ed7eef | ||
|
|
b83674e9b7 | ||
|
|
017356780c | ||
|
|
45916004d2 | ||
|
|
388c8b615e | ||
|
|
4219473632 | ||
|
|
f2283cdb7f | ||
|
|
72ce9cfd6b | ||
|
|
b26375d25a | ||
|
|
a2a823f358 | ||
|
|
62164cf628 | ||
|
|
0b5fc22181 | ||
|
|
0df905f777 | ||
|
|
a539a948f6 | ||
|
|
6bd8364b5f | ||
|
|
70b70bc3e7 | ||
|
|
ac50f8917e | ||
|
|
f935b2c0b6 | ||
|
|
245c9d1119 | ||
|
|
9476313725 | ||
|
|
2d27a74278 | ||
|
|
823a5115eb | ||
|
|
33ab1e1f5e | ||
|
|
8db984d1fd | ||
|
|
a00415657a | ||
|
|
527837cc56 | ||
|
|
ac9ddff8b1 | ||
|
|
4ebae2a167 | ||
|
|
11f1685f42 | ||
|
|
8199101891 | ||
|
|
4f3ce323ae | ||
|
|
76befc7c70 | ||
|
|
8b0ad06676 | ||
|
|
d7f091a3a9 | ||
|
|
679b00229c | ||
|
|
0cfc636fb6 | ||
|
|
bd3c31e150 | ||
|
|
8e9547b75a | ||
|
|
d38ecc0f96 | ||
|
|
85834497e0 | ||
|
|
0d8997db02 | ||
|
|
cb53450ca5 | ||
|
|
f38ae36eb6 | ||
|
|
8218b0c8a6 | ||
|
|
ea036d2d53 | ||
|
|
b163eb2cdb | ||
|
|
ba3568f312 | ||
|
|
80c9976832 | ||
|
|
b6326c25b9 | ||
|
|
35f591cf49 | ||
|
|
67e437bbd7 | ||
|
|
194dae8ce1 | ||
|
|
a89442ceb0 | ||
|
|
24debf6062 | ||
|
|
ff98846c99 | ||
|
|
e3f5a0bca1 | ||
|
|
7278e4f051 | ||
|
|
709a511c1d | ||
|
|
452027f085 | ||
|
|
8574802428 | ||
|
|
79fb044921 | ||
|
|
13ac634fea | ||
|
|
04a68bc262 | ||
|
|
47de15ab68 | ||
|
|
512af24a05 | ||
|
|
e5ff46d3bb | ||
|
|
c7a0979140 | ||
|
|
7fd7245df2 | ||
|
|
026301b011 | ||
|
|
5cc77f90ae | ||
|
|
0d4568ac8a | ||
|
|
a6ed491a39 | ||
|
|
90dfc3f1ae | ||
|
|
36388fb0d7 | ||
|
|
043166d0c8 | ||
|
|
b92d488851 | ||
|
|
d841a04a89 | ||
|
|
d8553baa78 | ||
|
|
8521d5aee3 | ||
|
|
ebe21d9c7f | ||
|
|
3b83abdbd3 | ||
|
|
aead2463c9 | ||
|
|
5cc5676672 | ||
|
|
ecc32ca18d | ||
|
|
661640de79 | ||
|
|
96dfdab7ed | ||
|
|
56bed5fd3b | ||
|
|
3fd3b18406 | ||
|
|
45bac97a16 | ||
|
|
2c6eca4a92 | ||
|
|
8109d59655 | ||
|
|
8a15571cd2 | ||
|
|
a15c8f2e60 | ||
|
|
cec3d6c04d | ||
|
|
d872604855 | ||
|
|
2b6fb933a4 | ||
|
|
1da892e863 | ||
|
|
19bfedd1a3 | ||
|
|
cb87392d9d | ||
|
|
7cd5bc9ec3 | ||
|
|
edcc1a30ab | ||
|
|
6f93f6ab06 | ||
|
|
9de1f44288 | ||
|
|
3d360b0881 | ||
|
|
cf1c415846 | ||
|
|
90133e2444 | ||
|
|
81246046b8 | ||
|
|
20e037ab9e | ||
|
|
bc27036ba7 | ||
|
|
1cd470b90b | ||
|
|
64471e34bc | ||
|
|
f4c5d3de09 | ||
|
|
0dc59405e3 | ||
|
|
7c775bdc9b | ||
|
|
61400ff4d4 | ||
|
|
e119e34ebe | ||
|
|
6f059747bf | ||
|
|
24d72641fa | ||
|
|
b91fca3aa6 | ||
|
|
a6f1947837 | ||
|
|
6919131cef | ||
|
|
9186d801fc | ||
|
|
76e2f200bd | ||
|
|
1400bbd9ce | ||
|
|
fd37628ac2 | ||
|
|
4396d5afc4 | ||
|
|
f5faf80883 | ||
|
|
ba32da97c8 | ||
|
|
ec2de73d3a | ||
|
|
f4d032e5c7 | ||
|
|
4114aac6c3 | ||
|
|
0c43c6bb5f | ||
|
|
7b3c965b88 | ||
|
|
d1035268f6 | ||
|
|
8968f30bf9 | ||
|
|
84c2c29600 | ||
|
|
b2a59f261c | ||
|
|
363a330f8e | ||
|
|
1d2aa059ee | ||
|
|
f2bfa908a1 | ||
|
|
02a8de4696 | ||
|
|
22fa3eff71 | ||
|
|
69361209c3 | ||
|
|
ff0aeaa4ef | ||
|
|
3c461dfd4b | ||
|
|
c6beda383e | ||
|
|
3d59f3befd | ||
|
|
e54f0db239 | ||
|
|
0f877f2749 | ||
|
|
b69ba165d9 | ||
|
|
965076fe52 | ||
|
|
f4d6cb0430 | ||
|
|
19d412188c | ||
|
|
798d85978a | ||
|
|
819742d753 | ||
|
|
9b32fa6219 | ||
|
|
2c93661726 | ||
|
|
bddaca2a1e | ||
|
|
2f06f2e051 | ||
|
|
1d26e46bd9 | ||
|
|
fa0ff826a3 | ||
|
|
e1b3114c83 | ||
|
|
a655f075db | ||
|
|
13d4ebbf6b | ||
|
|
913d10b1ee | ||
|
|
eb541a0104 | ||
|
|
2063186994 | ||
|
|
860d571039 | ||
|
|
c6d79adf9a | ||
|
|
5453900ba1 | ||
|
|
5029ff1e37 | ||
|
|
47fb691339 | ||
|
|
dff9dd17bf | ||
|
|
5bc4a16b90 | ||
|
|
b1918953b0 | ||
|
|
6e89ed7007 | ||
|
|
744e8bc941 | ||
|
|
0b98ce7ffd | ||
|
|
ca8b293b06 | ||
|
|
e28d99a257 | ||
|
|
488feb6108 | ||
|
|
6cdb106f07 | ||
|
|
a7c5ccd27a | ||
|
|
136f9dbf0a | ||
|
|
16b45c3450 | ||
|
|
68330fad52 | ||
|
|
dca167518d | ||
|
|
bcc44422ef | ||
|
|
e080e03466 | ||
|
|
b6e75490de | ||
|
|
196c014576 | ||
|
|
236110df5e | ||
|
|
b2ae192056 | ||
|
|
f080969a62 | ||
|
|
69d969898d | ||
|
|
a21a766926 | ||
|
|
f11fdb6b96 | ||
|
|
c7445df4c6 | ||
|
|
2c45c9bc5b | ||
|
|
ae5ed27cb6 | ||
|
|
11f9fe3c8b | ||
|
|
e93ad3bd33 | ||
|
|
20c26ea0a8 | ||
|
|
5925a80d3b | ||
|
|
56cb95e523 | ||
|
|
a6e101cc5d | ||
|
|
e8292b6f81 | ||
|
|
37a4392c94 | ||
|
|
a897f75ecf | ||
|
|
79055d3779 | ||
|
|
3d39aa7f97 | ||
|
|
2c1d09affc | ||
|
|
4775358a79 | ||
|
|
cb5f8e8191 | ||
|
|
8209b4ff01 | ||
|
|
e110134d24 | ||
|
|
c2248fdd49 | ||
|
|
58fea5b0ca | ||
|
|
7a36946545 | ||
|
|
563d9a8a36 | ||
|
|
bdbd0617b5 | ||
|
|
67006d88cb | ||
|
|
ded2083462 | ||
|
|
87b7d044f8 | ||
|
|
9781cef29b | ||
|
|
52c393148b | ||
|
|
b98d617d6f | ||
|
|
b475573e0e | ||
|
|
ba3c85d5b2 | ||
|
|
410777efb3 | ||
|
|
0b3fb452b4 | ||
|
|
aaff565172 | ||
|
|
dd0786648e | ||
|
|
e145ffa111 | ||
|
|
b322468c1c | ||
|
|
992d8b909c | ||
|
|
d5327c6370 | ||
|
|
0d13bb5f8f | ||
|
|
3ad08a33a9 | ||
|
|
533e0ed736 | ||
|
|
e7ba77b600 | ||
|
|
f3b84b04f7 | ||
|
|
f4c948aca9 | ||
|
|
1507f5df5a | ||
|
|
0562d11a71 | ||
|
|
b3a9f5cce0 | ||
|
|
5974a3c85a | ||
|
|
78c732d2b8 | ||
|
|
d087b2dc16 | ||
|
|
16c5d014aa | ||
|
|
e661ff400f | ||
|
|
b8c8e2d04d | ||
|
|
8fc36f2b20 | ||
|
|
4b73a09a09 | ||
|
|
65c4d5d5b7 | ||
|
|
19d0702aee | ||
|
|
b74e8330de | ||
|
|
334b837d43 | ||
|
|
169cb37f08 | ||
|
|
8f29c3f0da | ||
|
|
bec5cc4a04 | ||
|
|
af627ee202 | ||
|
|
1e091a3e7c | ||
|
|
8840da91d7 | ||
|
|
1f4ff04ed3 | ||
|
|
60974e8f72 | ||
|
|
86f68994c2 | ||
|
|
21c4918486 | ||
|
|
c6a426ec25 | ||
|
|
db75a22c1c | ||
|
|
7e85d22ecd | ||
|
|
67adadc0a4 | ||
|
|
6b78562454 | ||
|
|
4f13afc867 | ||
|
|
c34e8f193f | ||
|
|
4bcb507eae | ||
|
|
a50d457d75 | ||
|
|
9f119265a9 | ||
|
|
0b121a624b | ||
|
|
0f47f5ec8f | ||
|
|
f89896d041 | ||
|
|
5e335fd5e8 | ||
|
|
fd245dec14 | ||
|
|
774cdc5de3 | ||
|
|
633cfad1a8 | ||
|
|
cb7875c320 | ||
|
|
7960a57fc0 | ||
|
|
a23f693921 | ||
|
|
c49cb8bc4a | ||
|
|
02c425cfc0 | ||
|
|
be96ba0a0e | ||
|
|
df5e00977a | ||
|
|
f055650365 | ||
|
|
b0baddda3b | ||
|
|
69359cba05 | ||
|
|
8b0b29e39b | ||
|
|
21ac50667d | ||
|
|
b843a438ba | ||
|
|
441cc30c0b | ||
|
|
85adf5dc80 | ||
|
|
0c48f0981d | ||
|
|
88b646e41c | ||
|
|
dc4c3e0a99 | ||
|
|
262f6d55a0 | ||
|
|
2d68400670 | ||
|
|
8acaae3f0d | ||
|
|
a5cb26528f | ||
|
|
ac2520a03f | ||
|
|
9c15cc7b33 | ||
|
|
c38f460163 | ||
|
|
9bda8c9e77 | ||
|
|
558be68bad | ||
|
|
6b9d27ce9b | ||
|
|
412745eede | ||
|
|
91ea771af1 | ||
|
|
238ab03db3 | ||
|
|
2d63da193d | ||
|
|
fa4c20a241 | ||
|
|
6294fc33d1 | ||
|
|
c4cf48a94b | ||
|
|
2934c7eb57 | ||
|
|
46ce454105 | ||
|
|
9ab06a0ea9 | ||
|
|
e6f742380a | ||
|
|
2686812470 | ||
|
|
cd11b5b7b2 | ||
|
|
aae35dc640 | ||
|
|
f0b669ff85 | ||
|
|
237605bb9f | ||
|
|
1778046581 | ||
|
|
ff10adfabb | ||
|
|
1cb0f8d7ba | ||
|
|
5813bbdcd1 | ||
|
|
b38e5b177e | ||
|
|
9d66cf248c | ||
|
|
ebcf90d426 | ||
|
|
51904db187 | ||
|
|
4fc8755b8d | ||
|
|
7afcbfaa26 | ||
|
|
55cb96d978 | ||
|
|
a1de099974 | ||
|
|
a0238732fe | ||
|
|
6c100b0679 | ||
|
|
e4d159840f | ||
|
|
0375b3ff02 | ||
|
|
746bae5103 | ||
|
|
70eb2c4500 | ||
|
|
69175f3ae1 | ||
|
|
ed5fab2c54 | ||
|
|
1425ff8e6c | ||
|
|
832ab549a1 | ||
|
|
4ec1661c26 | ||
|
|
ea27712b62 | ||
|
|
6f65efe2d8 | ||
|
|
8edcf60baf | ||
|
|
74f6aec367 | ||
|
|
62c65a766a | ||
|
|
acbcaa337e | ||
|
|
f4dbe57244 | ||
|
|
b494c64a2f | ||
|
|
321e086b95 | ||
|
|
fb60d6b867 | ||
|
|
8ff2e2074a | ||
|
|
1151a1c43f | ||
|
|
13bc6cecc4 | ||
|
|
a4ea572458 | ||
|
|
880df4dee9 | ||
|
|
b75e86dd11 | ||
|
|
75c84092ae | ||
|
|
c69db97da8 | ||
|
|
9c2a8892ae | ||
|
|
f92111563c | ||
|
|
0abb3e78cb | ||
|
|
fb83071419 | ||
|
|
f593c6df8b | ||
|
|
9b452b25c2 | ||
|
|
c835fcf99a | ||
|
|
e4373edc54 | ||
|
|
686c05785f | ||
|
|
994358a793 | ||
|
|
b02ca3757c | ||
|
|
164ec25415 | ||
|
|
8ee85cd9ca | ||
|
|
c07bf05754 | ||
|
|
2e2a08a765 | ||
|
|
10be5f442f | ||
|
|
0fcd8565d8 | ||
|
|
e07eee86dd | ||
|
|
f25d5d73c6 | ||
|
|
28b4d00d3c | ||
|
|
c75cf8a539 | ||
|
|
ff7199b857 | ||
|
|
5613fd81b7 | ||
|
|
c1458502f7 | ||
|
|
b2f620bd3d | ||
|
|
0e1030f186 | ||
|
|
ff4ffb8ec5 | ||
|
|
941458a381 | ||
|
|
560eb924b8 | ||
|
|
c3fab9e48b | ||
|
|
fc4dc74f9e | ||
|
|
35f0362910 | ||
|
|
27dfaa5f06 | ||
|
|
cf1866710a | ||
|
|
b3a5d06c4a | ||
|
|
7c904ff331 | ||
|
|
c7855a9dd1 | ||
|
|
5faee6a05f | ||
|
|
9213f9f54f | ||
|
|
c5e8351d76 | ||
|
|
e8e245ac0b | ||
|
|
2d8d6851d1 | ||
|
|
54f3e2ceda | ||
|
|
81d98917c3 | ||
|
|
8651f1e5d6 | ||
|
|
db1a26424d | ||
|
|
16405810dd | ||
|
|
f4f7fc1b0c | ||
|
|
e1145a743a | ||
|
|
6e5b54bbfe | ||
|
|
a948219e1a | ||
|
|
5675e926d5 | ||
|
|
cb7f8bbaab | ||
|
|
61e7fd8f40 | ||
|
|
76fab2671a | ||
|
|
dbc2bd2d62 | ||
|
|
73e62935ff | ||
|
|
c9e28b5482 | ||
|
|
6bf58eae4a | ||
|
|
3e09574b3c | ||
|
|
a7a00b9ca6 | ||
|
|
7a62e2df27 | ||
|
|
317f1ccae7 | ||
|
|
884631409a | ||
|
|
14dca5e2cb | ||
|
|
3a0b856d47 | ||
|
|
e66f8af022 | ||
|
|
13e4560d86 | ||
|
|
5ea789df7f | ||
|
|
debda9ec11 | ||
|
|
b3f126181b | ||
|
|
6bd110cae7 | ||
|
|
635f4ccde3 | ||
|
|
01da2685a5 | ||
|
|
b040aad8d1 | ||
|
|
84a0f08618 | ||
|
|
1f64c0d672 | ||
|
|
5bfff87e21 | ||
|
|
47db0e1c46 | ||
|
|
9a9fdc418f | ||
|
|
c30c89ed40 | ||
|
|
d7bb89968f | ||
|
|
f9b431d158 | ||
|
|
a1364896af | ||
|
|
2870a999a2 | ||
|
|
98646a6bd9 | ||
|
|
8ec894f576 | ||
|
|
254a67b9a8 | ||
|
|
eebfb79c27 | ||
|
|
1a1d7ec783 | ||
|
|
4482144b4d | ||
|
|
827279c9a8 | ||
|
|
b1d3488842 | ||
|
|
90112ae1ae | ||
|
|
1f4b9390b9 | ||
|
|
cc142aca40 | ||
|
|
89513b2c0d | ||
|
|
bfcd00acec | ||
|
|
9833b28a50 | ||
|
|
d0404dd29c | ||
|
|
9d3761e7f6 | ||
|
|
03515acc68 | ||
|
|
f8413f4cfb | ||
|
|
24f7f67e63 | ||
|
|
85129cdfe1 | ||
|
|
6d4f8b2731 | ||
|
|
24a0efcce1 | ||
|
|
ce6be1b4d5 | ||
|
|
723ac47c48 | ||
|
|
720d163bdb | ||
|
|
a74047d4e5 | ||
|
|
f6538f93c7 | ||
|
|
49cb0b3ef5 | ||
|
|
c81845ba3a | ||
|
|
053ae64008 | ||
|
|
48989840b8 | ||
|
|
36c7bcd87f | ||
|
|
a50eca1600 | ||
|
|
f70dc8eb46 | ||
|
|
f13d816c5b | ||
|
|
3429e658b6 | ||
|
|
0c6f9d6041 | ||
|
|
4a668499b0 | ||
|
|
f1057252b3 | ||
|
|
4e3c866536 | ||
|
|
c585cb370c | ||
|
|
2211a2b1d4 | ||
|
|
42069e2aac | ||
|
|
fd499a17fe | ||
|
|
0cc56d3da7 | ||
|
|
2096f55ce8 | ||
|
|
a4afe0ac10 | ||
|
|
d523b66970 | ||
|
|
192335249c | ||
|
|
e02879b3d7 | ||
|
|
bf7157fb3e | ||
|
|
7c2ae87c73 | ||
|
|
c1357bb2e1 | ||
|
|
c298c3773e | ||
|
|
7d09c6501c | ||
|
|
1a051d42af | ||
|
|
22bbcc5217 | ||
|
|
017f153002 | ||
|
|
cf4762ad04 | ||
|
|
6ba920e26a | ||
|
|
a66acf0ef9 | ||
|
|
8ab982ac38 | ||
|
|
0c32a126a9 | ||
|
|
fd47881f88 | ||
|
|
61298235fd | ||
|
|
4a38277c3e | ||
|
|
fd7912f631 | ||
|
|
4f1b0e99e4 | ||
|
|
086e375cea | ||
|
|
f90b132ccb | ||
|
|
f4bd217445 | ||
|
|
5524e2f689 | ||
|
|
42b8201f37 | ||
|
|
f71c821128 | ||
|
|
28330d3ad6 | ||
|
|
5afd576a3c | ||
|
|
edcf82d139 | ||
|
|
69e5143a27 | ||
|
|
215d0faa53 | ||
|
|
470142a640 | ||
|
|
8e67a8d679 | ||
|
|
be5baf9c87 | ||
|
|
7a05e42f3f | ||
|
|
34240ec01f | ||
|
|
0bf6eccb8b | ||
|
|
1f3b694231 | ||
|
|
470358585d | ||
|
|
4c69b555ae | ||
|
|
aef60afcd8 | ||
|
|
ec753c50a5 | ||
|
|
cbebe878aa | ||
|
|
e9d930507e | ||
|
|
3eba768d06 | ||
|
|
76a5732997 | ||
|
|
32987c1274 | ||
|
|
8990b97a32 | ||
|
|
65b427121f | ||
|
|
81dd259672 | ||
|
|
05c2031d47 | ||
|
|
2b2de7550f | ||
|
|
f9a8244086 | ||
|
|
86f3904b8a | ||
|
|
017aab4b0a | ||
|
|
e33777c961 | ||
|
|
ac14acd042 | ||
|
|
e9f07df010 | ||
|
|
5d3855cdfa | ||
|
|
938e76fb4a | ||
|
|
c0f6722c18 | ||
|
|
54e8922bc3 | ||
|
|
81b47dbf45 | ||
|
|
312401d80f | ||
|
|
8927ab7e36 | ||
|
|
6d99576e36 | ||
|
|
5618cd19cb | ||
|
|
da11c6f5b6 | ||
|
|
6e370e776a | ||
|
|
ab6b319738 | ||
|
|
aca03cacf9 | ||
|
|
01b5e7ced0 | ||
|
|
6d8ef1d4a4 | ||
|
|
f029636757 | ||
|
|
168b396daa | ||
|
|
0873a59392 | ||
|
|
3c646f57e6 | ||
|
|
940db64678 | ||
|
|
da1c980743 | ||
|
|
e3a4b636f7 | ||
|
|
9434898efa | ||
|
|
5d1c17e6ff | ||
|
|
4f736b352a | ||
|
|
037e2fbab1 | ||
|
|
4b24858631 | ||
|
|
81904a3a7b | ||
|
|
6e63a789cb | ||
|
|
4b977ec4df | ||
|
|
fa692caaa8 | ||
|
|
7082003e4a | ||
|
|
dec35d9b8a | ||
|
|
90711465ba | ||
|
|
1bb74f20b4 | ||
|
|
b2cce37490 | ||
|
|
22e41eeacc | ||
|
|
600f2543a6 | ||
|
|
9e7185ae6d | ||
|
|
11725afa5a | ||
|
|
3bb94d05be | ||
|
|
7290db72e8 | ||
|
|
4dc92b081e | ||
|
|
68c614d9dd | ||
|
|
efca8d0161 | ||
|
|
6d86b15800 | ||
|
|
f43b2df6fc | ||
|
|
9f3eb593f8 | ||
|
|
9ca7c41fe7 | ||
|
|
f39746c116 | ||
|
|
88f1dc2c01 | ||
|
|
ee3daae665 | ||
|
|
9a47f06c2a | ||
|
|
6df173d30a | ||
|
|
f992394f6f | ||
|
|
98c19fcd7e | ||
|
|
12cc2439af | ||
|
|
2341100397 | ||
|
|
b15c9e4e39 | ||
|
|
dbf860ca7a | ||
|
|
aa481f415d | ||
|
|
59eeae791a | ||
|
|
0691a4420c | ||
|
|
66e744dd57 | ||
|
|
9f5eb72cec | ||
|
|
a021ab6e42 | ||
|
|
6a316e850c | ||
|
|
69413c1bed | ||
|
|
c152cd944e | ||
|
|
a055864676 | ||
|
|
cb64da2d5f | ||
|
|
5633e70a11 | ||
|
|
c1f6d0692b | ||
|
|
fe527f1668 | ||
|
|
774a2313fb | ||
|
|
a5f07706f5 | ||
|
|
2b6b8accf1 | ||
|
|
e6aca5533b | ||
|
|
dc60cc3ccb | ||
|
|
5613993019 | ||
|
|
1613101bd6 | ||
|
|
cb3440494e | ||
|
|
78b979f397 | ||
|
|
6742b71208 | ||
|
|
e0178ac2b5 | ||
|
|
e2141decaa | ||
|
|
4a68c62e72 | ||
|
|
bc7d5704f9 | ||
|
|
a984be2535 | ||
|
|
026f96d473 | ||
|
|
0dbca7895e | ||
|
|
0f390668f7 | ||
|
|
f4ced70d8e | ||
|
|
7b805df433 | ||
|
|
4b66171388 | ||
|
|
0cf80753ae | ||
|
|
6f3d315851 | ||
|
|
475d4b4a80 | ||
|
|
bd8633de0d | ||
|
|
5d2937c896 | ||
|
|
eb89284834 | ||
|
|
f5777b2a68 | ||
|
|
9431a4dd6c | ||
|
|
82a4dfdfd5 | ||
|
|
9bd63d15e9 | ||
|
|
f6e5c8e0b1 | ||
|
|
3b56f6dc6f | ||
|
|
2c24079552 | ||
|
|
f58a846826 | ||
|
|
8bc74a8833 | ||
|
|
5bd0033ff0 | ||
|
|
e45758be80 | ||
|
|
5033348eed | ||
|
|
2327fd099c | ||
|
|
6afa02ea71 | ||
|
|
9cf1b38e56 | ||
|
|
241a9ffea5 | ||
|
|
3e0749ad60 | ||
|
|
0f55ff4295 | ||
|
|
d8f8c34991 | ||
|
|
7ddd323b65 | ||
|
|
36bbb6e708 | ||
|
|
06638a8cdc | ||
|
|
42d8a8fde0 | ||
|
|
e2997fbbce | ||
|
|
5dd671eb4a | ||
|
|
59aff0f196 | ||
|
|
548def29b3 | ||
|
|
84d59eb7d4 | ||
|
|
1cc3b599a9 | ||
|
|
0e02b56d20 | ||
|
|
4e8d99f557 | ||
|
|
f3add6e3e3 | ||
|
|
32a2a93eb5 | ||
|
|
0090ee516f | ||
|
|
42e4e958df | ||
|
|
b6970d1da6 | ||
|
|
d7ce6c9a4a | ||
|
|
e6d18cbec8 | ||
|
|
3140f6b19f | ||
|
|
b493bf88a8 | ||
|
|
8877609f2a | ||
|
|
d3e5aa00df | ||
|
|
2b88f58e58 | ||
|
|
1f6fd659d5 | ||
|
|
42583407d0 | ||
|
|
cb6b30f4cf | ||
|
|
7a372bfbd1 | ||
|
|
adb8763706 | ||
|
|
ce709408af | ||
|
|
d577b58c52 | ||
|
|
d939b081ff | ||
|
|
b029ff0cfb | ||
|
|
2e473e7a65 | ||
|
|
8b0c2b7815 | ||
|
|
9eb9f83108 | ||
|
|
d724473bc2 | ||
|
|
ed3dac054a | ||
|
|
2c7294684f | ||
|
|
79016437e4 | ||
|
|
20d8131661 | ||
|
|
14b6bb18f3 | ||
|
|
c919b2bce3 | ||
|
|
bf4d65b179 | ||
|
|
6e7a50468b | ||
|
|
fd3c5900b0 | ||
|
|
b531fe4243 | ||
|
|
df39e73748 | ||
|
|
5478aeb96b | ||
|
|
4ef190261a | ||
|
|
164fd80065 | ||
|
|
03d437712c | ||
|
|
9b14c201c4 | ||
|
|
b4710bda0e | ||
|
|
1821ffbe7b | ||
|
|
7687328957 | ||
|
|
c02e1277d9 | ||
|
|
d1f0508391 | ||
|
|
ccf6395796 | ||
|
|
e9e1d47aff | ||
|
|
7e609e30a2 | ||
|
|
b97acbf8a5 | ||
|
|
cca1a2a270 | ||
|
|
ccbd7b7fe6 | ||
|
|
7e1865f676 | ||
|
|
da3c1f946c | ||
|
|
6c09cbc2d9 | ||
|
|
cfcb81b657 | ||
|
|
948458c404 | ||
|
|
2886672d20 | ||
|
|
3d0f2f2d80 | ||
|
|
a0b20127cb | ||
|
|
8e0092d647 | ||
|
|
347444edd2 | ||
|
|
559fa300a2 | ||
|
|
e1d6813fa7 | ||
|
|
fae99b9a29 | ||
|
|
75d2d58d0d | ||
|
|
fd2f9dc972 | ||
|
|
0697ca9bef | ||
|
|
759a7ba41f | ||
|
|
109cb8d0fd | ||
|
|
3d031b30b5 | ||
|
|
e95915d4be | ||
|
|
005e52c803 | ||
|
|
6d22f2c129 | ||
|
|
7fdadb14ae | ||
|
|
4d76ed5f00 | ||
|
|
37dc166adc | ||
|
|
014d3f234f | ||
|
|
0bb3b2a110 | ||
|
|
e3aa5ec75d | ||
|
|
81f2f57666 | ||
|
|
562c475d2b | ||
|
|
9366cb3de9 | ||
|
|
9a2bd94e4a | ||
|
|
cc61b16d3d | ||
|
|
b56b8063f3 | ||
|
|
9b08c8b27b | ||
|
|
50f4ca8d1e | ||
|
|
74fb2f3f57 | ||
|
|
e18e08a983 | ||
|
|
9967218524 | ||
|
|
44a9e0d6e0 | ||
|
|
91f153b109 | ||
|
|
ead845f7bc | ||
|
|
0908cacb9f | ||
|
|
9dd47fe9ae | ||
|
|
724acdaba8 | ||
|
|
08bdd870a5 | ||
|
|
54a43f6045 | ||
|
|
25a9cc3608 | ||
|
|
7f52a53e62 | ||
|
|
20e9c82854 | ||
|
|
fe92e53f7b | ||
|
|
130aeb01b9 | ||
|
|
7439b5e362 | ||
|
|
166059b9bd | ||
|
|
7e5fc40768 | ||
|
|
aadb2c1e40 | ||
|
|
f317452c80 | ||
|
|
cb98a00cfa | ||
|
|
75deeb247a | ||
|
|
b17eec0647 | ||
|
|
5ddcc24563 | ||
|
|
9b4ecdf7bf | ||
|
|
6ba4efe1bb | ||
|
|
84ae6b4247 | ||
|
|
7510c6a539 | ||
|
|
de45907c91 | ||
|
|
17e9546671 | ||
|
|
c0a382fefc | ||
|
|
bf7ca3e9b1 | ||
|
|
af1c23d72d | ||
|
|
1bdea5727b | ||
|
|
3dc573cce1 | ||
|
|
4d1b8ca9e8 | ||
|
|
aec1cff72c | ||
|
|
520a0e71eb | ||
|
|
9485d36565 | ||
|
|
48ce8a1b0e | ||
|
|
8a4c469e16 | ||
|
|
3ae7ba20d1 | ||
|
|
2b4adcf8bb | ||
|
|
d8a237f94f | ||
|
|
02e62465b7 | ||
|
|
c0db543d49 | ||
|
|
5a1f620d88 | ||
|
|
c418283845 | ||
|
|
44b00cc050 | ||
|
|
3d33e1a713 | ||
|
|
ccd1040ba6 | ||
|
|
35f7d6d71e | ||
|
|
be3da7d66c | ||
|
|
ccb706aef1 | ||
|
|
20d1c4fb23 | ||
|
|
99a459ae4f | ||
|
|
e8e4cb5ebe | ||
|
|
87175e6e89 | ||
|
|
301340b512 | ||
|
|
e4388201c2 | ||
|
|
ac3b2b7c80 | ||
|
|
5e79354705 | ||
|
|
d39ef0693f | ||
|
|
2577333d79 | ||
|
|
115c335916 | ||
|
|
4bfbdf476f | ||
|
|
faea8cd616 | ||
|
|
6f1db7f9ef | ||
|
|
204977cc49 | ||
|
|
8e825a58f0 | ||
|
|
3e567c6ffb | ||
|
|
8845f2a964 | ||
|
|
a1400992af | ||
|
|
fa721e2e51 | ||
|
|
c46a315280 | ||
|
|
81d6f34c35 | ||
|
|
6825e3d389 | ||
|
|
01e329234b | ||
|
|
cdac73a18a | ||
|
|
3469349da5 | ||
|
|
9d814f9b66 | ||
|
|
81bcf5d6df | ||
|
|
b5c595d1d6 | ||
|
|
484872cc11 | ||
|
|
c96f6df171 | ||
|
|
2a98c2e8b4 | ||
|
|
36e6ac3301 | ||
|
|
c20a0d3f32 | ||
|
|
a609812960 | ||
|
|
b6f3e66770 | ||
|
|
0f41e98e5e | ||
|
|
a808056229 | ||
|
|
314bdebde3 | ||
|
|
ab7afb342c | ||
|
|
691049617d | ||
|
|
f747d58c71 | ||
|
|
c193a38782 | ||
|
|
4e8b0ba168 | ||
|
|
fd37134fcd | ||
|
|
5acf1aaf0e | ||
|
|
d0e3bbc55f | ||
|
|
0c9dfb5829 | ||
|
|
987bd6bcc1 | ||
|
|
939cf7c0df | ||
|
|
9f2256b547 | ||
|
|
b301b9fb95 | ||
|
|
a61c49cf68 | ||
|
|
9ab2967129 | ||
|
|
1aefb38a7c | ||
|
|
c359312e9d | ||
|
|
fe24317a9e | ||
|
|
68996d56ee | ||
|
|
9e2843460e | ||
|
|
2e08287e1c | ||
|
|
ccf10e1444 | ||
|
|
8172f648ab | ||
|
|
113816f418 | ||
|
|
85bd807bf7 | ||
|
|
a17827dbf4 | ||
|
|
ef1f29a34f | ||
|
|
e283a6a955 | ||
|
|
7944627dab | ||
|
|
7757b10b4d | ||
|
|
2b182e182b | ||
|
|
d6fafd5b34 | ||
|
|
f36b3a0912 | ||
|
|
04cae30629 | ||
|
|
38cdeeed6a |
No files matched your search
@@ -0,0 +1,55 @@
|
||||
from PIL import Image
|
||||
import numpy, os
|
||||
|
||||
####################################################################################################
|
||||
|
||||
def preprocess_image(file_data, size, channels=1):
|
||||
width, height = size
|
||||
wah = int(numpy.ceil(numpy.sqrt(len(file_data) / channels)))
|
||||
arr = numpy.frombuffer(file_data, dtype=numpy.uint8)
|
||||
img = numpy.zeros(wah*wah*channels, dtype=numpy.uint8)
|
||||
img[:len(file_data)] = arr
|
||||
image = Image.fromarray(img.reshape((wah, wah)), 'L')
|
||||
return image.resize((width, height), Image.Resampling.NEAREST)
|
||||
|
||||
####################################################################################################
|
||||
|
||||
def get_type(file_path):
|
||||
suffix = {".com", ".dll", ".drv", ".exe", ".ocx", ".scr", ".sys", ".mui", ".cpl"}
|
||||
try:
|
||||
file_content = None
|
||||
if not os.path.splitext(file_path)[-1].lower() in suffix:
|
||||
return file_content
|
||||
with open(file_path, 'rb') as f:
|
||||
file_content = f.read()
|
||||
except:
|
||||
pass
|
||||
return file_content
|
||||
|
||||
####################################################################################################
|
||||
|
||||
def file_to_images(input_dir, output_dir):
|
||||
for root, dirs, files in os.walk(input_dir):
|
||||
for file in files:
|
||||
try:
|
||||
file_path = os.path.join(root, file)
|
||||
file_content = get_type(file_path)
|
||||
if file_content:
|
||||
print(file_path)
|
||||
relative_path = os.path.relpath(root, input_dir)
|
||||
output_path_dir = os.path.join(output_dir, relative_path)
|
||||
|
||||
if not os.path.exists(output_path_dir):
|
||||
os.makedirs(output_path_dir)
|
||||
image = preprocess_image(file_content, (224, 224))
|
||||
safe_name = os.path.basename(file_path).replace('/', '_').replace('\\', '_')
|
||||
image.save(os.path.join(output_path_dir, f"{safe_name}.png"))
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
####################################################################################################
|
||||
|
||||
input_directory = input('Enter the folder path: ')
|
||||
output_directory = "./Image_Output"
|
||||
file_to_images(input_directory, output_directory)
|
||||
input('Conversion Complete')
|
||||
@@ -0,0 +1,34 @@
|
||||
import os, hashlib
|
||||
|
||||
####################################################################################################
|
||||
|
||||
def calc_sha256(path):
|
||||
with open(path, "rb") as f:
|
||||
return hashlib.sha256(f.read()).digest()
|
||||
|
||||
def dedup_realtime(root):
|
||||
seen = set()
|
||||
deleted = 0
|
||||
for dirpath, _, files in os.walk(root):
|
||||
for name in files:
|
||||
p = os.path.join(dirpath, name)
|
||||
try:
|
||||
h = calc_sha256(p)
|
||||
except Exception:
|
||||
continue
|
||||
if h in seen:
|
||||
try:
|
||||
os.remove(p)
|
||||
print(p)
|
||||
deleted += 1
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
seen.add(h)
|
||||
print(f"deleted {deleted}")
|
||||
|
||||
####################################################################################################
|
||||
|
||||
if __name__ == "__main__":
|
||||
dedup_realtime(input("Input file path: "))
|
||||
input('Deduplicate Complete')
|
||||
@@ -0,0 +1,163 @@
|
||||
import tensorflow as tf
|
||||
import os, tf2onnx, numpy, random
|
||||
from PIL import Image
|
||||
from tensorflow.keras import *
|
||||
from collections import Counter
|
||||
|
||||
####################################################################################################
|
||||
|
||||
Image.MAX_IMAGE_PIXELS = None
|
||||
tf.keras.mixed_precision.set_global_policy('mixed_float16')
|
||||
|
||||
####################################################################################################
|
||||
|
||||
def load_dataset(data_dir, image_size=(224, 224), val_split=0.00001, batch_size=256, color_mode="grayscale"):
|
||||
channels = 1 if color_mode == "grayscale" else 3
|
||||
file_paths, labels, class_indices = get_file_list(data_dir)
|
||||
|
||||
combined = list(zip(file_paths, labels))
|
||||
random.shuffle(combined)
|
||||
file_paths[:], labels[:] = zip(*combined)
|
||||
|
||||
num_val = int(val_split * len(file_paths))
|
||||
train_files = file_paths[num_val:]
|
||||
train_labels = labels[num_val:]
|
||||
val_files = file_paths[:num_val]
|
||||
val_labels = labels[:num_val]
|
||||
num_classes = len(class_indices)
|
||||
|
||||
train_ds = tf.data.Dataset.from_tensor_slices((train_files, train_labels))
|
||||
train_ds = train_ds.map(lambda f, l: parse_fn(f, l, image_size, channels, num_classes), num_parallel_calls=tf.data.AUTOTUNE)
|
||||
train_ds = train_ds.batch(batch_size).prefetch(tf.data.AUTOTUNE)
|
||||
|
||||
val_ds = tf.data.Dataset.from_tensor_slices((val_files, val_labels))
|
||||
val_ds = val_ds.map(lambda f, l: parse_fn(f, l, image_size, channels, num_classes), num_parallel_calls=tf.data.AUTOTUNE)
|
||||
val_ds = val_ds.batch(batch_size).prefetch(tf.data.AUTOTUNE)
|
||||
|
||||
train_ds.class_indices = class_indices
|
||||
return train_ds, val_ds
|
||||
|
||||
####################################################################################################
|
||||
|
||||
def parse_fn(filename, label, image_size, channels, num_classes):
|
||||
img = tf.io.read_file(filename)
|
||||
img = tf.image.decode_image(img, channels=channels, expand_animations=False)
|
||||
img = tf.cond(tf.reduce_all(tf.equal(tf.shape(img)[:2], image_size)), lambda: tf.cast(img, tf.float32), lambda: tf.image.resize(img, image_size))
|
||||
img = tf.cast(img, tf.float32) / 255.0
|
||||
label = tf.one_hot(label, depth=num_classes)
|
||||
return img, label
|
||||
|
||||
def get_file_list(directory):
|
||||
file_paths, labels, class_indices = [], [], {}
|
||||
for i, cls in enumerate(sorted([d for d in os.listdir(directory) if os.path.isdir(os.path.join(directory, d))])):
|
||||
class_indices[cls] = i
|
||||
cls_dir = os.path.join(directory, cls)
|
||||
|
||||
for root, _, files in os.walk(cls_dir):
|
||||
for file in files:
|
||||
if file.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp', '.gif')):
|
||||
file_paths.append(os.path.join(root, file))
|
||||
labels.append(i)
|
||||
return file_paths, labels, class_indices
|
||||
|
||||
####################################################################################################
|
||||
|
||||
def multi_conv(x, strides):
|
||||
convs = []
|
||||
for k in [(1, 7), (1, 1), (3, 3), (5, 5)]:
|
||||
c = layers.DepthwiseConv2D(kernel_size=k, strides=strides, padding='same', activation='gelu')(x)
|
||||
convs.append(c)
|
||||
|
||||
x = layers.Concatenate()(convs)
|
||||
x = layers.BatchNormalization()(x)
|
||||
return layers.Activation('gelu')(x)
|
||||
|
||||
def gated_conv(x, strides):
|
||||
c = layers.DepthwiseConv2D(3, strides=strides, padding='same', activation='gelu')(x)
|
||||
g = layers.DepthwiseConv2D(3, strides=strides, padding='same', activation='sigmoid')(x)
|
||||
return layers.Multiply()([c, g])
|
||||
|
||||
def coordinate_attention(x, reduction):
|
||||
input_shape = tf.shape(x)
|
||||
h, w = input_shape[1], input_shape[2]
|
||||
filters = x.shape[-1]
|
||||
mip = max(8, filters // reduction)
|
||||
|
||||
x_h = layers.Lambda(lambda t: tf.reduce_mean(t, axis=2, keepdims=True))(x)
|
||||
x_w = layers.Lambda(lambda t: tf.reduce_mean(t, axis=1, keepdims=True))(x)
|
||||
x_w_t = layers.Permute((2, 1, 3))(x_w)
|
||||
|
||||
x_cat = layers.Concatenate(axis=1)([x_h, x_w_t])
|
||||
x_cat = layers.Conv2D(mip, 1, padding='valid', use_bias=False)(x_cat)
|
||||
x_cat = layers.BatchNormalization()(x_cat)
|
||||
x_cat = layers.Activation('gelu')(x_cat)
|
||||
|
||||
x_cat_h, x_cat_w = layers.Lambda(lambda t: tf.split(t[0], [t[1], t[2]], axis=1))([x_cat, h, w])
|
||||
x_h_sigmoid = layers.Conv2D(filters, 1, padding='valid', activation='sigmoid')(x_cat_h)
|
||||
x_cat_w = layers.Permute((2, 1, 3))(x_cat_w)
|
||||
x_w_sigmoid = layers.Conv2D(filters, 1, padding='valid', activation='sigmoid')(x_cat_w)
|
||||
|
||||
return layers.Multiply()([x, x_h_sigmoid, x_w_sigmoid])
|
||||
|
||||
def build_model(input_shape, num_classes):
|
||||
i = layers.Input(shape=input_shape)
|
||||
x = multi_conv(i, strides=1)
|
||||
x = gated_conv(x, strides=2)
|
||||
x = multi_conv(x, strides=2)
|
||||
x = multi_conv(x, strides=2)
|
||||
x = multi_conv(x, strides=2)
|
||||
x = multi_conv(x, strides=2)
|
||||
|
||||
x = coordinate_attention(x, reduction=4)
|
||||
x = layers.GlobalMaxPooling2D()(x)
|
||||
|
||||
x = layers.Dense(x.shape[-1] // 2, activation='gelu', dtype='float32')(x)
|
||||
o = layers.Dense(num_classes, activation='softmax', dtype='float32')(x)
|
||||
return models.Model(i, o)
|
||||
|
||||
####################################################################################################
|
||||
|
||||
def calculate_lr_cosine_sq(epoch, total_epochs=30, lr_start=5e-4, lr_end=5e-7):
|
||||
cos_val = 0.5 * (1 + numpy.cos(epoch / total_epochs * numpy.pi))
|
||||
return lr_end + (lr_start - lr_end) * (cos_val ** 2)
|
||||
|
||||
def lr_scheduler(epoch):
|
||||
return calculate_lr_cosine_sq(epoch)
|
||||
|
||||
def categorical_focal_loss(gamma=2.0, alpha=0.25):
|
||||
def focal_loss(y_true, y_pred):
|
||||
y_pred = tf.clip_by_value(y_pred, tf.keras.backend.epsilon(), 1.0 - tf.keras.backend.epsilon())
|
||||
cross_entropy = -y_true * tf.math.log(y_pred)
|
||||
loss = alpha * tf.math.pow(1.0 - y_pred, gamma) * cross_entropy
|
||||
return tf.reduce_sum(loss, axis=-1)
|
||||
return focal_loss
|
||||
|
||||
class CustomModelCheckpoint(callbacks.Callback):
|
||||
def on_epoch_end(self, epoch, logs=False):
|
||||
models.save_model(self.model, f"PYAS_Model_Epoch_{epoch + 1}.h5")
|
||||
spec = (tf.TensorSpec((None,) + train_ds.image_shape, tf.float32),)
|
||||
model_proto, _ = tf2onnx.convert.from_keras(self.model, input_signature=spec, opset=17)
|
||||
with open(f"PYAS_Model_Epoch_{epoch + 1}.onnx", "wb") as f:
|
||||
f.write(model_proto.SerializeToString())
|
||||
|
||||
####################################################################################################
|
||||
|
||||
train_ds, val_ds = load_dataset(r'.\Image_Full_Pefile')
|
||||
for imgs, _ in train_ds.take(1):
|
||||
train_ds.image_shape = imgs.shape[1:]
|
||||
break
|
||||
|
||||
try:
|
||||
model = models.load_model('PYAS_Model_Epoch_0.h5')
|
||||
print("Load model from disk")
|
||||
except:
|
||||
print("Creating a new model")
|
||||
model = build_model(train_ds.image_shape, len(train_ds.class_indices))
|
||||
|
||||
print(f"Total parameters: {model.count_params()}")
|
||||
model.compile(optimizer='adam', loss=categorical_focal_loss(gamma=2.0, alpha=0.25),
|
||||
metrics=['accuracy', metrics.Precision(name='precision'), metrics.Recall(name='recall'),
|
||||
metrics.FalsePositives(name='fp'), metrics.TrueNegatives(name='tn')])
|
||||
|
||||
model.fit(train_ds, epochs=30, callbacks=[CustomModelCheckpoint(), callbacks.LearningRateScheduler(lr_scheduler)], validation_data=val_ds)
|
||||
input('Training Complete')
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
-21
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 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.
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
87owo Publicly Available Source Code License Agreement
|
||||
Last updated: 2025-12-19
|
||||
|
||||
1. License and Ownership
|
||||
- This software and its source code are source available for public view.
|
||||
- Access or execution of certain features may require an activation key.
|
||||
- 87owo reserves all legal rights, no intellectual property is transferred.
|
||||
- All project archives, source code, and binaries remain fully proprietary.
|
||||
|
||||
2. Use and Prohibitions
|
||||
- You may view, download, and modify the code for local and personal use.
|
||||
- Redistribution of any original or modified code requires prior consent.
|
||||
- Commercial hosting or SaaS deployment is prohibited without permission.
|
||||
- Reverse engineering, license removal, or illegal use is strictly barred.
|
||||
|
||||
3. Data and Privacy
|
||||
- This project may collect operational data for optimization and analysis.
|
||||
- All collected data is strictly anonymized to ensure the user's privacy.
|
||||
- Transmission of information is encrypted to prevent unauthorized access.
|
||||
|
||||
4. Updates and Terms
|
||||
- New releases may include critical patches, enhancements, or UI changes.
|
||||
- Continued use of these services constitutes acceptance of updated terms.
|
||||
- The author reserves the right to modify these license terms at any time.
|
||||
|
||||
5. Warranty and Liability
|
||||
- All services and assets are provided "as is" without any form of warranty.
|
||||
- 87owo is not liable for any direct or indirect damages from software use.
|
||||
- Users assume all risks regarding performance, data, and system integrity.
|
||||
|
||||
© 2020-2026 87owo (PYAS Security). All rights reserved.
|
||||
@@ -1,30 +0,0 @@
|
||||
GetSystemDirectory
|
||||
BroadcastSystemMessage
|
||||
BroadcastSystemMessage
|
||||
CreateIcon
|
||||
RegOpenCurrentUser
|
||||
RegSetValue
|
||||
RegCreateKey
|
||||
RegDeleteValue
|
||||
RegisterClass
|
||||
RegisterHotKey
|
||||
RegisterClipboardFormat
|
||||
RegisterWindowMessage
|
||||
RegisterClass
|
||||
CryptDestroyKey
|
||||
CryptGenKey
|
||||
CryptDecrypt
|
||||
CryptEncrypt
|
||||
CryptImportKey
|
||||
CryptSetKeyParam
|
||||
CryptDeriveKey
|
||||
CryptCreateHash
|
||||
CryptHashData
|
||||
CryptStringToBinary
|
||||
CryptBinaryToString
|
||||
CryptGetKeyParam
|
||||
CryptGetHashParam
|
||||
CryptDestroyHash
|
||||
CryptImportPublicKeyInfo
|
||||
UnlockFile
|
||||
LockFile
|
||||
@@ -1 +0,0 @@
|
||||
0
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB |
@@ -1 +0,0 @@
|
||||
(pyas md5 hash)
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
translate_dict = {
|
||||
"traditional_switch": {"开启":"開啟","关闭":"關閉","On":"開啟","Off":"關閉"},
|
||||
|
||||
"simplified_switch": {"開啟":"开启","關閉":"关闭","On":"开启","Off":"关闭",
|
||||
"錯誤":"错误","發現":"发现","關閉":"关闭","裝置":"设备","記憶體":"内存",
|
||||
"軟體":"软件","檔案":"文件","確定":"确认","設定":"设置","關於":"关于",
|
||||
"總數":"总数","註冊":"注册","圖標":"图标","路徑":"路径","網路":"网络",
|
||||
"位元":"字节","靈敏":"敏感","複製":"复制","開啟":"开启","靜態":"静态",
|
||||
"訊":"讯","項":"项","掃":"扫","試":"试","黃":"黄","嗎":"吗","防":"保",
|
||||
"鑰":"钥","當":"当","後":"后","護":"护","導":"导","區":"区","復":"复",
|
||||
"攔":"拦","請":"请","統":"统","刪":"删","進":"进","個":"个","選":"选",
|
||||
"啟":"启","監":"监","並":"并","徑":"径","盤":"盘","隱":"隐","動":"动",
|
||||
"狀":"状","誌":"志","這":"这","會":"会","題":"题","擇":"择","語":"语",
|
||||
"無":"无","顯":"显","變":"变","戶":"户","碼":"码","雲":"云","介":"界",
|
||||
"稱":"称","類":"类","輸":"输","執":"执","數":"数","尋":"寻","網":"网",
|
||||
"詢":"询","製":"制","員":"员","許":"许","條":"条","藍":"蓝","紅":"红",
|
||||
"綠":"绿","態":"态","務":"务","連":"连","檢":"检","測":"测","關":"关",
|
||||
"強":"强","驅":"驱","為":"为","腳":"脚","單":"单","開":"开","擴":"扩",
|
||||
"惡":"恶","據":"据","庫":"库","經":"经","敗":"败","謝":"谢","別":"别",
|
||||
"載":"载","誤":"误","報":"报","鏈":"链","竄":"窜","蹤":"踪","與":"与",
|
||||
"異":"异","實":"实","時":"时","彈":"弹","窗":"窗","暫":"暂","訂":"订",
|
||||
"資":"资","產":"产","金":"密","離":"离","規":"规","則":"则","來":"来",
|
||||
"殼":"壳","碼":"码","線":"线","餘":"余",},
|
||||
|
||||
"english_switch": {"開啟":"On","關閉":"Off","开启":"On","关闭":"Off",",":", ",
|
||||
"立即刪除":"Delete Now","安全模式":"Safe Mode","官方網站":"Official Website ",
|
||||
"腳本":"Script ","鏈式":"Chain ","記憶體":"Memory ","正在加載":"Loading ","加載":"Load ",
|
||||
"行為":"Behavior ","可疑":"Suspicious ","勒索":"Ransom ","主要":"Main ",
|
||||
"許可條款":"License Terms ","惡意":"Malicious", "開發":"Developers ",
|
||||
"啟用":"Enable ","禁用":"Disable ","正在初始化中":"Initializing ","初始化":"initialize ",
|
||||
"正在掃描":"Scanning ","正在刪除":"Deleting ","正在追蹤":"Tracking ",
|
||||
"最小化到":"Minimize To ","靈敏度":"Sensitivity ","正在檢查":"Checking ",
|
||||
"確定要":"Sure Want To ","引擎靈敏度":"Sensitivity ","更新":"Update ",
|
||||
"白色主題":"White","黃色主題":"Yellow","紅色主題":"Red","語言":"Language ",
|
||||
"藍色主題":"Blue","綠色主題":"Green","自訂主題":"Custom","黑色主題":"Black",
|
||||
"特別感謝":"Contributors ","版本資訊":"Information","通訊":"Connect ",
|
||||
"註冊":"Registry ","退出":"Quit ","檔案":"File ","當前":"Currently ",
|
||||
"狀態":"State ","掃描":"Scan ","工具":"Tools ","防護":"Protect ",
|
||||
"失敗":"Failed ","請":"Please ","路徑":"Path ","方式":"Method ",
|
||||
"需要":"Need ","病毒":"Virus ","選擇":"Select ","返回":"Back",
|
||||
"受到":"Been ","錯誤":"Error","完成":"Complete ","引擎":"Engine ",
|
||||
"托盤":"Tray ","圖標":"Icon ","不安全":"Unsafe","增強":"Enhance ",
|
||||
"系統":"System ","雲端":"Cloud ","重啟":"Reboot ","修復":"Repair ",
|
||||
"裝置":"Device ","發現":"Found ","成功":"Success ","清理":"Cleanup ",
|
||||
"確定":"OK","執行":"Execute ","警告":"Warning ","使用":"Use ",
|
||||
"網路":"Network ","變更":"Change ","總數":"Total","結束":"End ",
|
||||
"選項":"Options ","監控":"Monitor ","連接":"Connect ","可以":"Can ",
|
||||
"進程":"Process ","攔截":"Block ","引導":"Boot ","刪除":"Delete ",
|
||||
"分區":"Partition ","設定":"Setting ","關於":"About","模式":"Mode ",
|
||||
"提高":"Improve ","安全":"Security ","顯色":"Color ","顏色":"Color ",
|
||||
"主題":"Theme ", "回收":"Collect ", "無用":"Useless ","導入":"Import ",
|
||||
"風險":"Risk ","介面":"UI ","核心":"Core ","服務":"Services ",
|
||||
"管理":"Manage","所有":"All ","您":"You ","取消":"Cancel ","未":"Not ",
|
||||
"垃圾":"Junk ","位元":"byte ","本機":"Computer ","停止":"Stop ",
|
||||
"到":"To ","白名單":"White List ","軟體":"Software ","正在":"",
|
||||
"增加":"Add ","移除":"Delete ","項目":"Items ","生成":"Create ","稱":"",
|
||||
"複製":"Copy ","此":"This ","並":"And ","全盤":"Full ","最新":"Latest ",
|
||||
"已存在":"Already ","數據庫":"Database ","誤報":"False Positive ",
|
||||
"高":"High ","新":"New ","和":"And ","可能會":"Possible ","會":"Can ",
|
||||
"日誌":"Log","已":"Has ","彈窗":"Window ","要":"To ","驅動":"Driver ",
|
||||
"的":"","顯示":"","個":"","嗎":"","了":"","行":"","立即":"","規則":"Rule ",
|
||||
"密鑰":"Key ","檢測":"Detect ","製作":"Maker ","運行":"Running",
|
||||
"擴展":"Extension ","套件":"Kit ","自動":"Auto ","上報":"Report ",
|
||||
"分析":"Analysis ","自身":"Self ","其他":"Other ","配置":"Config ",
|
||||
"丟失":"Lost ","網站":"Website ","不兼容":"Not Compatible ","列表":"List ",
|
||||
"竄改":"Tamper ","第三方":"Other ","實時":"Real Time ","查看":"View ",
|
||||
"指定":"Specify ","清空":"Empty ","資源回收桶":"Recycle Bin ", "無法":"Cannot ",
|
||||
"與":"With ","當":"When ","功能":"Function ","異常":"Abnormal ", "來":"To ",
|
||||
"重置":"Reset ","窗口":"Window ","暫存":"Temp ","自訂":"Custom ",
|
||||
"不支持":"Not Support ","共":"Total ","秒":"Seconds ","耗時":"Takes ",
|
||||
"沙箱":"Sandbox ", "虛擬":"Virtual ", "隔離":"Quarantine ", "時":"",
|
||||
"建立":"Create ","環境":"Environment ","沙箱":"Sandbox ","化":"", "表":"",
|
||||
"達":"Reached ", "上限":"Limit ", "區":"", "金鑰":"Key ", "產品":"Product ",
|
||||
"運行庫":".NET CLR ","殼碼":"Shellcode ","線程":"Thread ","注入":"Inject ",
|
||||
"前往":"Go ","檢查":"Check ","可用":"Available ","靜態":"Static ",
|
||||
"版本":"Version ","是":"","剩餘":"Remain ","遠控":"Remote ","監控":"Monitor ",
|
||||
" ":" "},
|
||||
|
||||
"white_switch": {
|
||||
"_white": "_black",},
|
||||
"red_switch": {
|
||||
"235, 235, 235": "255, 235, 235",
|
||||
"245, 245, 245": "255, 225, 225",
|
||||
"255, 255, 255": "255, 245, 245",
|
||||
"240, 240, 240": "255, 220, 220",
|
||||
"250, 250, 250": "255, 210, 210",
|
||||
"220, 255, 220": "255, 220, 220",
|
||||
"210, 255, 210": "255, 210, 210",
|
||||
"_white": "_black"
|
||||
},
|
||||
"yellow_switch": {
|
||||
"235, 235, 235": "255, 255, 235",
|
||||
"245, 245, 245": "255, 255, 225",
|
||||
"255, 255, 255": "255, 255, 245",
|
||||
"240, 240, 240": "255, 255, 220",
|
||||
"250, 250, 250": "255, 255, 210",
|
||||
"220, 255, 220": "255, 255, 220",
|
||||
"210, 255, 210": "255, 255, 210",
|
||||
"_white": "_black"
|
||||
},
|
||||
"green_switch": {
|
||||
"235, 235, 235": "235, 255, 235",
|
||||
"245, 245, 245": "225, 255, 225",
|
||||
"255, 255, 255": "245, 255, 245",
|
||||
"240, 240, 240": "220, 255, 220",
|
||||
"250, 250, 250": "210, 255, 210",
|
||||
"_white": "_black"
|
||||
},
|
||||
"blue_switch": {
|
||||
"235, 235, 235": "235, 235, 255",
|
||||
"245, 245, 245": "225, 225, 255",
|
||||
"255, 255, 255": "245, 245, 255",
|
||||
"240, 240, 240": "220, 220, 255",
|
||||
"250, 250, 250": "210, 210, 255",
|
||||
"220, 255, 220": "220, 220, 255",
|
||||
"210, 255, 210": "210, 210, 255",
|
||||
"_white": "_black"
|
||||
},
|
||||
"black_switch": {
|
||||
"255, 255, 255": "20, 20, 20",
|
||||
"245, 245, 245": "40, 40, 40",
|
||||
"235, 235, 235": "30, 30, 30",
|
||||
"240, 240, 240": "70, 70, 70",
|
||||
"250, 250, 250": "80, 80, 80",
|
||||
"220, 255, 220": "70, 70, 70",
|
||||
"210, 255, 210": "80, 80, 80",
|
||||
"0, 0, 0": "255, 255, 255",
|
||||
"_black": "_white"
|
||||
}
|
||||
}
|
||||
+322
@@ -0,0 +1,322 @@
|
||||
import os, yara, time, numpy, base64, requests
|
||||
import ctypes, ctypes.wintypes, hashlib, onnxruntime
|
||||
|
||||
from PIL import Image
|
||||
from io import BytesIO
|
||||
|
||||
####################################################################################################
|
||||
|
||||
class GUID(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("Data1", ctypes.wintypes.DWORD),
|
||||
("Data2", ctypes.wintypes.WORD),
|
||||
("Data3", ctypes.wintypes.WORD),
|
||||
("Data4", ctypes.c_ubyte * 8)]
|
||||
|
||||
class WINTRUST_FILE_INFO(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("cbStruct", ctypes.wintypes.DWORD),
|
||||
("pcwszFilePath", ctypes.wintypes.LPCWSTR),
|
||||
("hFile", ctypes.wintypes.HANDLE),
|
||||
("pgKnownSubject", ctypes.wintypes.LPVOID)]
|
||||
|
||||
class WINTRUST_DATA(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("cbStruct", ctypes.wintypes.DWORD),
|
||||
("pPolicyCallbackData", ctypes.wintypes.LPVOID),
|
||||
("pSIPClientData", ctypes.wintypes.LPVOID),
|
||||
("dwUIChoice", ctypes.wintypes.DWORD),
|
||||
("fdwRevocationChecks", ctypes.wintypes.DWORD),
|
||||
("dwUnionChoice", ctypes.wintypes.DWORD),
|
||||
("pFile", ctypes.POINTER(WINTRUST_FILE_INFO)),
|
||||
("dwStateAction", ctypes.wintypes.DWORD),
|
||||
("hWVTStateData", ctypes.wintypes.HANDLE),
|
||||
("pwszURLReference", ctypes.wintypes.LPCWSTR),
|
||||
("dwProvFlags", ctypes.wintypes.DWORD),
|
||||
("dwUIContext", ctypes.wintypes.DWORD),
|
||||
("pSignatureSettings", ctypes.wintypes.LPVOID)]
|
||||
|
||||
####################################################################################################
|
||||
|
||||
class sign_scanner:
|
||||
def __init__(self):
|
||||
self.verify = GUID(0x00AAC56B, 0xCD44, 0x11D0, (0x8C, 0xC2, 0x00, 0xC0, 0x4F, 0xC2, 0x95, 0xEE))
|
||||
|
||||
def init_windll(self, path):
|
||||
for name in path:
|
||||
try:
|
||||
setattr(self, name.lower(), ctypes.WinDLL(name, use_last_error=True))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
self.WinVerifyTrust = self.wintrust.WinVerifyTrust
|
||||
self.WinVerifyTrust.restype = ctypes.wintypes.LONG
|
||||
self.WinVerifyTrust.argtypes = [ctypes.wintypes.HWND, ctypes.POINTER(GUID), ctypes.c_void_p]
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def sign_verify(self, file_path):
|
||||
try:
|
||||
fi = WINTRUST_FILE_INFO(ctypes.sizeof(WINTRUST_FILE_INFO), file_path, None, None)
|
||||
data = WINTRUST_DATA(ctypes.sizeof(WINTRUST_DATA), None, None, 2, 0, 1,
|
||||
ctypes.pointer(fi), 1, None, None, 0, 0, None)
|
||||
s = self.WinVerifyTrust(None, ctypes.byref(self.verify), ctypes.byref(data))
|
||||
data.dwStateAction = 2
|
||||
self.WinVerifyTrust(None, ctypes.byref(self.verify), ctypes.byref(data))
|
||||
return s == 0
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
####################################################################################################
|
||||
|
||||
class rule_scanner:
|
||||
def __init__(self):
|
||||
self.rules = None
|
||||
self.network = []
|
||||
|
||||
def load_path(self, path, callback=None):
|
||||
yara_files = {}
|
||||
for root, _, files in os.walk(path):
|
||||
for file in files:
|
||||
full_path = os.path.join(root, file)
|
||||
if callback:
|
||||
callback(full_path)
|
||||
ext = os.path.splitext(file)[1].lower()
|
||||
if ext in ('.yara', '.yar'):
|
||||
namespace = os.path.relpath(full_path, path).replace(os.sep, '_')
|
||||
yara_files[namespace] = full_path
|
||||
elif ext in ('.yc', '.yrc'):
|
||||
self.load_compiled_rule(full_path)
|
||||
elif ext in ('.ip', '.txt'):
|
||||
self.load_network_list(full_path)
|
||||
|
||||
if yara_files:
|
||||
self.compile_all_rules(yara_files)
|
||||
|
||||
def load_compiled_rule(self, file):
|
||||
try:
|
||||
self.rules = yara.load(file)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def load_network_list(self, file):
|
||||
try:
|
||||
with open(file, "r", encoding="utf-8", errors="ignore") as f:
|
||||
self.network.extend(line.strip() for line in f if line.strip())
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def compile_all_rules(self, file_map):
|
||||
try:
|
||||
self.rules = yara.compile(filepaths=file_map)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def yara_scan(self, file_path):
|
||||
try:
|
||||
if not self.rules:
|
||||
return False, False
|
||||
|
||||
matches = self.rules.match(filepath=file_path)
|
||||
if matches:
|
||||
rule_name = str(matches[0])
|
||||
types = rule_name.split("_")[0]
|
||||
label = rule_name.split("_")[1]
|
||||
level = rule_name.split("_")[2]
|
||||
return f"{types}/{label}", level
|
||||
return False, False
|
||||
except Exception:
|
||||
return False, False
|
||||
|
||||
####################################################################################################
|
||||
|
||||
class model_scanner:
|
||||
def __init__(self):
|
||||
self.models = []
|
||||
self.labels = ["Pefile/White", "Pefile/General"]
|
||||
self.detect_set = {"Pefile/General"}
|
||||
self.resize = (224, 224)
|
||||
|
||||
def load_path(self, path, callback=None):
|
||||
for root, _, files in os.walk(path):
|
||||
for file in files:
|
||||
full_path = os.path.join(root, file)
|
||||
if callback:
|
||||
callback(full_path)
|
||||
self.load_file(full_path)
|
||||
|
||||
def load_file(self, file):
|
||||
if file.lower().endswith('.onnx'):
|
||||
try:
|
||||
session = onnxruntime.InferenceSession(file)
|
||||
self.models.append(session)
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def model_scan(self, file_path, full_output=False):
|
||||
if not self.models:
|
||||
return (False, False) if not full_output else ([], str(file_path), None)
|
||||
|
||||
data = self.get_data(file_path)
|
||||
if not data:
|
||||
return (False, False) if not full_output else ([], str(file_path), None)
|
||||
|
||||
image = self.preprocess_image(data, self.resize)
|
||||
if not image:
|
||||
return (False, False) if not full_output else ([], str(file_path), None)
|
||||
|
||||
arr = numpy.asarray(image).astype('float32') / 255.0
|
||||
arr = numpy.expand_dims(arr, axis=0)
|
||||
if arr.ndim == 3:
|
||||
arr = numpy.expand_dims(arr, axis=-1)
|
||||
|
||||
results = []
|
||||
best_malicious = None
|
||||
|
||||
for model in self.models:
|
||||
input_meta = model.get_inputs()[0]
|
||||
input_name = input_meta.name
|
||||
input_shape = input_meta.shape
|
||||
|
||||
curr_arr = arr.copy()
|
||||
if len(input_shape) == 4:
|
||||
if input_shape[1] in (1, 3) and input_shape[3] not in (1, 3):
|
||||
curr_arr = curr_arr.transpose(0, 3, 1, 2)
|
||||
|
||||
try:
|
||||
probs = model.run(None, {input_name: curr_arr})[0]
|
||||
pred = probs[0]
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
idx = int(numpy.argmax(pred))
|
||||
label = self.labels[idx] if idx < len(self.labels) else f"Class_{idx}"
|
||||
conf = round(float(pred[idx]) * 100, 2)
|
||||
|
||||
if full_output:
|
||||
results.append(("Whole File", label, conf, self.pil_to_base64(image)))
|
||||
|
||||
if label in self.detect_set:
|
||||
if best_malicious is None or conf > best_malicious[1]:
|
||||
best_malicious = (label, int(conf))
|
||||
|
||||
if full_output:
|
||||
results.sort(key=lambda x: (x[1] not in self.detect_set, -x[2]))
|
||||
malicious_count = sum(1 for _, lbl, _, _ in results if lbl in self.detect_set)
|
||||
total = len(results)
|
||||
return results, str(file_path), f"{malicious_count}/{total}"
|
||||
|
||||
return best_malicious if best_malicious else (False, False)
|
||||
|
||||
def pil_to_base64(self, img):
|
||||
buf = BytesIO()
|
||||
img.save(buf, format='PNG')
|
||||
return base64.b64encode(buf.getvalue()).decode()
|
||||
|
||||
def preprocess_image(self, data, size, channels=1):
|
||||
width, height = size
|
||||
wah = int(numpy.ceil(numpy.sqrt(len(data) / channels)))
|
||||
arr = numpy.frombuffer(data, dtype=numpy.uint8)
|
||||
imgbuf = numpy.zeros(wah * wah * channels, dtype=numpy.uint8)
|
||||
imgbuf[:len(arr)] = arr
|
||||
image = Image.fromarray(imgbuf.reshape((wah, wah)), 'L')
|
||||
return image.resize((width, height), Image.Resampling.NEAREST)
|
||||
|
||||
def get_data(self, file_path):
|
||||
try:
|
||||
with open(file_path, 'rb') as f:
|
||||
return f.read()
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
####################################################################################################
|
||||
|
||||
class cloud_scanner:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def calc_hash(self, file_path, block_size=65536):
|
||||
try:
|
||||
h = hashlib.sha256()
|
||||
with open(file_path, "rb") as f:
|
||||
for chunk in iter(lambda: f.read(block_size), b""):
|
||||
h.update(chunk)
|
||||
return h.hexdigest()
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
def upload_file(self, file_path, api_host, api_key):
|
||||
try:
|
||||
sha256 = self.calc_hash(file_path)
|
||||
if not sha256:
|
||||
return False, None
|
||||
|
||||
base = api_host.rstrip('/')
|
||||
base_headers = {"X-API-Key": api_key, "User-Agent": "PYAS-Client/1.0"}
|
||||
|
||||
def _req(m, ep, files=None, **k):
|
||||
try:
|
||||
return requests.request(m, f"{base}{ep}", headers=base_headers, files=files, timeout=120, **k)
|
||||
except:
|
||||
return None
|
||||
|
||||
r = _req("GET", f"/api/processing_status/{sha256}")
|
||||
status = r.json().get('status') if r and r.status_code == 200 else 'missing'
|
||||
if status in ['failed', 'error']:
|
||||
status = 'missing'
|
||||
|
||||
if status == 'missing':
|
||||
with open(file_path, 'rb') as f:
|
||||
r = _req("POST", "/api/upload", files={'file': f})
|
||||
if not r or r.status_code != 200:
|
||||
return False, sha256
|
||||
|
||||
return True, sha256
|
||||
except Exception:
|
||||
return False, None
|
||||
|
||||
def get_result(self, sha256, api_host, api_key):
|
||||
try:
|
||||
if not sha256:
|
||||
return False
|
||||
|
||||
base = api_host.rstrip('/')
|
||||
headers = {"X-API-Key": api_key, "User-Agent": "PYAS-Client/1.0"}
|
||||
|
||||
def _req(m, ep, **k):
|
||||
try:
|
||||
return requests.request(m, f"{base}{ep}", headers=headers, timeout=10, **k)
|
||||
except:
|
||||
return None
|
||||
|
||||
for _ in range(30):
|
||||
r = _req("GET", f"/api/processing_status/{sha256}")
|
||||
st = r.json().get('status') if r else 'error'
|
||||
if st == 'done':
|
||||
break
|
||||
if st in ['error', 'failed']:
|
||||
return False
|
||||
time.sleep(1)
|
||||
|
||||
r = _req("GET", f"/api/report/{sha256}")
|
||||
if r and r.status_code == 200:
|
||||
data = r.json().get('data', {})
|
||||
res = data.get('detection', {}).get('results', {}).get('PYAS', {})
|
||||
label = res.get('label', 'Unsupport')
|
||||
sims = data.get('similar', [])
|
||||
|
||||
is_malicious = 'General' in label
|
||||
sim_malicious_count = 0
|
||||
valid_sim_count = 0
|
||||
for s in sims:
|
||||
if s.get('similarity', 0) > 80:
|
||||
valid_sim_count += 1
|
||||
if "General" in s.get('label'):
|
||||
sim_malicious_count += 1
|
||||
|
||||
if is_malicious and (valid_sim_count == 0 or sim_malicious_count == valid_sim_count):
|
||||
return True
|
||||
except Exception:
|
||||
pass
|
||||
return False
|
||||
-100
@@ -1,100 +0,0 @@
|
||||
english_list = {
|
||||
"提示":"Tips",
|
||||
"已開啟":"On",
|
||||
"已關閉":"Off",
|
||||
"已开启":"On",
|
||||
"已关闭":"Off",
|
||||
"正在刪除: ":"Deleting: ",
|
||||
"正在删除":"Deleting: ",
|
||||
"存取被拒":"Access denied",
|
||||
" > [提示] 尚未啟用實時防護":" > [Tips] Real-time Protect is not enabled",
|
||||
" > [提示] 尚未启用实时防护":" > [Tips] Real-time Protect is not enabled",
|
||||
" > [行為防護] 成功攔截了惡意檔案創建行為。":" > [Behavior Protection] Successfully blocked malicious file creation behavior.",
|
||||
" 被移動":" Moved",
|
||||
" 被創建":" Created",
|
||||
" 被刪除":" Deleted",
|
||||
" 被編輯":" Edited",
|
||||
"請輸入需要尋找的檔案":"Please enter the file you want to find",
|
||||
"请输入需要寻找的档案":"Please enter the file you want to find",
|
||||
"✔成功: 已執行成功。":"✔Success: Executed successfully.",
|
||||
"這部裝置已受到保護":"This device has been protected",
|
||||
"✖錯誤: 執行失敗。":"✖Error: Execution failed.",
|
||||
" > [病毒掃描] 掃描出":" > [Virus Scan] scan out ",
|
||||
"個病毒":" Virus",
|
||||
"這部裝置目前不安全":"This device is currently unsafe",
|
||||
"✖當前已發現惡意軟體共{}項。":"✖A total of {} items of malware have been found so far.",
|
||||
'✔當前未發現惡意軟體。':'✔ No malware currently found.',
|
||||
'正在掃描: ':'Scanning: ',
|
||||
'正在扫描: ':'Scanning: ',
|
||||
"病毒掃描":"Virus scan",
|
||||
"正在初始化中,請稍後...":"Initializing, please wait...",
|
||||
"✖當前已發現惡意軟體。":"✖Malware has currently been detected.",
|
||||
"✖掃描失敗。":"✖Scan failed.",
|
||||
"請選擇掃描方式":"Please select a scan method",
|
||||
"您確定要修復系統權限嗎?":"Are you sure you want to fix system permissions?",
|
||||
"修復完成!":"Repair complete!",
|
||||
"完成":'Finish',
|
||||
"您確定要修復系統檔案嗎?":"Are you sure you want to repair the system files?",
|
||||
"修復系統檔案":'Repair System Files',
|
||||
"錯誤":"Error",
|
||||
"錯誤: ":"Error: ",
|
||||
"[錯誤] ":"[Error] ",
|
||||
"修復失敗":"Repair failed",
|
||||
'清理系統檔案':'Clean up system files',
|
||||
"您確定要清理系統檔案嗎?":"Are you sure you want to clean the system files?",
|
||||
"清理完成":"Cleanup complete",
|
||||
"清理失敗":"Cleanup failed",
|
||||
"啟用安全模式":"Enable safe mode",
|
||||
"您確定啟用安全模式嗎?":"Are you sure you enable safe mode?",
|
||||
"使用該選項後需要重啟,現在要重啟嗎?":"A reboot is required after using this option, do you want to reboot now?",
|
||||
"啟用失敗":"Enable failed",
|
||||
'禁用安全模式':'Disable safe mode',
|
||||
"您確定禁用安全模式嗎?":"Are you sure you want to disable Safe Mode?",
|
||||
"禁用失敗":"Disable failed",
|
||||
"刪除檔案":"Delete file",
|
||||
"您確定刪除該檔案嗎?":"Are you sure you want to delete this file?",
|
||||
"刪除成功":"Success to deleted",
|
||||
"刪除失敗":"Failed to delete",
|
||||
"運行成功":"Run successfully",
|
||||
"不是有效命令":"Not a valid command",
|
||||
"您輸入了錯誤的HEKY":"You entered the wrong HEKY",
|
||||
"警告":"Warning",
|
||||
"成功的創建或修改註冊表值":"Successfully created or modified registry value",
|
||||
"分析文件函數":"Analyze File Func",
|
||||
"分析文件哈希值":"Analyze File Hashes",
|
||||
"分析文件位元":"Analyze File Bits",
|
||||
'尋找結果:':'Find result:',
|
||||
'正在尋找: ':'Searching: ',
|
||||
'找到檔案:':'File found:',
|
||||
'未找到檔案':'File Not Found',
|
||||
'創建日期:':'Created Date:',
|
||||
"您確定要修改用戶密碼嗎?":"Are you sure you want to change the user password?",
|
||||
"IP查詢":"IP query",
|
||||
"您的ip地址為:{}":"Your ip address is: {}",
|
||||
"您確定要重置網路配置嗎?":"Are you sure you want to reset the network configuration?",
|
||||
"重置網路配置成功":"Reset network configuration successful",
|
||||
"設定":"Setting",
|
||||
"關於":"About",
|
||||
"結束進程":"End process",
|
||||
"啟用該選項可以實時監控進程中的惡意軟體並清除。":"Enable this option to monitor and remove malware in the system in real time.",
|
||||
"启用该选项可以实时监控进程中的恶意软件并清除。":"Enable this option to monitor and remove malware in the system in real time.",
|
||||
"啟用該選項可以提高掃描靈敏度,但這也可能會造成誤殺。":"Enable this option can improve scanning sensitivity, but it can also cause manslaughter.",
|
||||
"启用该选项可以提高扫描灵敏度,但这也可能会造成误杀。":"Enable this option can improve scanning sensitivity, but it can also cause manslaughter.",
|
||||
'{} > [實時防護] 成功攔截了一個惡意軟體:':'{} > [Real-Time Protect] Malware blocking success:',
|
||||
'{} > [實時防護] 惡意軟體攔截失敗:':'{} > [Real-Time Protect] Malware blocking failed:',
|
||||
'修復系統權限':"Repair System Permissions",
|
||||
'啟用該選項可以實時監控系統的檔案讀寫變更行為。':"Enable this option can improve scanning sensitivity, but it can also cause manslaughter.",
|
||||
'PYAS':"""PYAS Python Antivirus Software Security
|
||||
========================================
|
||||
PYAS Create Date: 2020/12/17
|
||||
Official Github: https://github.com/87owo/PYAS
|
||||
Official Website: https://pyantivirus.wixsite.com/pyas
|
||||
PYAS Core Developer: 87owo
|
||||
PYAS GUI Developer: mtkiao
|
||||
PYAS Data Collector: yang5487
|
||||
PYAS Testers: 87owo, mtkiao
|
||||
Special Thanks: Wix, Avast, Github, Google, Python,
|
||||
Microsoft, VirusTotal, VirusShare, LenStevens
|
||||
========================================
|
||||
Thanks For Using PYAS Python Antivirus Software
|
||||
"""}
|
||||
+1576
File diff suppressed because it is too large.
Load diff
+14520
File diff suppressed because it is too large.
Load diff
-2949
File diff suppressed because it is too large.
Load diff
@@ -1 +0,0 @@
|
||||
<RCC/>
|
||||
-5585
File diff suppressed because it is too large.
Load diff
-4109
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,11 @@
|
||||
import pyinstaller_versionfile
|
||||
|
||||
pyinstaller_versionfile.create_versionfile(
|
||||
output_file="versionfile.txt",
|
||||
version='3.3.9',
|
||||
company_name="PYAS Security",
|
||||
file_description="Python Antivirus Software",
|
||||
internal_name="PYAS",
|
||||
legal_copyright="PYAS Security",
|
||||
original_filename="PYAS.exe",
|
||||
product_name="PYAS")
|
||||
@@ -1,10 +0,0 @@
|
||||
import pyinstaller_versionfile
|
||||
pyinstaller_versionfile.create_versionfile(
|
||||
output_file="versionfile.txt",
|
||||
version='2.4.9',
|
||||
company_name="PYAS Security",
|
||||
file_description="Python Antivirus Software",
|
||||
internal_name="PYAS",
|
||||
legal_copyright="© PYAS Security",
|
||||
original_filename="PYAS.exe",
|
||||
product_name="PYAS")
|
||||
@@ -0,0 +1,144 @@
|
||||
#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';
|
||||
|
||||
#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 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 struct _PYAS_MESSAGE {
|
||||
ULONG MessageCode;
|
||||
ULONG ProcessId;
|
||||
WCHAR Path[MAX_PATH_LEN];
|
||||
} PYAS_MESSAGE, * PPYAS_MESSAGE;
|
||||
|
||||
typedef struct _DRIVER_DATA {
|
||||
PDRIVER_OBJECT DriverObject;
|
||||
PFLT_FILTER FilterHandle;
|
||||
PFLT_PORT ServerPort;
|
||||
PFLT_PORT ClientPort;
|
||||
PEPROCESS PyasProcess;
|
||||
ULONG PyasPid;
|
||||
LARGE_INTEGER Cookie;
|
||||
FAST_MUTEX PortMutex;
|
||||
FAST_MUTEX TrackerMutex;
|
||||
EX_RUNDOWN_REF PortRundown;
|
||||
} DRIVER_DATA, * PDRIVER_DATA;
|
||||
|
||||
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 InitializeProcessProtection();
|
||||
VOID UninitializeProcessProtection();
|
||||
NTSTATUS InitializeRegistryProtection(PDRIVER_OBJECT DriverObject);
|
||||
VOID UninitializeRegistryProtection();
|
||||
|
||||
VOID ImageLoadNotify(PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO ImageInfo);
|
||||
|
||||
BOOLEAN IsProcessTrusted(HANDLE ProcessId);
|
||||
BOOLEAN IsCriticalSystemProcess(HANDLE ProcessId);
|
||||
BOOLEAN IsTargetProtected(HANDLE ProcessId);
|
||||
BOOLEAN IsInstallerProcess(HANDLE ProcessId);
|
||||
BOOLEAN WildcardMatch(PCWSTR Pattern, PCWSTR String, USHORT StringLengthBytes);
|
||||
|
||||
BOOLEAN CheckRegistryRule(PCUNICODE_STRING KeyName);
|
||||
BOOLEAN CheckFileExtensionRule(PCUNICODE_STRING FileName);
|
||||
BOOLEAN CheckProtectedPathRule(PCUNICODE_STRING FileName);
|
||||
BOOLEAN CheckRansomActivity(HANDLE ProcessId, PUNICODE_STRING FileName, PVOID Buffer, ULONG Length, BOOLEAN IsWrite);
|
||||
|
||||
NTSTATUS SendMessageToUser(ULONG Code, ULONG Pid, PWCHAR Path, USHORT PathSize);
|
||||
|
||||
FORCEINLINE PVOID PyasAllocate(SIZE_T Size) {
|
||||
#if (NTDDI_VERSION >= NTDDI_WIN10_VB)
|
||||
return ExAllocatePool2(POOL_FLAG_NON_PAGED, Size, PYAS_POOL_TAG);
|
||||
#else
|
||||
PVOID Buffer = ExAllocatePoolWithTag(NonPagedPoolNx, Size, PYAS_POOL_TAG);
|
||||
if (Buffer) RtlZeroMemory(Buffer, Size);
|
||||
return Buffer;
|
||||
#endif
|
||||
}
|
||||
|
||||
FORCEINLINE VOID PyasFree(PVOID Ptr) {
|
||||
if (Ptr) ExFreePoolWithTag(Ptr, PYAS_POOL_TAG);
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
#include "DriverCommon.h"
|
||||
|
||||
DRIVER_DATA GlobalData;
|
||||
|
||||
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 DriverUnload(FLT_FILTER_UNLOAD_FLAGS Flags) {
|
||||
if (!(Flags & FLTFL_FILTER_UNLOAD_MANDATORY)) {
|
||||
ExAcquireFastMutex(&GlobalData.PortMutex);
|
||||
BOOLEAN IsConnected = (GlobalData.ClientPort != NULL);
|
||||
ExReleaseFastMutex(&GlobalData.PortMutex);
|
||||
|
||||
if (IsConnected) {
|
||||
return STATUS_FLT_DO_NOT_DETACH;
|
||||
}
|
||||
}
|
||||
|
||||
PsRemoveLoadImageNotifyRoutine(ImageLoadNotify);
|
||||
UninitializeRegistryProtection();
|
||||
UninitializeProcessProtection();
|
||||
|
||||
ExWaitForRundownProtectionRelease(&GlobalData.PortRundown);
|
||||
|
||||
if (GlobalData.ServerPort) {
|
||||
FltCloseCommunicationPort(GlobalData.ServerPort);
|
||||
}
|
||||
if (GlobalData.FilterHandle) {
|
||||
FltUnregisterFilter(GlobalData.FilterHandle);
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS PortConnect(PFLT_PORT ClientPort, PVOID ServerPortCookie, PVOID ConnectionContext, ULONG SizeOfContext, PVOID* ConnectionPortCookie) {
|
||||
UNREFERENCED_PARAMETER(ServerPortCookie);
|
||||
UNREFERENCED_PARAMETER(ConnectionContext);
|
||||
UNREFERENCED_PARAMETER(SizeOfContext);
|
||||
UNREFERENCED_PARAMETER(ConnectionPortCookie);
|
||||
|
||||
ExAcquireFastMutex(&GlobalData.PortMutex);
|
||||
|
||||
GlobalData.ClientPort = ClientPort;
|
||||
GlobalData.PyasPid = (ULONG)(ULONG_PTR)PsGetCurrentProcessId();
|
||||
GlobalData.PyasProcess = PsGetCurrentProcess();
|
||||
|
||||
ExReInitializeRundownProtection(&GlobalData.PortRundown);
|
||||
|
||||
ExReleaseFastMutex(&GlobalData.PortMutex);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static VOID PortDisconnect(PVOID ConnectionCookie) {
|
||||
UNREFERENCED_PARAMETER(ConnectionCookie);
|
||||
|
||||
ExAcquireFastMutex(&GlobalData.PortMutex);
|
||||
GlobalData.ClientPort = NULL;
|
||||
GlobalData.PyasPid = 0;
|
||||
if (GlobalData.PyasProcess) {
|
||||
GlobalData.PyasProcess = NULL;
|
||||
}
|
||||
ExReleaseFastMutex(&GlobalData.PortMutex);
|
||||
|
||||
ExWaitForRundownProtectionRelease(&GlobalData.PortRundown);
|
||||
}
|
||||
|
||||
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) {
|
||||
UNREFERENCED_PARAMETER(RegistryPath);
|
||||
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
PSECURITY_DESCRIPTOR sd = NULL;
|
||||
OBJECT_ATTRIBUTES oa = { 0 };
|
||||
UNICODE_STRING name = { 0 };
|
||||
|
||||
RtlZeroMemory(&GlobalData, sizeof(GlobalData));
|
||||
GlobalData.DriverObject = DriverObject;
|
||||
ExInitializeFastMutex(&GlobalData.PortMutex);
|
||||
ExInitializeFastMutex(&GlobalData.TrackerMutex);
|
||||
|
||||
ExInitializeRundownProtection(&GlobalData.PortRundown);
|
||||
|
||||
status = FltRegisterFilter(DriverObject, &FilterRegistration, &GlobalData.FilterHandle);
|
||||
if (!NT_SUCCESS(status)) return status;
|
||||
|
||||
status = FltBuildDefaultSecurityDescriptor(&sd, FLT_PORT_ALL_ACCESS);
|
||||
if (NT_SUCCESS(status)) {
|
||||
RtlInitUnicodeString(&name, PYAS_PORT_NAME);
|
||||
InitializeObjectAttributes(&oa, &name, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, sd);
|
||||
status = FltCreateCommunicationPort(GlobalData.FilterHandle, &GlobalData.ServerPort, &oa, NULL, PortConnect, PortDisconnect, NULL, 1);
|
||||
FltFreeSecurityDescriptor(sd);
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
FltUnregisterFilter(GlobalData.FilterHandle);
|
||||
return status;
|
||||
}
|
||||
|
||||
InitializeProcessProtection();
|
||||
InitializeRegistryProtection(DriverObject);
|
||||
PsSetLoadImageNotifyRoutine(ImageLoadNotify);
|
||||
|
||||
return FltStartFiltering(GlobalData.FilterHandle);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
[Version]
|
||||
Signature = "$WINDOWS NT$"
|
||||
Class = ActivityMonitor
|
||||
ClassGuid = {b86dff51-a31e-4bac-b3cf-e8cfe75c9fc2}
|
||||
Provider = %ManufacturerName%
|
||||
DriverVer = 12/29/2025,1.0.0.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"
|
||||
@@ -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
|
||||
@@ -0,0 +1,128 @@
|
||||
<?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>
|
||||
</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>
|
||||
</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="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,51 @@
|
||||
<?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>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,34 @@
|
||||
#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();
|
||||
if (!IsProcessTrusted(Pid) && !IsInstallerProcess(Pid)) {
|
||||
UNICODE_STRING MsgStr = RTL_CONSTANT_STRING(L"Disk_Wiper_Attempt");
|
||||
SendMessageToUser(4001, (ULONG)(ULONG_PTR)Pid, MsgStr.Buffer, MsgStr.Length);
|
||||
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
|
||||
return FLT_PREOP_COMPLETE;
|
||||
}
|
||||
}
|
||||
return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
||||
}
|
||||
@@ -0,0 +1,289 @@
|
||||
#include "DriverCommon.h"
|
||||
|
||||
static BOOLEAN IsHoneyToken(PUNICODE_STRING Path) {
|
||||
if (!Path || !Path->Buffer) return FALSE;
|
||||
if (WildcardMatch(L"*PYAS_Honey*", Path->Buffer, Path->Length) ||
|
||||
WildcardMatch(L"*Backup_Secret*", Path->Buffer, Path->Length)) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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;
|
||||
UNICODE_STRING FileName = { 0 };
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
FLT_PREOP_CALLBACK_STATUS callbackStatus = FLT_PREOP_SUCCESS_NO_CALLBACK;
|
||||
|
||||
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)) {
|
||||
FltReleaseFileNameInformation(nameInfo);
|
||||
return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
||||
}
|
||||
|
||||
FileName = nameInfo->Name;
|
||||
if (!FileName.Buffer || FileName.Length == 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
HANDLE Pid = PsGetCurrentProcessId();
|
||||
BOOLEAN Trusted = IsProcessTrusted(Pid);
|
||||
|
||||
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);
|
||||
|
||||
if (IsHoneyToken(&FileName)) {
|
||||
if (!Trusted) {
|
||||
if ((Data->Iopb->Parameters.Create.SecurityContext->DesiredAccess & (FILE_WRITE_DATA | DELETE)) || IsCreateAction) {
|
||||
SendMessageToUser(5001, (ULONG)(ULONG_PTR)Pid, FileName.Buffer, FileName.Length);
|
||||
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
|
||||
callbackStatus = FLT_PREOP_COMPLETE;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (WildcardMatch(L"\\Device\\PhysicalDrive*", FileName.Buffer, FileName.Length) ||
|
||||
(WildcardMatch(L"\\Device\\Harddisk*", FileName.Buffer, FileName.Length) && !WildcardMatch(L"*Volume*", FileName.Buffer, FileName.Length))) {
|
||||
|
||||
if (Data->Iopb->Parameters.Create.SecurityContext->DesiredAccess &
|
||||
(FILE_WRITE_DATA | FILE_APPEND_DATA | GENERIC_WRITE | WRITE_DAC | WRITE_OWNER)) {
|
||||
|
||||
if (!Trusted && !IsInstallerProcess(Pid)) {
|
||||
UNICODE_STRING MsgStr = RTL_CONSTANT_STRING(L"Disk_Wiper_Attempt");
|
||||
SendMessageToUser(4001, (ULONG)(ULONG_PTR)Pid, MsgStr.Buffer, MsgStr.Length);
|
||||
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
|
||||
callbackStatus = FLT_PREOP_COMPLETE;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CheckProtectedPathRule(&FileName)) {
|
||||
if (!Trusted) {
|
||||
if ((Data->Iopb->Parameters.Create.SecurityContext->DesiredAccess &
|
||||
(FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES | DELETE | WRITE_DAC | GENERIC_WRITE)) || IsCreateAction) {
|
||||
SendMessageToUser(2001, (ULONG)(ULONG_PTR)Pid, FileName.Buffer, FileName.Length);
|
||||
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
|
||||
callbackStatus = FLT_PREOP_COMPLETE;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CheckFileExtensionRule(&FileName)) {
|
||||
if (!Trusted) {
|
||||
if (Data->Iopb->Parameters.Create.SecurityContext->DesiredAccess & (DELETE | FILE_DELETE_CHILD)) {
|
||||
if (CheckRansomActivity(Pid, &FileName, NULL, 0, FALSE)) {
|
||||
SendMessageToUser(5001, (ULONG)(ULONG_PTR)Pid, FileName.Buffer, FileName.Length);
|
||||
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
|
||||
callbackStatus = FLT_PREOP_COMPLETE;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (nameInfo) {
|
||||
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;
|
||||
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) {
|
||||
FltReleaseFileNameInformation(nameInfo);
|
||||
return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
||||
}
|
||||
|
||||
HANDLE Pid = PsGetCurrentProcessId();
|
||||
if (!IsProcessTrusted(Pid)) {
|
||||
|
||||
if (CheckProtectedPathRule(&nameInfo->Name)) {
|
||||
SendMessageToUser(2001, (ULONG)(ULONG_PTR)Pid, nameInfo->Name.Buffer, nameInfo->Name.Length);
|
||||
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
|
||||
FltReleaseFileNameInformation(nameInfo);
|
||||
return FLT_PREOP_COMPLETE;
|
||||
}
|
||||
|
||||
if (CheckFileExtensionRule(&nameInfo->Name)) {
|
||||
if (CheckRansomActivity(Pid, &nameInfo->Name, NULL, 0, FALSE)) {
|
||||
SendMessageToUser(5001, (ULONG)(ULONG_PTR)Pid, nameInfo->Name.Buffer, nameInfo->Name.Length);
|
||||
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
|
||||
FltReleaseFileNameInformation(nameInfo);
|
||||
return FLT_PREOP_COMPLETE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nameInfo) {
|
||||
FltReleaseFileNameInformation(nameInfo);
|
||||
}
|
||||
return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
||||
}
|
||||
|
||||
FLT_PREOP_CALLBACK_STATUS ProtectFile_SetSecurity(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) {
|
||||
FltReleaseFileNameInformation(nameInfo);
|
||||
return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
||||
}
|
||||
|
||||
SECURITY_INFORMATION SecurityInfo = Data->Iopb->Parameters.SetSecurity.SecurityInformation;
|
||||
|
||||
if (SecurityInfo & (OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION)) {
|
||||
|
||||
if (CheckProtectedPathRule(&nameInfo->Name)) {
|
||||
HANDLE Pid = PsGetCurrentProcessId();
|
||||
|
||||
if (!IsProcessTrusted(Pid) && !IsInstallerProcess(Pid)) {
|
||||
SendMessageToUser(2001, (ULONG)(ULONG_PTR)Pid, nameInfo->Name.Buffer, nameInfo->Name.Length);
|
||||
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
|
||||
FltReleaseFileNameInformation(nameInfo);
|
||||
return FLT_PREOP_COMPLETE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FltReleaseFileNameInformation(nameInfo);
|
||||
return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
||||
}
|
||||
|
||||
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 (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;
|
||||
NTSTATUS status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &nameInfo);
|
||||
|
||||
FLT_PREOP_CALLBACK_STATUS callbackStatus = FLT_PREOP_SUCCESS_NO_CALLBACK;
|
||||
|
||||
if (NT_SUCCESS(status) && nameInfo) {
|
||||
status = FltParseFileNameInformation(nameInfo);
|
||||
if (NT_SUCCESS(status) && nameInfo->Name.Buffer) {
|
||||
|
||||
if (CheckFileExtensionRule(&nameInfo->Name)) {
|
||||
HANDLE Pid = PsGetCurrentProcessId();
|
||||
|
||||
if (!IsProcessTrusted(Pid)) {
|
||||
|
||||
PVOID SystemBuffer = NULL;
|
||||
PMDL Mdl = Data->Iopb->Parameters.Write.MdlAddress;
|
||||
|
||||
if (!Mdl) {
|
||||
if (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);
|
||||
}
|
||||
|
||||
if (SystemBuffer) {
|
||||
if (CheckRansomActivity(Pid, &nameInfo->Name, SystemBuffer, WriteLength, TRUE)) {
|
||||
if (!IsInstallerProcess(Pid)) {
|
||||
SendMessageToUser(5001, (ULONG)(ULONG_PTR)Pid, nameInfo->Name.Buffer, nameInfo->Name.Length);
|
||||
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
|
||||
callbackStatus = FLT_PREOP_COMPLETE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FltReleaseFileNameInformation(nameInfo);
|
||||
}
|
||||
return callbackStatus;
|
||||
}
|
||||
|
||||
FLT_PREOP_CALLBACK_STATUS ProtectFile_FileSystemControl(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext) {
|
||||
UNREFERENCED_PARAMETER(FltObjects);
|
||||
UNREFERENCED_PARAMETER(CompletionContext);
|
||||
|
||||
if (Data->Iopb->Parameters.FileSystemControl.Common.FsControlCode != FSCTL_MANAGE_BYPASS_IO) {
|
||||
return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
||||
}
|
||||
|
||||
PFS_BPIO_INPUT InputBuffer = (PFS_BPIO_INPUT)Data->Iopb->Parameters.FileSystemControl.Neither.InputBuffer;
|
||||
if (!InputBuffer) return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
||||
|
||||
__try {
|
||||
if (InputBuffer->Operation == FS_BPIO_OP_ENABLE) {
|
||||
PFLT_FILE_NAME_INFORMATION nameInfo = NULL;
|
||||
if (NT_SUCCESS(FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &nameInfo)) && nameInfo) {
|
||||
if (NT_SUCCESS(FltParseFileNameInformation(nameInfo))) {
|
||||
if (CheckFileExtensionRule(&nameInfo->Name) || CheckProtectedPathRule(&nameInfo->Name)) {
|
||||
|
||||
Data->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||
FltReleaseFileNameInformation(nameInfo);
|
||||
return FLT_PREOP_COMPLETE;
|
||||
}
|
||||
}
|
||||
FltReleaseFileNameInformation(nameInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
||||
}
|
||||
|
||||
return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
#include "DriverCommon.h"
|
||||
|
||||
PVOID ObRegistrationHandle = NULL;
|
||||
OB_CALLBACK_REGISTRATION ObRegistration;
|
||||
OB_OPERATION_REGISTRATION ObCallbacks[1];
|
||||
|
||||
static BOOLEAN IsSystemImage(PUNICODE_STRING FullImageName) {
|
||||
if (!FullImageName || !FullImageName->Buffer) return FALSE;
|
||||
|
||||
if (WildcardMatch(L"*\\Windows\\System32\\*", FullImageName->Buffer, FullImageName->Length) ||
|
||||
WildcardMatch(L"*\\Windows\\SysWOW64\\*", FullImageName->Buffer, FullImageName->Length) ||
|
||||
WildcardMatch(L"*\\Windows\\WinSxS\\*", FullImageName->Buffer, FullImageName->Length) ||
|
||||
WildcardMatch(L"*\\Windows\\Microsoft.NET\\*", FullImageName->Buffer, FullImageName->Length) ||
|
||||
WildcardMatch(L"*\\Common Files\\Microsoft Shared\\*", FullImageName->Buffer, FullImageName->Length) ||
|
||||
WildcardMatch(L"*\\Program Files*\\*", FullImageName->Buffer, FullImageName->Length)) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VOID ImageLoadNotify(PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO ImageInfo) {
|
||||
UNREFERENCED_PARAMETER(ImageInfo);
|
||||
|
||||
if (KeGetCurrentIrql() > APC_LEVEL) return;
|
||||
if (!FullImageName || !FullImageName->Buffer) return;
|
||||
if (ProcessId == (HANDLE)0) return;
|
||||
|
||||
if (IsSystemImage(FullImageName)) return;
|
||||
|
||||
if (IsTargetProtected(ProcessId)) {
|
||||
if (CheckFileExtensionRule(FullImageName)) {
|
||||
SendMessageToUser(6001, (ULONG)(ULONG_PTR)ProcessId, FullImageName->Buffer, FullImageName->Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static BOOLEAN IsBlacklistedAdminTool(HANDLE ProcessId) {
|
||||
if (KeGetCurrentIrql() > APC_LEVEL) return FALSE;
|
||||
|
||||
NTSTATUS status;
|
||||
BOOLEAN isBlacklisted = FALSE;
|
||||
PEPROCESS Process = NULL;
|
||||
PUNICODE_STRING imageFileName = NULL;
|
||||
|
||||
status = PsLookupProcessByProcessId(ProcessId, &Process);
|
||||
if (!NT_SUCCESS(status)) return FALSE;
|
||||
|
||||
status = SeLocateProcessImageName(Process, &imageFileName);
|
||||
|
||||
if (NT_SUCCESS(status) && imageFileName) {
|
||||
if (imageFileName->Buffer) {
|
||||
if (WildcardMatch(L"*Taskmgr.exe", imageFileName->Buffer, imageFileName->Length) ||
|
||||
WildcardMatch(L"*taskkill.exe", imageFileName->Buffer, imageFileName->Length) ||
|
||||
WildcardMatch(L"*ProcessHacker.exe", imageFileName->Buffer, imageFileName->Length) ||
|
||||
WildcardMatch(L"*procmon.exe", imageFileName->Buffer, imageFileName->Length)) {
|
||||
isBlacklisted = TRUE;
|
||||
}
|
||||
}
|
||||
ExFreePool(imageFileName);
|
||||
}
|
||||
|
||||
ObDereferenceObject(Process);
|
||||
return isBlacklisted;
|
||||
}
|
||||
|
||||
static OB_PREOP_CALLBACK_STATUS PreOpenProcess(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation) {
|
||||
UNREFERENCED_PARAMETER(RegistrationContext);
|
||||
|
||||
if (OperationInformation->KernelHandle) return OB_PREOP_SUCCESS;
|
||||
|
||||
PEPROCESS TargetProcess = (PEPROCESS)OperationInformation->Object;
|
||||
if (!TargetProcess) return OB_PREOP_SUCCESS;
|
||||
|
||||
HANDLE TargetPid = PsGetProcessId(TargetProcess);
|
||||
HANDLE SourcePid = PsGetCurrentProcessId();
|
||||
|
||||
if (SourcePid == TargetPid) return OB_PREOP_SUCCESS;
|
||||
|
||||
if ((ULONG)(ULONG_PTR)SourcePid == GlobalData.PyasPid) return OB_PREOP_SUCCESS;
|
||||
if (SourcePid == (HANDLE)4) return OB_PREOP_SUCCESS;
|
||||
|
||||
BOOLEAN bProtected = IsTargetProtected(TargetPid);
|
||||
|
||||
if (bProtected) {
|
||||
BOOLEAN bIsInstaller = IsInstallerProcess(SourcePid);
|
||||
|
||||
if (bIsInstaller) {
|
||||
if (IsBlacklistedAdminTool(SourcePid)) {
|
||||
bIsInstaller = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (bIsInstaller) return OB_PREOP_SUCCESS;
|
||||
|
||||
ACCESS_MASK DenyMask = PROCESS_TERMINATE |
|
||||
PROCESS_VM_OPERATION |
|
||||
PROCESS_VM_WRITE |
|
||||
PROCESS_CREATE_THREAD |
|
||||
PROCESS_VM_READ |
|
||||
PROCESS_DUP_HANDLE |
|
||||
PROCESS_SUSPEND_RESUME |
|
||||
PROCESS_SET_INFORMATION |
|
||||
PROCESS_SET_QUOTA;
|
||||
|
||||
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~DenyMask;
|
||||
OperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess &= ~DenyMask;
|
||||
|
||||
if (OperationInformation->Operation == OB_OPERATION_HANDLE_DUPLICATE) {
|
||||
OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess &= ~DenyMask;
|
||||
OperationInformation->Parameters->DuplicateHandleInformation.OriginalDesiredAccess &= ~DenyMask;
|
||||
}
|
||||
}
|
||||
|
||||
return OB_PREOP_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS InitializeProcessProtection() {
|
||||
static UNICODE_STRING Altitude = { 0 };
|
||||
RtlInitUnicodeString(&Altitude, L"320000");
|
||||
|
||||
ObCallbacks[0].ObjectType = PsProcessType;
|
||||
ObCallbacks[0].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
|
||||
ObCallbacks[0].PreOperation = PreOpenProcess;
|
||||
ObCallbacks[0].PostOperation = NULL;
|
||||
|
||||
ObRegistration.Version = OB_FLT_REGISTRATION_VERSION;
|
||||
ObRegistration.OperationRegistrationCount = 1;
|
||||
ObRegistration.Altitude = Altitude;
|
||||
ObRegistration.RegistrationContext = NULL;
|
||||
ObRegistration.OperationRegistration = ObCallbacks;
|
||||
|
||||
return ObRegisterCallbacks(&ObRegistration, &ObRegistrationHandle);
|
||||
}
|
||||
|
||||
VOID UninitializeProcessProtection() {
|
||||
if (ObRegistrationHandle) {
|
||||
ObUnRegisterCallbacks(ObRegistrationHandle);
|
||||
ObRegistrationHandle = NULL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
#include "DriverCommon.h"
|
||||
|
||||
LARGE_INTEGER Cookie;
|
||||
|
||||
static BOOLEAN IsBamRegistryPath(PCUNICODE_STRING KeyName) {
|
||||
if (!KeyName || !KeyName->Buffer) return FALSE;
|
||||
if (WildcardMatch(L"*\\Services\\bam\\*", KeyName->Buffer, KeyName->Length)) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (Class == RegNtPreSetValueKey || Class == RegNtPreDeleteKey || Class == RegNtPreCreateKey) {
|
||||
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))) {
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (KeyName && KeyName->Buffer) {
|
||||
|
||||
if (IsBamRegistryPath(KeyName)) {
|
||||
CmCallbackReleaseKeyObjectIDEx(KeyName);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (CheckRegistryRule(KeyName)) {
|
||||
HANDLE Pid = PsGetCurrentProcessId();
|
||||
if (WildcardMatch(L"*\\MACHINE\\SAM*", KeyName->Buffer, KeyName->Length) ||
|
||||
WildcardMatch(L"*\\MACHINE\\SECURITY*", KeyName->Buffer, KeyName->Length) ||
|
||||
WildcardMatch(L"*\\MACHINE\\SYSTEM*", KeyName->Buffer, KeyName->Length) ||
|
||||
WildcardMatch(L"*\\MACHINE\\BCD00000000*", KeyName->Buffer, KeyName->Length)) {
|
||||
|
||||
if (!IsCriticalSystemProcess(Pid)) {
|
||||
SendMessageToUser(3001, (ULONG)(ULONG_PTR)Pid, KeyName->Buffer, KeyName->Length);
|
||||
CmCallbackReleaseKeyObjectIDEx(KeyName);
|
||||
return STATUS_ACCESS_DENIED;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!IsProcessTrusted(Pid)) {
|
||||
if (!IsInstallerProcess(Pid)) {
|
||||
SendMessageToUser(3001, (ULONG)(ULONG_PTR)Pid, KeyName->Buffer, KeyName->Length);
|
||||
CmCallbackReleaseKeyObjectIDEx(KeyName);
|
||||
return STATUS_ACCESS_DENIED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (KeyName) {
|
||||
CmCallbackReleaseKeyObjectIDEx(KeyName);
|
||||
}
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS InitializeRegistryProtection(PDRIVER_OBJECT DriverObject) {
|
||||
UNICODE_STRING Altitude;
|
||||
RtlInitUnicodeString(&Altitude, L"320000");
|
||||
return CmRegisterCallbackEx(RegistryCallback, &Altitude, DriverObject, NULL, &Cookie, NULL);
|
||||
}
|
||||
|
||||
VOID UninitializeRegistryProtection() {
|
||||
if (Cookie.QuadPart != 0) {
|
||||
CmUnRegisterCallback(Cookie);
|
||||
Cookie.QuadPart = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,718 @@
|
||||
#include "DriverCommon.h"
|
||||
|
||||
constexpr auto MAX_TRACKERS = 64;
|
||||
constexpr auto RANSOM_TIME_WINDOW_MS = 3000;
|
||||
constexpr auto RANSOM_COUNT_THRESHOLD = 5;
|
||||
constexpr auto HIGH_ENTROPY_THRESHOLD = 15;
|
||||
|
||||
typedef struct _RANSOM_TRACKER {
|
||||
HANDLE ProcessId;
|
||||
ULONG ActivityCount;
|
||||
LARGE_INTEGER LastActivityTime;
|
||||
} RANSOM_TRACKER, * PRANSOM_TRACKER;
|
||||
|
||||
RANSOM_TRACKER RansomTrackers[MAX_TRACKERS];
|
||||
|
||||
const PCWSTR SafeSystemBinaries[] = {
|
||||
L"*\\Windows\\System32\\lsass.exe",
|
||||
L"*\\Windows\\System32\\services.exe",
|
||||
L"*\\Windows\\System32\\csrss.exe",
|
||||
L"*\\Windows\\System32\\smss.exe",
|
||||
L"*\\Windows\\System32\\wininit.exe",
|
||||
L"*\\Windows\\System32\\winlogon.exe",
|
||||
L"*\\Windows\\System32\\svchost.exe",
|
||||
L"*\\Windows\\System32\\SearchIndexer.exe",
|
||||
L"*\\Windows\\System32\\msiexec.exe",
|
||||
L"*\\Windows\\System32\\TrustedInstaller.exe",
|
||||
L"*\\Windows\\System32\\TiWorker.exe",
|
||||
L"*\\Windows\\System32\\dism.exe",
|
||||
L"*\\Windows\\System32\\dismhost.exe",
|
||||
L"*\\Windows\\System32\\wuauclt.exe",
|
||||
L"*\\Windows\\System32\\taskhostw.exe",
|
||||
L"*\\Windows\\System32\\MoUsoCoreWorker.exe",
|
||||
L"*\\Windows\\System32\\sppsvc.exe",
|
||||
L"*\\Windows\\System32\\backgroundTaskHost.exe",
|
||||
L"*\\Windows\\System32\\RuntimeBroker.exe",
|
||||
L"*\\Windows\\System32\\ctfmon.exe",
|
||||
L"*\\Windows\\System32\\smartscreen.exe",
|
||||
L"*\\Windows\\System32\\Taskmgr.exe",
|
||||
L"*\\Windows\\ImmersiveControlPanel\\SystemSettings.exe"
|
||||
};
|
||||
|
||||
const PCWSTR CriticalSystemBinaries[] = {
|
||||
L"*\\Windows\\ImmersiveControlPanel\\SystemSettings.exe",
|
||||
L"*\\Windows Defender\\MsMpEng.exe",
|
||||
L"*\\Windows\\System32\\lsass.exe",
|
||||
L"*\\Windows\\System32\\services.exe",
|
||||
L"*\\Windows\\System32\\wininit.exe",
|
||||
L"*\\Windows\\System32\\winlogon.exe",
|
||||
L"*\\Windows\\System32\\svchost.exe",
|
||||
L"*\\Windows\\System32\\smss.exe",
|
||||
L"*\\Windows\\System32\\csrss.exe",
|
||||
L"*\\Windows\\System32\\sppsvc.exe",
|
||||
L"*\\Windows\\System32\\msiexec.exe",
|
||||
L"*\\Windows\\System32\\TrustedInstaller.exe",
|
||||
L"*\\Windows\\System32\\TiWorker.exe",
|
||||
L"*\\Windows\\System32\\dism.exe",
|
||||
L"*\\Windows\\System32\\dismhost.exe",
|
||||
L"*\\Windows\\System32\\SgrmBroker.exe",
|
||||
L"*\\Windows\\System32\\WerFault.exe",
|
||||
L"*\\Windows\\System32\\wbem\\WmiApSrv.exe",
|
||||
L"*\\Windows\\System32\\wbem\\WmiPrvSE.exe",
|
||||
L"*\\Windows\\ImmersiveControlPanel\\SystemSettings.exe",
|
||||
L"*\\Windows\\System32\\ctfmon.exe",
|
||||
L"*\\Windows\\System32\\taskhostw.exe",
|
||||
L"*\\Windows\\System32\\fontdrvhost.exe",
|
||||
L"*\\Windows\\System32\\dwm.exe",
|
||||
L"*\\Windows\\System32\\SearchIndexer.exe",
|
||||
L"*\\Windows\\System32\\SearchProtocolHost.exe",
|
||||
L"*\\Windows\\System32\\SearchFilterHost.exe",
|
||||
L"*\\Windows\\System32\\smartscreen.exe",
|
||||
L"*\\Windows\\System32\\vssvc.exe",
|
||||
L"*\\Windows\\System32\\cleanmgr.exe",
|
||||
L"*\\Windows\\System32\\defrag.exe",
|
||||
L"*\\Windows\\System32\\chkdsk.exe",
|
||||
L"*\\Windows\\System32\\conhost.exe",
|
||||
L"*\\Windows\\System32\\RecoveryDrive.exe"
|
||||
};
|
||||
|
||||
const PCWSTR SafeProcessPatterns[] = {
|
||||
L"*\\Windows Defender\\*",
|
||||
L"*\\Windows Defender Advanced Threat Protection\\*",
|
||||
|
||||
L"*\\Program*\\*",
|
||||
L"*\\AppData\\Local\\*",
|
||||
L"*\\AppData\\Roaming\\*",
|
||||
|
||||
L"*\\Google\\Update\\*",
|
||||
L"*\\Google\\Chrome\\Application\\chrome.exe",
|
||||
L"*\\Internet Explorer\\iexplore.exe",
|
||||
L"*\\Microsoft\\EdgeUpdate\\*",
|
||||
L"*\\Microsoft\\Edge\\Application\\msedge.exe",
|
||||
L"*\\Microsoft\\EdgeWebView\\Application\\*",
|
||||
L"*\\Mozilla Firefox\\firefox.exe",
|
||||
L"*\\BraveSoftware\\Brave-Browser\\Application\\brave.exe",
|
||||
L"*\\Opera Software\\*\\opera.exe",
|
||||
L"*\\Vivaldi\\Application\\vivaldi.exe",
|
||||
|
||||
L"*\\WinRAR\\WinRAR.exe",
|
||||
L"*\\WinRAR\\UnRAR.exe",
|
||||
L"*\\7-Zip\\7zG.exe",
|
||||
L"*\\7-Zip\\7zFM.exe",
|
||||
L"*\\Bandizip\\Bandizip.exe",
|
||||
|
||||
L"*\\Microsoft Office\\root\\Office*\\*.EXE",
|
||||
L"*\\Microsoft Office\\root\\Office*\\WINWORD.EXE",
|
||||
L"*\\Microsoft Office\\root\\Office*\\EXCEL.EXE",
|
||||
L"*\\Microsoft Office\\root\\Office*\\POWERPNT.EXE",
|
||||
L"*\\Adobe\\Acrobat*\\*\\Acrobat.exe",
|
||||
L"*\\Adobe\\Acrobat*\\*\\AcroRd32.exe",
|
||||
L"*\\Foxit PDF Reader\\FoxitPDFReader.exe",
|
||||
L"*\\LibreOffice*\\program\\soffice.bin",
|
||||
L"*\\LibreOffice*\\program\\soffice.exe",
|
||||
L"*\\Notepad++\\notepad++.exe",
|
||||
L"*\\Sublime Text*\\sublime_text.exe",
|
||||
|
||||
L"*\\Microsoft\\Teams\\*\\Teams.exe",
|
||||
L"*\\Zoom\\bin\\Zoom.exe",
|
||||
L"*\\Slack\\app-*\\slack.exe",
|
||||
L"*\\Telegram Desktop\\Telegram.exe",
|
||||
L"*\\WhatsApp\\WhatsApp.exe",
|
||||
L"*\\Discord\\app-*\\Discord.exe",
|
||||
|
||||
L"*\\Microsoft Visual Studio\\*\\devenv.exe",
|
||||
L"*\\Microsoft VS Code\\Code.exe",
|
||||
L"*\\Git\\cmd\\git.exe",
|
||||
L"*\\Git\\mingw64\\bin\\git.exe",
|
||||
L"*\\bin\\cmake.exe",
|
||||
L"*\\nodejs\\node.exe",
|
||||
L"*\\Android Studio\\bin\\studio64.exe",
|
||||
L"*\\JetBrains\\*\\bin\\*.exe",
|
||||
|
||||
L"*\\Dropbox\\Client\\Dropbox.exe",
|
||||
L"*\\Google\\Drive\\*\\GoogleDriveFS.exe",
|
||||
L"*\\Microsoft OneDrive\\OneDrive.exe",
|
||||
|
||||
L"*\\Sangfor\\*",
|
||||
L"*\\SogouInput\\*",
|
||||
L"*\\baidu\\BaiduNetdisk\\*",
|
||||
L"*\\TortoiseSVN\\*",
|
||||
L"*\\TortoiseGit\\*",
|
||||
L"*\\TortoiseOverlays\\*",
|
||||
|
||||
L"*\\VideoLAN\\VLC\\vlc.exe",
|
||||
L"*\\Spotify\\Spotify.exe",
|
||||
L"*\\obs-studio\\bin\\*\\obs64.exe",
|
||||
L"*\\DaVinci Resolve\\Resolve.exe",
|
||||
L"*\\Adobe\\Adobe Premiere Pro*\\Adobe Premiere Pro.exe",
|
||||
L"*\\Adobe\\Adobe Photoshop*\\Photoshop.exe",
|
||||
|
||||
L"*\\Steam\\steam.exe",
|
||||
L"*\\Steam\\bin\\steamwebhelper.exe",
|
||||
L"*\\Steam\\steamapps\\*",
|
||||
L"*\\Epic Games\\Launcher\\Portal\\Binaries\\*\\EpicGamesLauncher.exe",
|
||||
L"*\\Battle.net\\*\\Battle.net.exe",
|
||||
|
||||
L"*\\NVIDIA Corporation\\*",
|
||||
L"*\\AMD\\*",
|
||||
L"*\\Intel\\*",
|
||||
L"*\\Logitech\\*",
|
||||
L"*\\Razer\\*",
|
||||
L"*\\Corsair\\*",
|
||||
L"*\\ASUS\\*"
|
||||
};
|
||||
|
||||
const PCWSTR RegistryBlockList[] = {
|
||||
L"\\REGISTRY\\MACHINE\\BCD00000000",
|
||||
L"\\REGISTRY\\MACHINE\\BCD00000000\\*",
|
||||
L"\\REGISTRY\\MACHINE\\SAM",
|
||||
L"\\REGISTRY\\MACHINE\\SAM\\*",
|
||||
L"\\REGISTRY\\MACHINE\\SECURITY",
|
||||
L"\\REGISTRY\\MACHINE\\SECURITY\\*",
|
||||
L"\\REGISTRY\\MACHINE\\SYSTEM",
|
||||
L"\\REGISTRY\\MACHINE\\SYSTEM\\*",
|
||||
|
||||
L"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\*",
|
||||
L"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce\\*",
|
||||
L"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\*",
|
||||
L"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartupApproved\\*",
|
||||
|
||||
L"\\REGISTRY\\USER\\*_Classes\\*\\shell\\open\\command\\*",
|
||||
L"\\REGISTRY\\USER\\S-1-*\\SOFTWARE\\NetWire\\*",
|
||||
L"\\REGISTRY\\USER\\S-1-*\\SOFTWARE\\Remcos*\\*",
|
||||
L"\\REGISTRY\\USER\\S-1-*\\SOFTWARE\\DC3_FEXEC\\*",
|
||||
L"*\\Image File Execution Options\\*",
|
||||
|
||||
L"*\\Classes\\.exe",
|
||||
L"*\\Classes\\.bat",
|
||||
L"*\\Classes\\.cmd",
|
||||
L"*\\Classes\\.com",
|
||||
L"*\\Classes\\exefile\\*",
|
||||
L"*\\Classes\\batfile\\*",
|
||||
L"*\\Classes\\cmdfile\\*",
|
||||
L"*\\Classes\\comfile\\*",
|
||||
L"*\\DefaultIcon",
|
||||
|
||||
L"*\\DisableAntiSpyware",
|
||||
L"*\\DisableWindowsUpdateAccess",
|
||||
L"*\\EnableLUA",
|
||||
L"*\\ConsentPromptBehaviorAdmin",
|
||||
L"*\\NoControlPanel",
|
||||
L"*\\NoDrives",
|
||||
L"*\\NoFileMenu",
|
||||
L"*\\NoFind",
|
||||
L"*\\NoStartMenuPinnedList",
|
||||
L"*\\NoSetFolders",
|
||||
L"*\\NoSetFolderOptions",
|
||||
L"*\\NoViewOnDrive",
|
||||
L"*\\NoClose",
|
||||
L"*\\NoDesktop",
|
||||
L"*\\NoLogoff",
|
||||
L"*\\NoFolderOptions",
|
||||
L"*\\RestrictRun",
|
||||
L"*\\NoViewContextMenu",
|
||||
L"*\\HideClock",
|
||||
L"*\\NoStartMenuMyGames",
|
||||
L"*\\NoStartMenuMyMusic",
|
||||
L"*\\DisableCMD",
|
||||
L"*\\NoAddingComponents",
|
||||
L"*\\NoWinKeys",
|
||||
L"*\\NoStartMenuLogOff",
|
||||
L"*\\NoSimpleNetIDList",
|
||||
L"*\\NoLowDiskSpaceChecks",
|
||||
L"*\\DisableLockWorkstation",
|
||||
L"*\\Restrict_Run",
|
||||
L"*\\DisableTaskMgr",
|
||||
L"*\\DisableRegistryTools",
|
||||
L"*\\DisableChangePassword",
|
||||
L"*\\Wallpaper",
|
||||
L"*\\NoComponents",
|
||||
L"*\\NoStartMenuMorePrograms",
|
||||
L"*\\NoActiveDesktop",
|
||||
L"*\\NoSetActiveDesktop",
|
||||
L"*\\NoRecentDocsMenu",
|
||||
L"*\\NoWindowsUpdate",
|
||||
L"*\\NoChangeStartMenu",
|
||||
L"*\\NoFavoritesMenu",
|
||||
L"*\\NoRecentDocsHistory",
|
||||
L"*\\NoSetTaskbar",
|
||||
L"*\\NoSMHelp",
|
||||
L"*\\NoTrayContextMenu",
|
||||
L"*\\NoManageMyComputerVerb",
|
||||
L"*\\NoRealMode",
|
||||
L"*\\NoRun",
|
||||
L"*\\ClearRecentDocsOnExit",
|
||||
L"*\\NoActiveDesktopChanges",
|
||||
L"*\\NoStartMenuNetworkPlaces",
|
||||
L"*\\NoLockScreen",
|
||||
L"*\\HideFastUserSwitching",
|
||||
L"*\\ConsentPromptBehaviorUser",
|
||||
L"*\\EnableSecureUIAPaths",
|
||||
L"*\\NoSRM",
|
||||
L"*\\NoInteractiveServices",
|
||||
L"*\\ShutdownWithoutLogon",
|
||||
L"*\\AutoAdminLogon",
|
||||
L"*\\ImagePath",
|
||||
L"*\\BootExecute",
|
||||
L"*\\SubSystems",
|
||||
L"*\\FirmwareBootDevice",
|
||||
L"*\\BootDriverFlags",
|
||||
L"*\\SystemStartOptions",
|
||||
L"*\\CrashDumpEnabled",
|
||||
L"*\\DisableAutomaticRestartOnFailure",
|
||||
L"*\\SystemBiosVersion",
|
||||
L"*\\NoTheme",
|
||||
L"*\\PendingFileRenameOperations",
|
||||
L"*\\SystemSetupInProgress",
|
||||
L"*\\CmdLine",
|
||||
L"*\\SetupType",
|
||||
L"*\\AutoReboot",
|
||||
L"*\\Userinit",
|
||||
L"*\\UIHost",
|
||||
L"*\\Debugger",
|
||||
L"*\\DefaultUserName",
|
||||
L"*\\DefaultPassword",
|
||||
L"*\\AltDefaultUserName",
|
||||
L"*\\AltDefaultPassword",
|
||||
L"*\\DisableCAD",
|
||||
L"*\\LegalNoticeCaption",
|
||||
L"*\\LegalNoticeText",
|
||||
L"*\\Run",
|
||||
L"*\\RunOnce",
|
||||
};
|
||||
|
||||
const PCWSTR DangerousExtensions[] = {
|
||||
L".exe", L".dll", L".sys", L".com", L".scr",
|
||||
L".zip", L".7z", L".rar", L".tar", L".gz",
|
||||
L".js", L".bat", L".cmd", L".ps1", L".vbs",
|
||||
L".ppt", L".pptx", L".wps", L".txt", L".rtf",
|
||||
L".pdf", L".xls", L".xlsx", L".doc", L".docx",
|
||||
L".jpg", L".jpeg", L".png", L".webp", L".gif",
|
||||
L".mp3", L".wav", L".aac", L".ogg", L".flac",
|
||||
L".mp4", L".avi", L".mov", L".wmv", L".mkv",
|
||||
L".aux", L".cur", L".mui", L".ttf", L".efi"
|
||||
};
|
||||
|
||||
const PCWSTR NaturallyCompressedExtensions[] = {
|
||||
L".zip", L".7z", L".rar", L".tar", L".gz",
|
||||
L".jpg", L".jpeg", L".png", L".webp", L".gif",
|
||||
L".mp3", L".wav", L".aac", L".ogg", L".flac",
|
||||
L".mp4", L".avi", L".mov", L".wmv", L".mkv",
|
||||
L".exe", L".dll", L".sys", L".mui", L".scr",
|
||||
L".docx", L".xlsx", L".pptx", L".pdf", L".wps",
|
||||
L".apk", L".jar", L".class", L".db", L".sqlite"
|
||||
};
|
||||
|
||||
const PCWSTR ProtectedPaths[] = {
|
||||
L"*\\PYAS.exe",
|
||||
L"*\\PYAS_Driver.sys",
|
||||
L"*\\ProgramData\\PYAS\\*.json",
|
||||
|
||||
L"*\\Windows\\System32\\config\\SAM*",
|
||||
L"*\\Windows\\System32\\config\\SECURITY*",
|
||||
L"*\\Windows\\System32\\config\\SOFTWARE*",
|
||||
L"*\\Windows\\System32\\config\\SYSTEM*",
|
||||
L"*\\Windows\\System32\\config\\DEFAULT*",
|
||||
L"*\\Windows\\System32\\config\\RegBack\\*",
|
||||
|
||||
L"*\\Windows\\System32\\drivers\\*",
|
||||
L"*\\Windows\\System32\\drivers\\etc\\hosts",
|
||||
L"*\\Windows\\System32\\*.exe",
|
||||
L"*\\Windows\\System32\\*.dll",
|
||||
L"*\\Windows\\SysWOW64\\*.exe",
|
||||
L"*\\Windows\\SysWOW64\\*.dll",
|
||||
L"*\\Windows\\Web\\Wallpaper\\*",
|
||||
L"*\\Windows\\explorer.exe",
|
||||
L"*\\Windows\\regedit.exe",
|
||||
|
||||
L"*\\bootmgr",
|
||||
L"*\\boot.ini",
|
||||
L"*\\BOOTNXT",
|
||||
L"*\\EFI",
|
||||
L"*\\EFI\\*",
|
||||
L"*\\Boot",
|
||||
L"*\\Boot\\*",
|
||||
L"*\\Recovery",
|
||||
L"*\\Recovery\\*",
|
||||
L"*\\System Volume Information\\*",
|
||||
|
||||
L"*\\CON",
|
||||
L"*\\CON\\*",
|
||||
L"*\\PRN",
|
||||
L"*\\PRN\\*",
|
||||
L"*\\AUX",
|
||||
L"*\\AUX\\*",
|
||||
L"*\\NUL",
|
||||
L"*\\NUL\\*",
|
||||
L"*\\CLOCK$",
|
||||
L"*\\CLOCK$\\*",
|
||||
L"*\\COM?",
|
||||
L"*\\COM?\\*",
|
||||
L"*\\LPT?",
|
||||
L"*\\LPT?\\*",
|
||||
L"*\\COM0",
|
||||
L"*\\COM0\\*",
|
||||
L"*\\LPT0",
|
||||
L"*\\LPT0\\*",
|
||||
L"*\\$Mft",
|
||||
L"*\\$Mft\\*",
|
||||
L"*\\$MftMirr",
|
||||
L"*\\$MftMirr\\*",
|
||||
L"*\\$LogFile",
|
||||
L"*\\$LogFile\\*",
|
||||
L"*\\$Volume",
|
||||
L"*\\$Volume\\*",
|
||||
L"*\\$AttrDef",
|
||||
L"*\\$AttrDef\\*",
|
||||
L"*\\$Bitmap",
|
||||
L"*\\$Bitmap\\*",
|
||||
L"*\\$Boot",
|
||||
L"*\\$Boot\\*",
|
||||
L"*\\$BadClus",
|
||||
L"*\\$BadClus\\*",
|
||||
L"*\\$Secure",
|
||||
L"*\\$Secure\\*",
|
||||
L"*\\$Upcase",
|
||||
L"*\\$Upcase\\*",
|
||||
L"*\\OSDATA",
|
||||
L"*\\OSDATA\\*",
|
||||
|
||||
L"*:*",
|
||||
L"*<*",
|
||||
L"*>*",
|
||||
L"*|*",
|
||||
};
|
||||
|
||||
static BOOLEAN HasSuffix(PCUNICODE_STRING String, PCWSTR Suffix) {
|
||||
if (!String || !String->Buffer || !Suffix) return FALSE;
|
||||
|
||||
SIZE_T StringLenChars = String->Length / sizeof(WCHAR);
|
||||
SIZE_T SuffixLenChars = 0;
|
||||
|
||||
while (Suffix[SuffixLenChars] != L'\0') {
|
||||
SuffixLenChars++;
|
||||
}
|
||||
|
||||
if (StringLenChars < SuffixLenChars) return FALSE;
|
||||
|
||||
PCWSTR Ptr = String->Buffer + (StringLenChars - SuffixLenChars);
|
||||
|
||||
for (SIZE_T i = 0; i < SuffixLenChars; i++) {
|
||||
if (RtlDowncaseUnicodeChar(Ptr[i]) != RtlDowncaseUnicodeChar(Suffix[i])) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN WildcardMatch(PCWSTR Pattern, PCWSTR String, USHORT StringLengthBytes) {
|
||||
if (!Pattern || !String) return FALSE;
|
||||
|
||||
PCWSTR mp = NULL;
|
||||
PCWSTR cp = NULL;
|
||||
PCWSTR StringEnd = (PCWSTR)((PUCHAR)String + StringLengthBytes);
|
||||
|
||||
while (String < StringEnd) {
|
||||
if (*Pattern == L'*') {
|
||||
mp = ++Pattern;
|
||||
cp = String + 1;
|
||||
}
|
||||
else if (*Pattern == L'?' || (RtlDowncaseUnicodeChar(*Pattern) == RtlDowncaseUnicodeChar(*String))) {
|
||||
Pattern++;
|
||||
String++;
|
||||
}
|
||||
else if (mp) {
|
||||
Pattern = mp;
|
||||
String = cp++;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
while (*Pattern == L'*') {
|
||||
Pattern++;
|
||||
}
|
||||
return !*Pattern;
|
||||
}
|
||||
|
||||
static NTSTATUS GetProcessImageName(HANDLE ProcessId, PUNICODE_STRING* ImageName) {
|
||||
NTSTATUS status;
|
||||
PEPROCESS Process = NULL;
|
||||
|
||||
*ImageName = NULL;
|
||||
status = PsLookupProcessByProcessId(ProcessId, &Process);
|
||||
if (!NT_SUCCESS(status)) return status;
|
||||
|
||||
status = SeLocateProcessImageName(Process, ImageName);
|
||||
ObDereferenceObject(Process);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
BOOLEAN IsProcessTrusted(HANDLE ProcessId) {
|
||||
if ((ULONG)(ULONG_PTR)ProcessId == GlobalData.PyasPid) return TRUE;
|
||||
if (ProcessId == (HANDLE)4) return TRUE;
|
||||
if (KeGetCurrentIrql() > APC_LEVEL) return FALSE;
|
||||
|
||||
PUNICODE_STRING imageFileName = NULL;
|
||||
NTSTATUS status = GetProcessImageName(ProcessId, &imageFileName);
|
||||
BOOLEAN isTrusted = FALSE;
|
||||
|
||||
if (NT_SUCCESS(status) && imageFileName && imageFileName->Buffer) {
|
||||
for (SIZE_T i = 0; i < sizeof(SafeSystemBinaries) / sizeof(SafeSystemBinaries[0]); i++) {
|
||||
if (WildcardMatch(SafeSystemBinaries[i], imageFileName->Buffer, imageFileName->Length)) {
|
||||
isTrusted = TRUE;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
for (SIZE_T i = 0; i < sizeof(SafeProcessPatterns) / sizeof(SafeProcessPatterns[0]); i++) {
|
||||
if (WildcardMatch(SafeProcessPatterns[i], imageFileName->Buffer, imageFileName->Length)) {
|
||||
isTrusted = TRUE;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (imageFileName) ExFreePool(imageFileName);
|
||||
return isTrusted;
|
||||
}
|
||||
|
||||
BOOLEAN IsCriticalSystemProcess(HANDLE ProcessId) {
|
||||
if ((ULONG)(ULONG_PTR)ProcessId == GlobalData.PyasPid) return TRUE;
|
||||
if (ProcessId == (HANDLE)4) return TRUE;
|
||||
if (KeGetCurrentIrql() > APC_LEVEL) return FALSE;
|
||||
|
||||
PUNICODE_STRING imageFileName = NULL;
|
||||
NTSTATUS status = GetProcessImageName(ProcessId, &imageFileName);
|
||||
BOOLEAN isCritical = FALSE;
|
||||
|
||||
if (NT_SUCCESS(status) && imageFileName && imageFileName->Buffer) {
|
||||
for (SIZE_T i = 0; i < sizeof(CriticalSystemBinaries) / sizeof(CriticalSystemBinaries[0]); i++) {
|
||||
if (WildcardMatch(CriticalSystemBinaries[i], imageFileName->Buffer, imageFileName->Length)) {
|
||||
isCritical = TRUE;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (imageFileName) ExFreePool(imageFileName);
|
||||
return isCritical;
|
||||
}
|
||||
|
||||
BOOLEAN IsInstallerProcess(HANDLE ProcessId) {
|
||||
return IsProcessTrusted(ProcessId);
|
||||
}
|
||||
|
||||
BOOLEAN IsTargetProtected(HANDLE ProcessId) {
|
||||
if ((ULONG)(ULONG_PTR)ProcessId == GlobalData.PyasPid) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN CheckRegistryRule(PCUNICODE_STRING KeyName) {
|
||||
if (!KeyName || !KeyName->Buffer) return FALSE;
|
||||
|
||||
if (KeyName->Length < 4 * sizeof(WCHAR)) return FALSE;
|
||||
|
||||
for (int i = 0; i < sizeof(RegistryBlockList) / sizeof(RegistryBlockList[0]); i++) {
|
||||
if (WildcardMatch(RegistryBlockList[i], KeyName->Buffer, KeyName->Length)) return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN CheckFileExtensionRule(PCUNICODE_STRING FileName) {
|
||||
if (!FileName || !FileName->Buffer) return FALSE;
|
||||
for (int i = 0; i < sizeof(DangerousExtensions) / sizeof(DangerousExtensions[0]); i++) {
|
||||
if (HasSuffix(FileName, DangerousExtensions[i])) return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN CheckProtectedPathRule(PCUNICODE_STRING FileName) {
|
||||
if (!FileName || !FileName->Buffer) return FALSE;
|
||||
|
||||
if (WildcardMatch(L"*\\Windows\\System32\\config\\systemprofile*", FileName->Buffer, FileName->Length)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (int i = 0; i < sizeof(ProtectedPaths) / sizeof(ProtectedPaths[0]); i++) {
|
||||
if (WildcardMatch(ProtectedPaths[i], FileName->Buffer, FileName->Length)) return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOLEAN IsHighEntropy(PVOID Buffer, ULONG Length) {
|
||||
if (!Buffer || Length < 256) return FALSE;
|
||||
|
||||
ULONG Histogram[256] = { 0 };
|
||||
PUCHAR Ptr = (PUCHAR)Buffer;
|
||||
ULONG ScanLen = (Length > 1024) ? 1024 : Length;
|
||||
|
||||
__try {
|
||||
for (ULONG i = 0; i < ScanLen; i++) {
|
||||
Histogram[Ptr[i]]++;
|
||||
}
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ULONG MaxFreq = 0;
|
||||
for (int i = 0; i < 256; i++) {
|
||||
if (Histogram[i] > MaxFreq) MaxFreq = Histogram[i];
|
||||
}
|
||||
|
||||
ULONG ExpectedAvg = ScanLen / 256;
|
||||
return (MaxFreq < (ExpectedAvg + HIGH_ENTROPY_THRESHOLD));
|
||||
}
|
||||
|
||||
static BOOLEAN IsNaturallyCompressed(PCUNICODE_STRING FileName) {
|
||||
if (!FileName || !FileName->Buffer) return FALSE;
|
||||
for (int i = 0; i < sizeof(NaturallyCompressedExtensions) / sizeof(NaturallyCompressedExtensions[0]); i++) {
|
||||
if (HasSuffix(FileName, NaturallyCompressedExtensions[i])) return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOLEAN IsNoisyRansomPath(PCUNICODE_STRING FileName) {
|
||||
if (!FileName || !FileName->Buffer) return FALSE;
|
||||
|
||||
if (WildcardMatch(L"*\\Windows\\Temp\\*", FileName->Buffer, FileName->Length) ||
|
||||
WildcardMatch(L"*\\Windows\\SystemTemp\\*", FileName->Buffer, FileName->Length) ||
|
||||
WildcardMatch(L"*\\Windows\\Prefetch\\*", FileName->Buffer, FileName->Length) ||
|
||||
WildcardMatch(L"*\\Windows\\Logs\\*", FileName->Buffer, FileName->Length) ||
|
||||
WildcardMatch(L"*\\Profiles\\*", FileName->Buffer, FileName->Length) ||
|
||||
WildcardMatch(L"*\\Program*\\*", FileName->Buffer, FileName->Length) ||
|
||||
WildcardMatch(L"*\\AppData\\Local\\*", FileName->Buffer, FileName->Length) ||
|
||||
WildcardMatch(L"*\\User Data\\*", FileName->Buffer, FileName->Length) ||
|
||||
WildcardMatch(L"*$Recycle.Bin*", FileName->Buffer, FileName->Length)) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOLEAN IsExplorerProcess(HANDLE ProcessId) {
|
||||
if (KeGetCurrentIrql() > APC_LEVEL) return FALSE;
|
||||
PUNICODE_STRING imageFileName = NULL;
|
||||
NTSTATUS status = GetProcessImageName(ProcessId, &imageFileName);
|
||||
BOOLEAN isExplorer = FALSE;
|
||||
if (NT_SUCCESS(status) && imageFileName && imageFileName->Buffer) {
|
||||
if (HasSuffix(imageFileName, L"\\explorer.exe")) isExplorer = TRUE;
|
||||
ExFreePool(imageFileName);
|
||||
}
|
||||
return isExplorer;
|
||||
}
|
||||
|
||||
BOOLEAN CheckRansomActivity(HANDLE ProcessId, PUNICODE_STRING FileName, PVOID Buffer, ULONG Length, BOOLEAN IsWrite) {
|
||||
if (IsNoisyRansomPath(FileName)) return FALSE;
|
||||
|
||||
if (!IsWrite) {
|
||||
if (IsExplorerProcess(ProcessId)) return FALSE;
|
||||
}
|
||||
|
||||
LARGE_INTEGER Now = { 0 };
|
||||
KeQuerySystemTime(&Now);
|
||||
BOOLEAN Result = FALSE;
|
||||
BOOLEAN SuspiciousWrite = FALSE;
|
||||
|
||||
if (IsWrite && Buffer && Length > 0) {
|
||||
if (!IsNaturallyCompressed(FileName) && IsHighEntropy(Buffer, Length)) {
|
||||
SuspiciousWrite = TRUE;
|
||||
}
|
||||
}
|
||||
if (IsWrite && !SuspiciousWrite) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ExAcquireFastMutex(&GlobalData.TrackerMutex);
|
||||
|
||||
PRANSOM_TRACKER Tracker = NULL;
|
||||
PRANSOM_TRACKER EmptySlot = NULL;
|
||||
|
||||
for (int i = 0; i < MAX_TRACKERS; i++) {
|
||||
if (RansomTrackers[i].ProcessId == ProcessId) {
|
||||
Tracker = &RansomTrackers[i];
|
||||
break;
|
||||
}
|
||||
if (RansomTrackers[i].ProcessId == NULL && !EmptySlot) {
|
||||
EmptySlot = &RansomTrackers[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (!Tracker) {
|
||||
if (EmptySlot) {
|
||||
Tracker = EmptySlot;
|
||||
Tracker->ProcessId = ProcessId;
|
||||
Tracker->ActivityCount = 0;
|
||||
Tracker->LastActivityTime = Now;
|
||||
}
|
||||
else {
|
||||
ExReleaseFastMutex(&GlobalData.TrackerMutex);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
LARGE_INTEGER Diff;
|
||||
Diff.QuadPart = Now.QuadPart - Tracker->LastActivityTime.QuadPart;
|
||||
|
||||
if (Diff.QuadPart > (RANSOM_TIME_WINDOW_MS * 10000LL)) {
|
||||
Tracker->ActivityCount = 0;
|
||||
Tracker->LastActivityTime = Now;
|
||||
}
|
||||
else {
|
||||
Tracker->LastActivityTime = Now;
|
||||
}
|
||||
ULONG Weight = 1;
|
||||
if (IsWrite) {
|
||||
Weight = SuspiciousWrite ? 2 : 1;
|
||||
}
|
||||
else {
|
||||
Weight = 2;
|
||||
}
|
||||
|
||||
Tracker->ActivityCount += Weight;
|
||||
|
||||
if (Tracker->ActivityCount >= RANSOM_COUNT_THRESHOLD) {
|
||||
Result = TRUE;
|
||||
}
|
||||
ExReleaseFastMutex(&GlobalData.TrackerMutex);
|
||||
return Result;
|
||||
}
|
||||
|
||||
NTSTATUS SendMessageToUser(ULONG Code, ULONG Pid, PWCHAR Path, USHORT PathSize) {
|
||||
if (KeGetCurrentIrql() > APC_LEVEL) return STATUS_UNSUCCESSFUL;
|
||||
|
||||
PYAS_MESSAGE msg;
|
||||
RtlZeroMemory(&msg, sizeof(msg));
|
||||
msg.MessageCode = Code;
|
||||
msg.ProcessId = Pid;
|
||||
|
||||
if (Path && PathSize > 0) {
|
||||
size_t MaxSize = sizeof(msg.Path) - sizeof(WCHAR);
|
||||
size_t BytesToCopy = PathSize;
|
||||
if (BytesToCopy > MaxSize) BytesToCopy = MaxSize;
|
||||
|
||||
__try {
|
||||
RtlCopyMemory(msg.Path, Path, BytesToCopy);
|
||||
msg.Path[BytesToCopy / sizeof(WCHAR)] = L'\0';
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
return STATUS_ACCESS_VIOLATION;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ExAcquireRundownProtection(&GlobalData.PortRundown)) {
|
||||
return STATUS_PORT_DISCONNECTED;
|
||||
}
|
||||
|
||||
NTSTATUS status = STATUS_PORT_DISCONNECTED;
|
||||
if (GlobalData.ClientPort) {
|
||||
LARGE_INTEGER timeout;
|
||||
timeout.QuadPart = -(5 * 10000);
|
||||
status = FltSendMessage(GlobalData.FilterHandle, &GlobalData.ClientPort, &msg, sizeof(msg), NULL, NULL, &timeout);
|
||||
}
|
||||
|
||||
ExReleaseRundownProtection(&GlobalData.PortRundown);
|
||||
return status;
|
||||
}
|
||||
@@ -1,23 +1,194 @@
|
||||
# PYAS (Python Antivirus Software)
|
||||
PYAS is not only free and open source without ads, A large number of offline databases are also built in, Always protect the privacy and data security of users.
|
||||

|
||||
# PYAS
|
||||
|
||||
Antivirus software written in Python and C++ that blocks threats through deep learning and behavioral monitoring!
|
||||
|
||||
## Official Website
|
||||
https://pyantivirus.wixsite.com/pyas ,
|
||||
https://github.com/87owo/PYAS
|
||||
<img width="2245" height="1477" alt="PYAS_UI" src="https://github.com/user-attachments/assets/87d40261-7655-49ad-a19c-1ffcca60584f" />
|
||||
|
||||
## Hashes Library
|
||||
https://virusshare.com/hashes ,
|
||||
https://github.com/87owo/ViruslistMD5/releases
|
||||
## Requirements
|
||||
|
||||
Python 3.10 is recommended. Other Python versions may require different pip commands.
|
||||
|
||||
```
|
||||
pip install requests==2.32.4
|
||||
pip install PySide6==6.9.1
|
||||
pip install yara-python==4.5.4
|
||||
pip install Pillow==11.0.0
|
||||
pip install numpy==1.26.4
|
||||
pip install tensorflow==2.10.0
|
||||
pip install tf2onnx==1.13.0
|
||||
pip install onnxruntime==1.18.1
|
||||
```
|
||||
|
||||
## File Information
|
||||
|
||||
The following lists the storage locations of all relevant code and other related documents.
|
||||
|
||||
```
|
||||
PYAS/
|
||||
├── Engine/
|
||||
│ ├── Models/
|
||||
│ │ ├── convert.py # Convert executable files or other files to images
|
||||
│ │ ├── train.py # TensorFlow CNN model training complete code
|
||||
│ │ └── ... # Other models folders and files
|
||||
│ │
|
||||
│ └── Rules/
|
||||
│ ├── rules.yar # Yara virus signature rule matching
|
||||
│ ├── rules.ips # IP network address rule matching
|
||||
│ └── ... # Other rules folders and files
|
||||
│
|
||||
├── Plugins/
|
||||
│ └── Filter/
|
||||
│ ├── DriverEntry.cpp # Main driver entry and initialization logic
|
||||
│ ├── DriverCommon.h # Global driver definitions, constants, and functions
|
||||
│ ├── ProtectBoot.cpp # Disk boot sector write protection
|
||||
│ ├── ProtectRegistry.cpp # Registry modification protection
|
||||
│ ├── ProtectRules.cpp # White, block list, and matching logic for files registry
|
||||
│ └── ... # Other driver folders and files
|
||||
│
|
||||
├── PYAS.py # Main application entry point and UI to engine interface
|
||||
├── PYAS_Config.py # Configuration loading, saving, and global parameters
|
||||
├── PYAS_Engine.py # Core scanning engine: YARA, IP, ONNX model execution
|
||||
├── PYAS_Interface.py # User interface components and event handling
|
||||
├── PYAS_Resource.py # Static image and icon resource management
|
||||
├── PYAS_Version.py # Version metadata for packaging and updates
|
||||
└── ... # Other supplementary folders and files
|
||||
```
|
||||
|
||||
## Architecture diagram
|
||||
|
||||
PYAS Security antivirus software general architecture diagram.
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
%% Global Styles
|
||||
classDef ui fill:#e1f5fe,stroke:#01579b,stroke-width:2px;
|
||||
classDef logic fill:#fff9c4,stroke:#fbc02d,stroke-width:2px;
|
||||
classDef engine fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px;
|
||||
classDef thread fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px;
|
||||
classDef kernel fill:#ffebee,stroke:#c62828,stroke-width:2px;
|
||||
classDef data fill:#eceff1,stroke:#455a64,stroke-width:2px,stroke-dasharray: 5 5;
|
||||
|
||||
User((User))
|
||||
|
||||
subgraph Presentation_Layer ["Presentation Layer (View)"]
|
||||
direction TB
|
||||
UI_Static["PYAS_Interface.py<br/>(Ui_main_window Class)"]:::ui
|
||||
UI_Controller["PYAS.py<br/>(MainWindow_Controller Class)"]:::ui
|
||||
TrayIcon["System Tray Icon"]:::ui
|
||||
|
||||
User <--> UI_Controller
|
||||
UI_Static --- UI_Controller
|
||||
UI_Controller --- TrayIcon
|
||||
end
|
||||
|
||||
subgraph Core_Logic_Layer ["Core Logic & Controller"]
|
||||
direction TB
|
||||
Init_Env["Initialization<br/>(init_environ, init_variable,<br/>init_windll)"]:::logic
|
||||
Config_Mgr["Configuration Manager<br/>(load_config, save_config)"]:::logic
|
||||
|
||||
subgraph System_Tools ["System Tools"]
|
||||
Sys_Repair["System Repair<br/>(repair_system_mbr,<br/>repair_system_image, etc.)"]:::logic
|
||||
Sys_Clean["System Cleaner<br/>(clean_button, traverse_temp)"]:::logic
|
||||
Proc_Mgr["Process Manager<br/>(list_process, kill_process)"]:::logic
|
||||
List_Mgr["List Manager<br/>(manage_named_list:<br/>Whitelist/Quarantine)"]:::logic
|
||||
end
|
||||
|
||||
UI_Controller --> Init_Env
|
||||
Init_Env --> Config_Mgr
|
||||
UI_Controller --> System_Tools
|
||||
end
|
||||
|
||||
subgraph Protection_Layer ["Real-time Protection Threads (Daemons)"]
|
||||
direction TB
|
||||
Thread_Proc["Process Guard Thread<br/>(protect_proc_thread)<br/>[WMI/Snapshot]"]:::thread
|
||||
Thread_File["File Guard Thread<br/>(protect_file_thread)<br/>[ReadDirectoryChangesW]"]:::thread
|
||||
Thread_Net["Network Guard Thread<br/>(protect_net_thread)<br/>[GetExtendedTcpTable]"]:::thread
|
||||
Thread_Sys["System Guard Thread<br/>(protect_system_thread)<br/>[Reg/MBR Check]"]:::thread
|
||||
Thread_Popup["Popup Blocker Thread<br/>(popup_intercept_thread)<br/>[EnumWindows]"]:::thread
|
||||
Thread_Pipe["Driver IPC Thread<br/>(pipe_server_thread)<br/>[NamedPipe Server]"]:::thread
|
||||
|
||||
Init_Env --> Thread_Proc
|
||||
Init_Env --> Thread_File
|
||||
Init_Env --> Thread_Net
|
||||
Init_Env --> Thread_Sys
|
||||
Init_Env --> Thread_Popup
|
||||
Init_Env --> Thread_Pipe
|
||||
end
|
||||
|
||||
subgraph Engine_Layer ["Detection Engine (PYAS_Engine.py)"]
|
||||
direction TB
|
||||
Scan_Worker["Scan Worker<br/>(scan_worker / scan_engine)"]:::engine
|
||||
|
||||
subgraph Scanners
|
||||
Sign_Check["Signature Scanner<br/>(sign_scanner)<br/>[WinVerifyTrust]"]:::engine
|
||||
AI_Model["AI Model Scanner<br/>(model_scanner)<br/>[ONNX/ResNet]"]:::engine
|
||||
Yara_Rules["Rule Scanner<br/>(rule_scanner)<br/>[Yara/IP Lists]"]:::engine
|
||||
end
|
||||
|
||||
Thread_Proc --> Scan_Worker
|
||||
Thread_File --> Scan_Worker
|
||||
Thread_Net --> Scan_Worker
|
||||
UI_Controller -->|Manual Scan| Scan_Worker
|
||||
|
||||
Scan_Worker --> Sign_Check
|
||||
Scan_Worker --> AI_Model
|
||||
Scan_Worker --> Yara_Rules
|
||||
end
|
||||
|
||||
subgraph Kernel_OS_Layer ["Windows Kernel & Driver"]
|
||||
direction TB
|
||||
WinAPI["Windows API (ctypes)<br/>(kernel32, user32, ntdll,<br/>advapi32, iphlpapi, psapi)"]:::kernel
|
||||
Driver_Sys["Kernel Driver<br/>(PYAS_Driver.sys)"]:::kernel
|
||||
OS_FS["File System (NTFS)"]:::kernel
|
||||
OS_Net["Network Stack"]:::kernel
|
||||
|
||||
Init_Env -- Load DLLs --> WinAPI
|
||||
Thread_File -- Monitor --> OS_FS
|
||||
Thread_Net -- Monitor --> OS_Net
|
||||
Thread_Proc -- Suspend/Kill --> WinAPI
|
||||
|
||||
Thread_Pipe <==>|"Named Pipe IPC<br/>(\\.\pipe\PYAS_Output_Pipe)"| Driver_Sys
|
||||
Driver_Sys -- Callback/Block --> WinAPI
|
||||
end
|
||||
|
||||
subgraph Data_Persistence ["Data & Resources"]
|
||||
Config_File[("Config.json")]:::data
|
||||
Model_Files[("Model Files<br/>(.onnx)")]:::data
|
||||
Rule_Files[("Rule Files<br/>(.yar)")]:::data
|
||||
Quarantine_Dir[("/Quarantine/")]:::data
|
||||
|
||||
Config_Mgr <--> Config_File
|
||||
AI_Model <--> Model_Files
|
||||
Yara_Rules <--> Rule_Files
|
||||
List_Mgr <--> Quarantine_Dir
|
||||
end
|
||||
```
|
||||
|
||||
## Support System
|
||||
Windows 8.1, 10, 11 (64-bit), Ram 1GB, Rom 1GB or higher
|
||||
|
||||
## Import Module
|
||||
os, sys, psutil, subprocess, cryptocode, threading, configparser, datetime, webbrowser, pefile, PYAS_English, pefile, hashlib, PyQt5, PYAS_UI, pywin32
|
||||
| Config | Permissions | System version | Processor | Memory | Storage |
|
||||
|-----------|---------------|----------------------|-----------|--------|---------|
|
||||
| Minimum | Administrator | >= Windows 10 (20H1) | 1 GHz | 200MB | 100MB |
|
||||
| Recommend | Administrator | >= Windows 10 (21H2) | 3 GHz | 500MB | 200MB |
|
||||
|
||||
## Special Thanks
|
||||
Wix, Avast, Github, Google, Python, Microsoft, VirusTotal, VirusShare, mtkiao129, LenStevens
|
||||
## Packaged Releases
|
||||
|
||||
Copyright© 2020~2022 PYAS Security
|
||||
Download the installer. If it is incompatible with your system, you can repackage it yourself.
|
||||
|
||||
Packaged Download: https://github.com/87owo/PYAS/releases
|
||||
|
||||
## Official Website
|
||||
|
||||
If you are interested in this project, you can visit the website to see other related content.
|
||||
|
||||
Source Available : https://github.com/87owo/PYAS
|
||||
|
||||
Official Website : https://pyas-security.com/antivirus
|
||||
|
||||
## Project License
|
||||
|
||||
For any questions, needs, or bug feedback, please contact us through the following website.
|
||||
|
||||
Source Issues : https://github.com/87owo/PYAS/issues
|
||||
|
||||
Official Email : mailto:service.pyas@gmail.com
|
||||
Reference in new issue
Block a user