📄 内核级利用通用hook函数方法检测进程.html
字号:
ResumeDestFunction();<br />
if(pDriverObject->DeviceObject != NULL)<br />
{<br />
status=IoDeleteSymbolicLink( &devLinkUnicd );<br />
if ( !NT_SUCCESS( status ) )<br />
{<br />
DbgPrint(( "IoDeleteSymbolicLink() failed\n" ));<br />
}<br />
IoDeleteDevice( pDriverObject->DeviceObject );<br />
}<br />
}<br />
<br />
void DisplayName(PKTHREAD Thread)<br />
{<br />
PKPROCESS Process = Thread->ApcState.Process;<br />
PEPROCESS pEprocess = (PEPROCESS)Process;<br />
DbgPrint("ImageFileName = %s \n",pEprocess->ImageFileName);<br />
sprintf(OutBuf[Count++],"%s",pEprocess->ImageFileName);<br />
}<br />
<br />
void cfunc (void)<br />
{<br />
ULONG PKHeader=0;<br />
__asm<br />
{<br />
mov PKHeader,ecx //ecx寄存器是KiReadyThread中的PRKTHREAD参数<br />
}<br />
ResumeDestFunction();<br />
<br />
if ( PKHeader != 0 && Count < 128 )<br />
{<br />
DisplayName((PKTHREAD)PKHeader); <br />
} <br />
}<br />
<br />
void HookDestFunction()<br />
{<br />
DisableWriteProtect(&orgcr0);<br />
memcpy((char*)OrgDestFunction,JmpMyCode,5);<br />
EnableWriteProtect(orgcr0); <br />
}<br />
<br />
void ResumeDestFunction()<br />
{<br />
DisableWriteProtect(&orgcr0);<br />
memcpy((char*)OrgDestFunction,OrgCode,5);<br />
EnableWriteProtect(orgcr0);<br />
}<br />
<br />
NTSTATUS DeviceIoControlDispatch(<br />
IN PDEVICE_OBJECT DeviceObject,<br />
IN PIRP pIrp<br />
)<br />
{<br />
PIO_STACK_LOCATION irpStack;<br />
NTSTATUS status;<br />
PVOID inputBuffer;<br />
ULONG inputLength;<br />
PVOID outputBuffer;<br />
ULONG outputLength;<br />
OBJECT_HANDLE_INFORMATION objHandleInfo;<br />
<br />
status = STATUS_SUCCESS;<br />
// 取出IOCTL请求代码<br />
irpStack = IoGetCurrentIrpStackLocation(pIrp);<br />
<br />
switch (irpStack->MajorFunction)<br />
{<br />
case IRP_MJ_CREATE :<br />
DbgPrint("Call IRP_MJ_CREATE\n");<br />
break;<br />
case IRP_MJ_CLOSE:<br />
DbgPrint("Call IRP_MJ_CLOSE\n");<br />
break;<br />
case IRP_MJ_DEVICE_CONTROL:<br />
DbgPrint("IRP_MJ_DEVICE_CONTROL\n");<br />
inputLength=irpStack->Parameters.DeviceIoControl.InputBufferLength;<br />
outputLength=irpStack->Parameters.DeviceIoControl.OutputBufferLength;<br />
switch (irpStack->Parameters.DeviceIoControl.IoControlCode) <br />
{<br />
case IOCTL_PASSBUF:<br />
{<br />
RtlCopyMemory(pIrp->UserBuffer, OutBuf, 20*16);<br />
<br />
memset(OutBuf,0,128*16);<br />
Count = 0;<br />
break;<br />
}<br />
default:<br />
break;<br />
}<br />
<br />
default:<br />
DbgPrint("Call IRP_MJ_UNKNOWN\n");<br />
break;<br />
}<br />
pIrp->IoStatus.Status = status; <br />
pIrp->IoStatus.Information = 0; <br />
IoCompleteRequest (pIrp, IO_NO_INCREMENT);<br />
return status;<br />
}<br />
<br />
////////////////////////////////<br />
// 1.asm<br />
////////////////////////////////<br />
.386<br />
.model small<br />
<br />
.data<br />
_OrgRet dd 0<br />
<br />
.code<br />
public _func@0<br />
extrn _cfunc@0:near<br />
extrn _HookDestFunction@0:near<br />
extrn _OrgDestFunction:DWORD<br />
<br />
_func@0 proc<br />
pushad<br />
call _cfunc@0<br />
popad<br />
push eax<br />
mov eax,[esp+4]<br />
mov ds:_OrgRet,eax<br />
pop eax<br />
mov [esp],retaddr<br />
jmp _OrgDestFunction<br />
retaddr:<br />
pushad<br />
call _HookDestFunction@0<br />
popad<br />
jmp ds:_OrgRet<br />
_func@0 endp<br />
END<br />
<br />
//////////////////////////////////////////<br />
// app.cpp<br />
//////////////////////////////////////////<br />
<br />
#include <windows.h><br />
#include <stdio.h><br />
<br />
#define FILE_DEVICE_EVENT 0x8000<br />
#define CTL_CODE( DeviceType, Function, Method, Access ) ( \<br />
((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \<br />
)<br />
<br />
#define FILE_ANY_ACCESS 0<br />
#define METHOD_BUFFERED 0<br />
#define FILE_DEVICE_UNKNOWN 0x00000022<br />
<br />
#define IOCTL_PASSBUF \<br />
CTL_CODE(FILE_DEVICE_EVENT, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)<br />
<br />
int main()<br />
{<br />
HANDLE hDevice; <br />
bool status; <br />
ULONG dwReturn;<br />
char outbuf[129][16];<br />
hDevice = NULL;<br />
m_hCommEvent = NULL;<br />
hDevice = CreateFile( "\\\\.\\MyEvent",<br />
GENERIC_READ|GENERIC_WRITE,<br />
FILE_SHARE_READ | FILE_SHARE_WRITE, <br />
NULL,<br />
OPEN_EXISTING, <br />
FILE_ATTRIBUTE_NORMAL, <br />
NULL);<br />
if(hDevice == INVALID_HANDLE_VALUE)<br />
{<br />
printf("createfile wrong\n");<br />
getchar();<br />
return 0;<br />
}<br />
while(1)<br />
{<br />
memset(outbuf,0,129*16);<br />
status =DeviceIoControl(hDevice,<br />
IOCTL_PASSBUF,<br />
NULL,<br />
0,<br />
&outbuf,<br />
128*16,<br />
&dwReturn,NULL);<br />
if( !status)<br />
{<br />
printf("IO wrong+%d\n", GetLastError());<br />
getchar();<br />
return 0;<br />
}<br />
int c=0;<br />
while( *((char*)(&outbuf)+c*16) )<br />
{<br />
//把csrss.exe和自身进程信息跳过,因为会产生有大量的信息。<br />
if ( strcmp((char*)(&outbuf)+c*16,"app.exe") && \<br />
strcmp((char*)(&outbuf)+c*16,"csrss.exe") )<br />
printf("%s\n",(char*)(&outbuf)+c*16);<br />
c++;<br />
}<br />
Sleep(1);<br />
}<br />
}<br />
<br />
试验结果:<br />
......<br />
TTPlayer.exe<br />
System<br />
TTPlayer.exe<br />
vrvmon.exe<br />
TTPlayer.exe<br />
System<br />
System<br />
Explorer.EXE<br />
Explorer.EXE<br />
Explorer.EXE<br />
......<br />
测试,编译环境 2000 Sp4 2000 DDK<br />
没写出线程的隐藏进程代码。不过基本上实现得差不多了,只需要把返回的信息,和Ring3级查询得到的信息进行适时对比就能查出异常进程了。<br />
<br />
本人水平有限,如哪里有错误,欢迎高手不吝赐教。<br />
感谢:sinister大哥对小弟的指点及其鼓励<br />
毕业在即将次愚作献给我的母校---重庆科技学院
</td>
</tr>
</table><div class="footer"> Copyright © 1998-2005 XFOCUS Team. All Rights Reserved</div></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -