阅读:2200回复:5
[求助]如何在SSDT中添加自己的系统调用?
小弟刚学写驱动,请各位大大详细指点迷津~
我试着修改SSDT里发服务描述表 typedef struct _SYSTEM_SERVICE_TABLE { PVOID ServiceTableBase; PULONG ServiceCounterTableBase; ULONG NumberOfService; ULONG ParamTableBase; }SYSTEM_SERVICE_TABLE,*PSYSTEM_SERVICE_TABLE; 在ServiceTableBase+NumberOfService*4上加一个地址指针指向自己写的系统调用,并把NumberOfService值修改为NumberOfService+1 但是这样写出来的东西,一运行系统就自动重起了 我郁闷了2天了,真不知道改怎么做. 请各位大大指点一下! |
|
沙发#
发布于:2007-04-05 10:34
我现在在实验室,不能开Q哦,等回去后我再加你Q聊吧!
|
|
板凳#
发布于:2007-04-05 10:30
你的qq多少,我的38998399,我也是前天才研究,dbgprint显示成功了,用windbg查看ssdt中并没有变,郁闷
|
|
地板#
发布于:2007-04-05 10:10
非常感谢!我先详细研究一下!
|
|
地下室#
发布于:2007-04-05 09:41
#define DEBUGMSG
#include <ntddk.h> #include "windef.h" #include "sysenthook.h" #include <stdio.h> #include<stdlib.h> typedef VOID *SSTAT[]; // SSTAT is an array of pointers to the // service handler addresses of each // service entry in the SST. typedef unsigned char SSTPT[]; // SSTPT is an array of bytes containing typedef SSTAT *LPSSTAT; // LPSSTAT is a pointer to an SSTAT.] typedef SSTPT *LPSSTPT; // LPSSTPT is a pointer to an SSTPT. #pragma pack(1) typedef struct ServiceDescriptorEntry { unsigned int *ServiceTableBase; unsigned int *ServiceCounterTableBase; unsigned int NumberOfServices; unsigned char *ParamTableBase; } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t; #pragma pack() ServiceDescriptorTableEntry_t KeServiceDescriptorTable; #pragma pack(1) typedef struct _GDT { WORD GdtLimit; DWORD GdtBase; }GDT,*PGDT; #pragma pack() int kb_int = 0x93; unsigned long old_ISR_pointer,ISR147_pointer; //函数声明 VOID MY_PROC(); VOID MY_SYSENTER_PROC(); VOID HookService(); VOID UnHookService(); VOID GetMSR_EIP(); VOID SetNewMSR_EIP(); VOID SetOldMSR_EIP(); /* 准备填加的服务 */ NTSTATUS SampleService0(void); NTSTATUS SampleService1(int param1); NTSTATUS SampleService2(int param1, int param2); NTSTATUS DriverDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp ); NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ); VOID UnloadDriver(IN PDRIVER_OBJECT pDriverObject); ULONG RawMSR_SYSENTER_EIP; //保存原始的MSR_SYSENTER_EIP内容 ULONG NewMSR_SYSENTER_EIP; ULONG Val_1; ULONG j; GDT gdt; WORD tr; /* 填加的服务表 */ unsigned int ServiceTableBase[]={(unsigned int)SampleService0, (unsigned int)SampleService1, (unsigned int)SampleService2 }; /* 填加的参数表 */ unsigned char ParamTableBase[]={0,4,8}; unsigned int *NewServiceTableBase; /* Pointer to new SSDT */ unsigned char *NewParamTableBase; /* Pointer to new SSPT */ unsigned int NewNumberOfServices; /* New number of services */ unsigned int StartingServiceId; NTSTATUS SampleService0(void) { DbgPrint(("Kernel service with 0 parameters called\n")); return STATUS_SUCCESS; } NTSTATUS SampleService1(int param1) { DbgPrint("Kernel service with 1 parameters called\n"); DbgPrint("param1=%x\n", param1); return STATUS_SUCCESS+1; } NTSTATUS SampleService2(int param1, int param2) { DbgPrint("Kernel service with 2 parameters called\n"); DbgPrint("param1=%x param2=%x\n", param1, param2); return STATUS_SUCCESS+2; } NTSYSAPI BOOLEAN NTAPI KeAddSystemServiceTable(LPSSTAT lpAddressTable, BOOLEAN bUnknown, ULONG dwNumEntries, LPSSTPT lpParameterTable, // Pointer to the SSTPT ULONG dwTableID // Index of the SSD to ); unsigned int GetAddrssofShadowTable() { int i; unsigned char *p; unsigned int dwordatbyte; p=(unsigned char *)KeAddSystemServiceTable; for (i=0; i<4096; i++, p++) { __try { dwordatbyte=*(unsigned int *)p; } __except (EXCEPTION_EXECUTE_HANDLER) { return 0; } if (MmIsAddressValid((PVOID)dwordatbyte)) { if (memcmp((PVOID)dwordatbyte, &KeServiceDescriptorTable, 16)==0) { if ((PVOID)dwordatbyte==&KeServiceDescriptorTable) { continue; } DbgPrint("Shadow @%x\n", dwordatbyte); return dwordatbyte; } } } return 0; } NTSTATUS AddServices() { PServiceDescriptorTableEntry_t KeServiceDescriptorTableShadow; unsigned int NumberOfServices; NumberOfServices=sizeof(ServiceTableBase)/sizeof(ServiceTableBase[0]); DbgPrint("KeServiceDescriptorTable=%x\n", &KeServiceDescriptorTable); KeServiceDescriptorTableShadow=(PServiceDescriptorTableEntry_t)GetAddrssofShadowTable(); if (KeServiceDescriptorTableShadow==NULL) { return STATUS_UNSUCCESSFUL; } DbgPrint("KeServiceDescriptorTableShadow=%x\n",KeServiceDescriptorTableShadow); NewNumberOfServices=KeServiceDescriptorTable.NumberOfServices+NumberOfServices; StartingServiceId=KeServiceDescriptorTable.NumberOfServices; /* Allocate sufficient memory to hold the existing 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, KeServiceDescriptorTable.NumberOfServices*sizeof(unsigned int)); memcpy(NewParamTableBase, KeServiceDescriptorTable.ParamTableBase, KeServiceDescriptorTable.NumberOfServices); /* Append to it new SSDT and SSPT */ memcpy(NewServiceTableBase+KeServiceDescriptorTable.NumberOfServices, ServiceTableBase, sizeof(ServiceTableBase)); memcpy(NewParamTableBase+KeServiceDescriptorTable.NumberOfServices, ParamTableBase, sizeof(ParamTableBase)); /* Modify the KeServiceDescriptorTableEntry to point to new SSDT and SSPT */ KeServiceDescriptorTable.ServiceTableBase=NewServiceTableBase; KeServiceDescriptorTable.ParamTableBase=NewParamTableBase; KeServiceDescriptorTable.NumberOfServices=NewNumberOfServices; /* Also update the KeServiceDescriptorTableShadow to point to new SSDT and SSPT */ KeServiceDescriptorTableShadow->ServiceTableBase=NewServiceTableBase; KeServiceDescriptorTableShadow->ParamTableBase=NewParamTableBase; KeServiceDescriptorTableShadow->NumberOfServices=NewNumberOfServices; /* Return Success */ DbgPrint("Returning success\n"); return STATUS_SUCCESS; } unsigned int StartingServiceId; //截获系统服务 VOID HookService(){ MmLockPagableDataSection( (PVOID) &RawMSR_SYSENTER_EIP); MmLockPagableCodeSection( (PVOID) &MY_SYSENTER_PROC); GetMSR_EIP(); SetNewMSR_EIP(); //将mySYSENTER_Proc设置为SYSENTER的入口 return; } |
|
5楼#
发布于:2007-04-05 04:48
好像还有个参数描述表
_KiServiceLimit dd 11Ch _KiArgumentTable |
|