关于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");
"某某内存不能读"这样的错误通常是指针、句柄等无效,楼主最好是单步调试下,至于原因,可能是加载文件不存在、文件位置不对等。
------解决方案--------------------
这个怎么样
#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"); 这个有用吗? 是不是应该要编写驱动进入内核才能做到?