Chinaunix首页 | 论坛 | 博客

=.=

  • 博客访问: 139356
  • 博文数量: 50
  • 博客积分: 3000
  • 博客等级: 中校
  • 技术积分: 550
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-25 17:22
文章分类

全部博文(50)

文章存档

2010年(7)

2009年(43)

我的朋友

分类: WINDOWS

2010-01-12 17:40:51

函数如果没有导出,我们基本上来说是没办法使用的,

但是,我们可以通过搜索系统模块内存的方式找出那些没导出的函数地址,

当然,我们首先要知道函数的特征值,这是必须的。

如果有了函数地址,我们再声明一下,就可以用了。

首先我们要使用ZwQuerySystemInformation这个Nativ API。

当然,他在系统里是已经导出了的。声明一下就可以使用了。

声明如下:

NTSYSAPI
NTSTATUS
NTAPI
ZwQuerySystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
INOUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
);


typedef struct _SYSTEM_MODULE_INFORMATION { // Information Class 11
    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;




其中,我们使用 SystemModuleInformation 这个标识,来枚举系统模块。它的定义是 11

然后,我们要知道,未导出函数的特征值,我们可以使用Windbg来找出函数的特征值。

我们以PspExitThread 为例吧:

在Windbg中,我们键入 dd pspexitthread

lkd> dd pspexitthread
805d30c2  3068786a e8804db9 fff69ac2 0124a164
805d30d2  f08b0000 8bb87589 000220be b47d8900
805d30e2  3b44468b 561274f8 658eb60f 51000001
805d30f2  056a5750 00067ee9 ffc93200 4d903015
805d3102  4c86f680 01000002 c0331074 56505050
805d3112  0000e968 065de900 7e800000 087d1033
805d3122  e856106a fff2b37e 02348e8d d1e80000
805d3132  8d0003a3 0000dd86 a9e85000 33ffff58


找到这个函数的特征值为 3068786a e8804db9 fff69ac2 0124a164 805d30d2 ...

当然,搜索的越多,越准确。这里我们找到前16个特征值就OK了。

所以我们就开始写函数了。


//

// Function:    GetFuncAddr()

// Parameters:    FuncFeature1: 函数的特征码

//                FuncFeature2: 函数的特征码

//                FuncFeature3: 函数的特征码

//                FuncFeature4: 函数的特征码

// Return:        正确返回未导出函数的地址

//                错误返回 NULL

// Description: 获取未导出函数的函数地址

// Date:        2010-01-12

//



VOID * GetFuncAddr( ULONG FuncFeature1, ULONG FuncFeature2, ULONG FuncFeature3, ULONG FuncFeature4 )
{
    ULONG size;
    ULONG i;
    ULONG j;
    PULONG p;
    NTSTATUS ntStatus;
    PSYSTEM_MODULE_INFORMATION pSystemModel;


    ULONG ulModelAddrStart;
    ULONG ulModelAddrEnd;


    ZwQuerySystemInformation( SystemModuleInformation, &size, 0, &size );

    p = ExAllocatePool( NonPagedPool, size );
    if ( !p )
    {
        return p;
    }

    ntStatus = ZwQuerySystemInformation( SystemModuleInformation,
        p,
        size * sizeof(p),
        0 );
    if ( !NT_SUCCESS( ntStatus ) )
    {
        DbgPrint( "ZwQuerySystemInformation Error!\n" );
        return NULL;
    }

    pSystemModel = (PSYSTEM_MODULE_INFORMATION)( p + 1 );

    for ( i = 0; i < *p; i++ )
    {
        DbgPrint( "SystemMode,Base: %x\n", pSystemModel[i].Base );
        DbgPrint( "SystemMode, ImageName,: %s\n", pSystemModel[i].ImageName );
        DbgPrint( "SystemMode, Size: %d\n", pSystemModel[i].Size );

        ulModelAddrStart = (ULONG)pSystemModel[i].Base;        
        ulModelAddrEnd = (ULONG)pSystemModel[i].Base + pSystemModel[i].Size;

        for ( j = ulModelAddrStart; j < ulModelAddrEnd; j++ )
        {
            // 如果 j + 12 已经大于 最大值,那就已经没有希望找到特征值了T_T

            if ( j + 12 > ulModelAddrEnd )
            {
                break;
            }

            if ( *((ULONG *)j) == FuncFeature1 &&
                *((ULONG *)(j + 4) ) == FuncFeature2 &&
                *((ULONG *)(j + 8) ) == FuncFeature3 &&
                *((ULONG *)(j + 12) ) == FuncFeature4 )
            {
                DbgPrint( "Find the Function Addr: %x!\n", j );
                return j;
            }
        }
    }

    return NULL;
}


VOID * PspExitThread = GetFuncAddr 0x3068786a,

                                     0xe8804db9,

                                     0xfff69ac2,

                                     0x0124a164 );



以后怎么使用就不用说了吧,呵呵。
阅读(1868) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~