首页
社区
课程
招聘
[求助]关于ssdt hook一段代码的疑惑
发表于: 2011-7-10 12:12 3862

[求助]关于ssdt hook一段代码的疑惑

2011-7-10 12:12
3862
void ReSSDT( IN HANDLE hDriver)   
{   
    HMODULE    hKernel;   
    DWORD    dwKSDT;                // rva of KeServiceDescriptorTable   
    DWORD    dwKiServiceTable;    // rva of KiServiceTable   
    PMODULES    pModules=(PMODULES)&pModules;   
    DWORD    dwNeededSize,rc;   
    DWORD    dwKernelBase,dwServices=0;   
    PCHAR    pKernelName;   
    PDWORD    pService;   
    PIMAGE_FILE_HEADER    pfh;   
    PIMAGE_OPTIONAL_HEADER    poh;   
    PIMAGE_SECTION_HEADER    psh;   
   
      
    FARPROC NtQuerySystemInformationAddr=GetProcAddress(GetModuleHandle("ntdll.dll"),"NtQuerySystemInformation");   
    // get system modules - ntoskrnl is always first there,  
    rc=((PFNNtQuerySystemInformation)NtQuerySystemInformationAddr)(11,pModules,4,&dwNeededSize);   
             if (rc==STATUS_INFO_LENGTH_MISMATCH)       {   
        pModules=(MODULES *)GlobalAlloc(GPTR,dwNeededSize);   
             rc=((PFNNtQuerySystemInformation)NtQuerySystemInformationAddr)(11,pModules,dwNeededSize,NULL);   
    }
    else
    {   
      strange:   
        printf("strange NtQuerySystemInformation()!\n");   
        return;   
    }   
    if (!NT_SUCCESS(rc)) goto strange;   //不成功则退出
      
    // imagebase   
    dwKernelBase=(DWORD)pModules->smi.Base;      
    // filename - it may be renamed in the boot.ini   
    pKernelName=pModules->smi.ModuleNameOffset+pModules->smi.ImageName;        
    // map ntoskrnl - hopefully it has relocs   
    hKernel=LoadLibraryEx(pKernelName,0,DONT_RESOLVE_DLL_REFERENCES);    //加载模块
    if (!hKernel) {   
        printf("Failed to load! LastError=%i\n",GetLastError());   
        return;           
    }   
   
    GlobalFree(pModules);    //释放空间
   
    // our own export walker is useless here - we have GetProcAddress :)        
    if (!(dwKSDT=(DWORD)GetProcAddress(hKernel,"KeServiceDescriptorTable")))
        {   //试图获取模块中的ssdt表基址,这里已经获取了地址
        printf("Can't find KeServiceDescriptorTable\n");   
        return;   
    }   
   
    // get KeServiceDescriptorTable rva   
    dwKSDT-=(DWORD)hKernel;      // find KiServiceTable   
    if (!(dwKiServiceTable=FindKiServiceTable(hKernel,dwKSDT)))
        {   //在模块中寻找ssdt表偏移地址为啥这里又去寻找ssdt表的地址了?
        printf("Can't find KiServiceTable...\n");   
        return;   
    }   
   
    printf("&KiServiceTable==%08X\n\nDumping 'old' ServiceTable:\n\n",dwKiServiceTable+dwKernelBase);      
      
    // let's dump KiServiceTable contents            
      
    // MAY FAIL!!!   
    // should get right ServiceLimit here, but this is trivial in the kernel mode   
    GetHeaders((PCHAR)hKernel,&pfh,&poh,&psh);        //获取文件头信息
   
    for (pService=(PDWORD)((DWORD)hKernel+dwKiServiceTable);   //基址+偏移
            *pService-poh->ImageBase<poh->SizeOfImage;   
            pService++,dwServices++)   
    {   
        ULONG ulAddr=*pService-poh->ImageBase+dwKernelBase;   //kernel库文件中服务绝对地址-文件的基址+kernel库文件的基址=相当于kernel文件基址的绝对地址
        SetProc( hDriver,dwServices, &ulAddr );               //通过驱动命令修改函数地址
        //printf("%08X\n",ulAddr);        
    }   
           
   
    printf("\n\nPossibly KiServiceLimit==%08X\n",dwServices);   
   
    FreeLibrary(hKernel);   
   
}   
   

DWORD FindKiServiceTable(HMODULE hModule,DWORD dwKSDT)  //模块句柄,SSTD表偏移地址  
{   
    PIMAGE_FILE_HEADER    pfh;   
    PIMAGE_OPTIONAL_HEADER    poh;   
    PIMAGE_SECTION_HEADER    psh;   
    PIMAGE_BASE_RELOCATION    pbr;   
    PIMAGE_FIXUP_ENTRY    pfe;      
      
    DWORD    dwFixups=0,i,dwPointerRva,dwPointsToRva,dwKiServiceTable;   
    BOOL    bFirstChunk;   
   
    GetHeaders((PCHAR)hModule,&pfh,&poh,&psh);   
        //获取模块dll的文件头信息,返回数据目录的绝对地址到psh,poh为文件头绝对地址,pfh为pe标志绝对地址
   
    // loop thru relocs to speed up the search   
    if ((poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) &&   
        (!((pfh->Characteristics)&IMAGE_FILE_RELOCS_STRIPPED)))
        {   //
           
        pbr=(PIMAGE_BASE_RELOCATION)RVATOVA(poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,hModule);   
               bFirstChunk=TRUE;   
        // 1st IMAGE_BASE_RELOCATION.VirtualAddress of ntoskrnl is 0   
        while (bFirstChunk || pbr->VirtualAddress) {   //
            bFirstChunk=FALSE;   
   
            pfe=(PIMAGE_FIXUP_ENTRY)((DWORD)pbr+sizeof(IMAGE_BASE_RELOCATION));   
这里pfe已经指向IMAGE_BASE_RELOCATION结构之后的另一个区段了?
   
            for (i=0;i<(pbr->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))>>1;i++,pfe++) {   
                if (pfe->type==IMAGE_REL_BASED_HIGHLOW)
          {   这里怎么能取本区段IMAGE_BASE_RELOCATION结构内的typeoffset里的类型?,下一个区段的?又不像
                    dwFixups++;   
                    dwPointerRva=pbr->VirtualAddress+pfe->offset;   
                    // DONT_RESOLVE_DLL_REFERENCES flag means relocs aren't fixed   
                    dwPointsToRva=*(PDWORD)((DWORD)hModule+dwPointerRva)-(DWORD)poh->ImageBase;   
   
                    // does this reloc point to KeServiceDescriptorTable.Base?   
                    if (dwPointsToRva==dwKSDT) {   
                        // check for mov [mem32],imm32. we are trying to find     
                        // "mov ds:_KeServiceDescriptorTable.Base, offset _KiServiceTable"   
                        // from the KiInitSystem.   
                        if (*(PWORD)((DWORD)hModule+dwPointerRva-2)==0x05c7) {   
                            // should check for a reloc presence on KiServiceTable here   
                            // but forget it   
                            dwKiServiceTable=*(PDWORD)((DWORD)hModule+dwPointerRva+4)-poh->ImageBase;   这里返回的偏移地址和之前GetProcAddress获取的区别是什么
                            return dwKiServiceTable;   
                        }   
                    }   
                       
                } else   
                    if (pfe->type!=IMAGE_REL_BASED_ABSOLUTE)   
                        // should never get here   
                        printf("\trelo type %d found at .%X\n",pfe->type,pbr->VirtualAddress+pfe->offset);   
            }   
            *(PDWORD)&pbr+=pbr->SizeOfBlock;   
        }   
    }   
      
    if (!dwFixups)   
        // should never happen - nt, 2k, xp kernels have relocation data   
        printf("No fixups!\n");   
    return 0;   
}  

由于刚接触ssdt hook,看得有点晕。还请各位大虾不吝赐教!谢谢

[注意]看雪招聘,专注安全领域的专业人才平台!

收藏
免费
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册