首页
社区
课程
招聘
[旧帖] [求助]最近在搞SSDT HOOK,遇到一些问题 0.00雪花
2009-10-27 00:07 2256

[旧帖] [求助]最近在搞SSDT HOOK,遇到一些问题 0.00雪花

2009-10-27 00:07
2256
hook ssdt
#include "ssdthook.h"

#pragma  pack(1)

typedef struct _SSDT_TABLE
{
  PVOID   ServiceTableBase;
  PULONG  ServiceCounterTableBase;
  ULONG   NumberOfService;
  ULONG   ParamTableBase;
}SSDT_TABLE,* PSSDT_TABLE;
#pragma pack()

struct _SYSTEM_THREADS
{
  LARGE_INTEGER           KernelTime;
  LARGE_INTEGER           UserTime;
  LARGE_INTEGER           CreateTime;
  ULONG                           WaitTime;
  PVOID                           StartAddress;
  CLIENT_ID                       ClientIs;
  KPRIORITY                       Priority;
  KPRIORITY                       BasePriority;
  ULONG                           ContextSwitchCount;
  ULONG                           ThreadState;
  KWAIT_REASON            WaitReason;
};


//===================================================
struct _SYSTEM_PROCESSES
{
  ULONG                           NextEntryDelta;
  ULONG                           ThreadCount;
  ULONG                           Reserved[6];
  LARGE_INTEGER           CreateTime;
  LARGE_INTEGER           UserTime;
  LARGE_INTEGER           KernelTime;
  UNICODE_STRING          ProcessName;
  KPRIORITY                       BasePriority;
  ULONG                           ProcessId;
  ULONG                           InheritedFromProcessId;
  ULONG                           HandleCount;
  ULONG                           Reserved2[2];
  VM_COUNTERS                     VmCounters;
  IO_COUNTERS                     IoCounters; //windows 2000 only
  struct _SYSTEM_THREADS          Threads[1];
};

struct _SYSTEM_PROCESSOR_TIMES
{
   LARGE_INTEGER          IdleTime;
   LARGE_INTEGER          KernelTime;
   LARGE_INTEGER          UserTime;
   LARGE_INTEGER          DpcTime;
   LARGE_INTEGER          InterruptTime;
   ULONG              InterruptCount;
};

//======================================================
typedef NTSTATUS (__stdcall *ZWQUERYSYSTEMINFORMATION)(
   IN ULONG SystemInformationClass, 
   IN PVOID SystemInformation, 
   IN ULONG SystemInformationLength, 
   OUT PULONG ReturnLength);

NTSTATUS MyZwQuerySystemInformation( 
   IN ULONG SystemInformationClass, 
   IN PVOID SystemInformation, 
   IN ULONG SystemInformationLength, 
   OUT PULONG ReturnLength);

//定义全局变量
extern "C" extern PSSDT_TABLE  KeServiceDescriptorTable;
ULONG  OldAddress;
ZWQUERYSYSTEMINFORMATION        OldZwQuerySystemInformation;
PVOID Base;

void UnHook();

VOID Unload (IN PDRIVER_OBJECT pDriverObject) 
{
        KdPrint(("Enter DriverUnload\n"));
        UnHook();   // mark

}

NTSTATUS MyZwQuerySystemInformation(IN ULONG SystemInformationClass, 
                                    IN PVOID SystemInformation, 
                                    IN ULONG SystemInformationLength, 
                                    OUT PULONG ReturnLength) //定义自己的Hook函数
{ 
    
    NTSTATUS rc; 
    UNICODE_STRING process_name;
    
    RtlInitUnicodeString(&process_name, L"taskmgr.exe");
    
    rc = (OldZwQuerySystemInformation) ( 
        SystemInformationClass, 
        SystemInformation, 
        SystemInformationLength, 
        ReturnLength); 
    
    if(NT_SUCCESS(rc)) 
    {
        if(5 == SystemInformationClass)
        { 
            struct _SYSTEM_PROCESSES *curr = (struct _SYSTEM_PROCESSES *)SystemInformation; 
            
            while(curr)
            {
                if (RtlEqualUnicodeString(&process_name, &curr->ProcessName, 1))
                {
                                        DbgPrint("before %wZ\n",&process_name); 
                                        RtlInitUnicodeString(&(curr->ProcessName), L"haha");                                          
                                        DbgPrint("after %wZ\n",&(curr->ProcessName)); 


                } // if (RtlEqualUnicodeString(&process_name, &curr->ProcessName, 1))
                

                if(curr->NextEntryDelta)
                    curr = (_SYSTEM_PROCESSES *)((ULONG)curr + curr->NextEntryDelta); 
                else 
                    curr = NULL;

            } //while(curr)
            
        } // if(5 == SystemInformationClass)
        
    }// if(NT_SUCCESS(rc))
    
    // KdPrint(("HookZwQuerySystemInformation is Succeessfully. \n"));
    return rc;
}

VOID Hook()

{

        DbgPrint("Entry Hook()\n");
        OldAddress =(ULONG)KeServiceDescriptorTable->ServiceTableBase + 4*0xAd;//用windbg反汇编查到zwquerysysteminformationde的ID号是0xADh
        DbgPrint("KeServiceDescriptorTable->ServiceTableBase is :0x%0x\n",KeServiceDescriptorTable->ServiceTableBase);
        //保存原来函数的地址
        OldZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION) *(ULONG *)OldAddress;
        DbgPrint("OldZwQuerySystemInformation is :0x%0x\n", OldZwQuerySystemInformation);
        DbgPrint("MyZwQuerySystemInformation is :0x%0x\n", MyZwQuerySystemInformation);
        
        //取消内存写保护
        _asm
        { 
        cli
        mov  eax,cr0
        and  eax,not 10000h
        mov  cr0,eax
        }

        *(ULONG*)OldAddress =(ULONG) MyZwQuerySystemInformation;       //mark   MyZwQuerySystemInformation;
        
        //还原内存写保护
        _asm
        {
        mov  eax,cr0
        or   eax,10000h
        mov  cr0,eax 
        sti
        }
}

void UnHook()
{
  ULONG  Address;

  Address =(ULONG) KeServiceDescriptorTable->ServiceTableBase +0xAD*4;

  __asm
  {
    cli
    mov  eax,cr0
    and  eax,not 10000h
    mov  cr0,eax
  }

  *(ULONG*)Address =(ULONG) OldZwQuerySystemInformation;

  __asm
  {  
    mov  eax,cr0
    or   eax,10000h
    mov  cr0,eax
    sti
  }

  DbgPrint("Unhook leave!\n");
}

extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT  pDriverObject, IN PUNICODE_STRING  pRegistryPath)
{

  DbgPrint("Entry Hook Function!\n");
  pDriverObject->DriverUnload = Unload;
  Hook();
  DbgPrint("Leave DriverEntry!\n");
  return STATUS_SUCCESS;
} 


运行结果:
Entry Hook Function!
Entry Hook()
KeServiceDescriptorTable->ServiceTableBase is :0x804e2d20
OldZwQuerySystemInformation is :0x8057cc27
MyZwQuerySystemInformation is :0xf8ed4080
Leave DriverEntry!
before taskmgr.exe
after haha

但为什么在 任务栏管理 中的 taskmgr.exe 进程名显示为空呢?

[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

收藏
点赞7
打赏
分享
最新回复 (3)
雪    币: 59
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
rujisike 2009-10-28 01:41
2
0
typedef struct UnicideString
{
        USHORT        Length;
        USHORT        MaxLength;
        PWSTR        Buffer;
}

lz使用RtlInitUnicodeString把局部变量“haha.exe”初始化到原来的curr->ProcessName里面去了

curr->ProcessName是一个UnicodeString,它其中的Buffer就指向了这个局部变量haha.exe,所以buffer指向了一个内核空间地址

任务管理器是用户层的  当然不能访问内核的地址  所以显示出来是个空的~~~~

lz可以调试一下   复制前curr->ProcessName的Buffer指向的是一个用户空间的地址~~~

所以lz要将“haha.exe”复制到curr->ProcessName

这样就可以了,我已经测试过了

NTSTATUS MyZwQuerySystemInformation(IN ULONG SystemInformationClass,IN PVOID SystemInformation,IN ULONG SystemInformationLength,OUT PULONG ReturnLength)
{
   
        struct _SYSTEM_PROCESSES *curr;
    NTSTATUS rc;
    UNICODE_STRING process_name,ChangeName;
   
    RtlInitUnicodeString(&process_name, L"smss.exe");
        RtlInitUnicodeString(&ChangeName,L"haha.exe");
   
    rc = OldZwQuerySystemInformation( SystemInformationClass,  SystemInformation,  SystemInformationLength,  ReturnLength);
   
    if(NT_SUCCESS(rc))
    {
        if(SystemInformationClass==5)
        {
                        curr = (struct _SYSTEM_PROCESSES *)SystemInformation;
            while(curr)
            {
                if (RtlEqualUnicodeString(&process_name, &(curr->ProcessName), 1))
                {
                                        DbgPrint("B:%wZ\n",&(curr->ProcessName));
                                        RtlCopyUnicodeString(&(curr->ProcessName),&ChangeName);         
                                    //curr = (struct _SYSTEM_PROCESSES *)((ULONG)curr + (ULONG)curr->NextEntryDelta);
                                        DbgPrint("A:%wZ\n",&(curr->ProcessName));
                                        break;
                                       
                } // if (RtlEqualUnicodeString(&process_name, &curr->ProcessName, 1))
               
                               
                if(curr->NextEntryDelta)
                                {
                    curr = (struct _SYSTEM_PROCESSES *)((ULONG)curr + (ULONG)curr->NextEntryDelta);
                                }
                else
                    curr = NULL;
                               
            } //while(curr)
            
        } // if(5 == SystemInformationClass)
        
    }// if(NT_SUCCESS(rc))
   
    // KdPrint(("HookZwQuerySystemInformation is Succeessfully. \n"));
    return rc;
}
雪    币: 370
活跃值: (52)
能力值: ( LV13,RANK:350 )
在线值:
发帖
回帖
粉丝
moonife 8 2009-10-28 10:07
3
0
补充RtlInitUnicodeString和RtlCopyUnicodeString的参考源码:
VOID NTAPI RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString,IN PCWSTR SourceString)
{
        SIZE_T DestSize;

        if(SourceString)
        {
                DestSize = utf16_wcslen(SourceString) * sizeof(WCHAR);
                DestinationString->Length = (USHORT)DestSize;
                DestinationString->MaximumLength = (USHORT)DestSize + sizeof(WCHAR);
        }
        else
        {
                DestinationString->Length = 0;
                DestinationString->MaximumLength = 0;
        }

        DestinationString->Buffer = (PWCHAR)SourceString;
}

VOID NTAPI RtlCopyUnicodeString( IN OUT PUNICODE_STRING DestinationString, IN PCUNICODE_STRING SourceString)
{
    ULONG SourceLength;

    if(SourceString == NULL)
    {
        DestinationString->Length = 0;
    }
    else
    {
        SourceLength = min(DestinationString->MaximumLength, SourceString->Length);
        DestinationString->Length = (USHORT)SourceLength;

        RtlCopyMemory(DestinationString->Buffer,SourceString->Buffer,SourceLength);

        if (DestinationString->Length < DestinationString->MaximumLength)
        {
            DestinationString->Buffer[SourceLength / sizeof(WCHAR)] = UNICODE_NULL;
        }
    }
}
雪    币: 8
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
budingw 2009-10-28 15:52
4
0
moonife, 你的源码哪里拿的?
我看MSDN上,没看到有说  RtlInitUnicodeString 会指向新分配的缓冲区
游客
登录 | 注册 方可回帖
返回