Compare commits

..
51 Commits
Author SHA1 Message Date
PYDT f4d032e5c7 Add files via upload 2024-02-25 02:17:22 +08:00
PYDT 4114aac6c3 Add files via upload 2024-02-25 01:45:23 +08:00
PYDT 0c43c6bb5f Add files via upload 2024-02-24 23:43:10 +08:00
PYDT 7b3c965b88 Add files via upload 2024-02-24 21:55:53 +08:00
PYDT 02a8de4696 Add files via upload 2024-02-23 08:38:55 +08:00
PYDT 22fa3eff71 Add files via upload 2024-02-22 14:32:17 +08:00
PYDT 69361209c3 Add files via upload 2024-02-22 01:08:15 +08:00
PYDT ff0aeaa4ef Add files via upload 2024-02-21 10:21:38 +08:00
PYDT 3c461dfd4b Add files via upload 2024-02-21 10:13:11 +08:00
PYDT c6beda383e Add files via upload 2024-02-21 07:10:15 +08:00
PYDT 3d59f3befd Add files via upload 2024-02-21 00:42:59 +08:00
PYDT e54f0db239 Update README.md 2024-02-20 14:41:04 +08:00
PYDT 0f877f2749 Delete PYAS_Function.vdb 2024-02-20 14:02:47 +08:00
PYDT b69ba165d9 Add files via upload 2024-02-20 14:02:37 +08:00
PYDT 965076fe52 Delete PYAS_Compress.py 2024-02-20 13:43:32 +08:00
PYDT f4d6cb0430 Add files via upload 2024-02-19 10:39:21 +08:00
PYDT 19d412188c Add files via upload 2024-02-19 10:38:19 +08:00
PYDT 798d85978a Add files via upload 2024-02-11 19:53:57 +08:00
PYDT 819742d753 Add files via upload 2024-02-11 16:12:59 +08:00
PYDT 9b32fa6219 Add files via upload 2024-02-11 10:56:55 +08:00
PYDT 2c93661726 Add files via upload 2024-02-10 23:02:45 +08:00
PYDT bddaca2a1e Add files via upload 2024-02-10 22:08:39 +08:00
PYDT 2f06f2e051 Add files via upload 2024-02-10 20:52:38 +08:00
PYDT 1d26e46bd9 Add files via upload 2024-02-10 20:01:52 +08:00
PYDT fa0ff826a3 Add files via upload 2024-02-10 19:50:01 +08:00
PYDT e1b3114c83 Add files via upload 2024-02-10 19:41:34 +08:00
PYDT a655f075db Add files via upload 2024-02-10 19:40:54 +08:00
PYDT 13d4ebbf6b Add files via upload 2024-02-09 14:24:52 +08:00
PYDT 913d10b1ee Add files via upload 2024-02-09 14:18:30 +08:00
PYDT eb541a0104 Add files via upload 2024-01-30 19:03:05 +08:00
PYDT 2063186994 Add files via upload 2024-01-28 16:20:22 +08:00
PYDT 860d571039 Delete PYAS_Function.py 2024-01-28 15:41:03 +08:00
PYDT c6d79adf9a Add files via upload 2024-01-28 15:40:44 +08:00
PYDT 5453900ba1 Add files via upload 2024-01-28 03:29:28 +08:00
PYDT 5029ff1e37 Add files via upload 2024-01-28 03:13:40 +08:00
PYDT 47fb691339 Add files via upload 2024-01-28 03:12:42 +08:00
PYDT dff9dd17bf Add files via upload 2024-01-27 11:58:36 +08:00
PYDT 5bc4a16b90 Add files via upload 2024-01-26 10:14:32 +08:00
PYDT b1918953b0 Update README.md 2024-01-26 09:35:36 +08:00
PYDT 6e89ed7007 Add files via upload 2024-01-26 09:33:16 +08:00
PYDT 744e8bc941 Add files via upload 2024-01-25 20:21:35 +08:00
PYDT 0b98ce7ffd Add files via upload 2024-01-25 20:19:27 +08:00
PYDT ca8b293b06 Delete PYAS_Function.zip 2024-01-25 18:10:50 +08:00
PYDT e28d99a257 Add files via upload 2024-01-25 18:09:58 +08:00
PYDT 488feb6108 Add files via upload 2024-01-25 16:12:47 +08:00
PYDT 6cdb106f07 Add files via upload 2024-01-24 22:58:36 +08:00
PYDT a7c5ccd27a Add files via upload 2024-01-24 22:56:15 +08:00
PYDT 136f9dbf0a Add files via upload 2024-01-24 22:47:40 +08:00
PYDT 16b45c3450 Add files via upload 2024-01-24 15:13:42 +08:00
PYDT 68330fad52 Add files via upload 2024-01-24 12:57:03 +08:00
PYDT dca167518d Add files via upload 2024-01-24 12:18:50 +08:00
9 changed files with 240 additions and 124 deletions

No files matched your search

+145 -82
View File
@@ -3,9 +3,8 @@ import hashlib, pefile, socket, msvcrt
import xml.etree.ElementTree as xmlet
import requests, pyperclip, win32file
import win32gui, win32api, win32con
from PYAS_Function import model_dict
from PYAS_Engine import ListSimHash
from PYAS_Extension import slist, alist
from PYAS_Compress import ListCompressor
from PYAS_Language import translate_dict
from PYAS_Interface import Ui_MainWindow
from threading import Thread
@@ -18,9 +17,10 @@ class MainWindow_Controller(QMainWindow):
super(MainWindow_Controller, self).__init__()
self.setAttribute(Qt.WA_TranslucentBackground)
self.setWindowFlags(Qt.FramelessWindowHint)
self.pyas = str(sys.argv[0]).replace("\\", "/")
self.pyae_version = "2024-01-23"
self.pyas_version = "3.0.1"
self.pyas = sys.argv[0].replace("\\", "/")
self.dir = os.path.dirname(self.pyas)
self.pyae_version = "SimHash Engine"
self.pyas_version = "3.0.5"
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.init_show_pyas()
@@ -36,10 +36,6 @@ class MainWindow_Controller(QMainWindow):
self.init_control()
self.init_threads()
def init_data_base(self):
self.pe = ListCompressor()
self.pe.load_model(model_dict)
def init_threads(self):
self.protect_proc_init()
self.protect_file_init()
@@ -54,6 +50,15 @@ class MainWindow_Controller(QMainWindow):
self.tray_icon.activated.connect(self.init_show_pyas)
self.tray_icon.show()
def init_data_base(self):
try:
file_path = os.path.join(self.dir, "PYAS_Model.json")
if os.path.exists(file_path):
self.pe = ListSimHash()
self.pe.load_model(file_path)
except Exception as e:
self.bug_event(e)
def init_config_boot(self):
try:
with open(r"\\.\PhysicalDrive0", "r+b") as f:
@@ -583,7 +588,7 @@ class MainWindow_Controller(QMainWindow):
self.send_notify(self.trans("PYAS 已最小化到系統托盤圖標"))
def closeEvent(self, event):
if QMessageBox.warning(self,self.trans("警告"),self.trans("您確定要退出 PYAS 和所有防護嗎?"),QMessageBox.Yes|QMessageBox.No) == 16384:
if self.question_event("您確定要退出 PYAS 和所有防護嗎?"):
self.virus_scan_break()
event.accept()
else:
@@ -591,24 +596,57 @@ class MainWindow_Controller(QMainWindow):
def bug_event(self, text):
try:
print(f"[Error] {text}")
QMessageBox.critical(self,self.trans("錯誤"), text, QMessageBox.Ok)
print(f"[Error] > {text}")
QMessageBox.critical(self, "Error", str(text), QMessageBox.Ok)
except:
pass
def info_event(self, text):
try:
print(f"[Info] > {text}")
QMessageBox.information(self, "Info", self.trans(str(text)), QMessageBox.Ok)
except:
pass
def question_event(self, text):
try:
print(f"[Quest] > {text}")
return QMessageBox.question(self, "Quest", self.trans(str(text)),QMessageBox.Yes|QMessageBox.No) == 16384
except:
return False
def send_notify(self, text):
try:
now_time = time.strftime('%Y/%m/%d %H:%M:%S')
now_time = time.strftime('%Y-%m-%d %H:%M:%S')
print(f"[Notify] > [{now_time}] {text}")
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
def update_database(self):
try:
if self.question_event("您確定要更新數據庫嗎?"):
file_path = os.path.join(self.dir, "PYAS_Model.json")
response = requests.get('http://27.147.30.238:5001/model', params={"version": self.pyae_version}, timeout=10)
if response.status_code == 200:
with open(file_path, 'wb') as f:
f.write(response.content)
self.init_data_base()
self.init_lang_text()
self.info_event(f"數據庫更新成功: {self.pyae_version}")
elif response.status_code == 204:
self.info_event(f"數據庫已經是最新: {self.pyae_version}")
except Exception as e:
self.bug_event(e)
def show_menu(self):
self.WindowMenu = QMenu()
Main_Settings = QAction(self.trans("設定"),self)
#Main_Update = QAction(self.trans("更新"),self)
Main_About = QAction(self.trans("關於"),self)
self.WindowMenu.addAction(Main_Settings)
#self.WindowMenu.addAction(Main_Update)
self.WindowMenu.addAction(Main_About)
Qusetion = self.WindowMenu.exec_(self.ui.Menu_Button.mapToGlobal(QPoint(0, 30)))
if Qusetion == Main_About and self.ui.About_widget.isHidden():
@@ -626,6 +664,8 @@ class MainWindow_Controller(QMainWindow):
self.ui.Window_widget.raise_()
self.change_animation_3(self.ui.Setting_widget,0.5)
self.change_animation_5(self.ui.Setting_widget,10,50,831,481)
#if Qusetion == Main_Update:
#self.update_database()
def change_sensitive(self):
sw_state = self.ui.high_sensitivity_switch_Button.text()
@@ -635,7 +675,7 @@ class MainWindow_Controller(QMainWindow):
self.ui.high_sensitivity_switch_Button.setStyleSheet("""
QPushButton{border:none;background-color:rgb(230,230,230);border-radius: 10px;}
QPushButton:hover{background-color:rgb(220,220,220);}""")
elif QMessageBox.warning(self,self.trans("警告"),self.trans("此選項可能會誤報檔案,您確定要開啟嗎?"),QMessageBox.Yes|QMessageBox.No) == 16384:
elif self.question_event("此選項可能會誤報檔案,您確定要開啟嗎?"):
self.json["high_sensitive"] = 1
self.ui.high_sensitivity_switch_Button.setText(self.trans("已開啟"))
self.ui.high_sensitivity_switch_Button.setStyleSheet("""
@@ -665,7 +705,7 @@ class MainWindow_Controller(QMainWindow):
QApplication.processEvents()
try:
for file in self.virus_list:
self.unlock_file(file)
self.lock_file(file, False)
except:
pass
self.scan_file = True
@@ -692,17 +732,14 @@ class MainWindow_Controller(QMainWindow):
copyPath.triggered.connect(lambda: copyPathFunc())
menu.exec_(self.ui.Virus_Scan_output.mapToGlobal(point))
def lock_file(self, file):
def lock_file(self, file, lock):
try:
self.virus_lock[file] = os.open(file, os.O_RDWR)
msvcrt.locking(self.virus_lock[file], msvcrt.LK_NBLCK, 0)
except:
pass
def unlock_file(self, file):
try:
msvcrt.locking(self.virus_lock[file], msvcrt.LK_UNLCK, 0)
os.close(self.virus_lock[file])
if lock:
self.virus_lock[file] = os.open(file, os.O_RDWR)
msvcrt.locking(self.virus_lock[file], msvcrt.LK_NBLCK, 0)
else:
msvcrt.locking(self.virus_lock[file], msvcrt.LK_UNLCK, 0)
os.close(self.virus_lock[file])
except:
pass
@@ -714,10 +751,10 @@ class MainWindow_Controller(QMainWindow):
if self.ui.Virus_Scan_output.findItems(file, Qt.MatchContains)[0].checkState() == Qt.Checked:
self.ui.Virus_Scan_text.setText(self.trans("正在刪除: ")+file)
QApplication.processEvents()
self.unlock_file(file)
self.lock_file(file, False)
os.remove(file)
else:
self.unlock_file(file)
self.lock_file(file, False)
except:
continue
self.virus_lock = {}
@@ -730,7 +767,7 @@ class MainWindow_Controller(QMainWindow):
def write_scan(self, state, file):
try:
self.lock_file(file)
self.lock_file(file, True)
self.virus_list.append(file)
self.virus_list_ui.append(f"[{state}] {file}")
item = QListWidgetItem()
@@ -825,8 +862,6 @@ class MainWindow_Controller(QMainWindow):
file = str(os.path.join(path,fd)).replace("\\", "/")
if self.scan_file == False:
break
elif ":/Windows" in file:
continue
elif os.path.isdir(file):
self.traverse_path(file)
elif file not in self.whitelist:
@@ -842,9 +877,8 @@ class MainWindow_Controller(QMainWindow):
if self.json["cloud_services"] == 1:
with open(file, "rb") as f:
text = str(hashlib.md5(f.read()).hexdigest())
QApplication.processEvents()
strBody = f'-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="md5s"\r\n\r\n{text}\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="format"\r\n\r\nXML\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="product"\r\n\r\n360zip\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="combo"\r\n\r\n360zip_main\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="v"\r\n\r\n2\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="osver"\r\n\r\n5.1\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="vk"\r\n\r\na03bc211\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="mid"\r\n\r\n8a40d9eff408a78fe9ec10a0e7e60f62\r\n-------------------------------7d83e2d7a141e--'
response = requests.post('http://qup.f.360.cn/file_health_info.php', data=strBody, timeout=3)
response = requests.post('http://qup.f.360.cn/file_health_info.php', data=strBody, timeout=5)
return response.status_code == 200 and float(xmlet.fromstring(response.text).find('.//e_level').text) > 50
return False
except:
@@ -867,17 +901,17 @@ class MainWindow_Controller(QMainWindow):
fn.append(str(func.name, "utf-8"))
except:
pass
m1, m0 = self.pe.predict(fn)
#print(m1, m0, file)
if self.json["high_sensitive"]:
return self.pe.predict(fn)
elif "_CorExeMain" not in fn:
return self.pe.predict(fn)
return False
return m1 >= m0
return m1 > 0.95 and m1 > m0
except:
return False
def proc_scan(self, pid):
def proc_scan(self, p):
try:
for entry in psutil.Process(pid).memory_maps():
for entry in psutil.Process(p.pid).memory_maps():
file = entry.path.replace("\\", "/")
if ":/Windows" not in file and ":/Program" not in file:
if self.api_scan(file) or self.pe_scan(file):
@@ -888,13 +922,13 @@ class MainWindow_Controller(QMainWindow):
def repair_system(self):
try:
if QMessageBox.warning(self,self.trans("警告"),self.trans("您確定要修復系統檔案嗎?"),QMessageBox.Yes|QMessageBox.No) == 16384:
if self.question_event("您確定要修復系統檔案嗎?"):
self.repair_system_wallpaper()
self.repair_system_restrict()
self.repair_system_file_type()
self.repair_system_file_icon()
self.repair_system_image()
QMessageBox.information(self,self.trans("成功"),self.trans("修復系統檔案成功"),QMessageBox.Ok)
self.info_event("修復系統檔案成功")
except Exception as e:
self.bug_event(e)
@@ -987,7 +1021,7 @@ class MainWindow_Controller(QMainWindow):
for i in Permission:
try:
win32api.RegDeleteValue(key,i)
self.proc.kill()
self.kill_process(self.proc)
file = self.proc.exe().replace("\\", "/")
self.send_notify(self.trans("惡意行為攔截: ")+file)
except:
@@ -1007,12 +1041,12 @@ class MainWindow_Controller(QMainWindow):
def clean_system(self):
try:
if QMessageBox.warning(self,self.trans("警告"),self.trans("您確定要清理系統垃圾嗎?"),QMessageBox.Yes|QMessageBox.No) == 16384:
if self.question_event("您確定要清理系統垃圾嗎?"):
self.total_deleted_size = 0
self.traverse_temp(f"C:/Users/{os.getlogin()}/AppData/Local/Temp/")
self.traverse_temp(f"C:/Windows/Temp/")
self.traverse_temp(f"C:/$Recycle.Bin/")
QMessageBox.information(self,self.trans("成功"),self.trans(f"成功清理了 {self.total_deleted_size} 位元的系統垃圾"),QMessageBox.Ok)
self.info_event(f"成功清理了 {self.total_deleted_size} 位元的系統垃圾")
except Exception as e:
self.bug_event(e)
@@ -1034,44 +1068,44 @@ class MainWindow_Controller(QMainWindow):
try:
file = str(QFileDialog.getOpenFileName(self,self.trans("增加到白名單"),"C:/")[0]).replace("\\", "/")
if file and file not in self.whitelist:
if QMessageBox.warning(self,self.trans("警告"),self.trans("您確定要增加到白名單嗎?"),QMessageBox.Yes|QMessageBox.No) == 16384:
if self.question_event("您確定要增加到白名單嗎?"):
self.whitelist.append(file)
with open("C:/ProgramData/PYAS/Whitelist.ini", "a+") as f:
f.write(f"{file}\n")
QMessageBox.information(self,self.trans("成功"),self.trans(f"成功增加到白名單: ")+file,QMessageBox.Ok)
elif file and QMessageBox.warning(self,self.trans("警告"),self.trans("您確定要取消增加到白名單嗎?"),QMessageBox.Yes|QMessageBox.No) == 16384:
self.info_event(f"成功增加到白名單: "+file)
elif file and self.question_event("您確定要取消增加到白名單嗎?"):
self.whitelist.remove(file)
with open("C:/ProgramData/PYAS/Whitelist.ini", "w") as f:
for white_file in self.whitelist:
f.write(f'{white_file}\n')
QMessageBox.information(self,self.trans("成功"),self.trans(f"成功取消增加到白名單: ")+file,QMessageBox.Ok)
self.info_event(f"成功取消增加到白名單: "+file)
except Exception as e:
self.bug_event(e)
def get_software_window(self):
try:
self.block_window = False
if QMessageBox.warning(self,self.trans("警告"),self.trans("請選擇要攔截的軟體彈窗"),QMessageBox.Yes|QMessageBox.No) == 16384:
if self.question_event("請選擇要攔截的軟體彈窗"):
while not self.block_window:
window_name = str(win32gui.GetWindowText(win32gui.GetForegroundWindow()))
QApplication.processEvents()
if window_name not in ["","PYAS",self.trans("警告")]:
if window_name not in self.blocklist:
if QMessageBox.warning(self,self.trans("警告"),self.trans(f"您確定要攔截 {window_name} 嗎?"),QMessageBox.Yes|QMessageBox.No) == 16384:
if self.question_event(f"您確定要攔截 {window_name} 嗎?"):
self.blocklist.append(window_name)
with open("C:/ProgramData/PYAS/Blocklist.ini", "a+") as f:
f.write(f'{window_name}\n')
QMessageBox.information(self,self.trans("成功"),self.trans(f"成功增加到彈窗攔截: ")+window_name,QMessageBox.Ok)
elif QMessageBox.warning(self,self.trans("警告"),self.trans(f"您確定要取消攔截 {window_name} 嗎?"),QMessageBox.Yes|QMessageBox.No) == 16384:
self.info_event(f"成功增加到彈窗攔截: "+window_name)
elif self.question_event(f"您確定要取消攔截 {window_name} 嗎?"):
self.blocklist.remove(window_name)
with open("C:/ProgramData/PYAS/Blocklist.ini", "w") as f:
for block_name in self.blocklist:
f.write(f'{block_name}\n')
QMessageBox.information(self,self.trans("成功"),self.trans(f"成功取消彈窗攔截: ")+window_name,QMessageBox.Ok)
self.info_event(f"成功取消彈窗攔截: "+window_name)
self.block_window = True
self.block_window_init()
except Exception as e:
self.bug_event(e)
self.bug_event(e)
def block_window_init(self):
self.block_window = True
@@ -1080,7 +1114,7 @@ class MainWindow_Controller(QMainWindow):
def block_software_window(self):
while self.block_window:
try:
time.sleep(0.5)
time.sleep(0.2)
for window_name in self.blocklist:
win32gui.PostMessage(win32gui.FindWindow(None, window_name), 274, 61536, 0)
except:
@@ -1088,9 +1122,9 @@ class MainWindow_Controller(QMainWindow):
def repair_network(self):
try:
if QMessageBox.warning(self,self.trans("警告"),self.trans("您確定要修復系統網路嗎?"),QMessageBox.Yes|QMessageBox.No) == 16384:
if self.question_event("您確定要修復系統網路嗎?"):
os.system("netsh winsock reset")
if QMessageBox.warning(self,self.trans("警告"),self.trans("使用此選項需要重啟,您確定要重啟嗎?"),QMessageBox.Yes|QMessageBox.No) == 16384:
if self.question_event("使用此選項需要重啟,您確定要重啟嗎?"):
os.system("shutdown -r -t 0")
except Exception as e:
self.bug_event(e)
@@ -1129,7 +1163,11 @@ class MainWindow_Controller(QMainWindow):
if self.Process_popMenu.exec_(self.ui.Process_list.mapToGlobal(pos)) == self.kill_Process:
for p in psutil.process_iter():
if p.pid == self.pid:
p.kill()
file = p.exe().replace("\\", "/")
if file == self.pyas:
self.close()
else:
p.kill()
except:
pass
@@ -1211,66 +1249,91 @@ class MainWindow_Controller(QMainWindow):
def protect_proc_thread(self):
existing_processes = set()
for p in psutil.process_iter():
if p.pid not in existing_processes:
existing_processes.add(p.pid)
existing_processes.add(p.pid)
psutil.Process(os.getpid()).nice(256)
while self.proc_protect:
time.sleep(0.05)
time.sleep(0.01)
for p in psutil.process_iter():
try:
if p.pid not in existing_processes:
existing_processes.add(p.pid)
name, file, cmd = p.name(), p.exe().replace("\\", "/"), p.cmdline()
if file != self.pyas and file not in self.whitelist:
psutil.Process(p.pid).suspend()
self.lock_process(p, True)
if "powershell" in name and self.api_scan(cmd[-1].split("'")[-2]):
p.kill()
self.kill_process(p)
file = cmd[-1].split("'")[-2].replace("\\", "/")
self.send_notify(self.trans("惡意腳本攔截: ")+file)
elif "cmd.exe" in name and self.api_scan(" ".join(cmd[2:])):
p.kill()
self.kill_process(p)
file = " ".join(cmd[2:]).replace("\\", "/")
self.send_notify(self.trans("惡意腳本攔截: ")+file)
elif ":/Windows" in file and self.api_scan(cmd[-1]):
p.kill()
self.kill_process(p)
file = cmd[-1].replace("\\", "/")
self.send_notify(self.trans("惡意軟體攔截: ")+file)
elif ":/Windows" not in file and self.proc_scan(p.pid):
p.kill()
elif ":/Windows" not in file and self.proc_scan(p):
self.kill_process(p)
self.send_notify(self.trans("惡意軟體攔截: ")+file)
elif ":/Windows" not in file and self.sign_scan(file):
self.proc = p
psutil.Process(p.pid).resume()
gc.collect()
self.lock_process(p, False)
existing_processes.add(p.pid)
elif not psutil.pid_exists(p.pid):
existing_processes.remove(p.pid)
except:
pass
self.lock_process(p, False)
def lock_process(self, p, lock):
try:
if lock:
psutil.Process(p.pid).suspend()
else:
psutil.Process(p.pid).resume()
except:
pass
def kill_process(self, parent):
try:
parent.kill()
for child in parent.children(recursive=True):
child.kill()
except:
pass
def protect_file_thread(self):
hDir = win32file.CreateFile("C:/Users/",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)
hDir = win32file.CreateFile("C:/",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 self.file_protect:
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 = str(f"C:/Users/{file}").replace("\\", "/")
fpath = str(f"C:/{file}").replace("\\", "/")
ftype = str(f".{fpath.split('.')[-1]}").lower()
if action == 3 and ftype in slist and os.path.getsize(fpath) <= 20971520:
if self.api_scan(fpath) or self.pe_scan(fpath):
os.remove(fpath)
self.send_notify(self.trans("惡意軟體刪除: ")+fpath)
if action == 2 and ":/Users" in fpath and "/AppData/" not in fpath:
if ftype in alist:
self.kill_process(self.proc)
file = self.proc.exe().replace("\\", "/")
self.send_notify(self.trans("勒索行為攔截: ")+file)
elif action == 3 and os.path.getsize(fpath) <= 20971520 and ftype in slist:
if ":/Users" in fpath or ":/Windows" not in fpath:
if self.api_scan(fpath) or self.pe_scan(fpath):
os.remove(fpath)
self.send_notify(self.trans("惡意軟體刪除: ")+fpath)
gc.collect()
except:
pass
def protect_boot_thread(self):
while self.mbr_protect and self.mbr_value:
try:
time.sleep(0.5)
time.sleep(0.2)
with open(r"\\.\PhysicalDrive0", "r+b") as f:
if self.mbr_value[510:512] != b'\x55\xAA':
self.proc.kill()
self.kill_process(self.proc)
file = self.proc.exe().replace("\\", "/")
self.send_notify(self.trans("惡意行為攔截: ")+file)
elif f.read(512) != self.mbr_value:
f.seek(0)
f.write(self.mbr_value)
self.proc.kill()
self.kill_process(self.proc)
file = self.proc.exe().replace("\\", "/")
self.send_notify(self.trans("惡意行為攔截: ")+file)
except:
@@ -1279,7 +1342,7 @@ class MainWindow_Controller(QMainWindow):
def protect_reg_thread(self):
while self.reg_protect:
try:
time.sleep(0.5)
time.sleep(0.2)
self.repair_system_image()
self.repair_system_restrict()
self.repair_system_file_type()
@@ -1290,13 +1353,13 @@ class MainWindow_Controller(QMainWindow):
def protect_net_thread(self):
while self.net_protect:
try:
time.sleep(0.5)
time.sleep(0.2)
local = socket.gethostbyname(socket.gethostname())
for conn in self.proc.connections():
file = self.proc.exe().replace("\\", "/")
if ":/Windows" not in file and ":/Program" not in file:
if conn.laddr.ip == local:
self.proc.kill()
self.kill_process(self.proc)
self.send_notify(self.trans("網路通訊攔截: ")+file)
except:
pass
-31
View File
@@ -1,31 +0,0 @@
import json
class ListCompressor:
def __init__(self):
self.model = {}
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_model(self, model_data):
if isinstance(model_data, str):
with open(model_data, 'r') as f:
model_data = json.load(f)
self.model['word'] = model_data['word']
self.model.update(model_data)
def train_model(self, label, data):
if label not in self.model:
self.model[label] = []
unique_words = set([item for sublist in data for item in sublist])
self.model['word'] = {word: idx for idx, word in enumerate(unique_words)}
self.model[label].extend([[self.model['word'][item] for item in lst] for lst in data])
def predict(self, new_list):
new_list = [self.model['word'].get(item, 1) for item in new_list if item in self.model['word']]
for label, items in self.model.items():
if label != 'word' and new_list in items:
return label
return None
+83
View File
@@ -0,0 +1,83 @@
import re, time, json, hashlib, numpy
from itertools import groupby
class ListSimHash:
def __init__(self):
self.model = {}
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_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 get_model(self, label):
return self.model[label]
def train_model(self, ones, zero, feature=128, batch_size=1000):
self.model["ones"] = []
self.model["zero"] = []
self.model["feature"] = feature
self.model["batch_size"] = batch_size
start = time.time()
print("Convert ones")
for i, x in enumerate(ones, 1):
self.model["ones"].append(self.build_text(x))
used = "{0:.2f}".format(time.time()-start)
self.progress_bar(i, len(ones), prefix=f'{i}/{len(ones)}:', suffix=f'{used}s')
start = time.time()
print("Convert zero")
for i, y in enumerate(zero, 1):
self.model["zero"].append(self.build_text(y))
used = "{0:.2f}".format(time.time()-start)
self.progress_bar(i, len(zero), prefix=f'{i}/{len(zero)}:', suffix=f'{used}s')
def build_text(self, content, width=4):
sums, batch, count = [], [], 0
if isinstance(content, list):
content = ' '.join(content)
elif isinstance(content, bytes):
content = content.decode('utf-8', errors='ignore')
content = ''.join(re.findall(r'[\w\u4e00-\u9fcc]+', content.lower()))
features = [content[i:i + width] for i in range(max(len(content) - width + 1, 1))]
features = {k: sum(1 for _ in g) for k, g in groupby(sorted(features))}
for f, w in features.items():
count += w
h = hashlib.md5(f.encode('utf-8')).digest()
batch.append(h * w)
if len(batch) >= self.model["batch_size"]:
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 sum_hashes(self, digests):
bitarray = numpy.unpackbits(numpy.frombuffer(b''.join(digests), dtype='>B'))
return numpy.sum(numpy.reshape(bitarray, (-1, self.model["feature"])), 0)
def progress_bar(self, iteration, total, prefix='', suffix='', length=50, fill='█'):
percent = min(100.0, max(0.0, 100 * (iteration / float(total))))
end_char = '\n' if percent >= 100 else '\r'
percent_string = "{0:.2f}".format(percent)
filled_length = int(length * iteration // total)
bar = fill * filled_length + ' ' * (length - filled_length)
print(f'\r {prefix: <10} |{bar}| {percent_string}% {suffix}', end=end_char)
def predict(self, query):
query_hash = self.build_text(query)
max_ones = max(self.similar(x, query_hash) for x in self.model["ones"])
max_zero = max(self.similar(y, query_hash) for y in self.model["zero"])
return max_ones, max_zero
def similar(self, x, y):
hamming_distance = bin(x ^ y).count('1')
similarity = 1 - hamming_distance / self.model["feature"]
return similarity
+1 -2
View File
@@ -5,5 +5,4 @@ alist = [".ppt",".pptx",".wps",".txt",".rtf",
".pdf",".xls",".xlsx",".doc",".docx",
".jpg",".jpeg",".png",".webp",".gif",
".mp3",".wav",".aac",".ogg",".flac",
".mp4",".avi",".mov",".wmv",".mkv",
".zip",".7z",".rar",".tar",".gz"]
".mp4",".avi",".mov",".wmv",".mkv"]
BIN
View File
Binary file not shown.
+6 -6
View File
@@ -15,17 +15,17 @@ translate_dict = {
"詢":"询","製":"制","員":"员","許":"许","條":"条","藍":"蓝","紅":"红",
"綠":"绿","態":"态","務":"务","連":"连","檢":"检","測":"测","關":"关",
"強":"强","驅":"驱","為":"为","腳":"脚","增":"增","單":"单","開":"开",
"惡":"恶"},
"惡":"恶","據":"据","庫":"库","經":"经","敗":"败"},
"en_US": {"已開啟":"On","已關閉":"Off","已开启":"On","已关闭":"Off",",":", ",
"立即刪除":"Delete Now","安全模式":"Safe Mode","官方網站":"Website",
"惡意檔案":"Virus ","惡意軟體":"Malware ","勒索軟體":"Ransom ",
"惡意檔案":"Virus ","惡意軟體":"Malware ","勒索行為":"Ransom ",
"惡意腳本":"Script ","惡意行為":"Behavior ","可疑軟體":"Suspicious ",
"許可條款":"License Terms","惡意":"Malicious","可疑":"Suspicious",
"啟用":"Enable ","禁用":"Disable ","正在初始化中":"Initializing ",
"正在掃描":"Scanning ","正在刪除":"Deleting ","最小化到":"Minimize To ",
"確定要":"Sure Want To ","靈敏度":"Sensitivity ","更新":"Update",
"確定要":"Sure Want To ","靈敏度":"Sensitivity ","更新":"Update ",
"白色主題":"White","黃色主題":"Yellow","紅色主題":"Red","語言":"Language ",
"藍色主題":"Blue","綠色主題":"Green","自定主題":"Custom",
"藍色主題":"Blue","綠色主題":"Green","自定主題":"Custom","最新":"Latest ",
"測試人員":"Testers","版本資訊":"Information","通訊":"Communication ",
"註冊表":"Registry ","退出":"Quit ","檔案":"File ","當前":"Currently ",
"狀態":"State ","掃描":"Scan ","工具":"Tools ","防護":"Protect ",
@@ -47,8 +47,8 @@ translate_dict = {
"增加到":"Add File To ","白名單":"White List ","軟體":"Software ",
"增加":"Add","移除":"Delete","項目":"Items ","生成":"Create ","稱":"",
"複製":"Copy ","開啟":"Open ","此":"This ","並":"And ","全盤":"Full ",
"已經是":"Already ","數據庫":"Database ","誤報":"False Positive ",
"高":"High ","新":"New ","和":"And ","可能會":"Possible ","會":"Can ",
"日誌":"Log","已":"Has ","彈窗":"Window ","要":"To ","驅動":"Drive ",
"的":"","顯示":"","個":"","嗎":"","中":"","了":"","行":"","立即":"",
"密鑰":"Key ","檢測":"Detect ","誤報":"False Positive ","製作":"Make",
" ":" "}}
"密鑰":"Key ","檢測":"Detect ","製作":"Make"," ":" "}}
+1
View File
@@ -0,0 +1 @@
{"ones": [138514579140422510314615591404235408110, 138884061479927293269157399561321625124, 106913533745562494950237068000717194857, 56400517596638244422894049797604820621, 57509758994800025148320631233619478382, 266907975564823269757642468520682218021, 268764573572222081482569414853338147421, 301824928671740406049708617676147983911, 216322613833371885512412681366080352834, 305869899604823982125728318036880769198, 139390375862009821188813492031092843045, 140636369840301821837859972310736757357, 93525514883026399429643965685843744494, 85423552611944120389541188728576853614, 212959202992585676402479957744392065258, 310175323171803986711996189701871919269, 267073946987621142567955636205481517613, 130213060982497483351391950606798445166, 309453635424025901100964431663839207981, 98595718339270037315648519699911042861, 804810740308425468096265735208257617, 308840950453806983092423514217084578476, 322017788596429201866715226549004966766, 96855081274446633945978062387702817317, 309443088174281869980853203902500569645, 145963460354456926129955518358155059877, 100726355023313678737270049805708838766, 163055950804159105041684713458861453642, 139400638929619405534171854486176686629, 314740690747489056417995540920077280813, 309174548517306493765742812127600992824, 42649730517016866640152470265639253071, 266991032348753532132223164567115948653, 310834785753961546009345771577019752617, 138794485055151379651410532066913608701, 131790595577365633473641510877883811372, 333214357055760258309229460312077263456, 266919150567781465017126522717174383268, 309443250354319958579894353439906751021, 314760122553781807187305329030403597869, 309526327094009133336072658832466510380, 140783818610473943253735333316647117357, 266908765191386477077819778373267636908, 141960523677151839211304480019230155437, 236708587517087268685876607084596151010, 147109497140790587393132625769962294828, 98101030488836797416915605797123547821, 309443006965336732125112839751851204645, 163777668652403995261587270005386479850, 96850943187510051473774485962306807341, 314740690747489056417995540920077280813, 266907874033546142647711315245141475885, 128087963732730699244600678440497496745, 122948904762874323200167759687292791479, 144623683762647410432822459404215795881, 175281760716791954210630508746562429745, 98185566304403225600012489980760220205, 312173101091522310981766359248219144333, 165719174729833763978390369816514151589, 130453416906105788293089319006359032458, 309459962424693681697118037040663257637, 312110631309585432258276350165909913633, 266898908365541525694120496365498163769, 301974605256105130746947982559953757414, 46088979409888770325991887802833783310, 98097114716132427630865195752911955500, 98179117726185629973687845690377904685, 128833381668692705604881271753964704076, 288187285762824132116353144464193487405, 440767454710337817086060213441032296, 308755229979748206303057066098374746633, 310789353473439559353693532556983984677, 309443331008521396576751777765001683629, 272224825421632604778319829685274829501, 314740690747489056417995540920077280813, 288162135445850533606754792760600323239, 266908765349823459293196338896727065260, 266919475084642627997330537792153215533, 118095062731544531316068994170817536096, 309460205972074921952248716662523977893, 138980104556989140895595181268125835917, 96753309757095605084115148461573554213, 96783566280022178361451345888136274605, 267006527672619154632784726463056593709, 268325411442133354907118265595969561133, 45423085047571636176304357087088791778, 140693602135645422745421550777944908460, 266908927450643968163503768535437820588, 139317724478784922140315175893335437861, 98075229203956313888405997203836658285, 139307136862901466424877793378792006181, 141949813792938456152307200983465099405, 266887023150038950813539942248450810413, 266907873517942888138024343981564256813, 309527625168214095599527134475951948333, 288176899901775619274666676430489666220, 132687201639749430771754766010675328697, 298809467903569967359434970965896200999, 266909251929602884051145652263806452396, 96856378081010667424655802311172842021, 334364013698977648789398548127408169731, 138478276465840759527093181786120602252, 309517280516176477337549624053815730737, 309532816881431070079891773455787762221, 267006688625182579765726710919333306917, 301342822028899395690309866891238953529, 140889247564697972421510238399255437956, 301704982992736118799149217975167423010, 123342205008290812825969949820881134509, 309444547834874662752143629118327890477, 120368316428277902366824346477250637709, 96608366161759132771693290653207750157, 309258884864988268167108821321512280229, 266887185302388558609052276779780547237, 120204759374330029658546372684809684013, 266750361825108195839408748923433296011, 309541905261615072912890344878225383465, 136838710717061085016646030313491257547, 139400638929619405533018932981569839653, 309535252305417442974606230157044113441, 96865343064503306525844664637493502501, 98091942701683498853848791423305786021, 12268668727495Line truncated
+2 -1
View File
@@ -1,7 +1,8 @@
import pyinstaller_versionfile
pyinstaller_versionfile.create_versionfile(
output_file="versionfile.txt",
version='3.0.1',
version='3.0.5',
company_name="PYAS Security",
file_description="Python Antivirus Software",
internal_name="PYAS",
+2 -2
View File
@@ -6,11 +6,11 @@
PYAS.py -> Main PYAS Program (including animation, scanning, protection functions, etc.)
PYAS_Compress.py -> Conversion Database (used to convert database dict and list to and from each other)
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_Function.* -> Compress Database (need to use zip to decompress and put it in the same directory)
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)