Compare commits

...
77 Commits
Author SHA1 Message Date
PYDT 316882bcd0 Add files via upload 2024-10-03 02:27:09 +08:00
PYDT b204e52297 Update README_zh_CN.md 2024-10-02 21:58:55 +08:00
PYDT f82a63f4c8 Update README_zh_TW.md 2024-10-02 21:58:40 +08:00
PYDT cb0f2108a4 Update README.md 2024-10-02 21:58:12 +08:00
PYDT 300b7a7a68 Add files via upload 2024-10-02 12:30:44 +08:00
PYDT c3852ca60d Add files via upload 2024-10-02 12:00:37 +08:00
PYDT a5fb735c93 Add files via upload 2024-09-28 11:15:53 +08:00
PYDT d0b04ba84f Add files via upload 2024-09-28 11:14:54 +08:00
PYDT 9552742a39 Add files via upload 2024-09-21 22:51:13 +08:00
PYDT 8e9bdf6c0c Add files via upload 2024-09-21 22:50:02 +08:00
PYDT 818cc48502 Add files via upload 2024-09-20 00:36:42 +08:00
PYDT adc4e28eb8 Add files via upload 2024-09-20 00:31:25 +08:00
PYDT 2e3a4d3bf1 Add files via upload 2024-09-14 15:41:49 +08:00
PYDT d9bcac78e7 Add files via upload 2024-09-14 15:12:14 +08:00
PYDT 2342947849 Add files via upload 2024-09-14 15:11:36 +08:00
PYDT 19204dee8d Add files via upload 2024-09-12 16:17:50 +08:00
PYDT 863fa90b80 Add files via upload 2024-09-12 16:08:26 +08:00
PYDT 6fdef4a8f1 Add files via upload 2024-09-12 16:08:10 +08:00
PYDT 9469ceaa02 Add files via upload 2024-09-12 15:25:07 +08:00
PYDT 857f184409 Add files via upload 2024-09-11 01:05:58 +08:00
PYDT a2f4a725f5 Add files via upload 2024-09-10 14:34:02 +08:00
PYDT d12449bbb9 Add files via upload 2024-09-10 13:35:57 +08:00
PYDT a41f4711dd Add files via upload 2024-09-10 13:34:16 +08:00
PYDT 3c2b018d49 Add files via upload 2024-09-07 10:49:46 +08:00
PYDT e221a09709 Add files via upload 2024-09-07 10:48:43 +08:00
PYDT 26ff4bd843 Update README_zh_TW.md 2024-08-26 07:42:37 +08:00
PYDT d8e28f384a Update README_zh_CN.md 2024-08-26 07:42:17 +08:00
PYDT 65e68c3cc4 Update README.md 2024-08-26 07:41:44 +08:00
PYDT 7b76ab2a59 Update README.md 2024-08-26 07:41:18 +08:00
PYDT ae2a01b463 Update README_zh_TW.md 2024-08-26 07:29:15 +08:00
PYDT cda022a9f4 Update README_zh_CN.md 2024-08-26 07:28:10 +08:00
PYDT 672e48c5f8 Update README.md 2024-08-26 07:26:34 +08:00
PYDT 6fbdb1354f Update README.md 2024-08-26 07:22:09 +08:00
PYDT 79bc7fd443 Update README_zh_TW.md 2024-08-20 10:57:17 +08:00
PYDT 5578dd3339 Update README_zh_CN.md 2024-08-20 10:57:03 +08:00
PYDT 0232dbd196 Update README.md 2024-08-20 10:56:46 +08:00
PYDT d44e192eaa Update README_zh_CN.md 2024-08-20 10:53:34 +08:00
PYDT 4f12b19cf8 Update README_zh_TW.md 2024-08-20 10:52:57 +08:00
PYDT 392ac1b1c7 Update README_zh_TW.md 2024-08-20 10:52:37 +08:00
PYDT 8ad175aca3 Update README.md 2024-08-20 10:51:48 +08:00
PYDT 6afa58c42b Delete PYAS_Extension.py 2024-08-18 12:48:43 +08:00
PYDT 8be03cf232 Add files via upload 2024-08-18 12:48:16 +08:00
PYDT 23ea53d3ff Add files via upload 2024-08-18 12:46:52 +08:00
PYDT 294f40e7ac Add files via upload 2024-08-18 12:46:11 +08:00
PYDT 4f5f706ee5 Delete Exten directory 2024-08-18 12:45:44 +08:00
PYDT 27c1a7b4e4 Add files via upload 2024-07-24 09:53:48 +08:00
PYDT cfaa5be6d7 Add files via upload 2024-07-20 18:11:08 +08:00
PYDT a6942280a0 Add files via upload 2024-07-20 17:51:33 +08:00
PYDT 159124e6a3 Add files via upload 2024-07-20 17:50:48 +08:00
PYDT 6e63293a3c Update README_zh_TW.md 2024-07-19 16:23:33 +08:00
PYDT 9a9dc0d788 Update README_zh_TW.md 2024-07-19 16:23:09 +08:00
PYDT e201cd074c Update README_zh_CN.md 2024-07-19 16:18:11 +08:00
PYDT 0fd49a6e1c Update README.md 2024-07-19 16:09:49 +08:00
PYDT 6169a85464 Update README.md 2024-07-19 16:08:28 +08:00
PYDT e583344fee Update README.md 2024-07-19 16:05:56 +08:00
PYDT dcee00394c Update README.md 2024-07-19 16:03:49 +08:00
PYDT e48dc99dc0 Update README.md 2024-07-19 15:59:20 +08:00
PYDT 3ba3dda384 Update README.md 2024-07-19 15:56:01 +08:00
PYDT bbf1ce993c Update README.md 2024-07-19 15:54:30 +08:00
PYDT 56245a8c9b Update README.md 2024-07-19 15:38:32 +08:00
PYDT 4f2e65094c Add files via upload 2024-07-19 15:31:08 +08:00
PYDT 0bf456cbc8 Delete Exten/hollows_hunter directory 2024-07-19 15:29:58 +08:00
PYDT 9213d0da16 Delete Exten/pe_sieve directory 2024-07-19 15:29:49 +08:00
PYDT 13f2ece0ff Delete Exten/Bitdefender directory 2024-07-19 15:16:22 +08:00
PYDT 45c2a74c94 Add files via upload 2024-07-19 15:15:47 +08:00
PYDT b1b3e90e9b Add files via upload 2024-07-19 15:14:41 +08:00
PYDT 90ef841dae Add files via upload 2024-07-17 11:31:20 +08:00
PYDT b46000e8eb Add files via upload 2024-07-17 11:30:35 +08:00
PYDT b24891355d Add files via upload 2024-07-16 20:42:42 +08:00
PYDT 14bde5a790 Add files via upload 2024-07-15 09:58:25 +08:00
PYDT d6445f17e3 Add files via upload 2024-07-15 09:57:20 +08:00
PYDT 6124c3fe40 Add files via upload 2024-07-15 09:55:10 +08:00
PYDT 5531a4b194 Add files via upload 2024-07-14 10:59:27 +08:00
PYDT 839a0bbd42 Add files via upload 2024-07-13 14:43:51 +08:00
PYDT 1ba6272e4e Add files via upload 2024-07-13 14:02:02 +08:00
PYDT fdd86815ef Add files via upload 2024-07-13 14:01:13 +08:00
PYDT c8091fdc84 Add files via upload 2024-07-11 15:40:46 +08:00
67 changed files with 256845 additions and 830 deletions

No files matched your search

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-15
View File
@@ -1,15 +0,0 @@
ExcludeXMD =
Extensions = exe;com;dll;ocx;scr;bin;dat;386;vxd;sys;wdm;cla;class;ovl;ole;hlp;doc;dot;xls;ppt;wbk;wiz;pot;ppa;xla;xlt;vbs;vbe;mdb;rtf;htm;hta;html;xml;xtp;php;asp;js;shs;chm;lnk;pif;prc;url;smm;pfd;msi;ini;csc;cmd;bas;nws;
ExcludeExtensions =
ConfigFile = bdc.ini
HttpProxy =
InfectedFolder = Infected
SuspectedFolder = Suspected
LogMaxSize = 1024
RenameExtension = vir
PluginsPaths = Plugins
LogName = bdc.log
UpdateHttpLocation = http://upgrade.bitdefender.com/av32bit-eps
XMD = *
LastUpdate = Wed Feb 18 16:39:59 2009
ProductID = {AAD1516D-28AB-4EB5-B7C8-DF54FE4442E9}
Binary file not shown.
-14
View File
@@ -1,14 +0,0 @@
<p>AVCORE v2.2 Windows/i386 11.0.1.21 (August 15, 2021)</p>
<p>disp.xmd - Dispatcher (0.00) 0x1[997] (r)</p>
<p>pyinstaller.xmd - PYInstaller unpacker (1.0) 0x8[12] (r)</p>
<p>rar.xmd - RAR5 unpacker (0.5) 0xA[12] (r)</p>
<p>thebat.xmd - TheBat Engine (0.03a) 0x4010[12] (r) +</p>
<p>html.xmd - HTML Parser (1.0) 0x4008[11] (r) +</p>
<p>mdx.xmd - Macro Defense Expert (3.57b) 0x1[11] 1[0] (r)</p>
<p>cevakrnl.xmd - CEVA (0.03a) 0x1[10] (r)</p>
<p>pdf.xmd - PDF Engine (2.0) 0x4009[10] (r) +</p>
<p>imp.xmd - IMP (1.4.2) 0x2[9] (r)</p>
<p>sfx.xmd - Sfx Engine (1.8.6) 0xA[9] (r)</p>
<p>sdx.xmd - SDX () 0x1[5] 191729[0] (r)</p>
<p>jpeg.xmd - JPEG Engine (0.05) 0x1[1] 14[1] (r)</p>
<p>rtf.xmd - RTF (1.0) 0x4008[0] (r) +</p>
Binary file not shown.
+9 -1
View File
@@ -1 +1,9 @@
{"Unknown": [38413146381396798812836662586219087594480760119241756145287379993031670453973, 96759775057307603829199050115151442660431386536877578909394799687553144825391], "White": [92860071170291586757870565976957954052649178883790647665503983139114277816413, 50625869624179221836524636484722091669820057030729734765256925026245308185143, 79303266820014134748061006437377483029320717142203104125806969476209010566146, 50391760446499089493384482654016917630509060287507523223191455177998253781572, 34733894651460458125941968926483828168477919119649839915356573816494375383659, 16447578251589668808184123721615810667991570306415913809506896532563163557975, 18668853151306203943053249777678854424409647574074706653144503993068509738028, 16447129799599854768187525514242197965987640167415805965954293039200573272151, 42965648781535883376480003940402366467478625051031283341289116138472520399484, 45637511530246203537935382208327538642024163565740899790237852717178844340385, 100662025713257198141308144602569453810226448934776598411982222249289646045820, 2813878798545665948450767843887867208740292941021073849284371582085785669685, 54695748401254225125045716155327877471149349614359435230254611073117412307518, 27428665293760567560050957450577436769403462770366418052177943137905489504373, 32018095881556959863902669246154132691484124511748151111295836576906027842532, 82735669648112373508385530969898006750362429118827185652448450648454052106395, 27853809242729492000984914092533936796891917926358854729439436487683423285261, 20030429995379197455160031864140436552884002299333955332088108013764717533796, 82338140557728967648601024370995428985866052631101882076231147335348455671038, 71339449324799277130427957011381342555145697382104653874846579353871764366968, 2432232479351500614611699169184443988440809841079862157291791071419485606436, 9463527399566410848087352636323112952591923803840644609432039785310381355253, 17287926889345790925003722717807755244540044472850272987265624141065166747251, 31507509644511868166890345905396462199402122513677304280568315890707028374136, 92802443753971611323223428952970105040389824130209263287070763891097867755624, 60491018752293550079699763462944244393253888103551546202593483014975813742967, 45133408084728538869955951560598604064861024543940290379768365214821771604584, 6759146298068049614085390992799666053918974602489525613718797088468975708017, 43161770374046173333870752071317153674965637163816017117315179871715332666383, 55200886519442939000007636174371797768786544863806926514781108850256791225983, 102124766481586899841647737641698083212305154684644839980199278690335383712492, 52992286898317605666180786036367620316269750824654214415314225077986227890804, 96307454545313440124283308270263825589093792315386382296096934270155352236733, 36073459579994433898643313577597321150634749356791285363958792075031385371364, 5354562433688861244299028006341553420425390015040147574513776499404802540118, 2671602537216404752611755689384448521170725107261295121211275163689399347529, 31174448189678483951801405655647041557287598300853213718404097030076935043252, 817984956081990458969224676381868506770627801582748844000835755782736667191, 6997953573828232905847825866256444005094471443450029313008738013465446666864, 41288968033780608769032189481784193916730262129846893330891418484950645535282, 56724589038911745751056508177185337741291265472470897077742981563488398484126, 3353938097938067320481103667469354721822387389147415219233498938990215839034, 21195721951654457114265478558602466514207347021822959737607658828495062116920, 2916561284514958799877078174216081002558870786437593202464334407456915288119, 93137488384582768487662730765406914258099784103320160609442537879778117334700, 21195721951654457114265478558602377311225888285332501136798116331518898022972, 85036278951571446667616241901438186945472743486751871120301019617002115253240, 14623491695050192413097067629676318500123044497134202517578785087180871258165, 2022308710750553104057453378681448926020203033444470910346149752954363011822, 16435447118324352510213480738895714506136417806014749563314727656196027207884, 20110908101408861236178371339075650317185505287106087252378028881915405550816, 97262306467112548995108413358594977802790545321935863056096364390382492643957, 96614497885586867524036482497010189662872359368622249290846422070379022959337, 1895288773648887609359329471072769468085207279473521707976899919066265183340, 2651591106060448314208209841614702280337184080195391257416359882876000875095, 114619913163036058498985801603082782363327281628924544162718017899237779173997, 2481883953883130814217575190747389944608730963897863224598923997640828351014, 45000300637061336566799421885334051647634671537987073940268834014403441552901, 79047998258892679051555952202178856054614923426747250310189496005785954516966, 92887093185298651693450115442544102614083847612212241647641096093293220418098, 7140769773119319253009453104401896171570019200295580355390762162793695491644, 17012496707Line truncated
{
"Labels": ["White/Pefile", "White/Script", "Virus/Pefile", "Virus/Script"],
"Detect": ["Virus/Pefile", "Virus/Script"],
"Pixels": [224, 224],
"Values": 95
}
Binary file not shown.
+199 -270
View File
@@ -1,39 +1,26 @@
import os, gc, sys, time, json, yara
import pefile, socket, msvcrt, psutil
import requests, pyperclip, win32file
import win32gui, win32api, win32con
from PYAS_Engine import ListSimHash
import os, gc, sys, time, json, psutil
import ctypes, struct, msvcrt, pyperclip
import win32gui, win32api, win32con, win32file
from PYAS_Engine import YRScan, DLScan
from PYAS_Suffixes import slist, alist
from PYAS_Language import translate_dict
from PYAS_Interface import Ui_MainWindow
from PYAS_Extension import ExtenRules
from threading import Thread
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from subprocess import *
# experimental version 2024/07 PYAS Security
class MainWindow_Controller(QMainWindow):
def __init__(self):
# init program window
super(MainWindow_Controller, self).__init__()
self.setAttribute(Qt.WA_TranslucentBackground)
self.setWindowFlags(Qt.FramelessWindowHint)
# get self program path
self.pyas = sys.argv[0].replace("\\", "/")
self.dir = os.path.dirname(self.pyas)
# init self program version
self.pyae_version = "Fusion Engine"
self.pyas_version = "3.1.4"
# startup ui config
self.pyae_version = "AI Engine"
self.pyas_version = "3.2.1"
self.first_startup = True
# init program config
self.init_data_base()
self.init_tray_icon()
self.init_config_qtui()
@@ -44,18 +31,14 @@ class MainWindow_Controller(QMainWindow):
self.init_startup()
def init_threads(self):
# init protect thread
self.protect_proc_init()
self.protect_file_init()
self.protect_sys_init()
self.protect_drv_init()
self.protect_net_init()
# init tools thread
self.block_window_init()
def init_tray_icon(self):
# init taskbar tray and icon
self.tray_icon = QSystemTrayIcon(self)
self.tray_icon.activated.connect(self.init_show_pyas)
self.tray_icon.setIcon(QFileIconProvider().icon(QFileInfo(self.pyas)))
@@ -63,70 +46,45 @@ class MainWindow_Controller(QMainWindow):
def init_startup(self):
try:
# check startup ui args
if len(sys.argv) > 1:
param = sys.argv[1]
if "h" not in param:
self.init_show_pyas()
elif len(sys.argv) <= 1:
self.init_show_pyas()
# startup ui complete
self.first_startup = False
except:
pass
def init_data_base(self):
try:
# init exten path ./Exten/* (from import)
self.exten = ExtenRules()
# init model path ./Model/* (from import)
self.model = ListSimHash()
data_path = os.path.join(self.dir, "Model")
self.model = DLScan()
data_path = os.path.join(self.dir, "Model")
for root, dirs, files in os.walk(data_path):
for file in files:
file_path = os.path.join(root, file)
ftype = str(f".{file.split('.')[-1]}").lower()
if ftype in [".json",".txt"]:
# SimHash model json file
self.model.load_model(file_path)
# init yara path ./Rules/* (from import)
self.rules = {}
self.model.load_model(file_path)
self.rules = YRScan()
data_path = os.path.join(self.dir, "Rules")
for root, dirs, files in os.walk(data_path):
for file in files:
file_path = os.path.join(root, file)
ftype = str(f".{file.split('.')[-1]}").lower()
if ftype in [".yara", ".yar"]:
# not compile yara rules
rules = yara.compile(file_path)
elif ftype in [".yc", ".yrc"]:
# compiled yara rules
rules = yara.load(file_path)
self.rules[file_path] = rules
self.rules.load_rules(file_path)
except Exception as e:
self.bug_event(e)
def init_config_boot(self):
try:
# init read system boot
with open(r"\\.\PhysicalDrive0", "r+b") as f:
# backup system mbr value
self.mbr_value = f.read(512)
# check if mbr is available
if self.mbr_value[510:512] != b'\x55\xAA':
self.mbr_value = False
except Exception as e:
# possible permission denied
self.mbr_value = False
self.bug_event(self.trans(f"引導防護錯誤: ")+str(e))
def write_config(self, config):
try:
# write json configs in ProgramData
with open("C:/ProgramData/PYAS/PYAS.json", "w") as f:
f.write(json.dumps(config, indent=4, ensure_ascii=False))
except Exception as e:
@@ -134,50 +92,42 @@ class MainWindow_Controller(QMainWindow):
def init_config_read(self):
try:
# init check exist process
self.track_proc = None
self.exist_process = set()
for p in psutil.process_iter():
self.exist_process.add(p.pid)
# check config path exists
if not os.path.exists("C:/ProgramData/PYAS"):
os.makedirs("C:/ProgramData/PYAS")
# check config file exists
if not os.path.exists("C:/ProgramData/PYAS/PYAS.json"):
self.write_config({"language":"en_US","theme_color":"White",
"high_sensitive":0,"cloud_services":"None"})
"high_sensitive":0,"extension_kits":0,"cloud_services":"None"})
try:
# read config json data
with open("C:/ProgramData/PYAS/PYAS.json", "r") as f:
self.json = json.load(f)
except:
self.json = {"language":"en_US","theme_color":"White",
"high_sensitive":0,"cloud_services":"None"}
# default json config
"high_sensitive":0,"extension_kits":0,"cloud_services":"None"}
self.json["language"] = self.json.get("language", "en_US")
self.json["theme_color"] = self.json.get("theme_color", "White")
self.json["high_sensitive"] = self.json.get("high_sensitive", 0)
self.json["extension_kits"] = self.json.get("extension_kits", 0)
self.json["cloud_services"] = self.json.get("cloud_services", "None")
# reflash high_sensitive ui text
if self.json["high_sensitive"] == 1:
self.ui.high_sensitivity_switch_Button.setText(self.trans("已開啟"))
self.ui.high_sensitivity_switch_Button.setStyleSheet("""
QPushButton{border:none;background-color:rgb(200, 250, 200);border-radius: 10px;}
QPushButton:hover{background-color:rgb(210, 250, 210);}""")
# reflash language ui setChecked
if self.json["extension_kits"] == 1:
self.ui.extension_kit_switch_Button.setText(self.trans("已開啟"))
self.ui.extension_kit_switch_Button.setStyleSheet("""
QPushButton{border:none;background-color:rgb(200, 250, 200);border-radius: 10px;}
QPushButton:hover{background-color:rgb(210, 250, 210);}""")
if self.json["language"] == "zh_TW":
self.ui.Language_Traditional_Chinese.setChecked(True)
elif self.json["language"] == "zh_CN":
self.ui.Language_Simplified_Chinese.setChecked(True)
elif self.json["language"] == "en_US":
self.ui.Language_English.setChecked(True)
# reflash theme_color ui setChecked
if self.json["theme_color"] == "White":
self.ui.Theme_White.setChecked(True)
elif self.json["theme_color"] == "Red":
@@ -190,14 +140,10 @@ class MainWindow_Controller(QMainWindow):
self.ui.Theme_Blue.setChecked(True)
elif os.path.exists(self.json["theme_color"]):
self.ui.Theme_Customize.setChecked(True)
# read whitelist lines from ProgramData
self.whitelist = []
if os.path.exists("C:/ProgramData/PYAS/Whitelist.ini"):
with open("C:/ProgramData/PYAS/Whitelist.ini", "r") as f:
self.whitelist = [l.strip() for l in f.readlines()]
# read blocklist lines from ProgramData
self.blocklist = []
if os.path.exists("C:/ProgramData/PYAS/Blocklist.ini"):
with open("C:/ProgramData/PYAS/Blocklist.ini", "r") as f:
@@ -206,7 +152,6 @@ class MainWindow_Controller(QMainWindow):
self.bug_event(e)
def init_control(self):
# connect main ui and function control
self.ui.Close_Button.clicked.connect(self.close)
self.ui.Minimize_Button.clicked.connect(self.showMinimized)
self.ui.Menu_Button.clicked.connect(self.show_menu)
@@ -214,8 +159,6 @@ class MainWindow_Controller(QMainWindow):
self.ui.Tools_Button.clicked.connect(self.change_tools_widget)
self.ui.Virus_Scan_Button.clicked.connect(self.change_scan_widget)
self.ui.Protection_Button.clicked.connect(self.change_protect_widget)
# connect scan ui and function control
self.ui.Virus_Scan_output.setContextMenuPolicy(Qt.CustomContextMenu)
self.ui.Virus_Scan_output.customContextMenuRequested.connect(self.Virus_Scan_output_menu)
self.ui.Virus_Scan_Solve_Button.clicked.connect(self.virus_solve)
@@ -224,8 +167,6 @@ class MainWindow_Controller(QMainWindow):
self.ui.File_Scan_Button.clicked.connect(self.file_scan)
self.ui.Path_Scan_Button.clicked.connect(self.path_scan)
self.ui.Disk_Scan_Button.clicked.connect(self.disk_scan)
# connect tools ui and function control
self.ui.System_Process_Manage_Button.clicked.connect(lambda:self.change_tools(self.ui.Process_widget))
self.ui.Process_Tools_Back.clicked.connect(lambda:self.back_to_tools(self.ui.Process_widget))
self.ui.Repair_System_Files_Button.clicked.connect(self.repair_system)
@@ -236,17 +177,13 @@ class MainWindow_Controller(QMainWindow):
self.ui.Process_list.customContextMenuRequested.connect(self.process_list_menu)
self.ui.About_Back.clicked.connect(self.ui.About_widget.hide)
self.ui.Setting_Back.clicked.connect(self.setting_back)
# connect protect ui and function control
self.ui.Protection_switch_Button.clicked.connect(self.protect_proc_init)
self.ui.Protection_switch_Button_2.clicked.connect(self.protect_file_init)
self.ui.Protection_switch_Button_3.clicked.connect(self.protect_sys_init)
self.ui.Protection_switch_Button_4.clicked.connect(self.protect_drv_init)
self.ui.Protection_switch_Button_5.clicked.connect(self.protect_net_init)
# connect settings ui and function control
self.ui.high_sensitivity_switch_Button.clicked.connect(self.change_sensitive)
self.ui.cloud_services_switch_Button.clicked.connect(self.cloud_service)
self.ui.extension_kit_switch_Button.clicked.connect(self.extension_kit)
self.ui.Add_White_list_Button.clicked.connect(self.add_white_list)
self.ui.Language_Traditional_Chinese.clicked.connect(self.init_change_lang)
self.ui.Language_Simplified_Chinese.clicked.connect(self.init_change_lang)
@@ -259,20 +196,13 @@ class MainWindow_Controller(QMainWindow):
self.ui.Theme_Red.clicked.connect(self.init_theme_color)
def init_config_qtui(self):
# connect ui and variable control
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
# init virus scan list
self.virus_lock = {}
self.virus_list = []
self.virus_list_ui = []
# init process tools list
self.Process_quantity = []
self.Process_list_all_pid = []
# connect effect ui and variable
self.Process_sim = QStringListModel()
self.Process_Timer = QTimer()
self.Process_Timer.timeout.connect(self.process_list)
@@ -306,34 +236,27 @@ class MainWindow_Controller(QMainWindow):
self.ui.About_widget.hide()
self.ui.State_output.style().polish(self.ui.State_output.verticalScrollBar())
self.ui.Virus_Scan_output.style().polish(self.ui.Virus_Scan_output.verticalScrollBar())
# PYAS License_terms
self.ui.License_terms.setText('''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.''')
def init_change_lang(self):
try:
# change lang function with init or clicked
if self.ui.Language_Traditional_Chinese.isChecked():
self.json["language"] = "zh_TW"
elif self.ui.Language_Simplified_Chinese.isChecked():
self.json["language"] = "zh_CN"
elif self.ui.Language_English.isChecked():
self.json["language"] = "en_US"
# write lang config and set lang text
self.write_config(self.json)
self.init_lang_text()
except Exception as e:
self.bug_event(e)
def trans(self, text):
# from PYAS_Language import translate_dict
for k, v in translate_dict.get(self.json["language"], translate_dict).items():
text = text.replace(str(k), str(v))
return text
def init_lang_text(self):
# original init language "zh_TW"
self.ui.State_title.setText(self.trans("此裝置已受到防護"))
self.ui.Window_title.setText(self.trans(f"PYAS Security"))
self.ui.PYAS_CopyRight.setText(self.trans(f"Copyright© 2020-{max(int(time.strftime('%Y')), 2020)} PYAS Security"))
@@ -374,7 +297,7 @@ class MainWindow_Controller(QMainWindow):
self.ui.Window_Block_Button.setText(self.trans("軟體彈窗攔截"))
self.ui.Repair_System_Network_Button.setText(self.trans("系統網路修復"))
self.ui.About_Back.setText(self.trans("返回"))
self.ui.PYAS_Version.setText(self.trans(f"PYAS V{self.pyas_version} ({self.pyae_version})"))
self.ui.PYAS_Version.setText(self.trans(f"PYAS Security V{self.pyas_version} ({self.pyae_version})"))
self.ui.GUI_Made_title.setText(self.trans("介面製作:"))
self.ui.GUI_Made_Name.setText(self.trans("mtkiao"))
self.ui.Core_Made_title.setText(self.trans("核心製作:"))
@@ -384,11 +307,11 @@ class MainWindow_Controller(QMainWindow):
self.ui.PYAS_URL_title.setText(self.trans("官方網站:"))
self.ui.PYAS_URL.setText(self.trans("<html><head/><body><p><a href=\"https://github.com/87owo/PYAS\"><span style=\" text-decoration: underline; color:#000000;\">https://github.com/87owo/PYAS</span></a></p></body></html>"))
self.ui.high_sensitivity_title.setText(self.trans("高靈敏度模式"))
self.ui.high_sensitivity_illustrate.setText(self.trans("啟用此選項可以提高引擎的靈敏度"))
self.ui.high_sensitivity_illustrate.setText(self.trans("啟用此選項可以提高掃描引擎靈敏度"))
self.ui.high_sensitivity_switch_Button.setText(self.trans(self.ui.high_sensitivity_switch_Button.text()))
self.ui.cloud_services_title.setText(self.trans("雲端上報服務"))
self.ui.cloud_services_illustrate.setText(self.trans("此選項可以選擇檔案並上報雲端分析"))
self.ui.cloud_services_switch_Button.setText(self.trans("選擇"))
self.ui.extension_kit_title.setText(self.trans("擴展掃描引擎"))
self.ui.extension_kit_illustrate.setText(self.trans("啟用此選項可以使用第三方擴展套件"))
self.ui.extension_kit_switch_Button.setText(self.trans(self.ui.extension_kit_switch_Button.text()))
self.ui.Add_White_list_title.setText(self.trans("增加到白名單"))
self.ui.Add_White_list_illustrate.setText(self.trans("此選項可以選擇檔案並增加到白名單"))
self.ui.Add_White_list_Button.setText(self.trans(self.ui.Add_White_list_Button.text()))
@@ -408,7 +331,6 @@ class MainWindow_Controller(QMainWindow):
def init_theme_color(self):
try:
# set theme color (Maybe it can be further optimized?)
if self.ui.Theme_White.isChecked():
self.json["theme_color"] = "White"
self.ui.State_icon.setPixmap(QPixmap(":/icon/Check.png"))
@@ -435,7 +357,6 @@ class MainWindow_Controller(QMainWindow):
self.ui.Window_widget.setStyleSheet("QWidget#Window_widget {background-color:rgb(250,250,230);}")
self.ui.Navigation_Bar.setStyleSheet("QWidget#Navigation_Bar {background-color:rgb(250,250,220);}")
elif self.ui.Theme_Customize.isChecked():
# check customize theme config
if not os.path.exists(os.path.join(self.json["theme_color"],"Color.ini")):
path = str(QFileDialog.getExistingDirectory(self,self.trans("自定主題"),"C:/"))
if path and os.path.exists(os.path.join(path,"Color.ini")):
@@ -446,10 +367,8 @@ class MainWindow_Controller(QMainWindow):
self.ui.Navigation_Bar.setStyleSheet(self.themecolor[1])
file = os.path.join(self.json["theme_color"],"Check.png")
self.ui.State_icon.setPixmap(QPixmap(file))
# write theme color config
self.write_config(self.json)
except:
# set default theme color when error
self.ui.Theme_White.setChecked(True)
self.json["theme_color"] = "White"
self.ui.State_icon.setPixmap(QPixmap(":/icon/Check.png"))
@@ -457,7 +376,6 @@ class MainWindow_Controller(QMainWindow):
self.ui.Navigation_Bar.setStyleSheet("QWidget#Navigation_Bar {background-color:rgb(230,230,230);}")
def change_animation(self,widget):
# animation for widget
x, y = 170, widget.pos().y()
self.anim = QPropertyAnimation(widget, b"geometry")
widget.setGeometry(QRect(x - 100,y, 671, 481))
@@ -468,7 +386,6 @@ class MainWindow_Controller(QMainWindow):
self.anim.start()
def change_animation_2(self,nx,ny):
# animation for scroll bar
x, y = self.ui.label.pos().x(), self.ui.label.pos().y()
self.anim2 = QPropertyAnimation(self.ui.label, b"geometry")
if y > ny:
@@ -488,7 +405,6 @@ class MainWindow_Controller(QMainWindow):
self.anim2.start()
def change_animation_3(self,widget,time):
# animation for OpacityEffect
self.opacity = QGraphicsOpacityEffect()
self.opacity.setOpacity(0)
self.opacity.i = self.opacity.opacity()
@@ -730,18 +646,20 @@ class MainWindow_Controller(QMainWindow):
# question event message
print(f"[Quest] > {text}")
if self.first_startup != True:
return QMessageBox.question(self, "Quest", self.trans(str(text)),QMessageBox.Yes|QMessageBox.No) == 16384
return QMessageBox.question(self, "Quest",
self.trans(str(text)),QMessageBox.Yes|QMessageBox.No) == 16384
except:
return False
def send_notify(self, text):
def send_notify(self, text, notify_bar=True):
try:
# send system notification
now_time = time.strftime('%Y-%m-%d %H:%M:%S')
print(f"[Notify] > [{now_time}] {text}")
if self.first_startup != True:
QMetaObject.invokeMethod(self.ui.State_output, "append",
Qt.QueuedConnection, Q_ARG(str, f"[{now_time}] {text}"))
if self.first_startup == False and notify_bar == True:
self.tray_icon.showMessage(now_time, text, 5000)
QMetaObject.invokeMethod(self.ui.State_output, "append", Qt.QueuedConnection, Q_ARG(str, f"[{now_time}] {text}"))
except:
pass
@@ -799,22 +717,23 @@ class MainWindow_Controller(QMainWindow):
QPushButton:hover{background-color:rgb(210,250,210);}""")
self.write_config(self.json)
def cloud_service(self):
try:
# cloud services config /ProgramData/PYAS.json
if self.json["cloud_services"] != "None":
# upload file cloud services
file = str(QFileDialog.getOpenFileName(self,self.trans("上報雲端分析"),"C:/")[0]).replace("\\", "/")
if file and self.question_event("您確定要上報雲端分析嗎?"):
response = requests.post(self.json["cloud_services"], files={'file': open(file, 'rb')})
if response.status_code == 200:
self.info_event(f"成功上報雲端分析: "+file)
else:
self.bug_event(response.status_code)
else:
self.bug_event(self.trans("未選擇雲端服務網站"))
except Exception as e:
self.bug_event(e)
def extension_kit(self):
sw_state = self.ui.extension_kit_switch_Button.text()
if sw_state == self.trans("已開啟"):
# close extension kit mode
self.json["extension_kits"] = 0
self.ui.extension_kit_switch_Button.setText(self.trans("已關閉"))
self.ui.extension_kit_switch_Button.setStyleSheet("""
QPushButton{border:none;background-color:rgb(230,230,230);border-radius: 10px;}
QPushButton:hover{background-color:rgb(220,220,220);}""")
else:
# open extension kit mode
self.json["extension_kits"] = 1
self.ui.extension_kit_switch_Button.setText(self.trans("已開啟"))
self.ui.extension_kit_switch_Button.setStyleSheet("""
QPushButton{border:none;background-color:rgb(200,250,200);border-radius: 10px;}
QPushButton:hover{background-color:rgb(210,250,210);}""")
self.write_config(self.json)
def init_scan(self):
try:
@@ -871,18 +790,23 @@ class MainWindow_Controller(QMainWindow):
try:
# delete file
if self.ui.Virus_Scan_output.findItems(file, Qt.MatchContains)[0].checkState() == Qt.Checked:
self.ui.Virus_Scan_title.setText(self.trans("正在刪除"))
self.ui.Virus_Scan_text.setText(file)
QMetaObject.invokeMethod(self.ui.Virus_Scan_title, "setText",
Qt.QueuedConnection, Q_ARG(str, self.trans("正在刪除")))
QMetaObject.invokeMethod(self.ui.Virus_Scan_text, "setText",
Qt.QueuedConnection, Q_ARG(str, file))
QApplication.processEvents()
self.lock_file(file, False)
self.ransom_counts = 0
os.remove(file)
else:
self.lock_file(file, False)
except:
continue
self.ui.Virus_Scan_output.clear()
self.ui.Virus_Scan_title.setText(self.trans("病毒掃描"))
self.ui.Virus_Scan_text.setText(self.trans("刪除成功"))
QMetaObject.invokeMethod(self.ui.Virus_Scan_title, "setText",
Qt.QueuedConnection, Q_ARG(str, self.trans("病毒掃描")))
QMetaObject.invokeMethod(self.ui.Virus_Scan_text, "setText",
Qt.QueuedConnection, Q_ARG(str, self.trans("刪除成功")))
except Exception as e:
self.bug_event(e)
@@ -902,7 +826,8 @@ class MainWindow_Controller(QMainWindow):
def answer_scan(self):
try:
self.ui.Virus_Scan_title.setText(self.trans("病毒掃描"))
QMetaObject.invokeMethod(self.ui.Virus_Scan_title, "setText",
Qt.QueuedConnection, Q_ARG(str, self.trans("病毒掃描")))
if self.virus_list:
self.ui.Virus_Scan_Solve_Button.show()
self.ui.Virus_Scan_Break_Button.hide()
@@ -911,7 +836,9 @@ class MainWindow_Controller(QMainWindow):
else:
self.virus_scan_break()
text = self.trans("當前未發現病毒")
self.ui.Virus_Scan_text.setText(text)
self.scan_thread.join()
QMetaObject.invokeMethod(self.ui.Virus_Scan_text, "setText",
Qt.QueuedConnection, Q_ARG(str, text))
self.send_notify(text)
gc.collect()
except Exception as e:
@@ -921,8 +848,10 @@ class MainWindow_Controller(QMainWindow):
self.scan_file = False
self.ui.Virus_Scan_Break_Button.hide()
self.ui.Virus_Scan_choose_Button.show()
self.ui.Virus_Scan_text.setText(self.trans("請選擇掃描方式"))
self.ui.Virus_Scan_title.setText(self.trans("病毒掃描"))
QMetaObject.invokeMethod(self.ui.Virus_Scan_title, "setText",
Qt.QueuedConnection, Q_ARG(str, self.trans("病毒掃描")))
QMetaObject.invokeMethod(self.ui.Virus_Scan_text, "setText",
Qt.QueuedConnection, Q_ARG(str, self.trans("請選擇掃描方式")))
def virus_scan_menu(self):
if self.ui.Virus_Scan_choose_widget.isHidden():
@@ -936,9 +865,10 @@ class MainWindow_Controller(QMainWindow):
file = str(QFileDialog.getOpenFileName(self,self.trans("病毒掃描"),"C:/")[0])
if file and file not in self.whitelist and file != self.pyas:
self.init_scan()
thread = Thread(target=self.write_scan, args=(self.start_scan(file),file,), daemon=True)
thread.start()
while thread.is_alive():
self.scan_thread = Thread(target=self.write_scan,
args=(self.start_scan(file),file,), daemon=True)
self.scan_thread.start()
while self.scan_thread.is_alive():
QApplication.processEvents()
self.answer_scan()
except Exception as e:
@@ -950,9 +880,9 @@ class MainWindow_Controller(QMainWindow):
path = str(QFileDialog.getExistingDirectory(self,self.trans("病毒掃描"),"C:/"))
if path:
self.init_scan()
thread = Thread(target=self.traverse_path, args=(path,), daemon=True)
thread.start()
while thread.is_alive():
self.scan_thread = Thread(target=self.traverse_path, args=(path,), daemon=True)
self.scan_thread.start()
while self.scan_thread.is_alive():
QApplication.processEvents()
self.answer_scan()
except Exception as e:
@@ -964,9 +894,9 @@ class MainWindow_Controller(QMainWindow):
self.init_scan()
for d in range(26):
if os.path.exists(f"{chr(65+d)}:/"):
thread = Thread(target=self.traverse_path, args=(f"{chr(65+d)}:/",), daemon=True)
thread.start()
while thread.is_alive():
self.scan_thread = Thread(target=self.traverse_path, args=(f"{chr(65+d)}:/",), daemon=True)
self.scan_thread.start()
while self.scan_thread.is_alive():
QApplication.processEvents()
self.answer_scan()
except Exception as e:
@@ -982,8 +912,10 @@ class MainWindow_Controller(QMainWindow):
elif os.path.isdir(file):
self.traverse_path(file)
elif file != self.pyas and file not in self.whitelist:
self.ui.Virus_Scan_title.setText(self.trans("正在掃描"))
self.ui.Virus_Scan_text.setText(file)
QMetaObject.invokeMethod(self.ui.Virus_Scan_title, "setText",
Qt.QueuedConnection, Q_ARG(str, self.trans("正在掃描")))
QMetaObject.invokeMethod(self.ui.Virus_Scan_text, "setText",
Qt.QueuedConnection, Q_ARG(str, file))
self.write_scan(self.start_scan(file),file)
gc.collect()
except:
@@ -991,64 +923,19 @@ class MainWindow_Controller(QMainWindow):
def start_scan(self, file):
try:
label, level = self.pe_scan(file)
if label and "Unknown" == label:
if self.rule_scan(file):
return "Rules"
elif self.exten.bdc_scan(file):
return "Exten"
elif label and "White" != label:
if self.json["high_sensitive"]:
return label
elif level and level >= 1.0:
return label
elif self.rule_scan(file):
return "Rules"
elif self.exten.bdc_scan(file):
return "Exten"
elif self.json["high_sensitive"]:
if self.rule_scan(file):
return "Rules"
elif self.exten.bdc_scan(file):
return "Exten"
return False
except:
return False
def pe_scan(self, file):
try:
fn = []
with pefile.PE(file, fast_load=True) as pe:
pe.parse_data_directories(directories=[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_IMPORT']])
for entry in pe.DIRECTORY_ENTRY_IMPORT:
for func in entry.imports:
if func.name:
try:
fn.append(str(func.name, "utf-8"))
except:
pass
if fn:
QApplication.processEvents()
return self.model.predict(fn)
return False, False
except:
return False, False
def sign_scan(self, file):
try:
with pefile.PE(file, fast_load=True) as pe:
return pe.OPTIONAL_HEADER.DATA_DIRECTORY[pefile.DIRECTORY_ENTRY["IMAGE_DIRECTORY_ENTRY_SECURITY"]].VirtualAddress == 0
except:
return True
def rule_scan(self, file):
try:
with open(file, "rb") as f:
data = f.read()
for name, rules in self.rules.items():
QApplication.processEvents()
if rules.match(data=data):
return True
if isinstance(file, dict):
match_data = file
elif os.path.exists(file):
match_data = self.model.get_type(file)
for ftype, data in match_data.items():
label, level = self.model.dl_scan(data)
if label and label in self.model.detect:
if self.json["high_sensitive"]:
return label
elif level >= self.model.values:
return label
if self.json["extension_kits"]:
return self.rules.yr_scan(file)[0]
return False
except:
return False
@@ -1156,7 +1043,7 @@ class MainWindow_Controller(QMainWindow):
win32api.RegDeleteValue(key,i)
name = self.track_proc.name()
if "cmd.exe" not in name and "powershell" not in name:
self.kill_process(self.track_proc, "註冊表攔截", True)
self.kill_process("註冊表攔截", *self.track_proc)
except:
pass
win32api.RegCloseKey(key)
@@ -1192,6 +1079,7 @@ class MainWindow_Controller(QMainWindow):
self.traverse_temp(file)
else:
file_size = os.path.getsize(file)
self.ransom_counts = 0
os.remove(file)
self.total_deleted_size += file_size
except:
@@ -1220,8 +1108,8 @@ class MainWindow_Controller(QMainWindow):
self.block_window = False
if self.question_event("請選擇要攔截的軟體彈窗"):
while not self.block_window:
window_name = str(win32gui.GetWindowText(win32gui.GetForegroundWindow()))
QApplication.processEvents()
window_name = str(win32gui.GetWindowText(win32gui.GetForegroundWindow()))
if window_name not in ["","PYAS",self.trans("警告")]:
if window_name not in self.blocklist:
if self.question_event(f"您確定要攔截 {window_name} 嗎?"):
@@ -1368,7 +1256,7 @@ class MainWindow_Controller(QMainWindow):
if not self.first_startup:
if result == 0 or result == 577:
if self.question_event("使用此選項需要重啟,您確定要重啟嗎?"):
Popen(f'"{file_path}/Uninstall_Driver.bat"', shell=True, stdout=PIPE, stderr=PIPE).wait()
Popen(f'"{file_path}/Uninstall_Driver.bat"', shell=True, stdout=PIPE, stderr=PIPE)
else:
Popen("sc start PYAS_Driver", shell=True, stdout=PIPE, stderr=PIPE).wait()
if result == 1062 or result == 1060:
@@ -1382,7 +1270,7 @@ class MainWindow_Controller(QMainWindow):
if result == 1060 or result == 3 or result == 577:
if self.question_event("此選項可能會與其他軟體不兼容,您確定要開啟嗎?"):
Popen("sc delete PYAS_Driver", shell=True, stdout=PIPE, stderr=PIPE).wait()
Popen(f'"{file_path}/Install_Driver.bat"', shell=True, stdout=PIPE, stderr=PIPE).wait()
Popen(f'"{file_path}/Install_Driver.bat"', shell=True, stdout=PIPE, stderr=PIPE)
else:
Popen("sc stop PYAS_Driver", shell=True, stdout=PIPE, stderr=PIPE).wait()
if result == 0 or result == 1056:
@@ -1430,7 +1318,7 @@ class MainWindow_Controller(QMainWindow):
pass
self.exist_process = new_process
if self.ui.Protection_switch_Button.text() == self.trans("已開啟"):
self.send_notify(self.trans(f"竄改警告: self.proc_protect"))
self.send_notify(self.trans(f"竄改警告: self.proc_protect"), False)
def handle_new_process(self, p):
try:
@@ -1438,68 +1326,109 @@ class MainWindow_Controller(QMainWindow):
if file != self.pyas and file not in self.whitelist:
if "powershell" in name:
file = str(cmd[-1].split("'")[-2]).replace("\\", "/")
if os.path.exists(file) and self.start_scan(file):
self.kill_process(p, "腳本攔截", False)
elif ":/Windows" not in file and ":/Program" not in file:
self.track_proc = p
elif "cmd.exe" in name:
file = str(" ".join(cmd[2:])).replace("\\", "/")
if os.path.exists(file) and self.start_scan(file):
self.kill_process(p, "腳本攔截", False)
elif ":/Windows" not in file and ":/Program" not in file:
self.track_proc = p
elif ":/Windows" in file:
file = str(cmd[-1]).replace("\\", "/")
if os.path.exists(file) and self.start_scan(file):
self.kill_process(p, "鏈式攔截", False)
elif not self.proc_scan(p):
if ":/Windows" not in file and ":/Program" not in file:
self.track_proc = p
if self.start_scan(file):
self.kill_process("病毒攔截", p, file, False)
elif self.load_scan(p):
self.kill_process("加載攔截", p, file, False)
elif self.memory_scan(p):
self.kill_process("記憶體攔截", p, file, False)
elif ":/Windows" not in file and ":/Program" not in file:
ftype = str(f".{file.split('.')[-1]}").lower()
if os.path.exists(file) and ftype in slist:
self.track_proc = p, file, True
except:
pass
def proc_scan(self, p):
def load_scan(self, p):
try:
if self.start_scan(p.exe()):
self.kill_process(p, "進程攔截", False)
return True
for entry in p.memory_maps():
for entry in p.memory_maps(grouped=True):
file = str(entry.path).replace("\\", "/")
if ":/Windows" not in file and self.start_scan(file):
self.kill_process(p, "加載攔截", False)
return True
self.lock_process(p, False)
time.sleep(0.2)
if self.exten.mem_scan(p):
self.kill_process(p, "記憶體攔截", True)
if ":/Windows" not in file and file not in self.whitelist:
ftype = str(f".{file.split('.')[-1]}").lower()
if ftype not in [".exe"] and self.start_scan(file):
return True
return False
except:
return False
def get_module_base(self, p):
try:
for entry in p.memory_maps(grouped=False):
file = str(entry.path).replace("\\", "/")
ftype = str(f".{file.split('.')[-1]}").lower()
if ftype in [".exe"] and file not in self.whitelist:
return int(entry.addr, 16)
return False
except:
return False
def memory_scan(self, p):
try:
match_data = {}
kernel32 = ctypes.windll.kernel32
base_address = self.get_module_base(p)
process_handle = kernel32.OpenProcess(0x1F0FFF, False, p.pid)
dos_header = ctypes.create_string_buffer(64)
kernel32.ReadProcessMemory(process_handle, ctypes.c_void_p(base_address), dos_header, 64, None)
nt_headers_offset = struct.unpack("<I", dos_header[0x3C:0x3C + 4])[0]
nt_headers = ctypes.create_string_buffer(248)
kernel32.ReadProcessMemory(process_handle,
ctypes.c_void_p(base_address + nt_headers_offset), nt_headers, 248, None)
number_of_sections = struct.unpack("<H", nt_headers[6:8])[0]
optional_header_size = struct.unpack("<H", nt_headers[20:22])[0]
section_headers_offset = nt_headers_offset + 24 + optional_header_size
for i in range(number_of_sections):
section_header = ctypes.create_string_buffer(40)
section_address = base_address + section_headers_offset + i * 40
kernel32.ReadProcessMemory(process_handle,
ctypes.c_void_p(section_address), section_header, 40, None)
section_name = section_header[:8].rstrip(b'\x00').decode('latin1')
virtual_size = struct.unpack("<I", section_header[8:12])[0]
virtual_address = struct.unpack("<I", section_header[12:16])[0]
characteristics = struct.unpack("<I", section_header[36:40])[0]
text_address = base_address + virtual_address
buffer = ctypes.create_string_buffer(virtual_size)
if kernel32.ReadProcessMemory(process_handle, ctypes.c_void_p(text_address), buffer,
virtual_size, ctypes.byref(ctypes.c_size_t(0))) and characteristics & 0x00000020:
if not any(shell in section_name.lower() for shell in self.model.shells):
match_data[section_name] = buffer.raw
kernel32.CloseHandle(process_handle)
if self.start_scan(match_data):
return True
return False
except:
return False
def lock_process(self, p, lock):
try:
if lock:
p.suspend()
else:
p.resume()
except:
pass
if lock:
p.suspend()
else:
p.resume()
def kill_process(self, p, info, relation=False):
def kill_process(self, info, p, target, relation):
try:
file = p.exe().replace("\\", "/")
if relation == True:
kill_items = []
for p2 in psutil.process_iter():
target = target.replace("\\", "/")
if relation == False:
p.kill()
elif relation == True:
for p in psutil.process_iter():
try:
if file == p2.exe().replace("\\", "/"):
p2.kill()
name, file, cmd = p.name(), p.exe(), p.cmdline()
if "powershell" in name:
file = str(cmd[-1].split("'")[-2])
elif "cmd.exe" in name:
file = str(" ".join(cmd[2:]))
elif ":/Windows" in file.replace("\\", "/"):
file = str(cmd[-1])
if target == file.replace("\\", "/"):
p.kill()
except:
pass
self.send_notify(self.trans(f"{info}: ")+file)
elif p.is_running():
p.kill()
self.send_notify(self.trans(f"{info}: ")+file)
self.send_notify(self.trans(f"{info}: ")+target, True)
self.track_proc = None
except:
self.track_proc = None
@@ -1514,7 +1443,7 @@ class MainWindow_Controller(QMainWindow):
ftype = str(f".{fpath.split('.')[-1]}").lower()
if self.ransom_counts >= 5 and self.track_proc:
self.ransom_counts = 0
self.kill_process(self.track_proc, "勒索攔截", False)
self.kill_process("勒索攔截", *self.track_proc)
elif ":/Windows" in fpath and "/Temp/" not in fpath:
if action == 2 and ftype in alist:
self.ransom_counts += 1
@@ -1525,13 +1454,15 @@ class MainWindow_Controller(QMainWindow):
self.ransom_counts += 1
elif action == 4 and ftype in alist:
self.ransom_counts += 1
if action == 3 and ftype in slist and self.start_scan(fpath):
os.remove(fpath)
self.send_notify(self.trans("病毒刪除: ")+fpath)
if ":/Windows" not in fpath and ftype in slist:
if action == 3 and self.start_scan(fpath):
self.ransom_counts = 0
os.remove(fpath)
self.send_notify(self.trans("病毒刪除: ")+fpath, True)
except:
pass
if self.ui.Protection_switch_Button_2.text() == self.trans("已開啟"):
self.send_notify(self.trans(f"竄改警告: self.file_protect"))
self.send_notify(self.trans(f"竄改警告: self.file_protect"), False)
def protect_boot_thread(self):
while self.sys_protect and self.mbr_value:
@@ -1539,15 +1470,15 @@ class MainWindow_Controller(QMainWindow):
time.sleep(0.2)
with open(r"\\.\PhysicalDrive0", "r+b") as f:
if self.mbr_value[510:512] != b'\x55\xAA':
self.kill_process(self.track_proc, "引導攔截", True)
self.kill_process("引導攔截", *self.track_proc)
elif f.read(512) != self.mbr_value:
f.seek(0)
f.write(self.mbr_value)
self.kill_process(self.track_proc, "引導攔截", True)
self.kill_process("引導攔截", *self.track_proc)
except:
self.kill_process(self.track_proc, "引導攔截", True)
self.kill_process("引導攔截", *self.track_proc)
if self.ui.Protection_switch_Button_3.text() == self.trans("已開啟"):
self.send_notify(self.trans(f"竄改警告: self.sys_protect (boot)"))
self.send_notify(self.trans(f"竄改警告: self.sys_protect (boot)"), False)
def protect_reg_thread(self):
while self.sys_protect:
@@ -1560,21 +1491,19 @@ class MainWindow_Controller(QMainWindow):
except:
pass
if self.ui.Protection_switch_Button_3.text() == self.trans("已開啟"):
self.send_notify(self.trans(f"竄改警告: self.sys_protect (reg)"))
self.send_notify(self.trans(f"竄改警告: self.sys_protect (reg)"), False)
def protect_net_thread(self):
while self.net_protect:
try:
time.sleep(0.2)
local = socket.gethostbyname(socket.gethostname())
for conn in self.track_proc.connections():
if ":/Windows" not in file and ":/Program" not in file:
if conn.laddr.ip == local:
self.kill_process(self.track_proc, "網路攔截", True)
for conn in self.track_proc[0].connections(kind='inet'):
if conn.raddr.ip in self.rules.network:
self.kill_process("網路攔截", *self.track_proc)
except:
pass
if self.ui.Protection_switch_Button_5.text() == self.trans("已開啟"):
self.send_notify(self.trans(f"竄改警告: self.net_protect"))
self.send_notify(self.trans(f"竄改警告: self.net_protect"), False)
if __name__ == '__main__':
QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
+102 -75
View File
@@ -1,84 +1,111 @@
import time, json, hashlib, numpy
from collections import Counter
import os, io, sys, time, json, yara
import numpy, pefile, onnxruntime
from PIL import Image, ImageShow
class ListSimHash:
class YRScan:
def __init__(self):
self.model = {}
self.rules = {}
self.network = []
def save_model(self, file_name):
with open(file_name, 'w') as f:
json.dump(self.model, f)
print(f"\nModel Is Saved In {file_name}")
def load_rules(self, file_path):
try:
ftype = str(f".{file_path.split('.')[-1]}").lower()
if ftype in [".yara", ".yar"]:
self.rules[file_path] = yara.compile(file_path)
elif ftype in [".yc", ".yrc"]:
self.rules[file_path] = yara.load(file_path)
elif ftype in [".ip", ".ips"]:
with open(file_path, "r") as f:
self.network += [l.strip() for l in f.readlines()]
except:
pass
def load_model(self, model_data):
if isinstance(model_data, str):
with open(model_data, 'r') as f:
model_data = json.load(f)
self.model = model_data
def yr_scan(self, file_path):
try:
if isinstance(file_path, str):
with open(file_path, "rb") as f:
file_path = f.read()
for name, rules in self.rules.items():
matchs_rules = rules.match(data=file_path)
if matchs_rules:
return "Virus/Rules", matchs_rules
return False, False
except:
return False, False
def get_model(self, label):
return self.model[label]
class DLScan:
def __init__(self):
self.models = {}
self.shells = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '!o',
'cry', 'test', 'ace', 'yg', 'obr', 'tvm', 'dec', 'enc', 'b1_', 'base',
'bss', 'clr_uef', 'cursors', 'trs_age', 'engine', 'enigma', 'protect',
'nep', 'no_bbt', 'wpp_sf', 'retpol', 'rt', 'rwexec', 'rygs', 'poolmi',
's:@', 'pgae', 'proxy', 'wisevec', 'segm', 'transit', 'vmp', 'extjmp',
'upx', 'tracesup', 'res', 'lzma', 'malloc_h', 'miniex', 'ndr64', 'be',
'mssmixer', 'wow', 'press', 'fio', 'pad', 'hexpthk', 'h~;', 'icapsec',
'sanontcp', 'secur', 'asmstub', 'nsys_wr', 'orpc', 'pack', 'wow64svc',
'uedbg', 'viahw', 'data', 'zk', 'fothk', 'qihoo']
def train_model(self, label, data):
start = time.time()
print(f"Convert {label}")
if label not in self.model:
self.model[label] = []
for i, x in enumerate(data, 1):
self.model[label].append(self.build_text(x))
used = "{0:.2f}".format(time.time()-start)
prefix, suffix = f'{i}/{len(data)}:', f'{used}s'
self.progress_bar(i, len(data), prefix, suffix)
def load_model(self, file_path):
try:
ftype = str(f".{file_path.split('.')[-1]}").lower()
if ftype in [".json", ".txt"]:
with open(file_path, 'r') as f:
self.class_names = json.load(f)
elif ftype in [".onnx"]:
self.models[file_path] = onnxruntime.InferenceSession(file_path)
self.labels = self.class_names['Labels']
self.detect = self.class_names['Detect']
self.pixels = self.class_names['Pixels']
self.values = self.class_names['Values']
except Exception as e:
pass
def build_text(self, content):
sums, batch, count = [], [], 0
features = dict(Counter(sorted(content)))
for f, w in features.items():
count += w
batch.append(hashlib.sha256(json.dumps(f).encode('utf-8')).digest() * w)
if len(batch) >= 10000:
sums.append(self.sum_hashes(batch))
batch = []
if batch:
sums.append(self.sum_hashes(batch))
combined_sums = numpy.sum(sums, 0)
v = numpy.packbits(combined_sums > count / 2).tobytes()
return int.from_bytes(v, 'big')
def dl_scan(self, file_data):
try:
target_size, sim = tuple(self.pixels), {}
image = self.preprocess_image(file_data, target_size)
image_array = numpy.array(image).astype('float32') / 255.0
image_expand = numpy.expand_dims(image_array, axis=0)
for model_name, model in self.models.items():
input_name = model.get_inputs()[0].name
pre_answer = model.run(None, {input_name: image_expand})[0][0]
number = numpy.argmax(pre_answer)
label = self.labels[number].replace("\n", "")
sim[label] = sim.setdefault(label, 0) + pre_answer[number]
for local_label, sim_sum in sim.items():
if sim_sum > len(self.models) / 2:
local_level = sim_sum / len(self.models)
print(local_label, local_level * 100)
return local_label, local_level * 100
return False, False
except Exception as e:
return False, False
def sum_hashes(self, digests):
bitarray = numpy.unpackbits(numpy.frombuffer(b''.join(digests), dtype='>B'))
return numpy.sum(numpy.reshape(bitarray, (-1, 256)), 0)
def get_type(self, file_path):
try:
match_data = {}
ftype = str(f".{file_path.split('.')[-1]}").lower()
if ftype in [".exe", ".dll", ".sys", ".scr", ".com"]:
with pefile.PE(file_path, fast_load=True) as pe:
for section in pe.sections:
section_name = section.Name.rstrip(b'\x00').decode('latin1')
if (section.Characteristics & 0x00000020 and not
any(shell in section_name.lower() for shell in self.shells)):
match_data[section_name] = section.get_data()
elif ftype in [".bat", ".vbs", ".ps1", ".cmd", ".js"]:
with open(file_path, 'rb') as file:
match_data[ftype] = file.read()
return match_data
except:
return {}
def progress_bar(self, items, total, prefix='', suffix='', length=50, fill='█'):
percent = min(100.0, max(0.0, 100 * (items / float(total))))
end_char = '\n' if percent >= 100 else '\r'
percent_string = "{0:.2f}".format(percent)
filled_length = int(length * items // total)
bar = fill * filled_length + ' ' * (length - filled_length)
print(f'\r{prefix: <15} |{bar}| {percent_string}% {suffix}', end=end_char)
def predict_all(self, query):
label_similarities = {}
query_hash = self.build_text(query)
for label in self.model:
max_similarity = 0
for data_point in self.model[label]:
similarity = self.similar(data_point, query_hash)
if similarity > max_similarity:
max_similarity = similarity
label_similarities[label] = max_similarity
return label_similarities
def predict(self, query):
max_similarity, max_label = 0, None
query_hash = self.build_text(query)
for label in self.model:
for data_point in self.model[label]:
similarity = self.similar(data_point, query_hash)
if similarity > max_similarity:
max_similarity, max_label = similarity, label
return max_label, max_similarity
def similar(self, x, y):
hamming_distance = bin(x ^ y).count('1')
return 1 - hamming_distance / 256
def preprocess_image(self, file_data, target_size):
file_data = numpy.frombuffer(file_data, dtype=numpy.uint8)
data_count = len(file_data)
wah = int(numpy.ceil(numpy.sqrt((data_count + 2) // 3)))
image_array = numpy.zeros((wah * wah * 3,), dtype=numpy.uint8)
image_array[:data_count] = file_data
image_array = image_array.reshape((wah, wah, 3))
image = Image.fromarray(image_array)
return image.resize(target_size, Image.Resampling.LANCZOS)
-24
View File
@@ -1,24 +0,0 @@
from subprocess import *
import os, re, sys
class ExtenRules:
def __init__(self):
self.exten = {}
self.pyas = sys.argv[0].replace("\\", "/")
self.dir = os.path.dirname(self.pyas)
self.exten = os.path.join(self.dir, "Exten")
def bdc_scan(self, file):
if self.exten.replace("\\", "/") not in file.replace("\\", "/"):
cmd = f'"{self.exten}\\Bitdefender\\bdc.exe" "{file}"'
p = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True, universal_newlines=True)
for matchs in re.finditer(r'(?P<filename>[^\s]+)\s+infected:\s+(?P<virusname>.+)', p.communicate()[0]):
return matchs
return False
def mem_scan(self, p):
if self.exten.replace("\\", "/") not in p.exe().replace("\\", "/"):
cmd = f'"{self.exten}\\hollows_hunter\\hollows_hunter.exe" /ofilter 2 /pid "{p.pid}"'
p = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True, universal_newlines=True)
return 'Detected' in p.communicate()[0]
return False
+35 -35
View File
@@ -1569,49 +1569,49 @@ class Ui_MainWindow(object):
self.Language_illustrate.raise_()
self.Language_Choose_widget.raise_()
self.Language_title.raise_()
self.Show_cloud_services = QtWidgets.QWidget(self.Setting_widget)
self.Show_cloud_services.setGeometry(QtCore.QRect(30, 130, 781, 81))
self.Show_cloud_services.setAcceptDrops(False)
self.Show_cloud_services.setAutoFillBackground(False)
self.Show_cloud_services.setObjectName("Show_cloud_services")
self.cloud_services_title = QtWidgets.QLabel(self.Show_cloud_services)
self.cloud_services_title.setGeometry(QtCore.QRect(20, 10, 451, 31))
self.Show_extension_kit = QtWidgets.QWidget(self.Setting_widget)
self.Show_extension_kit.setGeometry(QtCore.QRect(30, 130, 781, 81))
self.Show_extension_kit.setAcceptDrops(False)
self.Show_extension_kit.setAutoFillBackground(False)
self.Show_extension_kit.setObjectName("Show_extension_kit")
self.extension_kit_title = QtWidgets.QLabel(self.Show_extension_kit)
self.extension_kit_title.setGeometry(QtCore.QRect(20, 10, 451, 31))
font = QtGui.QFont()
font.setFamily("Microsoft YaHei")
font.setPointSize(17)
font.setBold(False)
font.setWeight(50)
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
self.cloud_services_title.setFont(font)
self.cloud_services_title.setStyleSheet("color: rgb(70,70,70);")
self.cloud_services_title.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
self.cloud_services_title.setObjectName("cloud_services_title")
self.cloud_services_illustrate = QtWidgets.QLabel(self.Show_cloud_services)
self.cloud_services_illustrate.setGeometry(QtCore.QRect(20, 40, 451, 31))
self.extension_kit_title.setFont(font)
self.extension_kit_title.setStyleSheet("color: rgb(70,70,70);")
self.extension_kit_title.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
self.extension_kit_title.setObjectName("extension_kit_title")
self.extension_kit_illustrate = QtWidgets.QLabel(self.Show_extension_kit)
self.extension_kit_illustrate.setGeometry(QtCore.QRect(20, 40, 451, 31))
font = QtGui.QFont()
font.setFamily("Microsoft YaHei")
font.setPointSize(11)
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
self.cloud_services_illustrate.setFont(font)
self.cloud_services_illustrate.setStyleSheet("color: rgb(70,70,70);")
self.cloud_services_illustrate.setScaledContents(False)
self.cloud_services_illustrate.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
self.cloud_services_illustrate.setWordWrap(True)
self.cloud_services_illustrate.setObjectName("cloud_services_illustrate")
self.cloud_services_switch_Button = QtWidgets.QPushButton(self.Show_cloud_services)
self.cloud_services_switch_Button.setGeometry(QtCore.QRect(660, 20, 91, 31))
self.extension_kit_illustrate.setFont(font)
self.extension_kit_illustrate.setStyleSheet("color: rgb(70,70,70);")
self.extension_kit_illustrate.setScaledContents(False)
self.extension_kit_illustrate.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
self.extension_kit_illustrate.setWordWrap(True)
self.extension_kit_illustrate.setObjectName("extension_kit_illustrate")
self.extension_kit_switch_Button = QtWidgets.QPushButton(self.Show_extension_kit)
self.extension_kit_switch_Button.setGeometry(QtCore.QRect(660, 20, 91, 31))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.cloud_services_switch_Button.sizePolicy().hasHeightForWidth())
self.cloud_services_switch_Button.setSizePolicy(sizePolicy)
sizePolicy.setHeightForWidth(self.extension_kit_switch_Button.sizePolicy().hasHeightForWidth())
self.extension_kit_switch_Button.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setFamily("Microsoft YaHei")
font.setPointSize(11)
font.setStyleStrategy(QtGui.QFont.PreferAntialias)
self.cloud_services_switch_Button.setFont(font)
self.cloud_services_switch_Button.setFocusPolicy(QtCore.Qt.StrongFocus)
self.cloud_services_switch_Button.setStyleSheet("QPushButton\n"
self.extension_kit_switch_Button.setFont(font)
self.extension_kit_switch_Button.setFocusPolicy(QtCore.Qt.StrongFocus)
self.extension_kit_switch_Button.setStyleSheet("QPushButton\n"
"{\n"
" border:none;\n"
" background-color:rgb(230,230,230);\n"
@@ -1622,12 +1622,12 @@ class Ui_MainWindow(object):
" background-color:rgb(220,220,220);\n"
"}\n"
"")
self.cloud_services_switch_Button.setIconSize(QtCore.QSize(16, 16))
self.cloud_services_switch_Button.setCheckable(False)
self.cloud_services_switch_Button.setObjectName("cloud_services_switch_Button")
self.cloud_services_illustrate.raise_()
self.cloud_services_switch_Button.raise_()
self.cloud_services_title.raise_()
self.extension_kit_switch_Button.setIconSize(QtCore.QSize(16, 16))
self.extension_kit_switch_Button.setCheckable(False)
self.extension_kit_switch_Button.setObjectName("extension_kit_switch_Button")
self.extension_kit_illustrate.raise_()
self.extension_kit_switch_Button.raise_()
self.extension_kit_title.raise_()
self.Setting_Back = QtWidgets.QPushButton(self.Setting_widget)
self.Setting_Back.setGeometry(QtCore.QRect(25, 10, 101, 41))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
@@ -1885,9 +1885,9 @@ class Ui_MainWindow(object):
self.Language_English.setText(_translate("MainWindow", "English"))
self.Language_Traditional_Chinese.setText(_translate("MainWindow", "繁體中文"))
self.Language_Simplified_Chinese.setText(_translate("MainWindow", "简体中文"))
self.cloud_services_title.setText(_translate("MainWindow", "雲端掃描服務"))
self.cloud_services_illustrate.setText(_translate("MainWindow", "啟用此選項可以連接雲端掃描服務"))
self.cloud_services_switch_Button.setText(_translate("MainWindow", "已關閉"))
self.extension_kit_title.setText(_translate("MainWindow", "雲端掃描服務"))
self.extension_kit_illustrate.setText(_translate("MainWindow", "啟用此選項可以連接雲端掃描服務"))
self.extension_kit_switch_Button.setText(_translate("MainWindow", "已關閉"))
self.Setting_Back.setText(_translate("MainWindow", "返回"))
self.Add_White_list_title.setText(_translate("MainWindow", "增加到白名單"))
self.Add_White_list_illustrate.setText(_translate("MainWindow", "此選項可以選擇檔案並增加到白名單"))
+8 -7
View File
@@ -16,15 +16,16 @@ translate_dict = {
"綠":"绿","態":"态","務":"务","連":"连","檢":"检","測":"测","關":"关",
"強":"强","驅":"驱","為":"为","腳":"脚","單":"单","開":"开","擴":"扩",
"惡":"恶","據":"据","庫":"库","經":"经","敗":"败","謝":"谢","別":"别",
"載":"载","誤":"误","報":"报","鏈":"链","竄":"窜","記憶體":"内存",},
"載":"载","誤":"误","報":"报","鏈":"链","竄":"窜","蹤":"踪","記憶體":"内存",},
"en_US": {"已開啟":"On","已關閉":"Off","已开启":"On","已关闭":"Off",",":", ",
"立即刪除":"Delete Now","安全模式":"Safe Mode","官方網站":"Website ",
"腳本":"Script ","鏈式":"Chain ","記憶體":"Memory ","加載":"Load ",
"行為":"Behavior ","可疑":"Suspicious ","勒索":"Ransom ",
"許可條款":"License Terms ","惡意":"Malicious","可疑":"Suspicious",
"啟用":"Enable ","禁用":"Disable ","正在初始化中":"Initializing ",
"正在掃描":"Scanning ","正在刪除":"Deleting ","最小化到":"Minimize To ",
"確定要":"Sure Want To ","靈敏度":"Sensitivity ","更新":"Update ",
"正在掃描":"Scanning ","正在刪除":"Deleting ","正在追蹤":"Tracking ",
"最小化到":"Minimize To ","靈敏度":"Sensitivity ","正在檢查":"Checking ",
"確定要":"Sure Want To ","引擎靈敏度":"Sensitivity ","更新":"Update ",
"白色主題":"White","黃色主題":"Yellow","紅色主題":"Red","語言":"Language ",
"藍色主題":"Blue","綠色主題":"Green","自定主題":"Custom","最新":"Latest ",
"特別感謝":"Contributors ","版本資訊":"Information","通訊":"Connect ",
@@ -45,7 +46,7 @@ translate_dict = {
"風險":"Risk ","介面":"GUI ","核心":"Core ","服務":"Services ",
"管理":"Manage","所有":"All ","您":"You ","取消":"Cancel ","未":"Not ",
"垃圾":"Junk ","位元":"byte ","本機":"Computer ","停止":"Stop ",
"增加到":"Add To ","白名單":"White List ","軟體":"Software ","正在":"Start ",
"增加到":"Add To ","白名單":"White List ","軟體":"Software ","正在":"",
"增加":"Add ","移除":"Delete","項目":"Items ","生成":"Create ","稱":"",
"複製":"Copy ","開啟":"Open ","此":"This ","並":"And ","全盤":"Full ",
"已經在":"Already ","數據庫":"Database ","誤報":"False Positive ",
@@ -53,7 +54,7 @@ translate_dict = {
"日誌":"Log","已":"Has ","彈窗":"Window ","要":"To ","驅動":"Driver ",
"的":"","顯示":"","個":"","嗎":"","中":"","了":"","行":"","立即":"",
"密鑰":"Key ","檢測":"Detect ","製作":"Maker ","運行":"Running",
"擴展套件":"Extension Kit ","自動":"Auto ","上報":"Report ","與":"With ",
"擴展":"Extension ","套件":"Kit ","自動":"Auto ","上報":"Report ",
"分析":"Analysis ","自身":"Self ","其他":"Other ","配置":"Config ",
"丟失":"Lost ","網站":"Website ","不兼容":"Not Compatible ","追蹤":"Tracking ",
"竄改":"Tamper "," ":" "}}
"丟失":"Lost ","網站":"Website ","不兼容":"Not Compatible ",
"竄改":"Tamper ","第三方":"Other ","與":"With "," ":" "}}
+4 -3
View File
@@ -1,7 +1,8 @@
slist = [".exe",".dll",".com",".msi",".scr",
".js",".bat",".cmd",".ps1",".vbs"]
slist = [".exe",".dll",".sys",".com",".scr",
".bat",".ps1",".vbs",".cmd",".js"]
alist = [".exe",".dll",".zip",".7z",".rar",
alist = [".exe",".dll",".sys",".com",".scr",
".zip",".7z",".rar",".tar",".gz",
".js",".bat",".cmd",".ps1",".vbs",
".ppt",".pptx",".wps",".txt",".rtf",
".pdf",".xls",".xlsx",".doc",".docx",
+1 -1
View File
@@ -2,7 +2,7 @@ import pyinstaller_versionfile
pyinstaller_versionfile.create_versionfile(
output_file="versionfile.txt",
version='3.1.4',
version='3.2.1',
company_name="PYAS Security",
file_description="Python Antivirus Software",
internal_name="PYAS",
+34 -129
View File
@@ -1,160 +1,65 @@
# PYAS (Python Antivirus Software)
![PYAS](https://github.com/87owo/PYAS/assets/85057800/8136aaca-d388-4321-bedb-abc4fcecfa8b)
![PYAS](https://github.com/user-attachments/assets/39c273b9-c467-480a-a8b3-31714a6df3ef)
## Readme Language
[繁體中文](https://github.com/87owo/PYAS/blob/main/README_zh_TW.md) ,
[简体中文](https://github.com/87owo/PYAS/blob/main/README_zh_CN.md)
繁體中文 : https://github.com/87owo/PYAS/blob/main/README_zh_TW.md
简体中文 : https://github.com/87owo/PYAS/blob/main/README_zh_CN.md
## Requirements
```
pip install psutil==5.9.5
pip install pefile==2023.2.7
pip install requests==2.31.0
pip install pyperclip==1.8.2
pip install pywin32==306
pip install PyQt5==5.15.9
pip install yara-python==4.5.1
pip install numpy==2.1.1
pip install onnxruntime==1.18.1
pip install pillow==10.4.0
```
## File Information
PYAS.py -> Main PYAS Program (including animation, scanning, protection functions, etc.)
PYAS_Engine.py -> Conversion Database (used to convert database dict and list to and from each other)
PYAS_Extension.py -> File Extension (including scanned file extensions and common file extensions)
PYAS_Model.* -> Virus Database (the virus database must be placed in the same directory)
PYAS_Interface.py -> PyQt5 Interface (designed by QT designer, must be matched with the main program)
PYAS_Resource.py -> PyQt5 Resource (status pictures, icon packages, button icons, etc.)
PYAS_Language.py -> Translate Dict (Traditional Chinese, Simplified Chinese, English)
PYAS_Version.py -> Pyinstaller Info (file information, version information, original name, etc.)
## Dir Information
```
PYAS/
├── Driver/
│ ├── PYAS_Driver.sys
│ ├── PYAS_Driver.sys -------> Driver Protect (self protection driver for pyas by 0sha0)
│ └── ...
│
├── Model/
│ ├── PYAS_Model.json
│ ├── PYAS_Model.txt
│ ├── PYAS_Model.json -------> Virus Database (the database must be in the specified dir)
│ └── ...
│
├── Rules/
│ ├── Yara_Rules.yar
│ ├── Compile_Rules.yrc
│ ├── Yara_Rules.yar ---------> Yara Rules (yara rules in plain text format)
│ ├── Yara_Rules.yrc ---------> Compile Rules (yara rules in compiled format)
│ └── ...
│
├── PYAS.py
├── PYAS_Engine.py
├── PYAS.py ---------------------> Main PYAS Program (including animation, scan, protect functions, ...)
├── PYAS_Engine.py -------------> Conversion Database (used to transform profiles and forecast data)
├── PYAS_Suffixes.py -----------> File Suffixes (including scanned file suffixes and common suffixes)
├── PYAS_Interface.py ----------> PyQt5 Interface (use QT designer, must be matched with the main program)
├── PYAS_Resource.py -----------> PyQt5 Resource (status pictures, icon packages, button icons, ...)
├── PYAS_Language.py -----------> Translate Dict (Traditional Chinese, Simplified Chinese, English)
├── PYAS_Version.py ------------> Pyinstaller (file information, version information, original name, ...)
└── ...
```
## Requirements
Use pip install requirements to install import module
```
psutil==5.9.5
pefile==2023.2.7
requests==2.31.0
pyperclip==1.8.2
pywin32==306
PyQt5==5.15.9
```
## Pefile Scanning
Get the pefile file function import table for scanning
```
import pefile
def pe_scan(file):
try:
fn = []
with pefile.PE(file) as pe:
for entry in pe.DIRECTORY_ENTRY_IMPORT:
for func in entry.imports:
try:
fn.append(str(func.name, "utf-8"))
except:
pass
if fn in known_malicious_list:
return "Virus"
return "Safe"
return "Unknown"
except Exception as e:
return f"Error: {e}"
info = pe_scan("path to file")
print(info)
```
## Process Detect
Show the new process name, file path, cmd line, pid
```
import psutil, time
def proc_detect():
existing_process = set()
for p in psutil.process_iter():
existing_process.add(p.pid)
while True:
time.sleep(0.1)
new_process = set()
for p in psutil.process_iter():
new_process.add(p.pid)
for pid in new_process - existing_process:
try:
p = psutil.Process(pid)
name, file, cmd = p.name(), p.exe(), p.cmdline()
print(f"Name: {name}")
print(f"File: {file}")
print(f"Pid: {p.pid}")
print(f"Cmd: {cmd}")
except Exception as e:
print(f"Error: {e}")
existing_process = new_process
proc_detect()
```
## File Detect
Monitor file changes under the specified path
```
import os, win32file, win32con
def file_detect(path):
hDir = win32file.CreateFile(path,win32con.GENERIC_READ,win32con.FILE_SHARE_READ|win32con.FILE_SHARE_WRITE|win32con.FILE_SHARE_DELETE,None,win32con.OPEN_EXISTING,win32con.FILE_FLAG_BACKUP_SEMANTICS,None)
while True:
for action, file in win32file.ReadDirectoryChangesW(hDir,10485760,True,win32con.FILE_NOTIFY_CHANGE_FILE_NAME|win32con.FILE_NOTIFY_CHANGE_DIR_NAME|win32con.FILE_NOTIFY_CHANGE_ATTRIBUTES|win32con.FILE_NOTIFY_CHANGE_SIZE|win32con.FILE_NOTIFY_CHANGE_LAST_WRITE|win32con.FILE_NOTIFY_CHANGE_SECURITY,None,None):
try:
fpath = os.path.join(path, file)
if action == 1:
print(f"File Create: {fpath}")
elif action == 2:
print(f"File Delete: {fpath}")
elif action == 3:
print(f"File Modify: {fpath}")
elif action == 4:
print(f"File Rename: {fpath}")
elif action == 5:
print(f"File Rename: {fpath}")
except:
pass
file_detect("path")
```
## Official Website
https://pyantivirus.wixsite.com/pyas
https://github.com/87owo/PYAS
## Microsoft Runtime
https://github.com/87owo/Microsoft_Runtime/releases
## PYAS Driver
https://github.com/0sha0/PYAS_Protection
+33 -129
View File
@@ -1,163 +1,67 @@
# PYAS (Python 杀毒软件)
![PYAS](https://github.com/87owo/PYAS/assets/85057800/8136aaca-d388-4321-bedb-abc4fcecfa8b)
![PYAS](https://github.com/user-attachments/assets/39c273b9-c467-480a-a8b3-31714a6df3ef)
## 安装要求
```
pip install psutil==5.9.5
pip install pefile==2023.2.7
pip install requests==2.31.0
pip install pyperclip==1.8.2
pip install pywin32==306
pip install PyQt5==5.15.9
pip install yara-python==4.5.1
pip install numpy==2.1.1
pip install onnxruntime==1.18.1
pip install pillow==10.4.0
```
## 文件信息
PYAS.py -> PYAS主程式(包括动画、扫描、保护功能等)
PYAS_Engine.py -> 转换资料库(用于相互转换资料库字典和清单)
PYAS_Extension.py -> 副文件名(包括扫描文件副文件名和常用副文件名)
PYAS_Model.* -> 病毒库(病毒库必须放在同一目录下)
PYAS_Interface.py -> PyQt5界面(由QT设计师设计,必须与主程式相符)
PYAS_Resource.py -> PyQt5资源(状态图片、图示包、按钮图示等)
PYAS_Language.py -> 翻译字典(繁体中文、简体中文、英文)
PYAS_Version.py -> Pyinstaller资讯(文件资讯、版本资讯、原名等)
## 目录信息
```
PYAS/
├── Driver/
│ ├── PYAS_Driver.sys
│ ├── PYAS_Driver.sys -------> 驱动程序 (0sha0 为 pyas 提供的自我保护驱动程序)
│ └── ...
│
├── Model/
│ ├── PYAS_Model.json
│ ├── PYAS_Model.txt
│ ├── PYAS_Model.json -------> 病毒数据库 (数据库必须位于指定目录中)
│ └── ...
│
├── Rules/
│ ├── Yara_Rules.yar
│ ├── Compile_Rules.yrc
│ ├── Yara_Rules.yar ---------> Yara 规则 (纯文本格式的 yara 规则)
│ ├── Yara_Rules.yrc ---------> 编译规则 (编译格式的 yara 规则)
│ └── ...
│
├── PYAS.py
├── PYAS_Engine.py
├── PYAS.py ---------------------> PYAS主程序(包含动画、扫描、保护等功能...)
├── PYAS_Engine.py -------------> 转换数据库(用于转换剖面图和预报数据)
├── PYAS_Suffixes.py -----------> 文件后缀(包含扫描文件后缀和常用后缀)
├── PYAS_Interface.py ----------> PyQt5界面(使用QT设计器,需与主程序搭配使用)
├── PYAS_Resource.py -----------> PyQt5资源(状态图片、图标包、按钮图标...)
├── PYAS_Language.py -----------> 翻译词典(繁体中文、简体中文、英文)
├── PYAS_Version.py ------------> 安裝信息(文件信息、版本信息、原名...)
└── ...
```
## 安装要求
使用 pip install requirements 来安装需要的模组
```
psutil==5.9.5
pefile==2023.2.7
requests==2.31.0
pyperclip==1.8.2
pywin32==306
PyQt5==5.15.9
```
## 文件扫描
取得pefile文件函数导入表进行扫描
```
import pefile
def pe_scan(file):
try:
fn = []
with pefile.PE(file) as pe:
for entry in pe.DIRECTORY_ENTRY_IMPORT:
for func in entry.imports:
try:
fn.append(str(func.name, "utf-8"))
except:
pass
if fn in known_malicious_list:
return "Virus"
return "Safe"
return "Unknown"
except Exception as e:
return f"Error: {e}"
info = pe_scan("path to file")
print(info)
```
## 进程监控
显示新进程名称、文件路径、cmd 行、pid
```
import psutil, time
def proc_detect():
existing_process = set()
for p in psutil.process_iter():
existing_process.add(p.pid)
while True:
time.sleep(0.1)
new_process = set()
for p in psutil.process_iter():
new_process.add(p.pid)
for pid in new_process - existing_process:
try:
p = psutil.Process(pid)
name, file, cmd = p.name(), p.exe(), p.cmdline()
print(f"Name: {name}")
print(f"File: {file}")
print(f"Pid: {p.pid}")
print(f"Cmd: {cmd}")
except Exception as e:
print(f"Error: {e}")
existing_process = new_process
proc_detect()
```
## 文件监控
监控指定路径下的文件变化
```
import os, win32file, win32con
def file_detect(path):
hDir = win32file.CreateFile(path,win32con.GENERIC_READ,win32con.FILE_SHARE_READ|win32con.FILE_SHARE_WRITE|win32con.FILE_SHARE_DELETE,None,win32con.OPEN_EXISTING,win32con.FILE_FLAG_BACKUP_SEMANTICS,None)
while True:
for action, file in win32file.ReadDirectoryChangesW(hDir,10485760,True,win32con.FILE_NOTIFY_CHANGE_FILE_NAME|win32con.FILE_NOTIFY_CHANGE_DIR_NAME|win32con.FILE_NOTIFY_CHANGE_ATTRIBUTES|win32con.FILE_NOTIFY_CHANGE_SIZE|win32con.FILE_NOTIFY_CHANGE_LAST_WRITE|win32con.FILE_NOTIFY_CHANGE_SECURITY,None,None):
try:
fpath = os.path.join(path, file)
if action == 1:
print(f"File Create: {fpath}")
elif action == 2:
print(f"File Delete: {fpath}")
elif action == 3:
print(f"File Modify: {fpath}")
elif action == 4:
print(f"File Rename: {fpath}")
elif action == 5:
print(f"File Rename: {fpath}")
except:
pass
file_detect("path")
```
## 官方网页
https://pyantivirus.wixsite.com/pyas
https://github.com/87owo/PYAS
## 开源协议
## 微软运行库
https://github.com/87owo/PYAS/blob/main/LICENSE.md
https://github.com/87owo/Microsoft_Runtime/releases
## 驱动程序
https://github.com/0sha0/PYAS_Protection
## 开源协议
https://github.com/87owo/PYAS/blob/main/LICENSE.md
## 支援系统
Windows 8.1, 10, 11 (64-bit), 内存 500MB, 存储 200MB 或更高
+33 -127
View File
@@ -1,161 +1,67 @@
# PYAS (Python 防毒軟體)
![PYAS](https://github.com/87owo/PYAS/assets/85057800/8136aaca-d388-4321-bedb-abc4fcecfa8b)
![PYAS](https://github.com/user-attachments/assets/39c273b9-c467-480a-a8b3-31714a6df3ef)
## 安裝要求
```
pip install psutil==5.9.5
pip install pefile==2023.2.7
pip install requests==2.31.0
pip install pyperclip==1.8.2
pip install pywin32==306
pip install PyQt5==5.15.9
pip install yara-python==4.5.1
pip install numpy==2.1.1
pip install onnxruntime==1.18.1
pip install pillow==10.4.0
```
## 檔案資訊
PYAS.py -> PYAS主程式(包括動畫、掃描、保護功能等)
PYAS_Engine.py -> 轉換資料庫(用於相互轉換資料庫字典和清單)
PYAS_Extension.py -> 檔案副檔名(包括掃描檔案副檔名和常用檔案副檔名)
PYAS_Model.* -> 病毒庫(病毒庫必須放在同一目錄下)
PYAS_Interface.py -> PyQt5 Interface(由QT設計師設計,必須與主程式相符)
PYAS_Resource.py -> PyQt5資源(狀態圖片、圖示包、按鈕圖示等)
PYAS_Language.py -> 翻譯字典(繁體中文、簡體中文、英文)
PYAS_Version.py -> Pyinstaller Info(檔案資訊、版本資訊、原名等)
## 目錄資訊
```
PYAS/
├── Driver/
│ ├── PYAS_Driver.sys
│ ├── PYAS_Driver.sys -------> 驅動程式 (0sha0 為 pyas 提供的自我保護驅動程式)
│ └── ...
│
├── Model/
│ ├── PYAS_Model.json
│ ├── PYAS_Model.txt
│ ├── PYAS_Model.json -------> 病毒資料庫 (資料庫必須位於指定目錄)
│ └── ...
│
├── Rules/
│ ├── Yara_Rules.yar
│ ├── Compile_Rules.yrc
│ ├── Yara_Rules.yar ---------> Yara 規則 (純文字格式的 yara 規則)
│ ├── Yara_Rules.yrc ---------> 編譯規則 (編譯格式的 yara 規則)
│ └── ...
│
├── PYAS.py
├── PYAS_Engine.py
├── PYAS.py ---------------------> PYAS主程式(包含動畫、掃描、保護等功能...)
├── PYAS_Engine.py -------------> 轉換資料庫(用於轉換剖面圖和預報資料)
├── PYAS_Suffixes.py -----------> 文件後綴(包含掃描文件後綴和常用後綴)
├── PYAS_Interface.py ----------> PyQt5介面(使用QT設計器,需與主程式搭配使用)
├── PYAS_Resource.py -----------> PyQt5資源(狀態圖片、圖示包、按鈕圖示...)
├── PYAS_Language.py -----------> 翻譯字典(繁體中文、簡體中文、英文)
├── PYAS_Version.py ------------> 安裝資訊(檔案資訊、版本資訊、原名...)
└── ...
```
## 安裝要求
使用 pip install requirements 來安裝需要的模組
```
psutil==5.9.5
pefile==2023.2.7
requests==2.31.0
pyperclip==1.8.2
pywin32==306
PyQt5==5.15.9
```
## 檔案掃描
取得pefile檔案函數導入表進行掃描
```
import pefile
def pe_scan(file):
try:
fn = []
with pefile.PE(file) as pe:
for entry in pe.DIRECTORY_ENTRY_IMPORT:
for func in entry.imports:
try:
fn.append(str(func.name, "utf-8"))
except:
pass
if fn in known_malicious_list:
return "Virus"
return "Safe"
return "Unknown"
except Exception as e:
return f"Error: {e}"
info = pe_scan("path to file")
print(info)
```
## 進程監控
顯示新進程名稱、檔案路徑、cmd 行、pid
```
import psutil, time
def proc_detect():
existing_process = set()
for p in psutil.process_iter():
existing_process.add(p.pid)
while True:
time.sleep(0.1)
new_process = set()
for p in psutil.process_iter():
new_process.add(p.pid)
for pid in new_process - existing_process:
try:
p = psutil.Process(pid)
name, file, cmd = p.name(), p.exe(), p.cmdline()
print(f"Name: {name}")
print(f"File: {file}")
print(f"Pid: {p.pid}")
print(f"Cmd: {cmd}")
except Exception as e:
print(f"Error: {e}")
existing_process = new_process
proc_detect()
```
## 檔案監控
監控指定路徑下的檔案變化
```
import os, win32file, win32con
def file_detect(path):
hDir = win32file.CreateFile(path,win32con.GENERIC_READ,win32con.FILE_SHARE_READ|win32con.FILE_SHARE_WRITE|win32con.FILE_SHARE_DELETE,None,win32con.OPEN_EXISTING,win32con.FILE_FLAG_BACKUP_SEMANTICS,None)
while True:
for action, file in win32file.ReadDirectoryChangesW(hDir,10485760,True,win32con.FILE_NOTIFY_CHANGE_FILE_NAME|win32con.FILE_NOTIFY_CHANGE_DIR_NAME|win32con.FILE_NOTIFY_CHANGE_ATTRIBUTES|win32con.FILE_NOTIFY_CHANGE_SIZE|win32con.FILE_NOTIFY_CHANGE_LAST_WRITE|win32con.FILE_NOTIFY_CHANGE_SECURITY,None,None):
try:
fpath = os.path.join(path, file)
if action == 1:
print(f"File Create: {fpath}")
elif action == 2:
print(f"File Delete: {fpath}")
elif action == 3:
print(f"File Modify: {fpath}")
elif action == 4:
print(f"File Rename: {fpath}")
elif action == 5:
print(f"File Rename: {fpath}")
except:
pass
file_detect("path")
```
## 官方網頁
https://pyantivirus.wixsite.com/pyas
https://github.com/87owo/PYAS
## 開源協議
## 微軟運行庫
https://github.com/87owo/PYAS/blob/main/LICENSE.md
https://github.com/87owo/Microsoft_Runtime/releases
## 驅動程式
https://github.com/0sha0/PYAS_Protection
## 開源協議
https://github.com/87owo/PYAS/blob/main/LICENSE.md
## 支援系統
Windows 8.1, 10, 11 (64-bit),記憶體 500MB, 磁碟容量 200MB 或更高
+256387
View File
File diff suppressed because it is too large. Load diff