diff --git a/PYAS.py b/PYAS.py index a0b40ab..a1b4356 100644 --- a/PYAS.py +++ b/PYAS.py @@ -19,7 +19,7 @@ def __init__(self): self.pyas = sys.argv[0].replace("\\", "/") self.dir = os.path.dirname(self.pyas) self.pyae_version = "AI Engine" - self.pyas_version = "3.2.0" + self.pyas_version = "3.2.1" self.first_startup = True self.init_data_base() self.init_tray_icon() @@ -646,7 +646,8 @@ def question_event(self, text): # 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 @@ -655,7 +656,8 @@ def send_notify(self, text, notify_bar=True): # send system notification now_time = time.strftime('%Y-%m-%d %H:%M:%S') print(f"[Notify] > [{now_time}] {text}") - QMetaObject.invokeMethod(self.ui.State_output, "append", Qt.QueuedConnection, Q_ARG(str, f"[{now_time}] {text}")) + 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) except: @@ -819,7 +821,6 @@ def write_scan(self, state, file): item.setFlags(item.flags() | Qt.ItemIsUserCheckable) item.setCheckState(Qt.Checked) self.ui.Virus_Scan_output.addItem(item) - self.send_notify(self.trans(f"發現病毒: ")+file, False) except: pass @@ -864,7 +865,8 @@ def file_scan(self): file = str(QFileDialog.getOpenFileName(self,self.trans("病毒掃描"),"C:/")[0]) if file and file not in self.whitelist and file != self.pyas: self.init_scan() - self.scan_thread = Thread(target=self.write_scan, args=(self.start_scan(file),file,), daemon=True) + 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() @@ -921,13 +923,17 @@ def traverse_path(self, file_path): def start_scan(self, file): try: - if os.path.exists(file): - self.send_notify(self.trans(f"正在掃描: ")+file, False) - label, level = self.model.dl_scan(file) - if label and self.json["high_sensitive"]: - return label - elif label and level >= self.model.values: - return label + 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 @@ -1362,6 +1368,7 @@ def get_module_base(self, p): def memory_scan(self, p): try: + match_data = {} base_address = self.get_module_base(p) process_handle = ctypes.windll.kernel32.OpenProcess(0x1F0FFF, False, p.pid) dos_header = ctypes.create_string_buffer(64) @@ -1386,11 +1393,12 @@ def memory_scan(self, p): text_address = base_address + virtual_address buffer = ctypes.create_string_buffer(virtual_size) if ctypes.windll.kernel32.ReadProcessMemory(process_handle, ctypes.c_void_p(text_address), - buffer, virtual_size, ctypes.byref(ctypes.c_size_t(0))) and characteristics & 0x20000000: + 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): - if self.start_scan(buffer.raw): - return True + match_data[section_name] = buffer.raw ctypes.windll.kernel32.CloseHandle(process_handle) + if self.start_scan(match_data): + return True return False except: return False diff --git a/PYAS_Engine.py b/PYAS_Engine.py index 3edb163..257c370 100644 --- a/PYAS_Engine.py +++ b/PYAS_Engine.py @@ -37,14 +37,16 @@ class DLScan: def __init__(self): self.models = {} self.detect = [] - self.values = 100 - self.shells = ['!o', '/4', '0a@', '?g_encry', '_test', 'ace', 'yg', 'obr', 'b1_', - 'base', 'bss', 'clr_uef', 'cursors', 'trs_age', 'engine', 'enigma', 'extjmp', - 'fio', 'fothk', 'hexpthk', 'h~;', 'icapsec', 'il2cpp', 'imageres', 'lzmadec', - 'malloc_h', 'miniex', 'mpress', 'mssmixer', 'ndr64', 'nep', 'no_bbt', 'wpp_sf', - 'nsys_wr', 'orpc', 'packer', 'pad', 'tvm', 'pgae', 'poolmi', 'proxy', 'segm', - 'retpol', 'rt', 'rwexec', 'u7m', 'rygs', 's:@', 'sanontcp', 'secur', 'asmstub', - 'tracesup', 'transit', 'upx', 'uedbg', 'viahw', 'vmp', 'wow64svc', 'be', 'zk'] + self.values = 0 + 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 load_model(self, file_path): try: @@ -59,7 +61,7 @@ def load_model(self, file_path): except: pass - def predict(self, file_data): + def dl_scan(self, file_data): try: target_size, sim = tuple(self.class_names['Pixels']), {} image = self.preprocess_image(file_data, target_size) @@ -79,29 +81,23 @@ def predict(self, file_data): except: return False, False - def dl_scan(self, file_path): + def get_type(self, file_path): try: - if isinstance(file_path, bytes): - label, level = self.predict(file_path) - if label and label in self.detect: - return label, level + 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: - match_data = [section.get_data() for section in pe.sections - if section.Characteristics & 0x20000000 and not - any(shell in section.Name.decode().strip('\x00').lower() - for shell in self.shells)] + for section in pe.sections: + section_name = section.Name.decode().strip('\x00') + 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 = [file.read()] - for file_data in match_data: - label, level = self.predict(file_data) - if label and label in self.detect: - return label, level - return False, False + match_data[ftype] = file.read() + return match_data except: - return False, False + return {} def preprocess_image(self, file_data, target_size): file_data = numpy.frombuffer(file_data, dtype=numpy.uint8) diff --git a/PYAS_Version.py b/PYAS_Version.py index 5fd4574..6f1002c 100644 --- a/PYAS_Version.py +++ b/PYAS_Version.py @@ -2,7 +2,7 @@ pyinstaller_versionfile.create_versionfile( output_file="versionfile.txt", -version='3.2.0', +version='3.2.1', company_name="PYAS Security", file_description="Python Antivirus Software", internal_name="PYAS",