获取未导出的内核函数地址

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

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

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

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

首先我们要使用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);  

以后怎么使用就不用说了吧,呵呵。 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值