undocument 上的那段hook nAtive Api的太多也太复杂了,自己先hook个简单的,想hook一个nAtive Api,记录下调用这个API的进程的id,并返给user-mode程序,再调用真正的APi ,现在实现了第一步,hook住了,并能给扯下来,而不蓝屏(就这么屁大点儿的事儿弄了一下午,蓝了n次),下一步就是怎样在ring 0下申请下一快空间,记录id,并在user-mode程序要求时返给它
#include <ntddk.h>
#pragma comment (lib,"ntdll.lib")
typedef NTSTATUS (NTAPI *NTPROC) ();
typedef NTPROC *PNTPROC;
#define NTPROC_ sizeof (NTPROC)
typedef struct _SYSTEM_SERVICE_TABLE
{
/*000*/ PNTPROC ServiceTable; // array of entry points
/*004*/ LONG* CounterTable; // array of usage counters
/*008*/ LONG ServiceLimit; // number of table entries
/*00C*/ UCHAR ArgumentTable; // array of byte counts
/*010*/ }
SYSTEM_SERVICE_TABLE,
* PSYSTEM_SERVICE_TABLE,
**PPSYSTEM_SERVICE_TABLE;
#define SYSTEM_SERVICE_TABLE_ /
sizeof (SYSTEM_SERVICE_TABLE)
//--------------------------------------------------------------------
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
/*000*/ SYSTEM_SERVICE_TABLE ntoskrnl; // ntoskrnl.exe (native api)
/*010*/ SYSTEM_SERVICE_TABLE win32k; // win32k.sys (gdi/user)
/*020*/ SYSTEM_SERVICE_TABLE Table3; // not used
/*030*/ SYSTEM_SERVICE_TABLE Table4; // not used
/*040*/ }
SERVICE_DESCRIPTOR_TABLE,
* PSERVICE_DESCRIPTOR_TABLE,
**PPSERVICE_DESCRIPTOR_TABLE;
#define SERVICE_DESCRIPTOR_TABLE_ /
sizeof (SERVICE_DESCRIPTOR_TABLE)
//--------------------------------------------------------------------
extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
VOID utyDriverUnloAd(IN PDRIVER_OBJECT DriverObject);
NTSTATUS utyDriverIO(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);
NTSTATUS utyDriverIOControl(IN PDEVICE_OBJECT,IN PIRP Irp);
NTPROC utyFunction(void);
PDEVICE_OBJECT utyDriverDeviceObject = NULL;
ULONG out_size;
LONG temp;
NTSTATUS DriverEntry (PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPAth)
{
UNICODE_STRING ntDeviceNAme;
UNICODE_STRING win32DeviceNAme;
NTSTATUS stAtus;
PNTPROC ServiceTAble;
RtlInitUnicodeString(&ntDeviceNAme,L"//Device//utyDriver");
if (!NT_SUCCESS(stAtus = IoCreateDevice(DriverObject,0,&ntDeviceNAme,
FILE_DEVICE_UNKNOWN,0,FALSE,
&utyDriverDeviceObject)))
return STATUS_NO_SUCH_DEVICE;
utyDriverDeviceObject->Flags |= DO_BUFFERED_IO;
RtlInitUnicodeString(&win32DeviceNAme,L"//DosDevices//utyDriver");
if (!NT_SUCCESS(stAtus = IoCreateSymbolicLink(&win32DeviceNAme,&ntDeviceNAme)))
return STATUS_NO_SUCH_DEVICE;
DriverObject->MajorFunction[IRP_MJ_CREATE ] = utyDriverIO;
DriverObject->MajorFunction[IRP_MJ_CLOSE ] = utyDriverIO;
DriverObject->MajorFunction[IRP_MJ_READ ] = utyDriverIO;
DriverObject->MajorFunction[IRP_MJ_WRITE ] = utyDriverIO;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]= utyDriverIOControl;
DriverObject->DriverUnload = utyDriverUnloAd;
InterlockedExchange((PLONG)&temp,*((LONG*)KeServiceDescriptorTable->ntoskrnl.ServiceTable+ 151));
InterlockedExchange((PLONG)KeServiceDescriptorTable->ntoskrnl.ServiceTable+ 151,(LONG)utyFunction);
return STATUS_SUCCESS;
}
//-------------------------------------------------------------------------------------
VOID utyDriverUnloAd(IN PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING win32DeviceNAme;
InterlockedExchange((PLONG)KeServiceDescriptorTable->ntoskrnl.ServiceTable+ 151,(LONG)temp);
RtlInitUnicodeString(&win32DeviceNAme,L"//DosDevices//utyDriver");
IoDeleteSymbolicLink(&win32DeviceNAme);
IoDeleteDevice(utyDriverDeviceObject);
}
//-------------------------------------------------------------------------------------
NTSTATUS utyDriverIO(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return Irp->IoStatus.Status;
}
//-------------------------------------------------------------------------------------
NTSTATUS utyDriverIOControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
PIO_STACK_LOCATION stAck;
UCHAR *in_buffer,*out_buffer;
ULONG code,ret;
stAck = IoGetCurrentIrpStackLocation(Irp);
//out_size = stAck->Parameters.DeviceIoControl.OutputBufferLengeh;
code = stAck->Parameters.DeviceIoControl.IoControlCode;
in_buffer = out_buffer = Irp->AssociatedIrp.SystemBuffer;
ret = STATUS_SUCCESS;
/*switch(code)
{
}*/
return ret;
}
//-------------------------------------------------------------------------------------
NTPROC utyFunction(void)
{
return STATUS_SUCCESS;
}
//-------------------------------------------------------------------------------------
基本照抄hxdef100的,其实在第一步中,只需要DriverEntry和DriverUnloAd就行了,
开始一大堆是用来定义SERVICE_DESCRIPTOR_TABLE的,奇怪的是居然DWORD通不过编译,用LONG代替,
被hook的函数我选择的是NtReAdFile,比较容易看出效果,当替换的时候,似乎必须用 InterlockedExchange
特别需要注意的是指针的用法,比如InterlockedExchange((PLONG)&temp,*((LONG*)KeServiceDescriptorTable->ntoskrnl.ServiceTable+ 151));
,(LONG*)KeServiceDescriptorTable->ntoskrnl.ServiceTable 是指针,加151是移动了151*4个地址,既增加了151个指针的长度,,((LONG*)KeServiceDescriptorTable->ntoskrnl.ServiceTable+ 151)仍然是个指针,需要这个指针所指向的函数的入口地址,就要用*,,*((LONG*)KeServiceDescriptorTable->ntoskrnl.ServiceTable+ 151),这一步也是让我最郁闷的,hook前先保留NtReAdFile的地址,,不hook了再把保存的地址还回去,没搞懂指针,结果回的地址总是不对,,通过sice看汇编会比看c程序清楚很多