最近学习驱动,昨天刚配置了下windebug调试器,下载了论坛的驱动教程,很不错,适合入门。看了几个老郁的教程,随便把驱动环境搭建好了。 在公司xp sp3的系统上测试了成功,OD下断点失效或报错。 --------------------------------------------------------------------------------------- 现在刚回家,家里是win7 32位系统,我过会改下进程结构各个属性的偏移量 打包上传上来。 #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; inteval.QuadPart = -20000000; KeSetPriorityThread(KeGetCurrentThread(),LOW_REALTIME_PRIORITY); while(1) { if(bTerminated) { break; } pCurrentProcess = IoGetCurrentProcess(); pFirstProcess = pCurrentProcess; // 操作系统win7 32位 版 进程结构偏移 如下: // +0x16c ImageFileName //进程名 偏移 // +0x0b8 ActiveProcessLinks //进程链,下一个 进程结构 偏移 // +0x0ec DebugPort //传说中的调试端口 偏移 //操作系统xp sp3 版的进程结构偏移 如下 // +0x174 ImageFileName //进程名 偏移 // +0x088 ActiveProcessLinks //进程链,下一个 进程结构 偏移 // +0x0bc DebugPort //传说中的调试端口 偏移 //先依据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; } } //以下这句是先计算出 debug端口变量的内存地址,然后将其强制转化为真正的内存地址即所谓的指针。 //然后修改内存地址上的数值,修改为0即可。 *(PULONG)((ULONG)pCurrentProcess + 0xec) = 0;//debug端口清零(核心代码就这一句,让OD断点没反应,或报错) //以下这句是获取进程名,进程名在进程结构中的偏移量为+ 0x16C ProcessName = (char*)((ULONG)pCurrentProcess+ 0x16C); //本来是研究 腾讯的debug端口清0的反调试器技术。偶尔在查阅的资料的时候发现还可以获取进程PID,哈哈 PID=PsGetProcessId(pCurrentProcess);//PsGetProcessId函数依据进程结构体获取进程PID数值 KdPrint(("Debug端口清零成功!被保护的进程名为: %s 进程PID为:%d \n", ProcessName,PID)); END: KeDelayExecutionThread(KernelMode,FALSE,&inteval); } } 这种还有一个重要的技巧就是,学会用windebug 查看进程结构体基址和偏移。简单,就是用命令而已。 方法1、windebug随便附加一个我们自己的进程,比如 VB写的Form1.exe 输入命令:dt _EPROCESS 然后会显示如下的进程结构信息 1. nt!_EPROCESS 7. +0x084 UniqueProcessId : Ptr32 Void 8. +0x088 ActiveProcessLinks : _LIST_ENTRY 9. +0x090 QuotaUsage : [3] Uint4B 14. +0x0b4 SessionProcessLinks : _LIST_ENTRY 15. +0x0bc DebugPort : Ptr32 Void 16. +0x0c0 ExceptionPort : Ptr32 Void 46. +0x174 ImageFileName : [16] UChar 我家里是 win7 32 位的笔记本,以前是 64位的win7,为了搞驱动技术,专门下载一个Ghost win7 32位。 Win7 32位系统,在windebug 随便附加一个我们自己的进程,然后 输入命令 dt _EPROCESS ,查看到进程结构为这般模样。 0:001> dt _EPROCESS ntdll!_EPROCESS +0x000 Pcb :_KPROCESS +0x0b8ActiveProcessLinks : _LIST_ENTRY +0x0e4 SessionProcessLinks : _LIST_ENTRY +0x0ec DebugPort : Ptr32 Void +0x0f0ExceptionPortData : Ptr32 Void +0x16c ImageFileName : [15] UChar 方法2、windebug 不附加进程,采用本机调试(不支持win7 32位,64位更加不用说,绝对不支持!只支持xp系统) 要是能本机调试的话, 输入命令: !process 0 0 功能:查看当前系统上所有的进程名和对应的进程结构体基址,然后在用 dt _eprocess 结构体基址 |
模仿腾讯实现内核进程的调试端口DebugPort 清零
最新推荐文章于 2023-11-04 09:08:41 发布