找回密码
 现在就去注册!
搜索
热搜: 活动 交友 discuz
查看: 1638|回复: 1

Hezhong AntiVirus 技术概括文档 代码解释文档

[复制链接]

44

主题

2

回帖

921

积分

官方人员

积分
921
发表于 2024-7-22 17:56:14 | 显示全部楼层 |阅读模式

此帖子为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 为导入表引擎 代码如下:

  1. <font _mstmutation="1">    def pescan(self, db, peo): # 导入表
  2.         try:
  3.             pefunc = []
  4.             for entry in peo.DIRECTORY_ENTRY_IMPORT:
  5.                 for func in entry.imports:
  6.                     try:
  7.                         pefunc.append(str(func.name, "utf-8"))
  8.                     except:
  9.                         plog(1, traceback.format_exc())
  10.             return pefunc in db

  11.         except:
  12.             plog(1, traceback.format_exc())
  13.             return False</font>
复制代码
函数接受一个PE类 遍历导入表并加入列表 检查导入列表是否命中病毒库

深度学习技术:
通过神经网络(CNN)算法进行预测,精准判断文件恶意性质。(依赖Tensorflow Keras)
本模型基于Malconv改进。
模型定义如下:
  1. def Malconv(max_len=200000, k_size=500, ssize=500, vocab_size=256, two_conv='T'):
  2.     if two_conv == 'T':
  3.         inp = Input((max_len,))
  4.         emb = Embedding(vocab_size, 8)(inp)

  5.         conv1 = Conv1D(kernel_size=(k_size), filters=128, strides=(ssize), padding='same')(emb)
  6.         conv2 = Conv1D(kernel_size=(k_size), filters=128, strides=(ssize), padding='same')(emb)
  7.         a = Activation('sigmoid', name='sigmoid')(conv2)

  8.         mul = multiply([conv1, a])
  9.         a = Activation('relu', name='relu')(mul)
  10.         p = GlobalMaxPool1D()(a)
  11.         d = Dense(64)(p)
  12.         out = Dense(1, activation='sigmoid')(d)

  13.         return Model(inp, out)
  14.     else:
  15.         inp = Input((max_len,))
  16.         emb = Embedding(vocab_size, 8)(inp)

  17.         conv1 = Conv1D(kernel_size=(k_size), filters=128, strides=(ssize), padding='same')(emb)
  18.         p = GlobalMaxPool1D()(conv1)
  19.         d = Dense(64)(p)
  20.         out = Dense(1, activation='sigmoid')(d)

  21.         return Model(inp, out)
复制代码
训练数据生成器:
  1. def data_generator_optimized(data_files, labels, max_len=200000, batch_size=64, shuffle=True):
  2.     def process_batch(file_indices):
  3.         xx = []
  4.         yy = []
  5.         len_list = []
  6.         for fn_idx in file_indices:
  7.             fn = data_files[fn_idx]
  8.             with open(fn, 'rb') as f:
  9.                 data = f.read()
  10.             seq, doc_len, label = preprocess_single_file(fn, max_len, data, labels[fn_idx])
  11.             xx.append(seq)
  12.             yy.append(label)
  13.             len_list.append(doc_len)
  14.         return np.array(xx), np.array(yy), len_list

  15.     idx = np.arange(len(data_files))
  16.     if shuffle:
  17.         np.random.shuffle(idx)
  18.     batches = [idx[range(batch_size * i, min(len(data_files), batch_size * (i + 1)))] for i in
  19.                range(len(data_files) // batch_size + 1)]

  20.     while True:
  21.         for i in batches:
  22.             xx, yy, _ = process_batch(i)
  23.             yield (xx, yy)
复制代码
模型预测器:
  1. import os
  2. from tensorflow.keras.preprocessing.sequence import pad_sequences


  3. def preprocess(fn, max_len, datas):


  4.     doc = bytearray(datas)

  5.     seq = pad_sequences([doc], maxlen=max_len, padding='post', truncating='post')
  6.     len_list = [len(doc)]

  7.     return seq[0], len_list[0]
复制代码
  1. def predict(self, model, fn_list, label, filedata, batch_size=1, verbose=0): # 神经网络预测器
  2.         max_len = model.input.shape[1]

  3.         sequence, _ = preprocess(fn_list, max_len, filedata)

  4.         if sequence is not None:
  5.             pred = model.predict(numpy.array([sequence]), verbose=0)
  6.             return pred
  7.         else:
  8.             return None
复制代码

模型为二分类,预测输出为黑文件概率(浮点 0-1),如果为1则代表模型十分肯定该文件恶意。
HZML模型标准侦测率为78%,误判率为2.1%

云扫描:
因为360关闭了泄露的云查杀接口 因此作废。
yara特征:
由getrules函数加载,代码如下:
  1.    
复制代码
  1.     def getrules(self, rulepath): # 读取yara规则
  2.         filepath = {}
  3.         for index, file in enumerate(os.listdir(rulepath)):
  4.             rupath = os.path.join(rulepath, file)
  5.             key = "rule" + str(index)
  6.             filepath[key] = rupath
  7.         yararule = yara.compile(filepaths=filepath)
  8.         return yararule
复制代码
遍历目录的所有文件并编译规则。
命中代码(yarascan函数)如下:
  1.     def yarascan(self, rule, file, fdb): # 检查yara规则
  2.         matches = rule.match(data=fdb)
  3.         if len(matches) > 0:
  4.             return matches
复制代码
直接进行匹配命中文件。
MD5扫描:
函数md5_scan如下:
  1.     def md5_scan(self, path, database, fdb):
  2.         file_md5 = hashlib.md5(fdb).hexdigest()
  3.         if file_md5 in database:
  4.             return ['Malware.Gen', file_md5]
  5.         else:
  6.             return [False, file_md5]
复制代码
直接利用in进行匹配命中文件。
保护机制:
利用watchdog,psutil,winapi进行监控。
文件监控,进程监控:
函数process_monitor进行进程监控,调起扫描函数进行扫描:
  1. def process_monitor():
  2.     sc = VirusScan()
  3.     global md5_watchdatabase
  4.     with open('./bd/bd.vdb') as f:
  5.         md5_watchdatabase = f.read()
  6.     with open('bd/white.data') as f:
  7.         whitedb = f.read()
  8.     seter = ConfigParser()
  9.     seter.read('cfg.ini')
  10.     model = load_model('./bd/hzml.h5') # 模型

  11.     yararule_co2 = VirusScan.getrules(sc, './bd/yara')
  12.     running_pross1 = []
  13.     running_pross2 = []
  14.     while 1:
  15.         time.sleep(0.01)
  16.         for proc in psutil.process_iter(['pid', 'name']):
  17.             try:
  18.                 pid = proc.info['pid']
  19.                 path = proc.exe()
  20.                 if pid in running_pross1 and path in running_pross2:
  21.                     continue
  22.             except:
  23.                 plog(1, traceback.format_exc())
  24.             time.sleep(0.01)
  25.             if prosswa is False:
  26.                 return 0

  27.             try:
  28.                 pid = proc.info['pid']
  29.                 path = proc.exe()
  30.                 running_pross2.append(path)
  31.                 running_pross1.append(pid)
  32.                 threading.Thread(target=process_monitor_scaner,
  33.                                  args=[seter, whitedb, yararule_co2, sc, model, proc, None, False]).start() # 调起扫描


  34.             except Exception:
  35.                 plog(1, traceback.format_exc())
复制代码
MBR监控:
循环读取磁盘并对比,发现错误即写回磁盘。(mbrmonitor)
  1. def mbrmonitor():
  2.     global monitonmbra
  3.     try:
  4.         with open('\\\\.\\PhysicalDrive0', 'rb') as mbrf:
  5.             mbrs = mbrf.read(1024)
  6.         while True:
  7.             time.sleep(0.01)
  8.             with open('\\\\.\\PhysicalDrive0', 'rb') as mbrf:
  9.                 mbrs2 = mbrf.read(1024)
  10.             if mbrs2 != mbrs:
  11.                 threading.Thread(target=show_noti2,
  12.                                  args=[trans('监控已经发现您的计算机磁盘保留扇区已经被更改,我们已经修复您的磁盘保留扇区。'), ],
  13.                                  daemon=True).start()
  14.                 with open('\\\\.\\PhysicalDrive0', 'r+b') as mbrf:
  15.                     mbrf.seek(0)
  16.                     mbrf.write(mbrs)
  17.             if not monitonmbra:
  18.                 break

  19.     except PermissionError:
  20.         plog(1, traceback.format_exc())
复制代码
注册表监控:
reg_mot 和 reg_mot2 函数进行监控。利用Win32API进行读取和写回。
  1. def reg_mot2():
  2.     global watchreg
  3.     while watchreg:
  4.         time.sleep(0.1)
  5.         try:
  6.             kye2 = win32api.RegOpenKeyEx(win32con.HKEY_CURRENT_USER,
  7.                                          'SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts',
  8.                                          0, win32con.KEY_ALL_ACCESS)
  9.             win32api.RegSetValue(kye2, '.exe', win32con.REG_SZ, '')
  10.             win32api.RegCloseKey(kye2)
  11.             kye1 = win32api.RegOpenKeyEx(win32con.HKEY_CURRENT_USER, 'SOFTWARE\Classes\.exe', 0,
  12.                                          win32con.KEY_ALL_ACCESS)
  13.             if win32api.RegQueryValueEx(kye1, '')[0] != 'exefile':
  14.                 win32api.RegSetValue(kye1, '', win32con.REG_SZ, 'exefile')
  15.                 threading.Thread(target=show_noti2,
  16.                                  args=[
  17.                                      trans('发现系统关键注册表被修改:EXE关联项目。注册表已经被修复。'), ],
  18.                                  daemon=True).start()
  19.             win32api.RegCloseKey(kye1)
  20.         except:
  21.             pass




  22. def reg_mot():  # reg_mot() 的注册表规则来自PYAS 云酱天天被撅
  23.     global watchreg
  24.     threading.Thread(target=reg_mot2, daemon=True).start()
  25.     while watchreg:
  26.         time.sleep(0.1)
  27.         try:

  28.             regs1 = ["NoControlPanel", "NoDrives", "NoFileMenu", "NoFind", "NoRealMode", "NoRecentDocsMenu",
  29.                      "NoSetFolders",
  30.                      "NoSetFolderOptions", "NoViewOnDrive", "NoClose", "NoRun", "NoDesktop", "NoLogOff",
  31.                      "NoFolderOptions", "RestrictRun", "DisableCMD",
  32.                      "NoViewContexMenu", "HideClock", "NoStartMenuMorePrograms", "NoStartMenuMyGames",
  33.                      "NoStartMenuMyMusic" "NoStartMenuNetworkPlaces",
  34.                      "NoStartMenuPinnedList", "NoActiveDesktop", "NoSetActiveDesktop", "NoActiveDesktopChanges",
  35.                      "NoChangeStartMenu", "ClearRecentDocsOnExit",
  36.                      "NoFavoritesMenu", "NoRecentDocsHistory", "NoSetTaskbar", "NoSMHelp", "NoTrayContextMenu",
  37.                      "NoViewContextMenu", "NoWindowsUpdate",
  38.                      "NoWinKeys", "StartMenuLogOff", "NoSimpleNetlDList", "NoLowDiskSpaceChecks",
  39.                      "DisableLockWorkstation", "NoManageMyComputerVerb",
  40.                      "DisableTaskMgr", "DisableRegistryTools", "DisableChangePassword", "Wallpaper", "NoComponents",
  41.                      "NoAddingComponents", "Restrict_Run"]
  42.             regs2 = [
  43.                 win32api.RegOpenKey(win32con.HKEY_CURRENT_USER,
  44.                                     r"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer",
  45.                                     0, win32con.KEY_ALL_ACCESS),
  46.                 win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE,
  47.                                     r"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer",
  48.                                     0, win32con.KEY_ALL_ACCESS),
  49.                 win32api.RegOpenKey(win32con.HKEY_CURRENT_USER,
  50.                                     r"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System", 0,
  51.                                     win32con.KEY_ALL_ACCESS),
  52.                 win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE,
  53.                                     r"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System",
  54.                                     0, win32con.KEY_ALL_ACCESS),
  55.                 win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE,
  56.                                     r"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\ActiveDesktop", 0,
  57.                                     win32con.KEY_ALL_ACCESS),
  58.                 win32api.RegOpenKey(win32con.HKEY_CURRENT_USER, r"SOFTWARE\Policies\Microsoft\Windows\System", 0,
  59.                                     win32con.KEY_ALL_ACCESS),
  60.                 win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, r"SOFTWARE\Policies\Microsoft\Windows\System", 0,
  61.                                     win32con.KEY_ALL_ACCESS),
  62.                 win32api.RegOpenKey(win32con.HKEY_CURRENT_USER,
  63.                                     r"Software\Policies\Microsoft\MMC\{8FC0B734-A0E1-11D1-A7D3-0000F87571E3}", 0,
  64.                                     win32con.KEY_ALL_ACCESS)]
  65.             for rgs2 in regs2:
  66.                 for rgs1 in regs1:
  67.                     try:
  68.                         win32api.RegDeleteValue(rgs2, rgs1)
  69.                         threading.Thread(target=show_noti2,
  70.                                          args=[
  71.                                              trans(f'发现系统关键注册表被修改:{str(rgs1)}。注册表已经被修复。'), ],
  72.                                          daemon=True).start()

  73.                     except:
  74.                         pass
  75.                 win32api.RegCloseKey(rgs2)
  76.         except Exception:
  77.             plog(1, traceback.format_exc())
复制代码
设置逻辑:
通过大量调用函数,利用ConfigParser修改ini。




























44

主题

2

回帖

921

积分

官方人员

积分
921
 楼主| 发表于 2024-7-22 18:32:40 | 显示全部楼层
提示: 该帖被管理员或版主屏蔽
您需要登录后才可以回帖 登录 | 现在就去注册!

本版积分规则

Archiver|手机版|小黑屋|Hezhong |网站地图

GMT+8, 2026-6-21 03:44 , Processed in 0.094200 second(s), 21 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表