看流星社区

 找回密码
 注册账号
查看: 2012|回复: 0

HOOK - 过保护 DebugPort 清零相关

[复制链接]

该用户从未签到

发表于 2017-6-1 17:20:46 | 显示全部楼层 |阅读模式
一个程序被ring3调试器调试时,有很多的调试特征可以检测,本论坛也有专门的帖子详细论述,但有个非常根本的标志ring3也是可以检测的比较少人提及,那就是_EPROCESS.DebugPort。DebugPort对于ring3调试器来说非常重要,没有它正常的ring3调试是无法进行的。当然要检测这个标志的前提是程序能够读取ring0内存,在XP以上的系统有个非常简单的方法就是使用ZwSystemDebugControl的SysDbgReadVirtualMemory方法,我们也可以mapphysicalmemory来操作。检测DebugPort之前首先要得到进程的eprocess地址,这可以通过ZwQuerySystemInformation的SystemHandleInformation方法得到,也可以直接搜索ring0内存的eprocess结构。
对于ring3直接检测DebugPort,我们可以通过禁止该进程访问ring0内存来对付,但是目标一旦使用驱动来检测,那么就非常麻烦了。下面介绍一种隐藏_EPROCESS.DebugPort的方法,这种方法的基本思路是,将一个正常被调试进程的DebugPort置零后,修正所有受影响的函数,使我们的调试器能够正常进行。这些函数如下:
PspCreateProcess、MmCreatePeb 进程创建,设置DebugPort
DbgkCreateThread发送线程或者进程创建的调试信息
KiDispatchException、DbgkForwardException和DbgkpQueueMessage 发送异常调试信息
PspExitThread、DbgkExitThread和DbgkExitProcess 发送线程退出、进程退出的调试信息
DbgkMapViewOfSection和DbgkUnMapViewOfSection 发送映像装载卸载调试信息
DbgkpSetProcessDebugObject和DbgkpMarkProcessPeb 当调试器附加进程时设置DebugPort
这类函数非常多的,如果都HOOK处理的话,那太恐怖了,这里使用一个非常简单的办法:偷龙转凤。我们看系统访问DebugPort的代码都是这样的(XP)
8b89bc000000mov ecx,dword ptr [ecx+0BCh] //0BCh就是DebugPort的偏移
我们可以把DebugPort转移到_EPROCESS的另外一个地方,比如我使用+0x070CreateTime,它是纪录进程创建时间的,进程创建之后,在进程退出前系统不会对它进行任何修改,而且我们修改后对系统或进程没有任何影响。这样我们可以把上面的代码改成这样
8b8970000000mov ecx,dword ptr [ecx+070h]//指向CreateTime,实际的DebugPort已经被移到这里
只需要修改一个字节,非常简单。
当然这种方法最麻烦的地方就是定位引用到DebugPort的函数(本人仅仅针对不同的XP系统制作特征码都累到吐血),这些函数都是不导出的,如果是特定系统,最简单的方法就是WinDbg->uf*** 直接找地址硬编码,只需要几分钟时间。

代码:

BOOLEANInitHackAddress(){_SEH_TRY{g_KernelBase=GetKernelBaseAndSize(&g_KernelSize);g_HackPspCreateProcess=SearchHackPspCreateProcess(&g_NopPspCreateProcess.Address);g_HackKiDispatchException=SearchKiDispatchException(g_KernelBase,g_KernelSize);g_HackDbgkpQueueMessage=SearchDbgkpQueueMessage(g_KernelBase,g_KernelSize);g_HackDbgkCreateThread=SearchDbgkCreateThread(g_KernelBase,g_KernelSize);SearchDbgkNotifyRoutine(g_KernelBase,g_KernelSize);g_HackPspExitThread=SearchPspExitThread();g_HackMmCreatePeb=SearchMmCreatePeb(g_HackPspCreateProcess);SearchDbgkpSetProcessDebugObject(g_KernelBase,g_KernelSize);if(g_HackDbgkpSetProcessDebugObject[3])g_HackDbgkpMarkProcessPeb=SearchDbgkpMarkProcessPeb(g_HackDbgkpSetProcessDebugObject[3]);if(g_NopPspCreateProcess.Address!=0){RtlFillMemory(g_NopPspCreateProcess.NopCode,sizeof(g_NopPspCreateProcess.NopCode),0x90);g_NopPspCreateProcess.Size=9;RtlCopyMemory(g_NopPspCreateProcess.OrigCode,(PVOID)g_NopPspCreateProcess.Address,g_NopPspCreateProcess.Size);}if(g_NopDbgkForwardException.Address!=0){RtlFillMemory(g_NopDbgkForwardException.NopCode,sizeof(g_NopDbgkForwardException.NopCode),0x90);RtlCopyMemory(g_NopDbgkForwardException.OrigCode,(PVOID)g_NopDbgkForwardException.Address,g_NopDbgkForwardException.Size);}if(g_NopDbgkExitThread.Address!=0){RtlFillMemory(g_NopDbgkExitThread.NopCode,sizeof(g_NopDbgkExitThread.NopCode),0x90);RtlCopyMemory(g_NopDbgkExitThread.OrigCode,(PVOID)g_NopDbgkExitThread.Address,g_NopDbgkExitThread.Size);}if(g_NopDbgkExitProcess.Address!=0){RtlFillMemory(g_NopDbgkExitProcess.NopCode,sizeof(g_NopDbgkExitProcess.NopCode),0x90);RtlCopyMemory(g_NopDbgkExitProcess.OrigCode,(PVOID)g_NopDbgkExitProcess.Address,g_NopDbgkExitProcess.Size);}if(g_NopDbgkMapViewOfSection.Address!=0){RtlFillMemory(g_NopDbgkMapViewOfSection.NopCode,sizeof(g_NopDbgkMapViewOfSection.NopCode),0x90);RtlCopyMemory(g_NopDbgkMapViewOfSection.OrigCode,(PVOID)g_NopDbgkMapViewOfSection.Address,g_NopDbgkMapViewOfSection.Size);}if(g_NopDbgkUnMapViewOfSection.Address!=0){RtlFillMemory(g_NopDbgkUnMapViewOfSection.NopCode,sizeof(g_NopDbgkUnMapViewOfSection.NopCode),0x90);RtlCopyMemory(g_NopDbgkUnMapViewOfSection.OrigCode,(PVOID)g_NopDbgkUnMapViewOfSection.Address,g_NopDbgkUnMapViewOfSection.Size);}}_SEH_HANDLER{DbgPrint("InitHackAddressException!\n");}return(g_HackPspCreateProcess!=0&&g_HackKiDispatchException!=0&&g_HackDbgkForwardException!=0&&g_HackDbgkpQueueMessage!=0&&g_NopPspCreateProcess.Address!=0&&g_NopDbgkForwardException.Address!=0&&g_HackDbgkCreateThread!=0&&g_HackDbgkExitThread!=0&&g_NopDbgkExitThread.Address!=0&&g_HackDbgkExitProcess!=0&&g_NopDbgkExitProcess.Address!=0&&g_HackDbgkMapViewOfSection!=0&&g_NopDbgkMapViewOfSection.Address!=0&&g_HackDbgkUnMapViewOfSection!=0&&g_NopDbgkUnMapViewOfSection.Address!=0&&g_HackPspExitThread!=0&&g_HackMmCreatePeb!=0&&g_HackDbgkpSetProcessDebugObject[0]!=0&&g_HackDbgkpSetProcessDebugObject[1]!=0&&g_HackDbgkpSetProcessDebugObject[2]!=0&&g_HackDbgkpSetProcessDebugObject[3]!=0&&g_HackDbgkpMarkProcessPeb!=0);}

代码:

//修改已经运行进程的DebugPort位置BOOLEANChangeProcessDebugPort(BOOLEANHide){ULONGeProcess=(ULONG)PsInitialSystemProcessLIST_ENTRYpListHead,pListWalk;ULONGDebugObject;if(!g_bIsAddressStartup){returnFALSE;}pListHead=(PLIST_ENTRY)(eProcess+ACTIVE_LINKS_OFFSET);pListWalk=pListHead;_SEH_TRY{do{if(pListWalk==NULL||eProcess==0)break;eProcess=((ULONG)pListWalk-ACTIVE_LINKS_OFFSET);if(Hide){DebugObject=*(ULONG*)(eProcess+DEBUG_PORT_OFFSET);*(ULONG*)(eProcess+CREATE_TIME_OFFSET)=DebugObject;*(ULONG*)(eProcess+DEBUG_PORT_OFFSET)=0;}else{DebugObject=*(ULONG*)(eProcess+CREATE_TIME_OFFSET);*(ULONG*)(eProcess+DEBUG_PORT_OFFSET)=DebugObject;}pListWalk=pListWalk->Flink;}while(pListWalk!=pListHead);}_SEH_HANDLER{DbgPrint("ChangeProcessDebugPortexception!\n");}returnTRUE;}代码:BOOLEANModifyDebugFunction(){if(!g_bIsAddressStartup){returnFALSE;}__asm{climoveax,cr0andeax,not10000hmovcr0,eax}*(ULONG*)g_HackPspCreateProcess=CREATE_TIME_OFFSET;*(ULONG*)g_HackKiDispatchException=CREATE_TIME_OFFSET;*(ULONG*)g_HackDbgkForwardException=CREATE_TIME_OFFSET;*(ULONG*)g_HackDbgkpQueueMessage=CREATE_TIME_OFFSET;*(ULONG*)g_HackDbgkCreateThread=CREATE_TIME_OFFSET;*(ULONG*)g_HackDbgkExitThread=CREATE_TIME_OFFSET;*(ULONG*)g_HackDbgkExitProcess=CREATE_TIME_OFFSET;*(ULONG*)g_HackDbgkMapViewOfSection=CREATE_TIME_OFFSET;*(ULONG*)g_HackDbgkUnMapViewOfSection=CREATE_TIME_OFFSET;*(ULONG*)g_HackPspExitThread=CREATE_TIME_OFFSET;*(ULONG*)g_HackDbgkpMarkProcessPeb=CREATE_TIME_OFFSET;*(ULONG*)g_HackMmCreatePeb=CREATE_TIME_OFFSET;*(ULONG*)g_HackDbgkpSetProcessDebugObject[0]=CREATE_TIME_OFFSET;*(ULONG*)g_HackDbgkpSetProcessDebugObject[1]=CREATE_TIME_OFFSET;*(ULONG*)g_HackDbgkpSetProcessDebugObject[2]=CREATE_TIME_OFFSET;*(ULONG*)g_HackDbgkpSetProcessDebugObject[3]=CREATE_TIME_OFFSET;RtlCopyMemory((PVOID)g_NopPspCreateProcess.Address,g_NopPspCreateProcess.NopCode,g_NopPspCreateProcess.Size);RtlCopyMemory((PVOID)g_NopDbgkForwardException.Address,g_NopDbgkForwardException.NopCode,g_NopDbgkForwardException.Size);RtlCopyMemory((PVOID)g_NopDbgkExitThread.Address,g_NopDbgkExitThread.NopCode,g_NopDbgkExitThread.Size);RtlCopyMemory((PVOID)g_NopDbgkExitProcess.Address,g_NopDbgkExitProcess.NopCode,g_NopDbgkExitProcess.Size);RtlCopyMemory((PVOID)g_NopDbgkMapViewOfSection.Address,g_NopDbgkMapViewOfSection.NopCode,g_NopDbgkMapViewOfSection.Size);RtlCopyMemory((PVOID)g_NopDbgkUnMapViewOfSection.Address,g_NopDbgkUnMapViewOfSection.NopCode,g_NopDbgkUnMapViewOfSection.Size);__asm{moveax,cr0oreax,10000hmovcr0,eaxsti}returnTRUE;}BOOLEANWriteBackDebugFunction(){if(!g_bIsAddressStartup){returnFALSE;}__asm{climoveax,cr0andeax,not10000hmovcr0,eax}*(ULONG*)g_HackPspCreateProcess=DEBUG_PORT_OFFSET;*(ULONG*)g_HackKiDispatchException=DEBUG_PORT_OFFSET;*(ULONG*)g_HackDbgkForwardException=DEBUG_PORT_OFFSET;*(ULONG*)g_HackDbgkpQueueMessage=DEBUG_PORT_OFFSET;*(ULONG*)g_HackDbgkCreateThread=DEBUG_PORT_OFFSET;*(ULONG*)g_HackDbgkExitThread=DEBUG_PORT_OFFSET;*(ULONG*)g_HackDbgkExitProcess=DEBUG_PORT_OFFSET;*(ULONG*)g_HackDbgkMapViewOfSection=DEBUG_PORT_OFFSET;*(ULONG*)g_HackDbgkUnMapViewOfSection=DEBUG_PORT_OFFSET;*(ULONG*)g_HackPspExitThread=DEBUG_PORT_OFFSET;*(ULONG*)g_HackDbgkpMarkProcessPeb=DEBUG_PORT_OFFSET;*(ULONG*)g_HackMmCreatePeb=DEBUG_PORT_OFFSET;*(ULONG*)g_HackDbgkpSetProcessDebugObject[0]=DEBUG_PORT_OFFSET;*(ULONG*)g_HackDbgkpSetProcessDebugObject[1]=DEBUG_PORT_OFFSET;*(ULONG*)g_HackDbgkpSetProcessDebugObject[2]=DEBUG_PORT_OFFSET;*(ULONG*)g_HackDbgkpSetProcessDebugObject[3]=DEBUG_PORT_OFFSET;RtlCopyMemory((PVOID)g_NopPspCreateProcess.Address,g_NopPspCreateProcess.OrigCode,g_NopPspCreateProcess.Size);RtlCopyMemory((PVOID)g_NopDbgkForwardException.Address,g_NopDbgkForwardException.OrigCode,g_NopDbgkForwardException.Size);RtlCopyMemory((PVOID)g_NopDbgkExitThread.Address,g_NopDbgkExitThread.OrigCode,g_NopDbgkExitThread.Size);RtlCopyMemory((PVOID)g_NopDbgkExitProcess.Address,g_NopDbgkExitProcess.OrigCode,g_NopDbgkExitProcess.Size);RtlCopyMemory((PVOID)g_NopDbgkMapViewOfSection.Address,g_NopDbgkMapViewOfSection.OrigCode,g_NopDbgkMapViewOfSection.Size);RtlCopyMemory((PVOID)g_NopDbgkUnMapViewOfSection.Address,g_NopDbgkUnMapViewOfSection.OrigCode,g_NopDbgkUnMapViewOfSection.Size);__asm{moveax,cr0oreax,10000hmovcr0,eaxsti}returnTRUE;}

  我想再嗦一下,上面代码大家看到很多函数有个NOPCode,这个实际上是对付线程PS_CROSS_THREAD_FLAGS_HIDEFROMDBG的,NOP掉相关地方后,就算线程被设置为ThreadHideFromDebugger也无法阻挡调试器接收调试信息。
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-19 17:12

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表