关于SSTD hook 有关问题

关于SSTD hook 问题
#define MAX_SYSTEM_SERVICE_NUMBER 1024 

 typedef ULONG NTSTATUS;
 //用来保存 SSDT 中所有的旧的服务函数的地址  
ULONG oldSysServiceAddr[MAX_SYSTEM_SERVICE_NUMBER];

typedef struct _KSYSTEM_SERVICE_TABLE  
{  
PULONG ServiceTableBase; // SSDT (System Service Dispatch Table)的基地址  
PULONG ServiceCounterTableBase; // 用于 checked builds, 包含 SSDT 中每个服务被调用的次数  
ULONG NumberOfService; // 服务函数的个数, NumberOfService * 4 就是整个地址表的大小  
ULONG ParamTableBase; // SSPT(System Service Parameter Table)的基地址  
} KSYSTEM_SERVICE_TABLE, *PKSYSTEM_SERVICE_TABLE;


typedef struct _KSERVICE_TABLE_DESCRIPTOR  
{  
KSYSTEM_SERVICE_TABLE ntoskrnl; // ntoskrnl.exe 的服务函数  
KSYSTEM_SERVICE_TABLE win32k; // win32k.sys 的服务函数(GDI32.dll/User32.dll 的内核支持)  
KSYSTEM_SERVICE_TABLE notUsed1;  
KSYSTEM_SERVICE_TABLE notUsed2;  
} KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR; 
 
 PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable;//导入由 ntoskrnl.exe 所导出的 SSDT 

void InitKeServiceDescriptorTable()
{
HINSTANCE hIns=::LoadLibrary("ntoskrnl.exe");
if(hIns)
{
PKSERVICE_TABLE_DESCRIPTOR *pinter=0;
pinter=(PKSERVICE_TABLE_DESCRIPTOR*)::GetProcAddress(hIns,"KeServiceDescriptorTable");//获得指向指针的指针
if(pinter)
{
KeServiceDescriptorTable=(*pinter);
}

}else
{
printf("加ntoskrnl.exe失败");
}
}

//备份 SSDT 中所有系统服务的地址  
 void BackupSysServicesTable()
 {
ULONG i; 
for(i = 0; (i < KeServiceDescriptorTable->ntoskrnl.NumberOfService) && (i < MAX_SYSTEM_SERVICE_NUMBER); i++) 

oldSysServiceAddr[i] = KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[i];  
 
}

 }

 int main(int argc, char* argv[])
{
InitKeServiceDescriptorTable();
BackupSysServicesTable();//

return 1;
}

这个程序运行起来,显示某某内存不能读。不知道什么原因。是因为得到的KeServiceDescriptorTable没有初始化,还是其它什么原因,请高人们给看看,谢谢。

------解决方案--------------------
直觉这句可能会有问题,最好设置断点检查下
HINSTANCE hIns=::LoadLibrary("ntoskrnl.exe");

"某某内存不能读"这样的错误通常是指针、句柄等无效,楼主最好是单步调试下,至于原因,可能是加载文件不存在、文件位置不对等。
------解决方案--------------------
这个怎么样
C/C++ code
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<Windows.h>
#include<psapi.h>

static PIMAGE_DOS_HEADER nt=0;
static size_t lnkbase=0,realbase=0;

unsigned GetServiceIndexFromNtdll(char*name)
{
    static HMODULE ntdll=0;
    if(!ntdll)ntdll=GetModuleHandleW(L"ntdll.dll");
    return *(unsigned*)((char*)GetProcAddress(ntdll,name)+1);
}

unsigned GetServiceIndex(char*name)
{
        return *(unsigned*)((char*)GetProcAddress((HMODULE)nt,name)+1);
}

size_t GetServiceRVA(char*name)
{
        return (size_t)GetProcAddress((HMODULE)nt,name)-(size_t)nt;
}

size_t*GetKiServiceTable(void)
{
        unsigned NtCreateFile_Id,NtOpenFile_Id;size_t NtCreateFile_RVA,NtOpenFile_RVA,*p;MODULEINFO info;
        NtCreateFile_Id=GetServiceIndex("ZwCreateFile"),NtOpenFile_Id=GetServiceIndex("ZwOpenFile");
        NtCreateFile_RVA=GetServiceRVA("NtCreateFile"),NtOpenFile_RVA=GetServiceRVA("NtOpenFile");
        if(GetModuleInformation((HANDLE)-1,(HMODULE)nt,&info,sizeof(MODULEINFO)))
        for(p=(size_t*)nt;(size_t)p<(size_t)nt+info.SizeOfImage;++p)
        {
                if(*p==NtCreateFile_RVA+lnkbase&&p[NtOpenFile_Id-NtCreateFile_Id]==NtOpenFile_RVA+lnkbase)return p-NtCreateFile_Id;
        }
        return 0;
}

void*GetServiceFromTable(size_t*ServiceTable,unsigned id)
{
        return (void*)(ServiceTable[id]-lnkbase+realbase);
}

int main(int argc, char* argv[])
{
        size_t*ServiceTable;DWORD n;wchar_t filename[256];
        EnumDeviceDrivers((void**)&realbase,sizeof realbase,&n);
        GetDeviceDriverBaseNameW((void*)realbase,filename,256);
        nt=(PIMAGE_DOS_HEADER)LoadLibraryExW(filename,0,DONT_RESOLVE_DLL_REFERENCES);
        lnkbase=((PIMAGE_NT_HEADERS)((size_t)nt+nt->e_lfanew))->OptionalHeader.ImageBase;
        ServiceTable=GetKiServiceTable();
        printf("table RVA:%x\n",(size_t)ServiceTable-(size_t)nt);
        printf("address of NtAllocateVirtualMemory:%p\n",GetServiceFromTable(ServiceTable,GetServiceIndexFromNtdll("NtAllocateVirtualMemory")));
        return 0;
}

------解决方案--------------------
这是在hook系统调用吗? 就靠LoadLibrary("ntoskrnl.exe"); 这个有用吗? 是不是应该要编写驱动进入内核才能做到?