`
yidongkaifa
  • 浏览: 4051938 次
文章分类
社区版块
存档分类
最新评论

Kaspersky 7.0 HOOK SSDT分析

 
阅读更多

Kaspersky 7.0 HOOK SSDT分析

-卡巴驱动klif.sys逆向工程

作者:Cloud
Email:shangguanwan2@yahoo.cn
2007-11-6

一、测试版本和环境
卡巴斯基反病毒软件7.0 版本7.0.0.125d (简体中文版)
平台:Windows XP Professional(5.1,版本2600)
Mobile Inter? Celeron? CPU 1.60GHz
工具:IDA Version 5.0.0.879(32bit)
目标文件:卡巴的核心驱动klif.sys,位于SystemDirectory/system32/drivers目录下

二、目标
通过逆向工程,分析卡巴是怎样向系统服务函数表(SSDT)添加自己的服务函数的,并写出自己的实现。

三、分析
使用IDA分析在sub_291A0处发现驱动向SSDT添加自己的系统服务函数。基本流程就是分配内存,构造一个自己的SSDT,再把系统的KeServiceDescriptorTable改为指向这个构造的SSDT。最后还要修改一个叫KeAddSystemServiceTable的结构。

下面来一步一步分析:

sub_291A0 proc near

var_pKeAddSystemServiceTable= dword ptr -8
var_NewSerNum= dword ptr -4

sub esp, 8
mov eax, ds:KeServiceDescriptorTable
push ebx
push ebp
push esi
mov esi, [eax+8]
push edi
add esi, 0Dh ; 增加SSDT的服务函数的数目,
; 之后会添加一些自己的系统服务
mov [esp+18h+var_NewSerNum], esi
call CheckKeAddSystemServiceTable
test eax, eax
mov [esp+18h+var_pKeAddSystemServiceTable], eax
jnz short loc_291D0

驱动先取得SSDT表的指针,获取系统服务数目,保存在esi中,然后把它增大0Dh(13d),之后会增加13个自己的系统服务到SSDT。然后调用了CheckKeAddSystemServiceTable,在这个函数中将KeAddSystemServiceTable函数代码所在的页进行确认,确保代码全部被交换到内存中。返回后eax保存的就是KeAddSystemServiceTable函数的地址。

loc_291D0:
mov ecx, ds:KeServiceDescriptorTable
mov edi, ds:ExAllocatePoolWithTag
lea eax, ds:0[esi*4]
push 2D536542h ; Tag
mov edx, [ecx+8] ; ecx+8,指向SSDT中系统服务数
push eax ; NumberOfBytes
push 0 ; PoolType
mov ds:NumOfOldSSDT, edx
call edi ; ExAllocatePoolWithTag ; 在SSDT中分配空间以保存自定义的
; 服务函数
mov ebx, eax
test ebx, ebx
jz loc_29352

然后开始分配内存保存自定义的SSDT,大小等于新的系统服务数*4,返回的地址保存在ebx。

push 2D536542h ; Tag
push esi ; NumberOfBytes
push 0 ; PoolType
call edi ; ExAllocatePoolWithTag
mov ebp, eax
test ebp, ebp
jz loc_2934B
接着在再次分配内存,大小esi,用于保存参数表。返回的地址在ebp。然后就开始构造SSDT和SSPT。

mov eax, ds:KeServiceDescriptorTable
mov edi, ebx
mov ecx, [eax+8]
mov esi, [eax] ; 取得SSDT的基地址
shl ecx, 2 ; 即ecx*4
mov eax, ecx
shr ecx, 2 ; 将整个SSDT复制到
; 刚才第一次分配的内存中
rep movsd
mov ecx, eax
and ecx, 3
rep movsb
mov eax, ds:KeServiceDescriptorTable
mov edi, ebp
mov ecx, [eax+8]
mov esi, [eax+0Ch] ; [eax+0ch]指向参数表的基地址
mov edx, ecx ; 复制参数表
shr ecx, 2
rep movsd
mov ecx, edx
and ecx, 3
rep movsb
mov eax, ds:KeServiceDescriptorTable
mov esi, offset off_33D0C ; 这里的off_33D0C指向的就是卡巴自己的
; 系统服务,分析卡巴逻辑最重要的就是这里
mov ecx, [eax+8]
lea edi, [ebx+ecx*4]
mov ecx, 0Dh ; 复制自定义系统服务到刚才
; 第一次分配的内存中去
rep movsd
mov edx, ds:KeServiceDescriptorTable
mov ecx, dword_33D40 ; 这是卡巴自己的服务函数的参数信息
; 拷贝这些信息到SSPT中去
xor esi, esi
mov eax, [edx+8]
add eax, ebp
mov [eax], ecx
mov edx, dword_33D44
mov [eax+4], edx
mov ecx, dword_33D48
mov [eax+8], ecx
mov dl, byte_33D4C
mov [eax+0Ch], dl ; 至此,已经构造了一个完整的SSDT
mov eax, ds:KeServiceDescriptorTable
cmp [eax+4], esi
jz short loc_29310

以上注释写得很清楚,就不说了。最后的地方它测试KeServiceDescriptorTable结构的ServiceCounterTableBase成员,等于零就可以修改KeServiceDescriptorTable,完成HOOK。不等于零的情况下会重新分配内存换一种方式构造SSDT,如果你有兴趣可以自己分析。

loc_29314:
mov ecx, ds:KeServiceDescriptorTable
pop edi
pop esi
mov [ecx], ebx ; 修改SSDT entry,指向卡巴构建的SSDT
mov edx, ds:KeServiceDescriptorTable
mov ecx, [esp+10h+var_NewSSDTNum]
mov [edx+0Ch], ebp ; 修改参数表地址
mov edx, ds:KeServiceDescriptorTable
mov [edx+8], ecx ; 更新服务数目
mov [eax+0Ch], ebp
mov [eax], ebx
mov [eax+8], ecx
pop ebp ; 从这里的操作来看,KeAddSystemServiceTable
; 和KeServiceDescriptorTable的结构应该是相同的
mov ds:flag_bSuccess, 1 ; 修改标志,成功
xor eax, eax
pop ebx
add esp, 8
retn

OK,分析完毕。根据以上分析,你完全可以写一个自己的实现代码。
有什么疑问可以和我联系,一起探讨学习,笔者乐意之至。QQ:329967612博客:shangguanhome.bokee.comEmail:shangguanwan2@yahoo.cn

你可以通过这个链接引用该篇文章:http://shangguanhome.bokee.com/tb.b?diaryId=21446910

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics