首页
社区
课程
招聘
[分享]增加SSDT服务~ (学习笔记3)
发表于: 2008-12-10 17:34 7392

[分享]增加SSDT服务~ (学习笔记3)

2008-12-10 17:34
7392
最初听说卡巴斯基能自己增加服务,查了下资料,找到了份源代码,找个别人的模板驱动程序 整合整理并注释了下。
附件包含ring3和ring0代码

自己调用服务 则输出
Kernel service with 1 parameters called
param1=15

驱动加载完成后 查看RKU 看到了SSDT已经正确的增加了

RING3是这样调用的
function SampleService1( param : DWORD) : dword;
var
  stackframe : Pointer;   // 参数地址
begin
  stackframe := @param;
        asm
    mov eax, ServiceStart
    add eax, 1                     //eax存放调用号  调用自己增加的第二个服务
    mov edx, stackframe            //edx存放参数堆栈的地址
    int 2eh                        //这句执行后会看到dbgview输出上面的信息
  end;
end;

下面是驱动中两个主要功能函数的实现
1,KeServiceDescriptorTableShadow的定位
2,KeServiceDescriptorTable的处理

// 得到KeServiceDescriptorTableShadow的地址  原理搜索KeAddSystemServiceTable中的常量 因为KeAddSystemServiceTable使用了得到KeServiceDescriptorTableShadow的地址
unsigned int GetAddrssofShadowTable()
{
        int i;
        unsigned char *p;
        unsigned int dwordatbyte;
        p=(unsigned char *)KeAddSystemServiceTable;
    DbgPrint("KeServiceDescriptorTable->ServiceTableBase = %x\n", KeServiceDescriptorTable->ServiceTableBase);
    DbgPrint("KeAddSystemServiceTable = %x\n", KeAddSystemServiceTable);
        for (i=0; i<4096; i++, p++) {
                __try {
                        dwordatbyte=*(unsigned int *)p;
                }
                __except (EXCEPTION_EXECUTE_HANDLER) {
                        DbgPrint("发生异常\n");
                        return 0;
                }
               
                if (MmIsAddressValid((PVOID)dwordatbyte)) {
                        if (memcmp((PVOID)dwordatbyte, KeServiceDescriptorTable, 16)==0) {
                                if ((PVOID)dwordatbyte==KeServiceDescriptorTable) {
                                        continue;
                                }
                                return dwordatbyte;
                        }
                }
        }
        return 0;
}

NTSTATUS AddServices()
{
        ULONG Addrtemp;
        DbgPrint("AddServices开始执行\n");

    PServiceDescriptorTableEntry KeServiceDescriptorTableShadow;            

    unsigned int NumberOfServices;
       
    NumberOfServices=sizeof(ServiceTableBase)/sizeof(ServiceTableBase[0]);                   // 将要增加的服务函数的个数
       
    KeServiceDescriptorTableShadow=(PServiceDescriptorTableEntry)GetAddrssofShadowTable();   //获取 Shadow SSDT 地址
       
    if (KeServiceDescriptorTableShadow==NULL) {
                DbgPrint("没有找到TableShadow\n");
                return STATUS_UNSUCCESSFUL;
    }
   
    DbgPrint("KeServiceDescriptorTableShadow=%x\n", KeServiceDescriptorTableShadow);
   
    NewNumberOfServices=KeServiceDescriptorTable->NumberOfServices+NumberOfServices;         //增加后服务数目
    StartingServiceId=KeServiceDescriptorTable->NumberOfServices;                            //得到后来增加服务中第一个服务的序号
       
       
        DbgPrint("增加的第一个服务号是StartingServiceId  %x \n", StartingServiceId);       
       
    /* Allocate suffcient memory to hold the exising services as well as
    the services you want to add */
    NewServiceTableBase=(unsigned int *) ExAllocatePool(PagedPool, NewNumberOfServices*sizeof(unsigned int));  
    if (NewServiceTableBase==NULL) {
                return STATUS_INSUFFICIENT_RESOURCES;
    }
       
    NewParamTableBase=(unsigned char *) ExAllocatePool(PagedPool, NewNumberOfServices);
    if (NewParamTableBase==NULL) {
                ExFreePool(NewServiceTableBase);
                return STATUS_INSUFFICIENT_RESOURCES;
    }
       
    /* Backup the exising SSDT and SSPT */
    memcpy(NewServiceTableBase, KeServiceDescriptorTable->ServiceTableBase,    //原来的SSDT服务地址表拷贝到分配的NewServiceTableBase内存中去
                KeServiceDescriptorTable->NumberOfServices*sizeof(unsigned int));
    memcpy(NewParamTableBase, KeServiceDescriptorTable->ParamTableBase,         //原来的SSDT参数表拷贝到新分配的NewParamTableBase内存中去
                KeServiceDescriptorTable->NumberOfServices);
       
       
    /*对地址表和参数表追加*/
    memcpy(NewServiceTableBase+KeServiceDescriptorTable->NumberOfServices,
                ServiceTableBase, sizeof(ServiceTableBase));
    memcpy(NewParamTableBase+KeServiceDescriptorTable->NumberOfServices,
                ParamTableBase, sizeof(ParamTableBase));
       
    /*更新KeServiceDescriptorTableEntry的SSDT和 SSPT*/
    KeServiceDescriptorTable->ServiceTableBase=NewServiceTableBase;
    KeServiceDescriptorTable->ParamTableBase=NewParamTableBase;
    KeServiceDescriptorTable->NumberOfServices=NewNumberOfServices;
        //这里输出新的SSDT 服务函数的地址
    DbgPrint("NewServiceTableBase   KeServiceDescriptorTable->ServiceTableBase = %x\n", KeServiceDescriptorTable->ServiceTableBase);
    /* 更新KeServiceDescriptorTableShadow的SSDT和 SSPT*/
    KeServiceDescriptorTableShadow->ServiceTableBase=NewServiceTableBase;
    KeServiceDescriptorTableShadow->ParamTableBase=NewParamTableBase;
    KeServiceDescriptorTableShadow->NumberOfServices=NewNumberOfServices;

        //打印出第一个服务的地址
        Addrtemp = (ULONG)KeServiceDescriptorTable->ServiceTableBase ;
    Addrtemp = Addrtemp + StartingServiceId * 4;
        Addrtemp = *(ULONG*)Addrtemp;
        DbgPrint("增加的第一个服务的地址是 Addrtemp is %x\n", Addrtemp);

    return STATUS_SUCCESS;
}

[课程]Linux pwn 探索篇!

上传的附件:
收藏
免费 1
支持
分享
最新回复 (5)
雪    币: 364
活跃值: (152)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
2
我还是沙发~~~~~!顶
2008-12-10 17:54
0
雪    币: 217
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
哦啦啦娃哈哈
2008-12-10 21:09
0
雪    币: 193
活跃值: (26)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
4
好东西 我翻译成D的 用的正爽,终于可以不要频繁的DriveIoControl
2008-12-11 03:49
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
楼主很勤快,连续收了你好几篇文章 ^_^
2008-12-11 19:00
0
雪    币: 65
活跃值: (811)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
6
好厉害哦`~~~~
坚持下去`~~
2008-12-11 19:21
0
游客
登录 | 注册 方可回帖
返回
//