TA的每日心情 | 慵懒 2025-6-8 11:40 |
---|
签到天数: 14 天 [LV.3]偶尔看看II

官方人员
- 积分
- 868
|
此帖子为Hezhong Antivirus的遗产,以后不会再更新,你可以克隆仓库继续编写,因为代码
太狗屎所以我更新了这个文档。
本贴讲述有关Hezhong AntiVirus技术使用的文档 方便开发者进行开发。
文档基于6.31.02版本。
函数表:
trans(text) 翻译功能
plog(texttype, text) 日志功能
上面这些函数在导入最基本的库后就立即设定。
writecfg(datatext, xx, xx2) 写config
virusnamedecode(name) 解析yara病毒名
softwareexit() 退出软件
softwest()
softwaretp()
在类 VirusScan 中:
init
predict(self, model, fn_list, label, filedata, batch_size=1, verbose=0) 深度学习预测
yarascan(self, rule, file, fdb) Yara扫描
getrules(self, rulepath) Yara规则编译
md5_scan(self, path, database, fdb) MD5扫描
cscan(self, md5)
pescan(self, db, peo) 导入表
loadprotect()
process_monitor_scaner(seter, whitedb, rules, sc, model, proc=None, path=None, mot=False) 监控扫描
process_monitor() 进程监控
monitor_files(path) 文件监控
process_string(s, a) 字符缩减
runmonitor() 监控
在 show_noti(path, name) 中
close_window() 关闭
countdown(button, window, ti) 。
在 show_noti2(name) 中
close_window() 关闭
countdown(button, window, ti)。
在类 Watch_FileMonitor(FileSystemEventHandler) 中:
init
on_created(self, event) Event
on_modified(self, event) Event
show_popup(self, file_path, virus_name) Message
mbrmonitor()
reg_mot2()
reg_mot()
在 setyq() 中:
onheur() 设置
offheur()
onyara()
offyara()
onfileprotect()
offfileprotect()
onprocessp()
offprocessp()
onmbr()
offmbr()
onscan_skip_big_file()
offscan_skip_big_file()
onregw()
offregw()
onpe()
offpe()
onc()
offc()
tw_down()
gz_down()
offdlw()
ondlw()
lang_en()
lang_cn()
CloseEvent
在类 guiscan 中:
init
getfilepathgui(self) 获取路径
setrun(self) 设置模式
find_lastfile(self, folder) 寻找文件
geli(self) 隔离
govirusscan(self, autostart=False, stpath=None) 触发扫描
scan_a_file(file, model, md5db, yardb, Avscanclass, useyara, useheur, whitedb, usec, usepe) 扫描
start_scan(stpaths='') 启动扫描
scaners(fileer) 扫描器
update2check() 更新检查
update1check()
geliqu() 隔离区
about() 关于UI
在类UpdateProtectText_1(PyQt5.QtCore.QThread)中:
init
run(self)
在类UpdateProtectText_m(object)中:
update(self, msg) 更新Qt
maingui() 主函数
cfbutton1()
cfbutton2()
cfbutton3()
cfbutton4()
CloseEvent
except_hook(cls, exception, traceback)
反病毒引擎技术:
设置中的 PE启发式引擎 , 函数pescan 为导入表引擎 代码如下:
- <font _mstmutation="1"> def pescan(self, db, peo): # 导入表
- try:
- pefunc = []
- for entry in peo.DIRECTORY_ENTRY_IMPORT:
- for func in entry.imports:
- try:
- pefunc.append(str(func.name, "utf-8"))
- except:
- plog(1, traceback.format_exc())
- return pefunc in db
- except:
- plog(1, traceback.format_exc())
- return False</font>
复制代码 函数接受一个PE类 遍历导入表并加入列表 检查导入列表是否命中病毒库
深度学习技术:
通过神经网络(CNN)算法进行预测,精准判断文件恶意性质。(依赖Tensorflow Keras)
本模型基于Malconv改进。
模型定义如下:
- def Malconv(max_len=200000, k_size=500, ssize=500, vocab_size=256, two_conv='T'):
- if two_conv == 'T':
- inp = Input((max_len,))
- emb = Embedding(vocab_size, 8)(inp)
- conv1 = Conv1D(kernel_size=(k_size), filters=128, strides=(ssize), padding='same')(emb)
- conv2 = Conv1D(kernel_size=(k_size), filters=128, strides=(ssize), padding='same')(emb)
- a = Activation('sigmoid', name='sigmoid')(conv2)
- mul = multiply([conv1, a])
- a = Activation('relu', name='relu')(mul)
- p = GlobalMaxPool1D()(a)
- d = Dense(64)(p)
- out = Dense(1, activation='sigmoid')(d)
- return Model(inp, out)
- else:
- inp = Input((max_len,))
- emb = Embedding(vocab_size, 8)(inp)
- conv1 = Conv1D(kernel_size=(k_size), filters=128, strides=(ssize), padding='same')(emb)
- p = GlobalMaxPool1D()(conv1)
- d = Dense(64)(p)
- out = Dense(1, activation='sigmoid')(d)
- return Model(inp, out)
复制代码 训练数据生成器:
- def data_generator_optimized(data_files, labels, max_len=200000, batch_size=64, shuffle=True):
- def process_batch(file_indices):
- xx = []
- yy = []
- len_list = []
- for fn_idx in file_indices:
- fn = data_files[fn_idx]
- with open(fn, 'rb') as f:
- data = f.read()
- seq, doc_len, label = preprocess_single_file(fn, max_len, data, labels[fn_idx])
- xx.append(seq)
- yy.append(label)
- len_list.append(doc_len)
- return np.array(xx), np.array(yy), len_list
- idx = np.arange(len(data_files))
- if shuffle:
- np.random.shuffle(idx)
- batches = [idx[range(batch_size * i, min(len(data_files), batch_size * (i + 1)))] for i in
- range(len(data_files) // batch_size + 1)]
- while True:
- for i in batches:
- xx, yy, _ = process_batch(i)
- yield (xx, yy)
复制代码 模型预测器:
- import os
- from tensorflow.keras.preprocessing.sequence import pad_sequences
- def preprocess(fn, max_len, datas):
- doc = bytearray(datas)
- seq = pad_sequences([doc], maxlen=max_len, padding='post', truncating='post')
- len_list = [len(doc)]
- return seq[0], len_list[0]
复制代码- def predict(self, model, fn_list, label, filedata, batch_size=1, verbose=0): # 神经网络预测器
- max_len = model.input.shape[1]
- sequence, _ = preprocess(fn_list, max_len, filedata)
- if sequence is not None:
- pred = model.predict(numpy.array([sequence]), verbose=0)
- return pred
- else:
- return None
复制代码
模型为二分类,预测输出为黑文件概率(浮点 0-1),如果为1则代表模型十分肯定该文件恶意。
HZML模型标准侦测率为78%,误判率为2.1%
云扫描:
因为360关闭了泄露的云查杀接口 因此作废。
yara特征:
由getrules函数加载,代码如下:- def getrules(self, rulepath): # 读取yara规则
- filepath = {}
- for index, file in enumerate(os.listdir(rulepath)):
- rupath = os.path.join(rulepath, file)
- key = "rule" + str(index)
- filepath[key] = rupath
- yararule = yara.compile(filepaths=filepath)
- return yararule
复制代码 遍历目录的所有文件并编译规则。
命中代码(yarascan函数)如下:
- def yarascan(self, rule, file, fdb): # 检查yara规则
- matches = rule.match(data=fdb)
- if len(matches) > 0:
- return matches
复制代码 直接进行匹配命中文件。
MD5扫描:
函数md5_scan如下:
- def md5_scan(self, path, database, fdb):
- file_md5 = hashlib.md5(fdb).hexdigest()
- if file_md5 in database:
- return ['Malware.Gen', file_md5]
- else:
- return [False, file_md5]
复制代码 直接利用in进行匹配命中文件。
保护机制:
利用watchdog,psutil,winapi进行监控。
文件监控,进程监控:
函数process_monitor进行进程监控,调起扫描函数进行扫描:
- def process_monitor():
- sc = VirusScan()
- global md5_watchdatabase
- with open('./bd/bd.vdb') as f:
- md5_watchdatabase = f.read()
- with open('bd/white.data') as f:
- whitedb = f.read()
- seter = ConfigParser()
- seter.read('cfg.ini')
- model = load_model('./bd/hzml.h5') # 模型
- yararule_co2 = VirusScan.getrules(sc, './bd/yara')
- running_pross1 = []
- running_pross2 = []
- while 1:
- time.sleep(0.01)
- for proc in psutil.process_iter(['pid', 'name']):
- try:
- pid = proc.info['pid']
- path = proc.exe()
- if pid in running_pross1 and path in running_pross2:
- continue
- except:
- plog(1, traceback.format_exc())
- time.sleep(0.01)
- if prosswa is False:
- return 0
- try:
- pid = proc.info['pid']
- path = proc.exe()
- running_pross2.append(path)
- running_pross1.append(pid)
- threading.Thread(target=process_monitor_scaner,
- args=[seter, whitedb, yararule_co2, sc, model, proc, None, False]).start() # 调起扫描
- except Exception:
- plog(1, traceback.format_exc())
复制代码 MBR监控:
循环读取磁盘并对比,发现错误即写回磁盘。(mbrmonitor)
- def mbrmonitor():
- global monitonmbra
- try:
- with open('\\\\.\\PhysicalDrive0', 'rb') as mbrf:
- mbrs = mbrf.read(1024)
- while True:
- time.sleep(0.01)
- with open('\\\\.\\PhysicalDrive0', 'rb') as mbrf:
- mbrs2 = mbrf.read(1024)
- if mbrs2 != mbrs:
- threading.Thread(target=show_noti2,
- args=[trans('监控已经发现您的计算机磁盘保留扇区已经被更改,我们已经修复您的磁盘保留扇区。'), ],
- daemon=True).start()
- with open('\\\\.\\PhysicalDrive0', 'r+b') as mbrf:
- mbrf.seek(0)
- mbrf.write(mbrs)
- if not monitonmbra:
- break
- except PermissionError:
- plog(1, traceback.format_exc())
复制代码 注册表监控:
reg_mot 和 reg_mot2 函数进行监控。利用Win32API进行读取和写回。
- def reg_mot2():
- global watchreg
- while watchreg:
- time.sleep(0.1)
- try:
- kye2 = win32api.RegOpenKeyEx(win32con.HKEY_CURRENT_USER,
- 'SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts',
- 0, win32con.KEY_ALL_ACCESS)
- win32api.RegSetValue(kye2, '.exe', win32con.REG_SZ, '')
- win32api.RegCloseKey(kye2)
- kye1 = win32api.RegOpenKeyEx(win32con.HKEY_CURRENT_USER, 'SOFTWARE\Classes\.exe', 0,
- win32con.KEY_ALL_ACCESS)
- if win32api.RegQueryValueEx(kye1, '')[0] != 'exefile':
- win32api.RegSetValue(kye1, '', win32con.REG_SZ, 'exefile')
- threading.Thread(target=show_noti2,
- args=[
- trans('发现系统关键注册表被修改:EXE关联项目。注册表已经被修复。'), ],
- daemon=True).start()
- win32api.RegCloseKey(kye1)
- except:
- pass
- def reg_mot(): # reg_mot() 的注册表规则来自PYAS 云酱天天被撅
- global watchreg
- threading.Thread(target=reg_mot2, daemon=True).start()
- while watchreg:
- time.sleep(0.1)
- try:
- regs1 = ["NoControlPanel", "NoDrives", "NoFileMenu", "NoFind", "NoRealMode", "NoRecentDocsMenu",
- "NoSetFolders",
- "NoSetFolderOptions", "NoViewOnDrive", "NoClose", "NoRun", "NoDesktop", "NoLogOff",
- "NoFolderOptions", "RestrictRun", "DisableCMD",
- "NoViewContexMenu", "HideClock", "NoStartMenuMorePrograms", "NoStartMenuMyGames",
- "NoStartMenuMyMusic" "NoStartMenuNetworkPlaces",
- "NoStartMenuPinnedList", "NoActiveDesktop", "NoSetActiveDesktop", "NoActiveDesktopChanges",
- "NoChangeStartMenu", "ClearRecentDocsOnExit",
- "NoFavoritesMenu", "NoRecentDocsHistory", "NoSetTaskbar", "NoSMHelp", "NoTrayContextMenu",
- "NoViewContextMenu", "NoWindowsUpdate",
- "NoWinKeys", "StartMenuLogOff", "NoSimpleNetlDList", "NoLowDiskSpaceChecks",
- "DisableLockWorkstation", "NoManageMyComputerVerb",
- "DisableTaskMgr", "DisableRegistryTools", "DisableChangePassword", "Wallpaper", "NoComponents",
- "NoAddingComponents", "Restrict_Run"]
- regs2 = [
- win32api.RegOpenKey(win32con.HKEY_CURRENT_USER,
- r"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer",
- 0, win32con.KEY_ALL_ACCESS),
- win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE,
- r"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer",
- 0, win32con.KEY_ALL_ACCESS),
- win32api.RegOpenKey(win32con.HKEY_CURRENT_USER,
- r"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System", 0,
- win32con.KEY_ALL_ACCESS),
- win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE,
- r"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System",
- 0, win32con.KEY_ALL_ACCESS),
- win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE,
- r"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\ActiveDesktop", 0,
- win32con.KEY_ALL_ACCESS),
- win32api.RegOpenKey(win32con.HKEY_CURRENT_USER, r"SOFTWARE\Policies\Microsoft\Windows\System", 0,
- win32con.KEY_ALL_ACCESS),
- win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, r"SOFTWARE\Policies\Microsoft\Windows\System", 0,
- win32con.KEY_ALL_ACCESS),
- win32api.RegOpenKey(win32con.HKEY_CURRENT_USER,
- r"Software\Policies\Microsoft\MMC\{8FC0B734-A0E1-11D1-A7D3-0000F87571E3}", 0,
- win32con.KEY_ALL_ACCESS)]
- for rgs2 in regs2:
- for rgs1 in regs1:
- try:
- win32api.RegDeleteValue(rgs2, rgs1)
- threading.Thread(target=show_noti2,
- args=[
- trans(f'发现系统关键注册表被修改:{str(rgs1)}。注册表已经被修复。'), ],
- daemon=True).start()
- except:
- pass
- win32api.RegCloseKey(rgs2)
- except Exception:
- plog(1, traceback.format_exc())
复制代码 设置逻辑:
通过大量调用函数,利用ConfigParser修改ini。
|
|