#include <ntddk.h>
PETHREAD pThreadObj = NULL;
BOOLEAN bTerminated = FALSE;
UCHAR szProcessName[10] = "Form1.exe";
extern POBJECT_TYPE *PsProcessType;
extern POBJECT_TYPE *PsThreadType;
VOID DriverUnload(PDRIVER_OBJECT pDriverObject);
VOID AntiDbgThread(PVOID pContext);
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING pRegistryPath)
{
OBJECT_ATTRIBUTES ObjAddr = {0};
HANDLE ThreadHandle = 0;
NTSTATUS NtStatus = STATUS_SUCCESS;
KdPrint(("Driver Entry"));
pDriverObject->DriverUnload = DriverUnload;
InitializeObjectAttributes(&ObjAddr,NULL,OBJ_KERNEL_HANDLE,0,NULL);
NtStatus = PsCreateSystemThread(&ThreadHandle,THREAD_ALL_ACCESS,&ObjAddr,NULL,NULL,AntiDbgThread,NULL);
if(NT_SUCCESS(NtStatus))
{
KdPrint(("Thread Created"));
NtStatus = ObReferenceObjectByHandle(ThreadHandle,THREAD_ALL_ACCESS,*PsThreadType,KernelMode,&pThreadObj,NULL);
ZwClose(ThreadHandle);
if(!NT_SUCCESS(NtStatus))
{
bTerminated = TRUE;
}
}
return NtStatus;
}
VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
bTerminated = TRUE;
KeWaitForSingleObject(pThreadObj,Executive,KernelMode,FALSE,NULL);
ObDereferenceObject(pThreadObj);
}
VOID AntiDbgThread(PVOID pContext)
{
PEPROCESS pCurrentProcess = NULL;
PEPROCESS pFirstProcess = NULL;
LARGE_INTEGER inteval;
char *ProcessName;//
ULONG PID;//进程pid进程名
ULONG DebugPort;//调试端口
inteval.QuadPart = -20000000;
KeSetPriorityThread(KeGetCurrentThread(),LOW_REALTIME_PRIORITY);
pCurrentProcess = IoGetCurrentProcess();
pFirstProcess = pCurrentProcess;
while(1)
{
if(bTerminated)
{
break;
}
pCurrentProcess = IoGetCurrentProcess();
pFirstProcess = pCurrentProcess;
// 操作系统win7 32位 版 进程结构偏移 如下:
// +0x16c ImageFileName //进程名 偏移
// +0x0b8 ActiveProcessLinks //进程链,下一个 进程结构 偏移
// +0x0ec DebugPort //传说中的调试端口 偏移
// +b4 UniqueProcessId //进程PID
//操作系统xp sp3 版的进程结构偏移 如下
// +0x174 ImageFileName //进程名 偏移
// +0x088 ActiveProcessLinks //进程链,下一个 进程结构 偏移
// +0x0bc DebugPort //传说中的调试端口 偏移
// +84 UniqueProcessId //进程PID
//先依据ActiveProcessLinks 进程链地址来遍历出每一个进程的进程结构PEPROCES 体,也就是进程结构的基址。
//然后依据 进程结构的基址+偏移量的形式获取结构体内部的各种变量,比如进程名ImageFileName 、进程调试端口 DebugPort 。
//当然这里还有一个小收获,就是依据进程结构体来获取进程的pid值,用 内核函数PsGetProcessId获取PID.
while(RtlCompareMemory(szProcessName,(PUCHAR)((ULONG)pCurrentProcess + 0x16c),10) != 10)
{
pCurrentProcess= (PEPROCESS)(*(PULONG)((ULONG)pCurrentProcess + 0xb8) - 0xb8);
if(pCurrentProcess == pFirstProcess)//判断第一个进程结构是一个相互紧挨在一起的一个”手链“。判断到起初第一个进程结构的时候就说明,一次进程遍历完成了。
{
// KdPrint(("进程链表遍历结束,退出进程链表遍历"));
goto END;
}
}
*(PULONG)((ULONG)pCurrentProcess + 0xb4) = 1234;//修改进程PID, 伪造进程PID,嘿嘿(让OD和CE无法附加Form1.exe)
//以下这句是获取进程名,进程名在进程结构中的偏移量为+ 0x16C
ProcessName = (char*)((ULONG)pCurrentProcess+ 0x16C);
PID=PsGetProcessId(pCurrentProcess);//PsGetProcessId函数依据进程结构体获取进程PID数值
KdPrint(("被保护的进程名为: %s 进程PID为:%d \n", ProcessName,PID));
END:
KeDelayExecutionThread(KernelMode,FALSE,&inteval);
}
}