内核级利用通用Hook函数方法检测进程
生活随笔
收集整理的這篇文章主要介紹了
内核级利用通用Hook函数方法检测进程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
介紹通用Hook的一點思想:
????在系統內核級中,MS的很多信息都沒公開,包括函數的參數數目,每個參數的類型等。在系統內核中,訪問了大量的寄存器,而很多寄存器的值,是上層調用者提供的。如果值改變系統就會變得不穩定。很可能出現不可想象的后果。另外有時候對需要Hook的函數的參數不了解,所以不能隨便就去改變它的堆棧,如果不小心也有可能導致藍屏。所以Hook的最佳原則是在自己的Hook函數中呼叫原函數的時候,所有的寄存器值,堆棧里面的值和Hook前的信息一樣。這樣就能保證在原函數中不會出錯。一般我們自己的Hook的函數都是寫在C文件里面的。例如Hook的目標函數KiReadyThread。
那么一般就自己實現一個:
MyKiReadyThread(...)
{
????......
????call KiReadyThread
????......
}
但是用C編譯器編譯出來的代碼會出現一個堆棧幀:
Push ebp
mov??ebp,esp
這就和我們的初衷不改變寄存器的數違背了。所以我們可以自己用匯編來實現MyKiReadyThread。
_func@0 proc
????pushad????????;保存通用寄存器
????call _cfunc@0??;這里是在進入原來函數前進行的一些處理。
????popad ????????;恢復通用寄存器
????push eax??
????mov eax,[esp+4] ;得到系統在call 目標函數時入棧的返回地址。
????mov ds:_OrgRet,eax ;保存在一個臨時變量中
????pop eax
????mov [esp],retaddr??;把目標函數的返回地址改成自己的代碼空間的返回地址,使其返回????????????????后能接手繼續的處理
????jmp _OrgDestFunction ;跳到原目標函數中
retaddr:
????pushad???????? ;原函數處理完后保存寄存器
????call _HookDestFunction@0 ;再處理
????popad??????;回復寄存器
????jmp ds:_OrgRet ;跳到系統調用目標函數的下一條指令。
_func@0 endp
當我們要攔截目標API的時候,只要修改原函數頭5個字節的機器為一個JMP _func就行了。
然后把原來的5字節保存。在跳入原函數時,恢復那5個字節即可。
Hook KiReadyThread檢測系統中的進程:
在線程調度搶占的的時候會調用KiReadyThread,它的原型為
VOID FASTCALL KiReadyThread (IN PRKTHREAD Thread)
在進入KiReadyThread時,ecx指向Thread。
所以完全可以Hook KiReadyThread 然后用ecx的值得到但前線程的進程信息。
KiReadyThread沒被ntosknrl.exe導出,所以通過硬編碼來。在2000Sp4中地址為0x8043141f
具體實現:
// 1.cpp
#ifdef __cplusplus
extern "C" {
#endif
#include "ntddk.h"
#include "string.h"
#include "ntifs.h"
#include "stdio.h"
#define FILE_DEVICE_EVENT??0x8000
#define IOCTL_PASSBUF /
????CTL_CODE(FILE_DEVICE_EVENT, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
void DriverUnload (IN PDRIVER_OBJECT pDriverObject);
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
void cfunc ();
void HookDestFunction();
NTSTATUS DeviceIoControlDispatch(IN??PDEVICE_OBJECT??DeviceObject,
???????????????????????????????? IN??PIRP????????????pIrp);
extern void func();
void ResumeDestFunction();
const WCHAR devLink[]??= L"//??//MyEvent";
const WCHAR devName[]??= L"//Device//MyEvent";
UNICODE_STRING??????????devNameUnicd;
UNICODE_STRING??????????devLinkUnicd;????
ULONG OrgDestFunction = (ULONG)0x8043141f; //KiReadyThread
char JmpMyCode [] = {0xE9,0x00,0x00,0x00,0x00};
char OrgCode [5];
char OutBuf[128][16];
int Count = 0;
ULONG orgcr0;
#ifdef __cplusplus
}
#endif
VOID DisableWriteProtect( PULONG pOldAttr)
{
???? ULONG uAttr;
???? _asm
????{
??????????push eax;
??????????mov??eax, cr0;
??????????mov??uAttr, eax;
??????????and??eax, 0FFFEFFFFh; // CR0 16 BIT = 0
??????????mov??cr0, eax;
??????????pop??eax;
????};
???? *pOldAttr = uAttr; //保存原有的 CRO 屬性
}
VOID EnableWriteProtect( ULONG uOldAttr )
{
??_asm
??{
?????? push eax;
?????? mov??eax, uOldAttr; //恢復原有 CR0 屬性
?????? mov??cr0, eax;
?????? pop??eax;
??};
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegistryPath)
{
????NTSTATUS????????????????Status;
????PDEVICE_OBJECT????????????pDevice;
????DbgPrint("DriverEntry called!/n");
????RtlInitUnicodeString (&devNameUnicd, devName );
????RtlInitUnicodeString (&devLinkUnicd, devLink );
????Status = IoCreateDevice ( pDriverObject,
????0,
???? ????&devNameUnicd,
????FILE_DEVICE_UNKNOWN,
?????? 0,
?????? TRUE,
?????? &pDevice );
????????if( !NT_SUCCESS(Status))
????????{
????????DbgPrint(("Can not create device./n"));
????????return Status;
????}
?? ????Status = IoCreateSymbolicLink (&devLinkUnicd, &devNameUnicd);
?? ????if( !NT_SUCCESS(Status))
?? ????{
?????? ????DbgPrint(("Cannot create link./n"));
?????? ????return Status;
?? ????}
?? ????pDriverObject->DriverUnload??= DriverUnload;
?? ????pDriverObject->MajorFunction[IRP_MJ_CREATE] =
????pDriverObject->MajorFunction[IRP_MJ_CLOSE] =
????pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =????DeviceIoControlDispatch;
??????
????pDriverObject->DriverUnload = DriverUnload;
????* ( (ULONG*) (JmpMyCode+1) ) = (ULONG)func - (ULONG)OrgDestFunction - 5;
????memcpy(OrgCode,(char*)OrgDestFunction,5);
????HookDestFunction();
????
????return STATUS_SUCCESS;
}
void DriverUnload (IN PDRIVER_OBJECT pDriverObject)
{
????NTSTATUS????????????status;
????ResumeDestFunction();
????if(pDriverObject->DeviceObject != NULL)
????????{
?????? ????status=IoDeleteSymbolicLink( &devLinkUnicd );
????????if ( !NT_SUCCESS( status ) )
????????????{
????????????????????DbgPrint((??"IoDeleteSymbolicLink() failed/n" ));
????????????}
????????????IoDeleteDevice( pDriverObject->DeviceObject );
????????}
}
void DisplayName(PKTHREAD Thread)
{
????PKPROCESS Process = Thread->ApcState.Process;
????PEPROCESS pEprocess = (PEPROCESS)Process;
????DbgPrint("ImageFileName = %s /n",pEprocess->ImageFileName);
????sprintf(OutBuf[Count++],"%s",pEprocess->ImageFileName);
}
void cfunc (void)
{
????ULONG PKHeader=0;
????__asm
????{
????????mov PKHeader,ecx??//ecx寄存器是KiReadyThread中的PRKTHREAD參數
????}
????ResumeDestFunction();
????
????if ( PKHeader != 0 && Count < 128 )
????{
????????DisplayName((PKTHREAD)PKHeader);????
????}????
}
void HookDestFunction()
{
????DisableWriteProtect(&orgcr0);
????memcpy((char*)OrgDestFunction,JmpMyCode,5);
????EnableWriteProtect(orgcr0);????
}
void ResumeDestFunction()
{
????DisableWriteProtect(&orgcr0);
????memcpy((char*)OrgDestFunction,OrgCode,5);
????EnableWriteProtect(orgcr0);
}
NTSTATUS DeviceIoControlDispatch(
???????????????????????????????? IN??PDEVICE_OBJECT??DeviceObject,
???????????????????????????????? IN??PIRP????????????pIrp
???????????????????????????????? )
{
????PIO_STACK_LOCATION??????????????irpStack;
????NTSTATUS????????????????????????status;
????PVOID?????????????????????????? inputBuffer;
????ULONG?????????????????????????? inputLength;
????PVOID?????????????????????????? outputBuffer;
????ULONG?????????????????????????? outputLength;
????OBJECT_HANDLE_INFORMATION?????? objHandleInfo;
????status = STATUS_SUCCESS;
????// 取出IOCTL請求代碼
????irpStack = IoGetCurrentIrpStackLocation(pIrp);
????switch (irpStack->MajorFunction)
????{
????case IRP_MJ_CREATE :
????????DbgPrint("Call IRP_MJ_CREATE/n");
????????break;
????case IRP_MJ_CLOSE:
????????DbgPrint("Call IRP_MJ_CLOSE/n");
????????break;
????case IRP_MJ_DEVICE_CONTROL:
????????DbgPrint("IRP_MJ_DEVICE_CONTROL/n");
????????inputLength=irpStack->Parameters.DeviceIoControl.InputBufferLength;
????????outputLength=irpStack->Parameters.DeviceIoControl.OutputBufferLength;
????????switch (irpStack->Parameters.DeviceIoControl.IoControlCode)
????????{
????????????case????IOCTL_PASSBUF:
????????????{
????????????????RtlCopyMemory(pIrp->UserBuffer, OutBuf, 20*16);
????????????????
????????????????memset(OutBuf,0,128*16);
????????????????Count = 0;
????????????????break;
????????????}
????????????default:
????????????????break;
????????}
????default:
????????DbgPrint("Call IRP_MJ_UNKNOWN/n");
????????break;
????}
????pIrp->IoStatus.Status = status;
????pIrp->IoStatus.Information = 0;
????IoCompleteRequest (pIrp, IO_NO_INCREMENT);
????return status;
}
// 1.asm
.386
.model small
.data
_OrgRet dd 0
.code
public _func@0
extrn _cfunc@0:near
extrn _HookDestFunction@0:near
extrn _OrgDestFunction:DWORD
_func@0 proc
????pushad
????call _cfunc@0
????popad
????push eax
????mov eax,[esp+4]
????mov ds:_OrgRet,eax
????pop eax
????mov [esp],retaddr
????jmp _OrgDestFunction
retaddr:
????pushad
????call _HookDestFunction@0
????popad
????jmp ds:_OrgRet
_func@0 endp
END
//
// app.cpp
//
#include <windows.h>
#include <stdio.h>
#define FILE_DEVICE_EVENT??0x8000
#define CTL_CODE( DeviceType, Function, Method, Access ) (???????????????? /
????((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) /
)
#define FILE_ANY_ACCESS???????????????? 0
#define METHOD_BUFFERED???????????????? 0
#define FILE_DEVICE_UNKNOWN???????????? 0x00000022
#define IOCTL_PASSBUF /
????CTL_CODE(FILE_DEVICE_EVENT, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
int main()
{
?? ????HANDLE??????hDevice;????
????????bool????????status;
?? ????ULONG?????? dwReturn;
????????char????????outbuf[129][16];
????????hDevice = NULL;
????????m_hCommEvent = NULL;
????????hDevice = CreateFile( ".//MyEvent",
????????????????????GENERIC_READ|GENERIC_WRITE,
????????????????????FILE_SHARE_READ | FILE_SHARE_WRITE,
????????????????????NULL,
????????????????????OPEN_EXISTING,
????????????????????FILE_ATTRIBUTE_NORMAL,
????????????????????NULL);
????????if(hDevice == INVALID_HANDLE_VALUE)
????????{
?????? ????printf("createfile wrong/n");
?????? ????getchar();
?????? ????return 0;
????????}
????while(1)
????{
????????memset(outbuf,0,129*16);
????????status =DeviceIoControl(hDevice,
????????????????????IOCTL_PASSBUF,
????????????????????NULL,
????????????????????0,
????????????????????&outbuf,
????????????????????128*16,
????????????????????&dwReturn,NULL);
????????if( !status)
????????{
????????????printf("IO wrong+%d/n", GetLastError());
????????????getchar();
????????????return 0;
????????}
????????int c=0;
????????while( *((char*)(&outbuf)+c*16) )
????????{
????????????//把csrss.exe和自身進程信息跳過,因為會產生有大量的信息。
????????????if ( strcmp((char*)(&outbuf)+c*16,"app.exe") && /
???????????????? strcmp((char*)(&outbuf)+c*16,"csrss.exe")??)
????????????????printf("%s/n",(char*)(&outbuf)+c*16);
????????????c++;
????????}
????????Sleep(1);
????}
}
試驗結果:
......
TTPlayer.exe
System
TTPlayer.exe
vrvmon.exe
TTPlayer.exe
System
System
Explorer.EXE
Explorer.EXE
Explorer.EXE
......
測試,編譯環境 2000 Sp4 2000 DDK
沒寫出線程的隱藏進程代碼。不過基本上實現得差不多了,只需要把返回的信息,和Ring3級查詢得到的信息進行適時對比就能查出異常進程了。
本人水平有限,如哪里有錯誤,歡迎高手不吝賜教。
感謝:sinister大哥對小弟的指點及其鼓勵
畢業在即將次愚作獻給我的母校---重慶科技學院
????在系統內核級中,MS的很多信息都沒公開,包括函數的參數數目,每個參數的類型等。在系統內核中,訪問了大量的寄存器,而很多寄存器的值,是上層調用者提供的。如果值改變系統就會變得不穩定。很可能出現不可想象的后果。另外有時候對需要Hook的函數的參數不了解,所以不能隨便就去改變它的堆棧,如果不小心也有可能導致藍屏。所以Hook的最佳原則是在自己的Hook函數中呼叫原函數的時候,所有的寄存器值,堆棧里面的值和Hook前的信息一樣。這樣就能保證在原函數中不會出錯。一般我們自己的Hook的函數都是寫在C文件里面的。例如Hook的目標函數KiReadyThread。
那么一般就自己實現一個:
MyKiReadyThread(...)
{
????......
????call KiReadyThread
????......
}
但是用C編譯器編譯出來的代碼會出現一個堆棧幀:
Push ebp
mov??ebp,esp
這就和我們的初衷不改變寄存器的數違背了。所以我們可以自己用匯編來實現MyKiReadyThread。
_func@0 proc
????pushad????????;保存通用寄存器
????call _cfunc@0??;這里是在進入原來函數前進行的一些處理。
????popad ????????;恢復通用寄存器
????push eax??
????mov eax,[esp+4] ;得到系統在call 目標函數時入棧的返回地址。
????mov ds:_OrgRet,eax ;保存在一個臨時變量中
????pop eax
????mov [esp],retaddr??;把目標函數的返回地址改成自己的代碼空間的返回地址,使其返回????????????????后能接手繼續的處理
????jmp _OrgDestFunction ;跳到原目標函數中
retaddr:
????pushad???????? ;原函數處理完后保存寄存器
????call _HookDestFunction@0 ;再處理
????popad??????;回復寄存器
????jmp ds:_OrgRet ;跳到系統調用目標函數的下一條指令。
_func@0 endp
當我們要攔截目標API的時候,只要修改原函數頭5個字節的機器為一個JMP _func就行了。
然后把原來的5字節保存。在跳入原函數時,恢復那5個字節即可。
Hook KiReadyThread檢測系統中的進程:
在線程調度搶占的的時候會調用KiReadyThread,它的原型為
VOID FASTCALL KiReadyThread (IN PRKTHREAD Thread)
在進入KiReadyThread時,ecx指向Thread。
所以完全可以Hook KiReadyThread 然后用ecx的值得到但前線程的進程信息。
KiReadyThread沒被ntosknrl.exe導出,所以通過硬編碼來。在2000Sp4中地址為0x8043141f
具體實現:
// 1.cpp
#ifdef __cplusplus
extern "C" {
#endif
#include "ntddk.h"
#include "string.h"
#include "ntifs.h"
#include "stdio.h"
#define FILE_DEVICE_EVENT??0x8000
#define IOCTL_PASSBUF /
????CTL_CODE(FILE_DEVICE_EVENT, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
void DriverUnload (IN PDRIVER_OBJECT pDriverObject);
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
void cfunc ();
void HookDestFunction();
NTSTATUS DeviceIoControlDispatch(IN??PDEVICE_OBJECT??DeviceObject,
???????????????????????????????? IN??PIRP????????????pIrp);
extern void func();
void ResumeDestFunction();
const WCHAR devLink[]??= L"//??//MyEvent";
const WCHAR devName[]??= L"//Device//MyEvent";
UNICODE_STRING??????????devNameUnicd;
UNICODE_STRING??????????devLinkUnicd;????
ULONG OrgDestFunction = (ULONG)0x8043141f; //KiReadyThread
char JmpMyCode [] = {0xE9,0x00,0x00,0x00,0x00};
char OrgCode [5];
char OutBuf[128][16];
int Count = 0;
ULONG orgcr0;
#ifdef __cplusplus
}
#endif
VOID DisableWriteProtect( PULONG pOldAttr)
{
???? ULONG uAttr;
???? _asm
????{
??????????push eax;
??????????mov??eax, cr0;
??????????mov??uAttr, eax;
??????????and??eax, 0FFFEFFFFh; // CR0 16 BIT = 0
??????????mov??cr0, eax;
??????????pop??eax;
????};
???? *pOldAttr = uAttr; //保存原有的 CRO 屬性
}
VOID EnableWriteProtect( ULONG uOldAttr )
{
??_asm
??{
?????? push eax;
?????? mov??eax, uOldAttr; //恢復原有 CR0 屬性
?????? mov??cr0, eax;
?????? pop??eax;
??};
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegistryPath)
{
????NTSTATUS????????????????Status;
????PDEVICE_OBJECT????????????pDevice;
????DbgPrint("DriverEntry called!/n");
????RtlInitUnicodeString (&devNameUnicd, devName );
????RtlInitUnicodeString (&devLinkUnicd, devLink );
????Status = IoCreateDevice ( pDriverObject,
????0,
???? ????&devNameUnicd,
????FILE_DEVICE_UNKNOWN,
?????? 0,
?????? TRUE,
?????? &pDevice );
????????if( !NT_SUCCESS(Status))
????????{
????????DbgPrint(("Can not create device./n"));
????????return Status;
????}
?? ????Status = IoCreateSymbolicLink (&devLinkUnicd, &devNameUnicd);
?? ????if( !NT_SUCCESS(Status))
?? ????{
?????? ????DbgPrint(("Cannot create link./n"));
?????? ????return Status;
?? ????}
?? ????pDriverObject->DriverUnload??= DriverUnload;
?? ????pDriverObject->MajorFunction[IRP_MJ_CREATE] =
????pDriverObject->MajorFunction[IRP_MJ_CLOSE] =
????pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =????DeviceIoControlDispatch;
??????
????pDriverObject->DriverUnload = DriverUnload;
????* ( (ULONG*) (JmpMyCode+1) ) = (ULONG)func - (ULONG)OrgDestFunction - 5;
????memcpy(OrgCode,(char*)OrgDestFunction,5);
????HookDestFunction();
????
????return STATUS_SUCCESS;
}
void DriverUnload (IN PDRIVER_OBJECT pDriverObject)
{
????NTSTATUS????????????status;
????ResumeDestFunction();
????if(pDriverObject->DeviceObject != NULL)
????????{
?????? ????status=IoDeleteSymbolicLink( &devLinkUnicd );
????????if ( !NT_SUCCESS( status ) )
????????????{
????????????????????DbgPrint((??"IoDeleteSymbolicLink() failed/n" ));
????????????}
????????????IoDeleteDevice( pDriverObject->DeviceObject );
????????}
}
void DisplayName(PKTHREAD Thread)
{
????PKPROCESS Process = Thread->ApcState.Process;
????PEPROCESS pEprocess = (PEPROCESS)Process;
????DbgPrint("ImageFileName = %s /n",pEprocess->ImageFileName);
????sprintf(OutBuf[Count++],"%s",pEprocess->ImageFileName);
}
void cfunc (void)
{
????ULONG PKHeader=0;
????__asm
????{
????????mov PKHeader,ecx??//ecx寄存器是KiReadyThread中的PRKTHREAD參數
????}
????ResumeDestFunction();
????
????if ( PKHeader != 0 && Count < 128 )
????{
????????DisplayName((PKTHREAD)PKHeader);????
????}????
}
void HookDestFunction()
{
????DisableWriteProtect(&orgcr0);
????memcpy((char*)OrgDestFunction,JmpMyCode,5);
????EnableWriteProtect(orgcr0);????
}
void ResumeDestFunction()
{
????DisableWriteProtect(&orgcr0);
????memcpy((char*)OrgDestFunction,OrgCode,5);
????EnableWriteProtect(orgcr0);
}
NTSTATUS DeviceIoControlDispatch(
???????????????????????????????? IN??PDEVICE_OBJECT??DeviceObject,
???????????????????????????????? IN??PIRP????????????pIrp
???????????????????????????????? )
{
????PIO_STACK_LOCATION??????????????irpStack;
????NTSTATUS????????????????????????status;
????PVOID?????????????????????????? inputBuffer;
????ULONG?????????????????????????? inputLength;
????PVOID?????????????????????????? outputBuffer;
????ULONG?????????????????????????? outputLength;
????OBJECT_HANDLE_INFORMATION?????? objHandleInfo;
????status = STATUS_SUCCESS;
????// 取出IOCTL請求代碼
????irpStack = IoGetCurrentIrpStackLocation(pIrp);
????switch (irpStack->MajorFunction)
????{
????case IRP_MJ_CREATE :
????????DbgPrint("Call IRP_MJ_CREATE/n");
????????break;
????case IRP_MJ_CLOSE:
????????DbgPrint("Call IRP_MJ_CLOSE/n");
????????break;
????case IRP_MJ_DEVICE_CONTROL:
????????DbgPrint("IRP_MJ_DEVICE_CONTROL/n");
????????inputLength=irpStack->Parameters.DeviceIoControl.InputBufferLength;
????????outputLength=irpStack->Parameters.DeviceIoControl.OutputBufferLength;
????????switch (irpStack->Parameters.DeviceIoControl.IoControlCode)
????????{
????????????case????IOCTL_PASSBUF:
????????????{
????????????????RtlCopyMemory(pIrp->UserBuffer, OutBuf, 20*16);
????????????????
????????????????memset(OutBuf,0,128*16);
????????????????Count = 0;
????????????????break;
????????????}
????????????default:
????????????????break;
????????}
????default:
????????DbgPrint("Call IRP_MJ_UNKNOWN/n");
????????break;
????}
????pIrp->IoStatus.Status = status;
????pIrp->IoStatus.Information = 0;
????IoCompleteRequest (pIrp, IO_NO_INCREMENT);
????return status;
}
// 1.asm
.386
.model small
.data
_OrgRet dd 0
.code
public _func@0
extrn _cfunc@0:near
extrn _HookDestFunction@0:near
extrn _OrgDestFunction:DWORD
_func@0 proc
????pushad
????call _cfunc@0
????popad
????push eax
????mov eax,[esp+4]
????mov ds:_OrgRet,eax
????pop eax
????mov [esp],retaddr
????jmp _OrgDestFunction
retaddr:
????pushad
????call _HookDestFunction@0
????popad
????jmp ds:_OrgRet
_func@0 endp
END
//
// app.cpp
//
#include <windows.h>
#include <stdio.h>
#define FILE_DEVICE_EVENT??0x8000
#define CTL_CODE( DeviceType, Function, Method, Access ) (???????????????? /
????((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) /
)
#define FILE_ANY_ACCESS???????????????? 0
#define METHOD_BUFFERED???????????????? 0
#define FILE_DEVICE_UNKNOWN???????????? 0x00000022
#define IOCTL_PASSBUF /
????CTL_CODE(FILE_DEVICE_EVENT, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
int main()
{
?? ????HANDLE??????hDevice;????
????????bool????????status;
?? ????ULONG?????? dwReturn;
????????char????????outbuf[129][16];
????????hDevice = NULL;
????????m_hCommEvent = NULL;
????????hDevice = CreateFile( ".//MyEvent",
????????????????????GENERIC_READ|GENERIC_WRITE,
????????????????????FILE_SHARE_READ | FILE_SHARE_WRITE,
????????????????????NULL,
????????????????????OPEN_EXISTING,
????????????????????FILE_ATTRIBUTE_NORMAL,
????????????????????NULL);
????????if(hDevice == INVALID_HANDLE_VALUE)
????????{
?????? ????printf("createfile wrong/n");
?????? ????getchar();
?????? ????return 0;
????????}
????while(1)
????{
????????memset(outbuf,0,129*16);
????????status =DeviceIoControl(hDevice,
????????????????????IOCTL_PASSBUF,
????????????????????NULL,
????????????????????0,
????????????????????&outbuf,
????????????????????128*16,
????????????????????&dwReturn,NULL);
????????if( !status)
????????{
????????????printf("IO wrong+%d/n", GetLastError());
????????????getchar();
????????????return 0;
????????}
????????int c=0;
????????while( *((char*)(&outbuf)+c*16) )
????????{
????????????//把csrss.exe和自身進程信息跳過,因為會產生有大量的信息。
????????????if ( strcmp((char*)(&outbuf)+c*16,"app.exe") && /
???????????????? strcmp((char*)(&outbuf)+c*16,"csrss.exe")??)
????????????????printf("%s/n",(char*)(&outbuf)+c*16);
????????????c++;
????????}
????????Sleep(1);
????}
}
試驗結果:
......
TTPlayer.exe
System
TTPlayer.exe
vrvmon.exe
TTPlayer.exe
System
System
Explorer.EXE
Explorer.EXE
Explorer.EXE
......
測試,編譯環境 2000 Sp4 2000 DDK
沒寫出線程的隱藏進程代碼。不過基本上實現得差不多了,只需要把返回的信息,和Ring3級查詢得到的信息進行適時對比就能查出異常進程了。
本人水平有限,如哪里有錯誤,歡迎高手不吝賜教。
感謝:sinister大哥對小弟的指點及其鼓勵
畢業在即將次愚作獻給我的母校---重慶科技學院
總結
以上是生活随笔為你收集整理的内核级利用通用Hook函数方法检测进程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php保存成乱序,PHP实现断点续传乱序
- 下一篇: php 表单录入,PHP 表单和用户输入