首页
社区
课程
招聘
[原创]用文档化方法列举系统模块
发表于: 2008-10-12 15:07 7645

[原创]用文档化方法列举系统模块

2008-10-12 15:07
7645
关于Enum Module的方法 ,我想最常用的就是ZwQuerySystemInformation函数。我们知道这个函数是一个undocumented function。未文档化的函数有一个地方让人不放心,就是微软可能在某个时候改变他。这里我想介绍一个文档化的方法来列举系统模块。实际上,这并不是一个新技术了,但是好像很多朋友还是在用未文档的ZwQuerySystemInformation列举系统模块,那么我就在这科普一下,只当是抛砖引玉。我建议大家还是尽量用文档化的方法,除非您更喜欢使用未文档的东西。^_^

     首先介绍下Auxiliary Kernel-Mode Library,中文名为辅助内核模式库。您可以在微软提供的WDK中找到他(aux_klib.h,aux_klib.lib),这就意味着他不会再DDK中出现。这个库里的几个函数可以让内核模式驱动程序访问部分系统功能。他们具体是:

AuxKlibInitialize
AuxKlibQueryModuleInformation
AuxKlibGetImageExportDirectory
AuxKlibGetBugCheckData

由函数名我们已经可以看出他们大概都是干什么的。这里我重点介绍一下AuxKlibQueryModuleInformation。

AuxKlibQueryModuleInformation的函数原型为
NTSTATUS
  AuxKlibQueryModuleInformation (
    IN OUT PULONG  BufferSize,
    IN ULONG  ElementSize,
    OUT PVOID  QueryInfo OPTIONAL
    );

BufferSize:是个指向ULONG的指针,用来传递或接收缓冲区大小。如果第三个参数QueryInfo是NULL,那么函数会返回系统模块的字节数。如果QueryInfo不是NULL那么该参数就必须包含缓冲区字节数。

ElementSize:传递一个字节数。函数 sizeof( AUX_MODULE_BASIC_INFO )或 sizeof( AUX_MODULE_EXTENDED_INFO ) 。函数用他来判断第三个参数返回的类型。

QueryInfo:返回一个指向 AUX_MODULE_BASIC_INFO 或 AUX_MODULE_EXTENDED_INFO 的指针。

再来看看 AUX_MODULE_BASIC_INFO 或 AUX_MODULE_EXTENDED_INFO 这两个数据结构
typedef struct _AUX_MODULE_BASIC_INFO {
  PVOID  ImageBase;
} AUX_MODULE_BASIC_INFO, *PAUX_MODULE_BASIC_INFO;

typedef struct _AUX_MODULE_EXTENDED_INFO {
  AUX_MODULE_BASIC_INFO BasicInfo;
  ULONG ImageSize;
  USHORT FileNameOffset;
  UCHAR FullPathName [AUX_KLIB_MODULE_PATH_LEN];
} AUX_MODULE_EXTENDED_INFO, *PAUX_MODULE_EXTENDED_INFO;

不用多做解释,结构中的变量只是SYSTEM_MODULE_INFORMATION的一部分而已。
typedef struct _SYSTEM_MODULE_INFORMATION {
    ULONG Reserved[2];
    PVOID Base;
    ULONG Size;
    ULONG Flags;
    USHORT Index;
    USHORT Unknown;
    USHORT LoadCount;
    USHORT ModuleNameOffset;
    CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

说到这里,您应该想到这个函数应该就是对ZwQuerySystemInformation进行了一个封装而已。大家是不是想赶快试一下这个函数了?但是请不要着急,还有一个地方要说。不知道大家注意了AuxKlibInitialize这个函数没有。(也许您找就看出来了吧^_^)AuxKlibInitialize这个函数是用来初始化Auxiliary Kernel-Mode Library 的。也就是出当您要调用AuxKlibQueryModuleInformation时,必须先写AuxKlibInitialize这个函数。这个函数很简单,我们看看他的原型。
NTSTATUS
  AuxKlibInitialize (
    VOID
    );

好了,说了这么多理论知识,也该动手试一试这个函数了。

NTSTATUS AUX_FUNC()
{
        NTSTATUS ns = STATUS_SUCCESS;
        ULONG uRet;
        AUX_MODULE_EXTENDED_INFO* stModuleInfo;
        ULONG uCount;
        ULONG i;
       
        ns = AuxKlibInitialize();
       
        ns = AuxKlibQueryModuleInformation( &uRet ,sizeof( AUX_MODULE_EXTENDED_INFO ) ,NULL );
        uCount = uRet / sizeof( AUX_MODULE_EXTENDED_INFO );
       
        stModuleInfo = (AUX_MODULE_EXTENDED_INFO*)ExAllocatePoolWithTag( PagedPool, uRet ,'AUX');
        RtlZeroMemory( stModuleInfo ,uRet );
        ns = AuxKlibQueryModuleInformation( &uRet ,sizeof( AUX_MODULE_EXTENDED_INFO ) ,stModuleInfo );

        for ( i = 0 ;i < uCount ; i++ )
        {
                KdPrint(( "%s\n" ,stModuleInfo[i].FullPathName ));
        }

        return ns;
}



这个过程很简单,只是为了说明这个文档化方法可以用。

好了,最后来证实一下我们刚刚的猜想,看他是否调用了ZwQuerySystemInformation。

用WinDbg调试一下可以看到在AuxKlibQueryModuleInformation函数中有以下代码
f781b0df 51              push    ecx
f781b0e0 50              push    eax
f781b0e1 53              push    ebx
f781b0e2 6a0b            push    0Bh
f781b0e4 ff15389081f7    call    dword ptr [AuxKlibQueryModuleInformation!_imp__ZwQuerySystemInformation (f7819038)] ds:0023:f7819038={nt!ZwQuerySystemInformation (8082cc34)}

下面是栈回溯的结果
kd> k
ChildEBP RetAddr  
f655dabc f781b0ea nt!ZwQuerySystemInformation [D:\wrk-v1.2\base\ntos\ke\i386\sysstubs.asm @ 1564]
f655dc40 f7818131 AuxKlibQueryModuleInformation!AuxKlibQueryModuleInformation+0x92 [d:\winmain\base\auxapilib\kmode\aux_klib.c @ 417]
f655dc68 f781820c AuxKlibQueryModuleInformation!AUX_FUNC+0x71 [f:\driver\auxklibquerymoduleinformation\auxklibquerymoduleinformation.c @ 54]
f655dc88 808ed241 AuxKlibQueryModuleInformation!DriverEntry+0x8c [f:\driver\auxklibquerymoduleinformation\auxklibquerymoduleinformation.c @ 83]

哦!还有更轻松的办法用来看出这一点。直接拖进IDA吧。^_^

可以看到这些代码。
PAGE:000140D9                 lea     ecx, [ebp+NumberOfBytes]
PAGE:000140DF                 push    ecx             ; ReturnLength
PAGE:000140E0                 push    eax             ; SystemInformationLength
PAGE:000140E1                 push    ebx             ; SystemInformation
PAGE:000140E2                 push    0Bh             ; SystemInformationClass
PAGE:000140E4                 call    ds:__imp__ZwQuerySystemInformation@16 ; ZwQuerySystemInformation(x,x,x,x)
PAGE:000140EA                 mov     [ebp+var_144], eax
PAGE:000140F0                 test    eax, eax

这样,我们就确定了。AuxKlibQueryModuleInformation的确调用了ZwQuerySystemInformation。
文章写到这里就该结束了。最后提醒大家一下记得设置SOURCES的TARGETLIBS,不然找不到aux_klib.lib。

祝大家玩的愉快!^_^

[课程]FART 脱壳王!加量不加价!FART作者讲授!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (3)
雪    币: 364
活跃值: (152)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
2
很好!有这个就不用担心ms的一个修改导致驱动不能用了,谢谢!
2008-10-13 00:09
0
雪    币: 225
活跃值: (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
3
这种方法,我都不知道,学习了!
2008-10-13 10:25
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
看不懂!!!
2008-10-15 17:03
0
游客
登录 | 注册 方可回帖
返回
//