Kaspersky 7.0 HOOK SSDT分析

作者: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,分析完毕。根据以上分析,你完全可以写一个自己的实现代码。 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值