首页
社区
课程
招聘
[求助]SSDT 函数替换问题的疑惑 懂的达人进下 谢谢
发表于: 2010-12-5 18:16 3700

[求助]SSDT 函数替换问题的疑惑 懂的达人进下 谢谢

2010-12-5 18:16
3700
帖子的原始代码来自http://bbs.pediy.com/showthread.php?t=78218

我做了些修改

关键代码在入口函数里面:

我今天试了一下午,还是没得一个正确的,一运行就蓝了,或者死机

想求助两个问题:

1: 代码中的,InterlockedExchange替换的第一个参数到底是什么呢
   是ZwTerminateProcess的入口地址 还是 NtTerminateProcess的入口地址
   是指向ZwTerminateProcess的入口地址的指针 还是指向NtTerminateProcess的入口地址的指针呢

   我把上面四种可能性都试过了,没有一种可用的..

2: 我下面的去掉cr0写保护的代码有没有错误呢。。。

   读写控制寄存器cr0直接修改,并没有把要修改的地址给他,这样能行吗 是不是表示整个空间可写,还是某个页可写,如果是页,那么是那个页,怎么给出呢

   原作者代码是用MDL的,里面初始化的时候有把描述表地址和大小给MDL的

   我想改成直接修改cr0的。。

求懂得大哥能指点下 谢谢

#include "ntddk.h"

#pragma pack(1)
typedef struct ServiceDescriptorEntry
{
    unsigned int *ServiceTableBase;
    unsigned int *ServiceCounterTableBase; //Used only in checked build
    unsigned int NumberOfServices;
    unsigned char *ParamTableBase;
} SSDTEntry;
__declspec(dllimport)  SSDTEntry KeServiceDescriptorTable;

#pragma pack()

NTKERNELAPI NTSTATUS ZwTerminateProcess(
                                        IN HANDLE ProcessHandle OPTIONAL, 
                                        IN NTSTATUS ExitStatus
                                        ); 


typedef NTSTATUS(*_ZwTerminateProcess)(
                                       IN HANDLE ProcessHandle OPTIONAL,
                                       IN NTSTATUS ExitStatus
                                       );
_ZwTerminateProcess Old_ZwTerminateProcess;


#define GetSystemFunc(FuncName) KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)FuncName+1)]
PMDL  MDSystemCall;
PVOID *MappedSCT;

#define GetIndex(_Function) *(PULONG)((PUCHAR)_Function+1)

#define HookOn(_Old, _New)  \
    (PVOID) InterlockedExchange( (PLONG) &MappedSCT[GetIndex(_Old)], (LONG) _New)

#define UnHook(_Old, _New)  \
    InterlockedExchange( (PLONG) &MappedSCT[GetIndex(_Old)], (LONG) _New)


NTSTATUS NewZwTerminateProcess(
                               IN HANDLE ProcessHandle OPTIONAL, 
                               IN NTSTATUS ExitStatus
                               )
{
    return STATUS_SUCCESS;
}


//Unload
VOID UnLoad(IN PDRIVER_OBJECT DriverObject)
{
    DbgPrint("UnLoad Driver.\n");
    //卸载Hook
    UnHook( ZwTerminateProcess, Old_ZwTerminateProcess);

    //解锁、释放MDL
    if(MDSystemCall)
    {
        MmUnmapLockedPages(MappedSCT, MDSystemCall);
        IoFreeMdl(MDSystemCall);
    }
}

//EntryPoint.
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, 
                     IN PUNICODE_STRING RegistryPath)
{
    DriverObject->DriverUnload = UnLoad;

    //找出旧函数地址并保存
    Old_ZwTerminateProcess =(_ZwTerminateProcess)(GetSystemFunc(ZwTerminateProcess));

    //MDSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4);
    //if(!MDSystemCall)
    //    return STATUS_UNSUCCESSFUL;
    //MmBuildMdlForNonPagedPool(MDSystemCall);
    //MDSystemCall->MdlFlags = MDSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
    //MappedSCT = MmMapLockedPages(MDSystemCall, KernelMode);

    //关闭写保护
    __asm
    {
            cli
            push eax
            mov eax, CR0
            and eax, 0FFFEFFFFh
            mov CR0, eax
            pop eax
    }
    
    //安装HOOK
    /*HookOn( ZwTerminateProcess, NewZwTerminateProcess);*/
    //在此处替换SSDT表中的函数地址为新的函数地址
    InterlockedExchange((PULONG)(KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)ZwTerminateProcess+1)]),(LONG)NewZwTerminateProcess);

    //关闭写保护
    __asm
    {
            push eax
            mov eax, CR0
            or eax, NOT 0FFFEFFFFh
            mov CR0, eax
            pop eax
            sti
    }
    return STATUS_SUCCESS;
}

[课程]FART 脱壳王!加量不加价!FART作者讲授!

收藏
免费 1
支持
分享
最新回复 (2)
雪    币: 2
活跃值: (164)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
又重新修改了下,可以了

替换的地址是SSDT表中 ZwTerminateProcess所对应服务号在SSDT表中的地址

但是第二个问题还是没太懂

清除写保护是对整个系统的,还是对哪个页的,还是对哪个页地址的

总感觉如上写 没有什么特指,没有MDL那么直接,MDL是标明了位置和大小的。。

到底怎么传递要修改的东西给cr0呢
2010-12-5 18:37
0
雪    币: 88
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
清除的是寄存器CR0的判定位,你说是对页还是整个内存呢?
2010-12-5 21:43
0
游客
登录 | 注册 方可回帖
返回
//