PsTerminateProcess函数用于结束一个进程。
#include <ntddk.h>
typedef NTSTATUS (*PSPTERMINATETPROCESS)(
PEPROCESS Process,
NTSTATUS ExitStatus
);
PSPTERMINATETPROCESS PspTerminateProcess;
typedef NTSTATUS (*NTQUERYSYSTEMINFORMATION)(
IN ULONG SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL);
typedef unsigned long DWORD;
NTQUERYSYSTEMINFORMATION NtQuerySystemInformation;
#define SystemModuleInformation 11
typedef struct _SYSTEM_MODULE_INFORMATION
{
ULONG Reserved[2];
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
ULONG GetFunctionAddr( IN PCWSTR FunctionName)
{
UNICODE_STRING UniCodeFunctionName;
RtlInitUnicodeString( &UniCodeFunctionName, FunctionName );
return (ULONG)MmGetSystemRoutineAddress( &UniCodeFunctionName );
}
VOID DoFind(IN PVOID pContext)
{
NTSTATUS ret;
PSYSTEM_MODULE_INFORMATION module = NULL;
ULONG n=0;
void *buf = NULL;
ULONG ntosknlBase;
ULONG ntosknlEndAddr;
ULONG curAddr;
ULONG code1_sp3=0x8b55ff8b,code2_sp3=0xA16456EC,code3_sp3=0x00000124,code4_sp3=0x3B08758B;
ULONG i;
NtQuerySystemInformation=(NTQUERYSYSTEMINFORMATION)GetFunctionAddr(L"NtQuerySystemInformation");
if (!NtQuerySystemInformation)
{
DbgPrint("Find NtQuerySystemInformation faild!");
goto Ret;
}
ret=NtQuerySystemInformation(SystemModuleInformation,&n,0,&n);
if (NULL==( buf=ExAllocatePoolWithTag(NonPagedPool, n, 'DFSP')))
{
DbgPrint("ExAllocatePool() failed\n" );
goto Ret;
}
ret=NtQuerySystemInformation(SystemModuleInformation,buf,n,NULL);
if (!NT_SUCCESS(ret)) {
DbgPrint("NtQuerySystemInformation faild!");
goto Ret;
}
module=(PSYSTEM_MODULE_INFORMATION)((PULONG)buf+1);
ntosknlEndAddr=(ULONG)module->Base+(ULONG)module->Size;
ntosknlBase=(ULONG)module->Base;
curAddr=ntosknlBase;
ExFreePool(buf);
for (i=curAddr;i<=ntosknlEndAddr;i++)
{
if (*((ULONG *)i)==code1_sp3)
{
if (*((ULONG *)(i+4))==code2_sp3)
{
if (*((ULONG *)(i+8))==code3_sp3)
{
if (*((ULONG *)(i+12))==code4_sp3)
{
PspTerminateProcess=(PSPTERMINATETPROCESS)i;
break;
}
}
}
}
}
Ret:
PsTerminateSystemThread(STATUS_SUCCESS);
}
VOID GetPspAddr()
{
HANDLE hThread;
PVOID objtowait=0;
NTSTATUS dwStatus =
PsCreateSystemThread(
&hThread,
0,
NULL,
(HANDLE)0,
NULL,
DoFind,
NULL
);
NTSTATUS st;
if ((KeGetCurrentIrql())!=PASSIVE_LEVEL)
{
st=KfRaiseIrql(PASSIVE_LEVEL);
}
if ((KeGetCurrentIrql())!=PASSIVE_LEVEL)
{
return;
}
ObReferenceObjectByHandle(
hThread,
THREAD_ALL_ACCESS,
NULL,
KernelMode,
&objtowait,
NULL
);
st=KeWaitForSingleObject(objtowait,Executive,KernelMode,FALSE,NULL); //NULL表示无限期等待.
return;
}
NTSTATUS CheckPspTerminateProcessIsHook()
{
int i = 0;
char *addr = (char *)PspTerminateProcess;
char code[] = { 0x8b, 0xff, 0x55, 0x8b, 0xec};
while(i<5)
{
DbgPrint("0x%02X", (unsigned char)addr[i]);
if(addr[i] != code[i])
{
return STATUS_UNSUCCESSFUL;
}
i++;
}
return STATUS_SUCCESS;
}
int MyPspTerminateProcess(
PEPROCESS Process,
NTSTATUS ExitStatus
)
{
DbgPrint("PspTerminateProcess hello\n");
return 1;
}
_declspec(naked) T_PspTerminateProcess(
PEPROCESS Process,
NTSTATUS ExitStatus
)
{
_asm
{
mov edi, edi
push ebp
mov ebp ,esp
push [ebp+0ch]
push [ebp+8]
call MyPspTerminateProcess
cmp eax,1
jz end
mov eax,PspTerminateProcess
add eax,5
jmp eax
end:
pop ebp
retn 8
}
}
VOID InlineHookPspTerminateProcess()
{
int JmpOffSet = 0;
unsigned char JmpCode[5] = { 0xe9, 0x00, 0x00, 0x00, 0x00 };
KIRQL oldIrql;
if (PspTerminateProcess == 0)
{
DbgPrint("PspTerminateProcess NOT FOUND\n");
return;
}
DbgPrint("PspTerminateProcess is found at:0x%08x\n", (ULONG)PspTerminateProcess );
DbgPrint("T_PspTerminateProcess is:%x\n",T_PspTerminateProcess);
JmpOffSet= (char*)T_PspTerminateProcess - (char*)PspTerminateProcess - 5;
DbgPrint("JmpOffSet is:%x\n",JmpOffSet);
RtlCopyMemory ( JmpCode+1, &JmpOffSet, 4 );
_asm
{
CLI
MOV EAX, CR0
AND EAX, NOT 10000H
MOV CR0, EAX
}
oldIrql = KeRaiseIrqlToDpcLevel();
RtlCopyMemory ( PspTerminateProcess, JmpCode, 5 );
DbgPrint("PspTerminateProcess is hook now \n");
KeLowerIrql(oldIrql);
_asm
{
MOV EAX, CR0
OR EAX, 10000H
MOV CR0, EAX
STI
}
}
VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
// 在win2000上是三字节
// push ebp
// mov ebp, esp
//
// 到了winxp以及后续系统上,则变成了五字节
// mov edi, edi
// push ebp
// mov ebp, esp
// 函数的序言
unsigned char Code[5]={0x8b,0xff,0x55,0x8b,0xec};
_asm
{
CLI
MOV eax, CR0
AND eax, NOT 10000H
MOV CR0, eax
pushad
mov edi, PspTerminateProcess
mov eax, dword ptr Code[0]
mov [edi], eax
mov al, byte ptr Code[4]
mov [edi+4], al
popad
MOV eax, CR0
OR eax, 10000H
MOV CR0, eax
STI
}
DbgPrint("Goodbye driver\n");
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath)
{
GetPspAddr();
if(PspTerminateProcess == NULL)
{
DbgPrint("PspFunc Not Find!\n");
return STATUS_UNSUCCESSFUL;
}
if(STATUS_SUCCESS != CheckPspTerminateProcessIsHook())
{
DbgPrint("PspTerminateProcess Match Failed !");
return STATUS_UNSUCCESSFUL;
}
InlineHookPspTerminateProcess();
pDriverObject->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
©著作权归作者所有:来自51CTO博客作者土匪猿的原创作品,如需转载,请注明出处,否则将追究法律责任
共同学习,写下你的评论
评论加载中...
作者其他优质文章