inline hook NtQuerySystemInformation 保护进程

inline hook & NtQuerySystemInformation & ring0
本文呢,是介绍一种保护进程不被结束的方法,这个方法不算新了,好旧好旧的了,其实呢,也是 hook 了某个函数来实现的,不过没有 hook NtOpenProcess 、NtTerminateProcess、KiInsertQueuApc 等函数,而是 hook 了 NtQuerySystemInformation 来保护我们的进程,NtQuerySystemInformation 是用来查询系统信息的,可以查询的系统信息有 54 种这么多,其中 ID 是 5 的话呢,就会返回一个链表,这个链表中包括了当前系统中的所以的进程名、进程 ID,也就是说这个函数可以获取系统的进程列表,我们可以 hook 这个函数来隐藏进程,不过这次是保护进程,不是隐藏哦
在 ring3 中,列举进程的方法是调用 Tool32 或者 psapi 中的 EnumProcess,可是这些函数都调用了 ZwQuerySystemInformation 然后在NtQuerySystemInformation,也就是我们 hook NtQuerySystemInformation 就可以保护&隐藏进程了哇
hookNtQuerySystemInformation 的方法有好的,可以修改 SSDT,也可以修改函数前 5 个字节,也就是inline hook了,本文采用后者哦
在函数开始的5个字节中,改为一个 Jmp 指令,让她在调用这个函数的时候跳转到我们的函数中,我们在经过一些处理后再调用原来的****
流程如下:
cli
mov eax,cr0
and eax,0fffeffffh
mov cr0,eax
修改前5个字节
mov eax,cr0
or eax,not 0fffeffffh
mov cr0,eax
sti
这儿说下怎么样保护进程,在NtQuerySystemInformation返回的链表中包含了进程的ID,想一下如果我们把某个进程的ID改了后再返回给别人,那么别人就不会得到某个进程的正确的ID了,这样她再怎么NtOpenProcess 也没有了吧,因为她得到是一个错误的ID了哇,(听起来好像好衰,但有什么办法呢,现实就是这样)
下面代码奉上


///////////////////////////////////////////////////////////////////////////////
///
/// Copyright (c) 2009 - <company name here>
///
/// original filename: zhenzhen_feifei_inlinehook_kernel.cpp
/// Project : zhenzhen_feifei_inlinehook_kernel
/// Date of creation : 2009-07-08
/// Author(s) :
///
/// Purpose : <description>
///
/// Revisions:
/// 0000 [2009-07-08] Initial revision.
///
///////////////////////////////////////////////////////////////////////////////

// $Id$

#ifdef __cplusplus
extern "C" {
#endif
#include <ntddk.h>
#include <ntifs.h>
#include <string.h>
#ifdef __cplusplus
}; // extern "C"
#endif

#include ".h"

#ifdef __cplusplus
namespace { // anonymous namespace to limit the scope of this global variable!
#endif
PDRIVER_OBJECT pdoGlobalDrvObj = 0;
#ifdef __cplusplus
}; // anonymous namespace
#endif
PVOID inlinehook(UNICODE_STRING *hookfunction,ULONG NewFunction,UCHAR oldCode[5]);
void uninlinehook(PVOID oldfunaddr,UCHAR oldcode[5]);
PVOID lpNtQuerySystemInformation;
UCHAR boldCode[5];
ULONG a;
NTSTATUS MyNtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG Length,
OUT PULONG ReturnLength);
NTSTATUS ZHENZHENFEIFEI_INLINEHOOK_KERNEL_DispatchCreateClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status = STATUS_SUCCESS;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}

NTSTATUS ZHENZHENFEIFEI_INLINEHOOK_KERNEL_DispatchDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);

switch(irpSp->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_ZHENZHENFEIFEI_INLINEHOOK_KERNEL_OPERATION:
// status = SomeHandlerFunction(irpSp);
break;
default:
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Information = 0;
break;
}

status = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}

VOID ZHENZHENFEIFEI_INLINEHOOK_KERNEL_DriverUnload(
IN PDRIVER_OBJECT DriverObject
)
{
PDEVICE_OBJECT pdoNextDeviceObj = pdoGlobalDrvObj->DeviceObject;
IoDeleteSymbolicLink(&usSymlinkName);

// Delete all the device objects
while(pdoNextDeviceObj)
{
PDEVICE_OBJECT pdoThisDeviceObj = pdoNextDeviceObj;
pdoNextDeviceObj = pdoThisDeviceObj->NextDevice;
IoDeleteDevice(pdoThisDeviceObj);
}
uninlinehook(lpNtQuerySystemInformation,boldCode);
}

#ifdef __cplusplus
extern "C" {
#endif
NTSTATUS DriverEntry(
IN OUT PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
PDEVICE_OBJECT pdoDeviceObj = 0;
NTSTATUS status = STATUS_UNSUCCESSFUL;
pdoGlobalDrvObj = DriverObject;

// Create the device object.
if(!NT_SUCCESS(status = IoCreateDevice(
DriverObject,
0,
&usDeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&pdoDeviceObj
)))
{
// Bail out (implicitly forces the driver to unload).;
return status;
};

// Now create the respective symbolic link object
if(!NT_SUCCESS(status = IoCreateSymbolicLink(
&usSymlinkName,
&usDeviceName
)))
{
IoDeleteDevice(pdoDeviceObj);
return status;
}

// NOTE: You need not provide your own implementation for any major function that
// you do not want to handle. I have seen code using DDKWizard that left the
// *empty* dispatch routines intact. This is not necessary at all!
DriverObject->MajorFunction[IRP_MJ_Create] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] = ZHENZHENFEIFEI_INLINEHOOK_KERNEL_DispatchCreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ZHENZHENFEIFEI_INLINEHOOK_KERNEL_DispatchDeviceControl;
DriverObject->DriverUnload = ZHENZHENFEIFEI_INLINEHOOK_KERNEL_DriverUnload;
UNICODE_STRING usNtOpenProcess;
RtlInitUnicodeString(&usNtOpenProcess,L"NtQuerySystemInformation");
lpNtQuerySystemInformation= inlinehook(&usNtOpenProcess,(ULONG)MyNtQuerySystemInformation,boldCode);
return STATUS_SUCCESS;
}
#ifdef __cplusplus
}; // extern "C"
#endif
PVOID inlinehook(UNICODE_STRING *hookfunction,ULONG NewFunction,UCHAR oldCode[5])
{
PVOID lpfunname = MmGetSystemRoutineAddress(hookfunction);
DbgPrint("\nyuan dizhi shi :%x,",oldCode);
int ijmpaddr;
UCHAR uchjmpcode[5] = {0xE9,0,0,0,0};
ijmpaddr = (UCHAR*)NewFunction - (UCHAR*)lpfunname - 5;
RtlCopyMemory(uchjmpcode+1,&ijmpaddr,4);
DbgPrint("\n%x",uchjmpcode);
__asm cli;
__asm mov eax,cr0;
__asm and eax,0fffeffffh;
__asm mov cr0,eax;
RtlCopyMemory(oldCode,lpfunname,5);
RtlCopyMemory(lpfunname,uchjmpcode,5);
__asm mov eax,cr0;
__asm or eax,not 0fffeffffh;
__asm mov cr0,eax;
__asm sti;
return lpfunname;
}
void uninlinehook(PVOID oldfunaddr,UCHAR oldcode[5])
{
__asm cli;
__asm mov eax,cr0;
__asm and eax,0fffeffffh;
__asm mov cr0,eax;
//DbgPrint("%x\n",oldCode);
RtlCopyMemory(oldfunaddr,oldcode,5);
__asm mov eax,cr0;
__asm or eax,not 0fffeffffh;
__asm mov eax,cr0;
__asm sti;
}
NTSTATUS
MyNtQuerySystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG Length,
OUT PULONG ReturnLength)
{
SYSTEM_PROCESSES_INFORMATION *lpspi = 0,*lpspia = 0;
lpspi = (SYSTEM_PROCESSES_INFORMATION*)SystemInformation;
//lpspia = lpspi;
UNICODE_STRING aProcessName;
RtlInitUnicodeString(&aProcessName,L"Explorer.exe");
uninlinehook(lpNtQuerySystemInformation,boldCode);
NTSTATUS a = Zwq(SystemInformationClass,SystemInformation,Length,ReturnLength);
UNICODE_STRING usNtOpenProcess;
RtlInitUnicodeString(&usNtOpenProcess,L"NtQuerySystemInformation");
lpNtQuerySystemInformation= inlinehook(&usNtOpenProcess,(ULONG)MyNtQuerySystemInformation,boldCode);

if(SystemInformationClass != 5 || !NT_SUCCESS(a)) {
return a;
}
while(lpspi->NextEntryDelta != 0) {
if(RtlEqualUnicodeString(&aProcessName,&lpspi->ProcessName,1)) {
//lpspia->NextEntryDelta += lpspi->NextEntryDelta;
lpspi->ProcessId = 123;
}
//lpspia = lpspi;
lpspi = (SYSTEM_PROCESSES_INFORMATION*)((PUCHAR)lpspi+lpspi->NextEntryDelta);
}
return a;
}

文章来自: 本站原创
Tags:
评论: 1 | 查看次数: 12499