频道栏目
首页 > 资讯 > 安全编程 > 正文

驱动笔记7:再谈ZwQuerySystemInformation

09-01-18        来源:[db:作者]  
收藏   我要投稿

文章作者:grayfox
作者主页:http://nokyo.blogbus.com
原始出处:http://nokyo.blogbus.com/logs/33542878.html 

    此前在“【科普6】利用NTDLL导出函数枚举进程”一文中我们曾经介绍了在ring3通过动态导出ntdll.dll中的ZwQuerySystemInformation函数来枚举系统进程,那么在ring0能否调用该函数呢?

    当然可以,而且在ring0调用会比在ring3更加简单,这样说来我们直接把ring3的代码复制到ring0就可以了?事实证明没有这么简单。

    因为这个函数属于未公开文档的函数,所以我们还是不能直接使用的,难道还要像在ring3一样,调用LoadLibrary和GetProcAddress从ntdll.dll中导出?靠,那和ring3还有什么区别?

    事实上,在ring0调用未公开文档函数是很容易的,只要在代码的开始声明一下就可以了,注意要这样声明:

NTKERNELAPI
NTSTATUS ZwQuerySystemInformation(
        IN  ULONG SystemInformationClass,
        IN  OUT PVOID SystemInformation,
        IN  ULONG SystemInformationLength,
        OUT PULONG ReturnLength OPTIONAL
);

    注意这里的开头使用了一个NTKERNELAPI,这个宏我不知道是干啥的,就到几个群里问了一下,得到了答案,它是在winddk.h这个头文件中声明的,如下:

#if (defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) || defined(_NTHAL_)) && !defined(_BLDR_)

    #define NTKERNELAPI DECLSPEC_IMPORT         // wdm

#else

    #define NTKERNELAPI

#endif

    这个我还真不敢准确地说是干啥用的,经验不够,不敢乱发言,反正就这么用着行了,有大牛路过的时候麻烦给俺们科普一下,扫下盲~~~

    函数照上面的方法声明之后就可以直接用了,如下是我的代码,基本和ring3没多大区别:

//////////////////////////////////////////////////////////////////////////
//
//    使用ZwQuerySystemInformation函数枚举进程
//
//////////////////////////////////////////////////////////////////////////
VOID
EnumProcessList1()
{
    ULONG cbBuffer = 0x10000;
    ULONG dwCount  = 0;
    PVOID pBuffer  = NULL;
    PSYSTEM_PROCESS_INFORMATION pInfo;

    pBuffer = ExAllocatePool(PagedPool, cbBuffer);
    // 获取进程信息
    KdPrint(("We Use ZwQuerySystemInformation!"));
    ZwQuerySystemInformation(    SystemProcessesAndThreadsInformation,
                                pBuffer,
                                cbBuffer,
                                NULL);

    pInfo = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
    for( ; ; )
    {
        dwCount++;
        if (pInfo->ProcessId == 0)
        {
            KdPrint(("[%6d] System Idle Process", pInfo->ProcessId));
        }
        else
        {
            KdPrint(("[%6d] %wZ", pInfo->ProcessId, pInfo->ProcessName));
        }

        if (pInfo->NextEntryDelta == 0)
        {
            break;
        }

        pInfo = (PSYSTEM_PROCESS_INFORMATION)(((PUCHAR)pInfo) + pInfo->NextEntryDelta);
    }
    KdPrint(("ProcessCount = %d", dwCount));
    ExFreePool(pBuffer);
}

相关TAG标签
上一篇:驱动笔记8:通过EPROCESS链表枚举进程
下一篇:新版显特性!QQ影音1.0 Beta2 Build268发布
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站