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

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

[复制链接]
  • TA的每日心情
    慵懒
    2025-6-8 11:40
  • 签到天数: 14 天

    [LV.3]偶尔看看II

    35

    主题

    2

    回帖

    868

    积分

    官方人员

    积分
    868
    发表于 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。




























  • TA的每日心情
    慵懒
    2025-6-8 11:40
  • 签到天数: 14 天

    [LV.3]偶尔看看II

    35

    主题

    2

    回帖

    868

    积分

    官方人员

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

    本版积分规则

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

    GMT+8, 2025-7-4 00:43 , Processed in 0.131104 second(s), 22 queries .

    Powered by Discuz! X3.5

    © 2001-2025 Discuz! Team.

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