对抗杀毒软件Kick the Heuristic Anti-virus out of the Rootkit

产业园区如何高效对接企业技术需求与高校科研成果?.docx 科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。 立即下载
By: drizt

 

Recently, Some friend complained to me that their rootkit driver had been killed by anti-virus software like McAfee and Nod32.So I began to find why.
I found that these "heuristic anti-virus" based on the export function mentioned in one of Jonna's article(BTW:Give my respect to Jonna).
First I take a look at McAfee, It has a strange heuristic strategy. if it found an export symbol "KeServiceDescriptorTable" ,while it didn`t found some normal driver function like "IoCreateDevice", It report the virus. So I think the first method is to find the KeServiceDescriptorTable dynamically.
With 90210's article "A more stable way to locate real KiServiceTable"(http://www.rootkit.com/newsread.php?newsid=176) and his help, I can find the KeServiceDescriptorTable's ServiceTableBase, it is enough.(Thank you 90210).
But I find NOD32 is more restrice, it will detect ZW* function and reported your driver as virus. So I must find a more common ways to locate export functions and symbols. Fortunately I found some pieces in from SVEN B. SCHREIBER. This book is cool!! The code is here:



PVOID SpyMemoryCreate (DWORD dSize)
    {
    return ExAllocatePoolWithTag (PagedPool, max (dSize, 1),
                                  SPY_TAG);
    }

// -----------------------------------------------------------------

PVOID SpyMemoryDestroy (PVOID pData)
    {
    if (pData != NULL) ExFreePool (pData);
    return NULL;
    }

// ==============================================================
// MODULE INFO MANAGEMENT
// =================================================================

PMODULE_LIST SpyModuleList (PDWORD    pdData,
                            PNTSTATUS pns)
    {
    DWORD        dSize;
    DWORD        dData = 0;
    NTSTATUS     ns    = STATUS_INVALID_PARAMETER;
    PMODULE_LIST pml   = NULL;

    for (dSize = PAGE_SIZE; (pml == NULL) && dSize; dSize <<= 1)
        {
        if ((pml = SpyMemoryCreate (dSize)) == NULL)
            {
            ns = STATUS_NO_MEMORY;
            break;
            }
        ns = ZwQuerySystemInformation (SystemModuleInformation,
                                       pml, dSize, &dData);
        if (ns != STATUS_SUCCESS)
            {
            pml   = SpyMemoryDestroy (pml);
            dData = 0;

            if (ns != STATUS_INFO_LENGTH_MISMATCH) break;
            }
        }
    if (pdData != NULL) *pdData = dData;
    if (pns    != NULL) *pns    = ns;
    return pml;
    }

// -----------------------------------------------------------------

PMODULE_LIST SpyModuleFind (PBYTE     pbModule,
                            PDWORD    pdIndex,
                            PNTSTATUS pns)
    {
    DWORD        i;
    DWORD        dIndex = -1;
    NTSTATUS     ns     = STATUS_INVALID_PARAMETER;
    PMODULE_LIST pml    = NULL;

    if ((pml = SpyModuleList (NULL, &ns)) != NULL)
        {
        for (i = 0; i < pml->dModules; i++)
            {
            if (!_stricmp (pml->aModules [i].abPath +
                           pml->aModules [i].wNameOffset,
                           pbModule))
                {
                dIndex = i;
                break;
                }
            }
        if (dIndex == -1)
            {
            pml = SpyMemoryDestroy (pml);
            ns  = STATUS_NO_SUCH_FILE;
            }
        }
    if (pdIndex != NULL) *pdIndex = dIndex;
    if (pns     != NULL) *pns     = ns;
    return pml;
    }

// -----------------------------------------------------------------

PVOID SpyModuleBase (PBYTE     pbModule,
                     PNTSTATUS pns)
    {
    PMODULE_LIST pml;
    DWORD        dIndex;
    NTSTATUS     ns    = STATUS_INVALID_PARAMETER;
    PVOID        pBase = NULL;

    if ((pml = SpyModuleFind (pbModule, &dIndex, &ns)) != NULL)
        {
        pBase = pml->aModules [dIndex].pBase;
        SpyMemoryDestroy (pml);
        }
    if (pns != NULL) *pns = ns;
    return pBase;
    }

// -----------------------------------------------------------------

PIMAGE_NT_HEADERS SpyModuleHeader (PBYTE     pbModule,
                                   PVOID    *ppBase,
                                   PNTSTATUS pns)
    {
    PVOID             pBase = NULL;
    NTSTATUS          ns    = STATUS_INVALID_PARAMETER;
    PIMAGE_NT_HEADERS pinh  = NULL;

    if (((pBase = SpyModuleBase (pbModule, &ns)) != NULL) &&
        ((pinh  = RtlImageNtHeader (pBase))      == NULL))
        {
        ns = STATUS_INVALID_IMAGE_FORMAT;
        }
    if (ppBase != NULL) *ppBase = pBase;
    if (pns    != NULL) *pns    = ns;
    return pinh;
    }

// -----------------------------------------------------------------

PIMAGE_EXPORT_DIRECTORY SpyModuleExport (PBYTE     pbModule,
                                         PVOID    *ppBase,
                                         PNTSTATUS pns)
    {
    PIMAGE_NT_HEADERS       pinh;
    PIMAGE_DATA_DIRECTORY   pidd;
    PVOID                   pBase = NULL;
    NTSTATUS                ns    = STATUS_INVALID_PARAMETER;
    PIMAGE_EXPORT_DIRECTORY pied  = NULL;

    if ((pinh = SpyModuleHeader (pbModule, &pBase, &ns)) != NULL)
        {
        pidd = pinh->OptionalHeader.DataDirectory
               + IMAGE_DIRECTORY_ENTRY_EXPORT;

        if (pidd->VirtualAddress &&
            (pidd->Size >= IMAGE_EXPORT_DIRECTORY_))
            {
            pied = PTR_ADD (pBase, pidd->VirtualAddress);
            }
        else
            {
            ns = STATUS_DATA_ERROR;
            }
        }
    if (ppBase != NULL) *ppBase = pBase;
    if (pns    != NULL) *pns    = ns;
    return pied;
    }

// -----------------------------------------------------------------

PVOID SpyModuleSymbol (PBYTE     pbModule,
                       PBYTE     pbName,
                       PVOID     *ppBase,
                       PNTSTATUS pns)
    {
    PIMAGE_EXPORT_DIRECTORY pied;
    PDWORD                  pdNames, pdFunctions;
    WORD                    *pwOrdinals;
    DWORD                   i, j;
    PVOID                   pBase    = NULL;
    NTSTATUS                ns       = STATUS_INVALID_PARAMETER;
    PVOID                   pAddress = NULL;

    if ((pied = SpyModuleExport (pbModule, &pBase, &ns)) != NULL)
        {
        pdNames     = PTR_ADD (pBase, pied->AddressOfNames);
        pdFunctions = PTR_ADD (pBase, pied->AddressOfFunctions);
        pwOrdinals  = PTR_ADD (pBase, pied->AddressOfNameOrdinals);

        for (i = 0; i < pied->NumberOfNames; i++)
            {
            j = pwOrdinals [i];

            if (!strcmp (PTR_ADD (pBase, pdNames [i]), pbName))
                {
                if (j < pied->NumberOfFunctions)
                    {
                    pAddress = PTR_ADD (pBase, pdFunctions [j]);
                    }
                break;
                }
            }
        if (pAddress == NULL)
            {
            ns = STATUS_PROCEDURE_NOT_FOUND;
            }
        }
    if (ppBase != NULL) *ppBase = pBase;
    if (pns    != NULL) *pns    = ns;
    return pAddress;
    }

// -----------------------------------------------------------------

PVOID SpyModuleSymbolEx (PBYTE     pbSymbol,
                         PVOID     *ppBase,
                         PNTSTATUS pns)
{
    DWORD    i;
    BYTE     abModule [MAXIMUM_FILENAME_LENGTH] = "ntoskrnl.exe";
    PBYTE    pbName   = pbSymbol;
    PVOID    pBase    = NULL;
    NTSTATUS ns       = STATUS_INVALID_PARAMETER;
    PVOID    pAddress = NULL;
    
    for (i = 0; pbSymbol [i] && (pbSymbol [i] != '!'); i++);
    
    if (pbSymbol [i++])
    {
        if (i <= MAXIMUM_FILENAME_LENGTH)
        {
            memcpy (abModule, pbSymbol, i);
            pbName = pbSymbol + i;
        }
        else
        {
            pbName = NULL;
        }
    }
    if (pbName != NULL)
    {
        pAddress = SpyModuleSymbol (abModule, pbName, &pBase, &ns);
    }
    if (ppBase != NULL) *ppBase = pBase;
    if (pns    != NULL) *pns    = ns;
    return pAddress;
}


So Now we can get symbol like this:

pKeServiceDescriptorTable = SpyModuleSymbolEx("KeServiceDescriptorTable", NULL, &ns);

cool!
28377D Bootloader 架构 阅读详情

相关推荐

微信小程序scroll-view,点击menu,滚动到锚点;滚动到锚点,激活menu。

首先看看效果图1、首先是点击菜单,滚动列表,这个实现比较简单。直接使用scroll-view 的 scroll-into-view属性,小程序文档。&lt;view class='container'&gt; &lt;!-- 菜单 --&gt; &lt;view class='menu'&gt; &lt;ul&gt; &lt;!-- scrollList 修改cate --&g...

weixin_39834214的博客 1万+

Heuristic (computer science)

1

qq_66485519的博客 556

cst-python联合仿真的问题解决

cst与python联合仿真出现无法调用CST的问题解决

ayihu_的博客 2373

NT STATUS CODE

00000000 STATUS_SUCCESS00000000 STATUS_WAIT_000000001 STATUS_WAIT_100000002 STATUS_WAIT_200000003 STATUS_WAIT_30000003F STATUS_WAIT_6300000080 STATUS_ABANDONED00000080 STATUS_ABANDONED_WAIT_0000000BF

我爱我家的专栏 7229

光通量与辐射通量之间的换算

由理论和实验可知存在两种定义: 1W1W1W(瓦特)的频率为540×1012Hz540\times10^{12}Hz540×1012Hz(赫兹)的单色辐射的辐射通量等于683lm(流明)683lm(流明)683lm(流明).。 1lm1lm1lm的频率为540×1012Hz540\times10^{12}Hz540×1012Hz的单色通量等于1683=0.001464W\frac{1}{683}=0.001464W6831​=0.001464W。 从上述定义中我们可以得到什么呢?我们知道光速: c=3×

u011699626的博客 3273

【硬件的单元测试 UT 3】PCIe 3.0及信号完整性测试方法

PCIe标准自从推出以来,1代和2代标准已经在PC和Server上逐渐普及,用于满足高速显卡、高速存储设备对于高速数据传输的要求。出于支持更高总线数据吞吐率的目的,PCI-SIG组织在2010年制定了PCIe 3.0,即PCIe 3代的规范,数据速率达到8Gbps。

qq_43416206的博客 1415

Kick the Heuristic Anti-virus out of the Rootkit

 Recently, Some friend complained to me that their rootkit driver had been killed by anti-virus software like McAfee and Nod32.So I began to find why.I found that these "heuristic anti-virus" based

1575

Android15音频进阶之4种调试线程死锁利器(八十九)

本篇目的:Android15音频进阶之4种调试线程死锁利器对于开发者来说,最令人头疼的,莫过于多线程交互出问题的时候,我们应该从哪里找突破口呢?下面来介绍一下调试Android音频中线程死锁的四种方案线程死锁是并发编程中常见的问题之一,它指的是在多个线程竞争资源的过程中,由于相互等待对方持有的资源而无法继续执行,从而导致所有线程都无法向前推进的现象。死锁不仅会导致系统性能严重下降,甚至可能导致整个系统崩溃。线程死锁的产生有四个必要条件:互斥条件:资源不能被多个线程共同使用,只能由一个线程独占。

Android系统攻城狮 1997

使用金山卫士的一些体会

  金山卫士已经在电脑里呆了一段时间,平时没见动静,今天检查出U盘上的病毒,总算有点反应了。顺便记下一些使用体会。

Purpleendurer@优快云 2995

QGIS编译(跨平台编译)001:Flex、Bison编译(安装)(Windows、Linux、MacOS环境下安装)

QGIS编译;Flex、Bison编译(安装)(Windows、Linux、MacOS环境下安装)

LuckyHanMo的博客 3080

ValueError: numpy.dtype size changed, may indicate binary incompatibility. Expected 96 from C 解决方案

本文主要介绍了ValueError: numpy.dtype size changed, may indicate binary incompatibility. Expected 96 from C header, got 88 from PyObject解决方案,希望能对使用Numpy的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 1万+

list

的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。,因此反向迭代器的实现可以借助正向迭代器,即:反向迭代器内部可以包含一个正向迭代器,对正向迭代器的接口进行包装即可。是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。迭代到该位置,在这段位置上迭代需要线性的时间开销;最大的缺陷是不支持任意位置的随机访问,比如:要访问。还需要一些额外的空间,以保存每个节点的相关联信息。个元素,必须从已知的位置。

xie0510_的博客 274

道路施工检测 (construction) - 基于Mapillary Vistas数据集的YOLOv11目标检测及UI界面实现

目标检测是计算机视觉的重要任务,目标是识别图像中的目标物体类别及其位置(用边界框表示)。两阶段检测器:如Faster R-CNN,准确度高但速度较慢单阶段检测器:如YOLO系列、SSD,速度快且精度相对较好,适合实时场景数据量:约25,000张高分辨率街景图标注类型:语义分割、实例分割、多类别检测类别示例:construction, road, car, person, traffic sign等格式:COCO风格JSON标注。

YOLO 496

Redis 数据类型详解:Hash 哈希与 List 列表

大 key 指单个 key 对应的 value 过大(如 Hash 字段数极多、List 元素极多)。危害包括:单次全量命令(

2303_77004089的博客 105

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

【C++】【STL】list

list 是带头结点的双向循环链表,通过哨兵位消除首尾边界判断,实现任意位置插入删除的常数时间复杂度。其节点独立分配,不支持随机访问,迭代器仅支持前后移动。与 vector 对比,list 在中间插入/删除时更高效,但遍历缓存命中率低;vector 适合随机访问和连续遍历,但头部操作代价高。二者在内存布局、访问效率与适用场景上形成互补。

这里是Cocatrice的博客,感谢大家一直以来的支持和鼓励,如果对C/C++方向感兴趣的话,可以通过主页的微信名片加Cocatrice的好友,也可以通过邮箱:Chen31980094@163.com 联系,一同加油! 637

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Java 集合框架(List、Set、Map)与常用基础

本文整理Java集合框架核心知识,涵盖集合体系、Collection接口API、List(ArrayList、LinkedList、Vector)、Set(HashSet、TreeSet)、Map(HashMap、TreeMap、Hashtable)实现类原理、泛型、增强for循环、可变参数与工具类,并附核心易错点速查表。

既然你都点开这里了,那可以给我点个关注吗?可以吗?可以吗? 487

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Bugku 326 Baby-heap1 题解:glibc 2.23 堆溢出到 FSOP 劫持 _IO_list_all(附完整 exp)

为什么 FSOP 在 2.23 这么好用?glibc 2.23 的_IO_FILE虚表调用没有 vtable 合法性检查是 2.24 才加入的),只要能把指向自己伪造的 FILE,就能让__overflow槽位指向任意函数。exit()一定会走因此把_mode置 0、置 1、置 0,就能进入;把fp首地址写成/bin/shsystem(fp)的参数就齐了。为什么用 fastbin attack 而不是?2.23 没有 tcache,fastbin 的fd。

kingx3的博客 211

List(下):LPOP / RPOP、BLPOP / BRPOP 与 LINDEX、LINSERT

这是《Redis C++ 实战笔记》系列的第 07 篇。上一篇是往列表里放,这一篇是往外拿——包括那个会"等"的弹出。

wbs_scy的博客 105

[C++]:7.STL:list

好久不见,firdawn小课堂又和大家见面啦。今天我们要学习的内容是list容器,list也是一种常用的数据结构。下面是本章的思维导图,那么让我们开始学习吧!自定义的list,由三个结构构成。分别是链表的最小组成单位,也就是链表节点。以及迭代器类和list类其实要特别说明的是, List的迭代器,它不是单纯的指针,因为我们如果对指针直接进行解引用操作的话,我们得到的是这个节点,而不是节点里面存储的值并且我们对这个指针加加,得到的也不是下一个节点的地址,而是所在节点的下一个单位的地址。

2301_80817679的博客 193

一个链表(Linked List)--为什么要用链表--deepseek

数组(如你定义的大盘子就像你在 FPGA 里例化了一块深度为 2500 的 BRAM。它必须是一块连续的、完整的内存。如果内存里全是碎片,凑不出 2500 个连续空位,数组就建立不起来。链表(Linked List)就像一堆散落在大街小巷的小仓库,每个仓库大小不固定,彼此不挨着。但是,每个仓库的门口都贴了一张小纸条,纸条上写着“下一个仓库的地址”。我们来画个图,这就是链表的核心——节点(Node)text。

AlibabaApple的博客 171

FreeRTos笔记(12c):从事件链表里删除节点 xTaskRemoveFromEventList、

(1) (2) 谢谢

zhangzhangkeji的博客 163

【C++初阶】list使用及相关实现,思路顺滑流畅!

list使用及相关实现

Severus_black的博客 208

List(上):LPUSH / RPUSH 与 LRANGE

这是《Redis C++ 实战笔记》系列的第 06 篇。String 讲完了,进入第二种类型:List。它是一串有顺序、可以重复的值,两头都能进出。

wbs_scy的博客 243

细粒度锁的线程安全list实现

【代码】细粒度锁的线程安全list实现。

weixin_43698578的博客 198

TypeError: must be str, not list

【代码】TypeError: must be str, not list。

Forerunner and Successor 先駆者と後継者 49

Java Arrays.asList 常见坑详解|UnsupportedOperationException、数组联动、基本类型 bug

解析 Arrays.asList 常见开发陷阱,演示 UnsupportedOperationException、底层数组引用共享、基本类型数组问题,区分 Arrays 内部 ArrayList 与 java.util.ArrayList,给出数组转 List 的各种场景正确代码。

weixin_42617033的博客 477
上一篇: bypass dll authentication in sygate and such
下一篇: Kernel Mode Ircbot
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值