• ZwQuerySystemInformation枚举内核模块及简单应用


    简单说,即调用第11号功能,枚举一下内核中已加载的模块。
    部分代码如下:
    //功能号为11,先获取所需的缓冲区大小
    ZwQuerySystemInformation(SystemModuleInformation,NULL,0,&needlen);
    //申请内存
    ZwAllocateVirtualMemory(NtCurrentProcess(),(PVOID*)&pBuf,0,&needlen,MEM_COMMIT,PAGE_READWRITE);
    //再次调用
    ZwQuerySystemInformation(SystemModuleInformation,(PVOID)pBuf,truelen,&needlen);
    ......
    //最后,释放内存
    ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&pBuf,&needlen,MEM_RELEASE);

    突出过程,省略了错误判断,和调用其它的功能时操作并没有什么区别。
    关键在返回的内容中,缓冲区pBuf的前四个字节是已加载的模块总数,记为ModuleCnt,接下来就是共有ModuleCnt个元素的模块信息数组了。
    该结构如下:

    typedef struct _SYSTEM_MODULE_INFORMATION {
    ULONG Count;
    SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
    } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

    模块详细信息结构如下:

    typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY {
    HANDLE Section;
    PVOID MappedBase;
    PVOID Base;
    ULONG Size;
    ULONG Flags;
    USHORT LoadOrderIndex;
    USHORT InitOrderIndex;
    USHORT LoadCount;
    USHORT PathLength;
    CHAR ImageName[256];
    } SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;

    一个for循环,循环ModuleCnt次就OK了。
    基于此,写了三个简单的函数。

    void ShowAllModules(char *pBuf)
    {
    //函数功能:输出所有模块信息
    //参数pBuf:ZwQuerySystemInformation返回的缓冲区首址
    PSYSTEM_MODULE_INFORMATION_ENTRY pSysModuleInfo;
    DWORD Modcnt=0;
    Modcnt=*(DWORD*)pBuf;
    pSysModuleInfo=(PSYSTEM_MODULE_INFORMATION_ENTRY)(pBuf+sizeof(DWORD));
    for (DWORD i=0;i<Modcnt;i++)
    {
       printf("%d	0x%08X 0x%08X %s
    ",pSysModuleInfo->LoadOrderIndex,pSysModuleInfo->Base,pSysModuleInfo->Size,pSysModuleInfo->ImageName);
       pSysModuleInfo++;
    }
    
    }
    void GetOSKrnlInfo(char *pBuf,DWORD *KernelBase,char *szKrnlPath)
    {
    //函数功能:返回系统内核(ntoskrnl.exe或ntkrnlpa.exe)的基址和路径
    //参数pBuf:ZwQuerySystemInformation返回的缓冲区首址
    //参数KernelBase:接收返回的系统内核的基址
    //参数szKrnlPath:接收返回的内核文件的路径
    PSYSTEM_MODULE_INFORMATION_ENTRY pSysModuleInfo;
    DWORD Modcnt=0;
    *KernelBase=0;
    Modcnt=*(DWORD*)pBuf;
    pSysModuleInfo=(PSYSTEM_MODULE_INFORMATION_ENTRY)(pBuf+sizeof(DWORD));
    //其实第一个模块就是了,还是验证一下吧
    if (strstr((strlwr(pSysModuleInfo->ImageName),pSysModuleInfo->ImageName),"nt"))
    {
       *KernelBase=(DWORD)pSysModuleInfo->Base;
       GetSystemDirectory(szKrnlPath,MAX_PATH);
       lstrcat(szKrnlPath,strrchr(pSysModuleInfo->ImageName,'\'));
    }
    }
    
    
    void DetectModule(char *pBuf,DWORD dwAddress,char *ModulePath)
    {
    //函数功能:找出给定地址所在的模块
    //参数pBuf:缓冲区地址,同上
    //参数dwAddress:要查询的内核地址
    //参数ModulePath:接收返回的模块路径
    PSYSTEM_MODULE_INFORMATION_ENTRY pSysModuleInfo;
    DWORD Modcnt=0;
    Modcnt=*(DWORD*)pBuf;
    pSysModuleInfo=(PSYSTEM_MODULE_INFORMATION_ENTRY)(pBuf+sizeof(DWORD));
    for (DWORD i=0;i<Modcnt;i++)
    {
       if ((dwAddress>=(DWORD)pSysModuleInfo->Base)&&(dwAddress<(DWORD)pSysModuleInfo->Base+pSysModuleInfo->Size))
       {
        lstrcpy(ModulePath,pSysModuleInfo->ImageName);
       }
       pSysModuleInfo++;
    }
  • 相关阅读:
    奇虎360安全牛人全球挑战赛无线部…
    C经典之14-双向链表存储1-10---ShinePans
    linux杂谈(十五):ftp的企业应用级的配置(二)
    Cocos2d-x 3.0心得(01)-图片载入与混合模式
    Windows装10gRAC须要注意的几个要点(怎样解决PRKH-1010和PRKR-1062的错误)
    query多选下拉框插件 jquery-multiselect(改动)
    SICP 习题 (1.42)解题总结
    电话号码 【trie树】
    hdu 3854 Glorious Array(线段树or树状数组)
    【转载】CGLib动态代理原理及实现
  • 原文地址:https://www.cnblogs.com/MaxWoods/p/3908764.html
Copyright © 2020-2023  润新知