首页
社区
课程
招聘
关于SSDT的一点总结
发表于: 2009-11-1 23:14 8427

关于SSDT的一点总结

2009-11-1 23:14
8427
SSDT HOOK中的获取函数服务号:(因为SSDT中的函数在ntdll.dll均为导出函数)
R3下:1)LoadLibrary  "ntdll.dll"
         2)GetProcAddress  得到ntdll.dll导出表中函数地址address
       3)FunctionIndex = *( PULONG )( address + 1 )
         4)服务号传给驱动
R0下:1)利用MmGetSystemRoutineAddress函数获取ntoskrnl.exe导出表中函数地址
       2)同样解析ntdll.dll导出表:1、利用ZwQuerySystemInformation获取ntdll.dll基址   2、ZwCreateFile  ZwCreateSection ZwMapViewOfSection映射内存获得ntdll.dll基址
SSDT的恢复:
原理:找到SSDT表在文件中的文件偏移,然后重定向,直接得到函数地址
R3下:由于R3无法访问内核文件(ntoskrnel.exe为例),因此要把内核文件映射到内存,R3搜索ntoskrnl.exe重定位表(因为该表是在KiInitSystem中初始化的)获得SSDT的文件偏移
R0下:R0可以直接访问ntoskrnl.exe,得到SSDT的文件偏移,然后重定位得到函数地址

SSDT服务号:解析ntdll.dll导出表
SSDT原始地址:文件偏移重定位
SSDT当前地址:传入服务号给驱动得到当前地址
SSDT函数名的定位:解析ntdll.dll导出表ENT就可得到SSDT函数名
SSDT模块查询:ZwQuerySystemInformation传入SystemModuleInformation(11)得到系统模块列表,得到每个模块的起始和结束地址
,比对地址,在那个范围就属于哪个模块,得到模块名。
除了获取原始SSDT地址今晚才搞明白,其他东西,我均以写出code,有何错误之处,欢迎各位指正!
都是老掉牙的东西,没办法咱初学者呢!

[课程]Android-CTF解题方法汇总!

收藏
免费 0
支持
分享
最新回复 (11)
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
2
//得到ntoskrnl.exe SSDT导出函数服务号
ULONG GetServiceId( PCWSTR FunctionName )  //PCWSTR常量指针,指向16位UNICODE
{
        UNICODE_STRING  UnicodeFunctionName;
        ULONG address;
        ULONG ServiceId;
        RtlInitUnicodeString( &UnicodeFunctionName, FunctionName );
        //MmGetSystemRoutineAddress函数是从Ntoskrnl.exe和HAL中查找导出函数地址
        address = (ULONG)MmGetSystemRoutineAddress( &UnicodeFunctionName );
        //打印导出函数地址
        KdPrint(("[GetServiceId] address:0x%x\n",address));
    ServiceId = *(PSHORT)(address + 1);
        //打印导出函数服务号
        KdPrint(("[GetServiceId] ServiceId:0x%x\n",ServiceId));
        return ServiceId;
}
/**************************************************************************************
*
*        函数名:        GetFunctionAddress
*        参数:
                                [IN] PUNICODE_STRING DllName, 
                                [IN] char* FunctionName FunctionName
*        功能描述:        解析PE的EAT表获取导出函数地址
*        返回值:        ULONG address
*        作者:                sysdog
*        修改记录:
*
***************************************************************************************/
/***************************************************************************************
*
*        原理:  R0下没有LoadLibrary函数
*                        利用ZwCreateFile打开文件
*                        利用ZwCreateSection创建区段
*                        利用ZwMapViewOfSection映射区段到当前进程的虚拟内存
*                        定位PE Header地址
*                        定位第一个数据目录
*                        到EAT导出表
*                        搜索函数名,定位函数地址
****************************************************************************************/
ULONG GetFunctionId( PUNICODE_STRING DllName, char* FunctionName )
{
        NTSTATUS ntstatus;
        HANDLE hFile = NULL, hSection = NULL ;
        OBJECT_ATTRIBUTES  object_attributes;
        IO_STATUS_BLOCK io_status = {0};
        PVOID baseaddress = NULL;
        SIZE_T size = 0;
        //模块基址
        PVOID ModuleAddress = NULL;
        //偏移量
        ULONG dwOffset = 0;
        PIMAGE_DOS_HEADER dos = NULL;
        PIMAGE_NT_HEADERS nt = NULL; 
        PIMAGE_DATA_DIRECTORY expdir = NULL;
        PIMAGE_EXPORT_DIRECTORY exports = NULL;
        ULONG addr;
        ULONG Size;
        PULONG functions;
        PSHORT ordinals;
        PULONG names;
        ULONG  max_name;
        ULONG  max_func;
        ULONG i;
        ULONG pFunctionAddress;
        
        ULONG ServiceId;
        //初始化OBJECT_ATTRIBUTES结构
        InitializeObjectAttributes( 
                &object_attributes,
                DllName,
                OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                NULL,
                NULL);
        //打开文件
        ntstatus = ZwCreateFile(
                &hFile,
                FILE_EXECUTE | SYNCHRONIZE,
                &object_attributes,
                &io_status,
                NULL,
                FILE_ATTRIBUTE_NORMAL,
                FILE_SHARE_READ,
                FILE_OPEN,
                FILE_NON_DIRECTORY_FILE |
                FILE_RANDOM_ACCESS |
                FILE_SYNCHRONOUS_IO_NONALERT,
                NULL,
                0);
        if( !NT_SUCCESS( ntstatus ))
        {
                KdPrint(("[GetFunctionAddress] error0\n"));
                KdPrint(("[GetFunctionAddress] ntstatus = 0x%x\n", ntstatus));
                return 0;
        }
        //创建区段
        InitializeObjectAttributes(
                &object_attributes,
                NULL,
                OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
                NULL,
        NULL);
        ntstatus = ZwCreateSection(
                &hSection,
                SECTION_ALL_ACCESS,
                &object_attributes,
                0,
                PAGE_EXECUTE,
                SEC_IMAGE,
                hFile);
        if( !NT_SUCCESS( ntstatus ))
        {
                KdPrint(("[GetFunctionAddress] error1\n"));
                KdPrint(("[GetFunctionAddress] ntstatus = 0x%x\n", ntstatus));
                return 0;
        }
        //映射区段到进程虚拟空间
        ntstatus = ZwMapViewOfSection(
                hSection,
                NtCurrentProcess(),  //ntddk.h定义的宏用来获取当前进程句柄
                &baseaddress,
                0,
                1000,
                0,
                &size,
                (SECTION_INHERIT)1,
                MEM_TOP_DOWN,
                PAGE_READWRITE);
        if( !NT_SUCCESS( ntstatus ))
        {
                KdPrint(("[GetFunctionAddress] error2\n"));
                KdPrint(("[GetFunctionAddress] ntstatus = 0x%x\n", ntstatus));
                return 0;
        }
        ZwClose( hFile );
        //得到模块基址
        dwOffset = ( ULONG )baseaddress;
        //验证基址
        KdPrint(("[GetFunctionAddress] BaseAddress:0x%x\n", dwOffset));
    dos =(PIMAGE_DOS_HEADER) baseaddress; 
    nt  =(PIMAGE_NT_HEADERS)((ULONG) baseaddress + dos->e_lfanew);
    expdir = (PIMAGE_DATA_DIRECTORY)(nt->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_EXPORT);
        
    addr = expdir->VirtualAddress;//数据块起始RVA
        Size = expdir->Size;                  //数据块长度
    exports =(PIMAGE_EXPORT_DIRECTORY)((ULONG) baseaddress + addr);
    functions =(PULONG)((ULONG) baseaddress + exports->AddressOfFunctions);
    ordinals =(PSHORT)((ULONG) baseaddress + exports->AddressOfNameOrdinals);
    names =(PULONG)((ULONG) baseaddress + exports->AddressOfNames);
    max_name  =exports->NumberOfNames;
    max_func  =exports->NumberOfFunctions;

    for (i = 0; i < max_name; i++)
    {
        ULONG ord = ordinals[i];
        if(i >= max_name || ord >= max_func) 
                {
            return 0;
        }
        if (functions[ord] < addr || functions[ord] >= addr + Size)
        {
            if (strcmp((PCHAR) baseaddress + names[i], FunctionName)  == 0)
            {
                pFunctionAddress =(ULONG)((ULONG) baseaddress + functions[ord]);
                break;
            }
                }
        }
        
        KdPrint(("[GetFunctionAddress] %s:0x%x\n",FunctionName, pFunctionAddress));
    ServiceId = *(PSHORT)(pFunctionAddress + 1);
        //打印导出函数服务号
        KdPrint(("[GetServiceId] ServiceId:0x%x\n",ServiceId));
        //卸载区段,释放内存
        ZwUnmapViewOfSection( NtCurrentProcess(), baseaddress);
        ZwClose( hSection);
        return ServiceId;
}
2009-11-1 23:14
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
3
贴段代码
2009-11-1 23:15
0
雪    币: 291
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
收下了 呵~
2009-11-1 23:19
0
雪    币: 7992
活跃值: (2566)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
学习了..的确很好很强大...
2009-11-1 23:51
0
雪    币: 45
活跃值: (17)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
学习的很用心,看好你。。。
2009-11-2 00:29
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
7
偶现在ring0能搞定的绝不麻烦ring3,ring3能搞定的绝不麻烦ring0,比如获取SSDT的服务号,ring0也可以从ntdll中取啊
2009-11-2 06:39
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
8
没错啊  ring0可以从ntdll中取啊我没说不能
那个简单用哪个
2009-11-2 10:08
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
9
R0下:1)利用MmGetSystemRoutineAddress函数获取ntoskrnl.exe导出表中函数地址
       2)同样解析ntdll.dll导出表:1、利用ZwQuerySystemInformation获取ntdll.dll基址   2、ZwCreateFile  ZwCreateSection ZwMapViewOfSection映射内存获得ntdll.dll基址
2009-11-2 10:08
0
雪    币: 20
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
原来sysdog就是竹君
2009-11-2 11:07
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
11
暴漏目标了
2009-11-2 11:15
0
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
sd老师到哪里都跑不掉的
2009-11-2 11:56
0
游客
登录 | 注册 方可回帖
返回
//