-
-
通用的inline hook,
-
发表于: 2014-3-3 11:34 718
-
#include "ntddk.h"
#include "ade32.h"
#define KERNEL_SEG 0x0008
UNICODE_STRING ObjPtrName = { 0 };
typedef void (*DBGPRINT)();
DBGPRINT MyDbgPrint = NULL;
typedef struct patch_info
{
int patch_len;
BYTE org_bytes[32];
PVOID org_func_addr;
PVOID new_func_addr;
}PATCH_INFO, *PPATCH_INFO;
ULONG g_uCr0 = 0;
void WPOFF()
{
ULONG uAttr;
_asm
{
push eax;
mov eax, cr0;
mov uAttr, eax;
and eax, 0FFFEFFFFh; // CR0 16 BIT = 0
mov cr0, eax;
pop eax;
cli
};
g_uCr0 = uAttr;
}
VOID WPON()
{
_asm
{
sti
push eax;
mov eax, g_uCr0;
mov cr0, eax;
pop eax;
};
}
NTSTATUS PatchCommonDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
PVOID GetKernelFuncAddr(PCHAR func_name)
{
ANSI_STRING ansi_name;
UNICODE_STRING uni_name;
PVOID func_addr;
RtlInitString(&ansi_name, func_name);
RtlAnsiStringToUnicodeString(&uni_name, &ansi_name, TRUE);
func_addr = MmGetSystemRoutineAddress(&uni_name);
RtlFreeUnicodeString(&uni_name);
return func_addr;
}
BOOLEAN IfDirty(PVOID func_addr, CHAR* startbytes, int len)
{
PCHAR addr = (PCHAR)func_addr;
int i = 0;
while(i < len)
{
if(addr[i] != startbytes[i])
return TRUE;
i++;
}
return FALSE;
}
__declspec(naked) NewStubForIoGetDeviceObjectPointer()
{
PUNICODE_STRING ObjectName;
_asm
{
nop
nop
nop
nop
nop
push ebp
mov ebp, esp
sub esp, __LOCAL_SIZE
mov edi, [ebp+8]
mov ObjectName, edi
}
_asm mov edi, DWORD PTR DbgPrint
_asm mov MyDbgPrint, edi
//MyDbgPrint("object name %ws/n", ObjectName->Buffer);
//_asm add esp, 8
if(RtlCompareUnicodeString((PUNICODE_STRING)ObjectName, &ObjPtrName, TRUE) == 0)
{
_asm
{
mov esp, ebp
pop ebp
mov eax, 0xC000000D
ret 10h
}
}
__asm
{
mov esp, ebp
pop ebp
//must declare this tag for insert orginal function's starting bytes here
_emit 0xaa
_emit 0xaa
_emit 0xaa
_emit 0xaa
}
}
int GetPatchLength(PCHAR func_start, int max_need_len)
{
int one_oplen = 0;
int actual_oplen = 0;
struct disasm_struct dis;
while(actual_oplen < max_need_len)
{
one_oplen = ade32_disasm(func_start, &dis);
func_start += one_oplen;
actual_oplen += one_oplen;
}
return actual_oplen;
}
BOOLEAN UnpatchX(PPATCH_INFO pach)
{
if(pach->patch_len &&
pach->org_func_addr)
{
RtlCopyMemory(pach->org_func_addr, pach->org_bytes, pach->patch_len);
return TRUE;
}
return FALSE;
}
BOOLEAN PatchX(PCHAR func_name, PVOID new_func, int new_func_len, PPATCH_INFO pach)
{
int i = 0;
BOOLEAN bFoundTag = FALSE;
WPOFF();
//get original function's address
pach->org_func_addr = GetKernelFuncAddr(func_name);
if(pach->org_func_addr)
{
pach->patch_len = GetPatchLength(pach->org_func_addr, 7);
pach->new_func_addr = (PVOID)ExAllocatePoolWithTag(NonPagedPool, new_func_len, ' kdD');
if(pach->new_func_addr)
{
RtlCopyMemory(pach->new_func_addr, new_func, new_func_len);
for(i = 0; i < new_func_len-(pach->patch_len + 7); i++)
{
//find tag for insert orginal function's starting bytes
if(((BYTE*)new_func)[i] == 0xaa &&
((BYTE*)new_func)[i+1] == 0xaa &&
((BYTE*)new_func)[i+2] == 0xaa &&
((BYTE*)new_func)[i+3] == 0xaa )
{
bFoundTag = TRUE;
break;
}
}
if(bFoundTag)
{
//save original function's starting bytes for later Unpatch
RtlCopyMemory(pach->org_bytes, pach->org_func_addr, pach->patch_len);
//modify new_func to jmp to original function
RtlCopyMemory((BYTE*)pach->new_func_addr + i, pach->org_func_addr, pach->patch_len);
((BYTE*)pach->new_func_addr + i + pach->patch_len)[0] = 0xea;
*(ULONG*)((BYTE*)pach->new_func_addr + i + pach->patch_len + 1) = (ULONG)pach->org_func_addr + pach->patch_len;
*(USHORT*)((BYTE*)pach->new_func_addr + i + pach->patch_len + 5) = KERNEL_SEG;
//modify original function to jmp to new_func first
((BYTE*)pach->org_func_addr)[0] = 0xea;
*(ULONG*)((BYTE*)pach->org_func_addr+1) = (ULONG)pach->new_func_addr;
*(USHORT*)((BYTE*)pach->org_func_addr+5) = KERNEL_SEG;
return TRUE;
}
else
{
ExFreePool(pach->new_func_addr);
pach->new_func_addr = NULL;
}
}
}
WPON();
return FALSE;
}
NTSTATUS PatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
WCHAR* DeviceName = L"//Device//Harddisk0//DR0";
UNICODE_STRING uni_name;
PDEVICE_OBJECT TempDeviceObject;
PFILE_OBJECT TempFileObject;
NTSTATUS status;
PATCH_INFO pach;
switch(irpSp->Parameters.DeviceIoControl.IoControlCode)
{
case 1:
RtlZeroMemory(&pach, sizeof(PATCH_INFO));
PatchX("IoGetDeviceObjectPointer", NewStubForIoGetDeviceObjectPointer, 256, &pach);
RtlInitUnicodeString(&uni_name, DeviceName);
status = IoGetDeviceObjectPointer(&uni_name, FILE_READ_DATA, &TempFileObject, &TempDeviceObject);
//UnpatchX(&pach);
//status = IoGetDeviceObjectPointer(&uni_name, FILE_READ_DATA, &TempFileObject, &TempDeviceObject);
break;
}
return PatchCommonDispatch(DeviceObject, Irp);
}
void PatchUnload( PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING uni_symbolic;
IoDeleteDevice(DriverObject->DeviceObject);
RtlInitUnicodeString(&uni_symbolic, L"//DosDevices//doptr");
IoDeleteSymbolicLink(&uni_symbolic);
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
PDEVICE_OBJECT DeviceObject;
WCHAR* DeviceName = L"//Device//doptr";
WCHAR* SymbolicName = L"//DosDevices//doptr";
UNICODE_STRING uni_name, uni_symbolic;
NTSTATUS status;
int i;
RtlInitUnicodeString(&ObjPtrName, L"//Device//Harddisk0//DR0");
for(i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
DriverObject->MajorFunction[i] = PatchCommonDispatch;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PatchDeviceControl;
DriverObject->DriverUnload = PatchUnload;
RtlInitUnicodeString(&uni_name, DeviceName);
status = IoCreateDevice(DriverObject,
0,
&uni_name,
0,
0,
FALSE,
&DeviceObject);
if(NT_SUCCESS(status))
{
DbgPrint("%ws/n", SymbolicName);
RtlInitUnicodeString(&uni_symbolic, SymbolicName);
status = IoCreateSymbolicLink(&uni_symbolic, &uni_name);
}
return status;
}
本文来自 xiaoqiangvs007的专栏
http://blog.csdn.net/xiaoqiangvs007/article/details/5543319
#include "ade32.h"
#define KERNEL_SEG 0x0008
UNICODE_STRING ObjPtrName = { 0 };
typedef void (*DBGPRINT)();
DBGPRINT MyDbgPrint = NULL;
typedef struct patch_info
{
int patch_len;
BYTE org_bytes[32];
PVOID org_func_addr;
PVOID new_func_addr;
}PATCH_INFO, *PPATCH_INFO;
ULONG g_uCr0 = 0;
void WPOFF()
{
ULONG uAttr;
_asm
{
push eax;
mov eax, cr0;
mov uAttr, eax;
and eax, 0FFFEFFFFh; // CR0 16 BIT = 0
mov cr0, eax;
pop eax;
cli
};
g_uCr0 = uAttr;
}
VOID WPON()
{
_asm
{
sti
push eax;
mov eax, g_uCr0;
mov cr0, eax;
pop eax;
};
}
NTSTATUS PatchCommonDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
PVOID GetKernelFuncAddr(PCHAR func_name)
{
ANSI_STRING ansi_name;
UNICODE_STRING uni_name;
PVOID func_addr;
RtlInitString(&ansi_name, func_name);
RtlAnsiStringToUnicodeString(&uni_name, &ansi_name, TRUE);
func_addr = MmGetSystemRoutineAddress(&uni_name);
RtlFreeUnicodeString(&uni_name);
return func_addr;
}
BOOLEAN IfDirty(PVOID func_addr, CHAR* startbytes, int len)
{
PCHAR addr = (PCHAR)func_addr;
int i = 0;
while(i < len)
{
if(addr[i] != startbytes[i])
return TRUE;
i++;
}
return FALSE;
}
__declspec(naked) NewStubForIoGetDeviceObjectPointer()
{
PUNICODE_STRING ObjectName;
_asm
{
nop
nop
nop
nop
nop
push ebp
mov ebp, esp
sub esp, __LOCAL_SIZE
mov edi, [ebp+8]
mov ObjectName, edi
}
_asm mov edi, DWORD PTR DbgPrint
_asm mov MyDbgPrint, edi
//MyDbgPrint("object name %ws/n", ObjectName->Buffer);
//_asm add esp, 8
if(RtlCompareUnicodeString((PUNICODE_STRING)ObjectName, &ObjPtrName, TRUE) == 0)
{
_asm
{
mov esp, ebp
pop ebp
mov eax, 0xC000000D
ret 10h
}
}
__asm
{
mov esp, ebp
pop ebp
//must declare this tag for insert orginal function's starting bytes here
_emit 0xaa
_emit 0xaa
_emit 0xaa
_emit 0xaa
}
}
int GetPatchLength(PCHAR func_start, int max_need_len)
{
int one_oplen = 0;
int actual_oplen = 0;
struct disasm_struct dis;
while(actual_oplen < max_need_len)
{
one_oplen = ade32_disasm(func_start, &dis);
func_start += one_oplen;
actual_oplen += one_oplen;
}
return actual_oplen;
}
BOOLEAN UnpatchX(PPATCH_INFO pach)
{
if(pach->patch_len &&
pach->org_func_addr)
{
RtlCopyMemory(pach->org_func_addr, pach->org_bytes, pach->patch_len);
return TRUE;
}
return FALSE;
}
BOOLEAN PatchX(PCHAR func_name, PVOID new_func, int new_func_len, PPATCH_INFO pach)
{
int i = 0;
BOOLEAN bFoundTag = FALSE;
WPOFF();
//get original function's address
pach->org_func_addr = GetKernelFuncAddr(func_name);
if(pach->org_func_addr)
{
pach->patch_len = GetPatchLength(pach->org_func_addr, 7);
pach->new_func_addr = (PVOID)ExAllocatePoolWithTag(NonPagedPool, new_func_len, ' kdD');
if(pach->new_func_addr)
{
RtlCopyMemory(pach->new_func_addr, new_func, new_func_len);
for(i = 0; i < new_func_len-(pach->patch_len + 7); i++)
{
//find tag for insert orginal function's starting bytes
if(((BYTE*)new_func)[i] == 0xaa &&
((BYTE*)new_func)[i+1] == 0xaa &&
((BYTE*)new_func)[i+2] == 0xaa &&
((BYTE*)new_func)[i+3] == 0xaa )
{
bFoundTag = TRUE;
break;
}
}
if(bFoundTag)
{
//save original function's starting bytes for later Unpatch
RtlCopyMemory(pach->org_bytes, pach->org_func_addr, pach->patch_len);
//modify new_func to jmp to original function
RtlCopyMemory((BYTE*)pach->new_func_addr + i, pach->org_func_addr, pach->patch_len);
((BYTE*)pach->new_func_addr + i + pach->patch_len)[0] = 0xea;
*(ULONG*)((BYTE*)pach->new_func_addr + i + pach->patch_len + 1) = (ULONG)pach->org_func_addr + pach->patch_len;
*(USHORT*)((BYTE*)pach->new_func_addr + i + pach->patch_len + 5) = KERNEL_SEG;
//modify original function to jmp to new_func first
((BYTE*)pach->org_func_addr)[0] = 0xea;
*(ULONG*)((BYTE*)pach->org_func_addr+1) = (ULONG)pach->new_func_addr;
*(USHORT*)((BYTE*)pach->org_func_addr+5) = KERNEL_SEG;
return TRUE;
}
else
{
ExFreePool(pach->new_func_addr);
pach->new_func_addr = NULL;
}
}
}
WPON();
return FALSE;
}
NTSTATUS PatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
WCHAR* DeviceName = L"//Device//Harddisk0//DR0";
UNICODE_STRING uni_name;
PDEVICE_OBJECT TempDeviceObject;
PFILE_OBJECT TempFileObject;
NTSTATUS status;
PATCH_INFO pach;
switch(irpSp->Parameters.DeviceIoControl.IoControlCode)
{
case 1:
RtlZeroMemory(&pach, sizeof(PATCH_INFO));
PatchX("IoGetDeviceObjectPointer", NewStubForIoGetDeviceObjectPointer, 256, &pach);
RtlInitUnicodeString(&uni_name, DeviceName);
status = IoGetDeviceObjectPointer(&uni_name, FILE_READ_DATA, &TempFileObject, &TempDeviceObject);
//UnpatchX(&pach);
//status = IoGetDeviceObjectPointer(&uni_name, FILE_READ_DATA, &TempFileObject, &TempDeviceObject);
break;
}
return PatchCommonDispatch(DeviceObject, Irp);
}
void PatchUnload( PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING uni_symbolic;
IoDeleteDevice(DriverObject->DeviceObject);
RtlInitUnicodeString(&uni_symbolic, L"//DosDevices//doptr");
IoDeleteSymbolicLink(&uni_symbolic);
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
PDEVICE_OBJECT DeviceObject;
WCHAR* DeviceName = L"//Device//doptr";
WCHAR* SymbolicName = L"//DosDevices//doptr";
UNICODE_STRING uni_name, uni_symbolic;
NTSTATUS status;
int i;
RtlInitUnicodeString(&ObjPtrName, L"//Device//Harddisk0//DR0");
for(i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
DriverObject->MajorFunction[i] = PatchCommonDispatch;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PatchDeviceControl;
DriverObject->DriverUnload = PatchUnload;
RtlInitUnicodeString(&uni_name, DeviceName);
status = IoCreateDevice(DriverObject,
0,
&uni_name,
0,
0,
FALSE,
&DeviceObject);
if(NT_SUCCESS(status))
{
DbgPrint("%ws/n", SymbolicName);
RtlInitUnicodeString(&uni_symbolic, SymbolicName);
status = IoCreateSymbolicLink(&uni_symbolic, &uni_name);
}
return status;
}
本文来自 xiaoqiangvs007的专栏
http://blog.csdn.net/xiaoqiangvs007/article/details/5543319
赞赏
他的文章
看原图
赞赏
雪币:
留言: