• HOOK


    原文地址:http://142461.blog.51cto.com/132461/838805

    一个程序被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)
            8b89bc000000    mov     ecx,dword ptr [ecx+0BCh] //0BCh就是DebugPort的偏移
         我们可以把DebugPort转移到_EPROCESS的另外一个地方,比如我使用+0x070CreateTime,它是纪录进程创建时间的,进程创建之后,在进程退出前系统不会对它进行任何修改,而且我们修改后对系统或进程没有任何影响。这样我们可以把上面的代码改成这样
            8b8970000000    mov     ecx,dword ptr [ecx+070h]//指向CreateTime,实际的DebugPort已经被移到这里
         只需要修改一个字节,非常简单。
        当然这种方法最麻烦的地方就是定位引用到DebugPort的函数(本人仅仅针对不同的XP系统制作特征码都累到吐血),这些函数都是不导出的,如果是特定系统,最简单的方法就是WinDbg->uf*** 直接找地址硬编码,只需要几分钟时间。
        
    代码:

    1. BOOLEAN InitHackAddress() 
    2.   _SEH_TRY 
    3.   { 
    4.    g_KernelBase = GetKernelBaseAndSize( &g_KernelSize );       
    5.    g_HackPspCreateProcess = SearchHackPspCreateProcess(&g_NopPspCreateProcess.Address ); 
    6.     g_HackKiDispatchException =SearchKiDispatchException( g_KernelBase,g_KernelSize );   
    7.    g_HackDbgkpQueueMessage = SearchDbgkpQueueMessage( g_KernelBase,g_KernelSize); 
    8.     g_HackDbgkCreateThread = SearchDbgkCreateThread(g_KernelBase,g_KernelSize );     
    9.     SearchDbgkNotifyRoutine(g_KernelBase,g_KernelSize ); 
    10.     g_HackPspExitThread =SearchPspExitThread();   
    11.     g_HackMmCreatePeb = SearchMmCreatePeb(g_HackPspCreateProcess ); 
    12.     SearchDbgkpSetProcessDebugObject(g_KernelBase,g_KernelSize ); 
    13.     if( g_HackDbgkpSetProcessDebugObject[3]) 
    14.       g_HackDbgkpMarkProcessPeb = SearchDbgkpMarkProcessPeb(g_HackDbgkpSetProcessDebugObject[3] ) ; 
    15.      
    16.     if(g_NopPspCreateProcess.Address != 0 ){ 
    17.       RtlFillMemory(g_NopPspCreateProcess.NopCode,sizeof(g_NopPspCreateProcess.NopCode),0x90 ); 
    18.       g_NopPspCreateProcess.Size = 9; 
    19.       RtlCopyMemory(g_NopPspCreateProcess.OrigCode,(PVOID)g_NopPspCreateProcess.Address,g_NopPspCreateProcess.Size); 
    20.     } 
    21.     if( g_NopDbgkForwardException.Address != 0 ){       
    22.      RtlFillMemory(g_NopDbgkForwardException.NopCode,sizeof(g_NopDbgkForwardException.NopCode),0x90); 
    23.       RtlCopyMemory(g_NopDbgkForwardException.OrigCode,(PVOID)g_NopDbgkForwardException.Address,g_NopDbgkForwardException.Size); 
    24.     } 
    25.     if( g_NopDbgkExitThread.Address != 0 ){       
    26.       RtlFillMemory(g_NopDbgkExitThread.NopCode,sizeof(g_NopDbgkExitThread.NopCode),0x90 ); 
    27.      RtlCopyMemory(g_NopDbgkExitThread.OrigCode,(PVOID)g_NopDbgkExitThread.Address,g_NopDbgkExitThread.Size); 
    28.     } 
    29.     if( g_NopDbgkExitProcess.Address != 0 ){ 
    30.       RtlFillMemory(g_NopDbgkExitProcess.NopCode,sizeof(g_NopDbgkExitProcess.NopCode),0x90); 
    31.       RtlCopyMemory(g_NopDbgkExitProcess.OrigCode,(PVOID)g_NopDbgkExitProcess.Address,g_NopDbgkExitProcess.Size); 
    32.     } 
    33.     if( g_NopDbgkMapViewOfSection.Address != 0){ 
    34.       RtlFillMemory(g_NopDbgkMapViewOfSection.NopCode,sizeof(g_NopDbgkMapViewOfSection.NopCode),0x90); 
    35.       RtlCopyMemory(g_NopDbgkMapViewOfSection.OrigCode,(PVOID)g_NopDbgkMapViewOfSection.Address,g_NopDbgkMapViewOfSection.Size); 
    36.     } 
    37.     if( g_NopDbgkUnMapViewOfSection.Address != 0 ){ 
    38.       RtlFillMemory(g_NopDbgkUnMapViewOfSection.NopCode,sizeof(g_NopDbgkUnMapViewOfSection.NopCode),0x90); 
    39.       RtlCopyMemory(g_NopDbgkUnMapViewOfSection.OrigCode,(PVOID)g_NopDbgkUnMapViewOfSection.Address,g_NopDbgkUnMapViewOfSection.Size); 
    40.     }      
    41.      
    42.      
    43.   } 
    44.   _SEH_HANDLER 
    45.   {     
    46.    DbgPrint( "InitHackAddress Exception! " ); 
    47.   } 
    48.   return ( g_HackPspCreateProcess != 0 && 
    49.         g_HackKiDispatchException != 0 && 
    50.        g_HackDbgkForwardException!= 0 && 
    51.        g_HackDbgkpQueueMessage != 0 &&  
    52.       g_NopPspCreateProcess.Address != 0 && 
    53.       g_NopDbgkForwardException.Address != 0 && 
    54.       g_HackDbgkCreateThread != 0 && 
    55.        g_HackDbgkExitThread != 0&& 
    56.        g_NopDbgkExitThread.Address != 0 && 
    57.       g_HackDbgkExitProcess != 0 && 
    58.        g_NopDbgkExitProcess.Address !=0 && 
    59.        g_HackDbgkMapViewOfSection != 0 && 
    60.       g_NopDbgkMapViewOfSection.Address != 0 && 
    61.       g_HackDbgkUnMapViewOfSection != 0 && 
    62.       g_NopDbgkUnMapViewOfSection.Address != 0 && 
    63.       g_HackPspExitThread != 0 && 
    64.        g_HackMmCreatePeb != 0&& 
    65.        g_HackDbgkpSetProcessDebugObject[0] != 0&& 
    66.        g_HackDbgkpSetProcessDebugObject[1] != 0&& 
    67.        g_HackDbgkpSetProcessDebugObject[2] != 0&& 
    68.        g_HackDbgkpSetProcessDebugObject[3] != 0&& 
    69.        g_HackDbgkpMarkProcessPeb != 0); 

    代码:

    1. //修改已经运行进程的DebugPort位置 
    2. BOOLEAN ChangeProcessDebugPort(BOOLEAN Hide ) 
    3.   ULONG eProcess = (ULONG)PsInitialSystemProcess; 
    4. PLIST_ENTRY pListHead,pListWalk; 
    5.   ULONG DebugObject; 
    6.   if( !g_bIsAddressStartup ){ 
    7.     return FALSE; 
    8.   } 
    9.   pListHead = (PLIST_ENTRY)( eProcess + ACTIVE_LINKS_OFFSET ); 
    10.   pListWalk= pListHead; 
    11.   _SEH_TRY 
    12.   {     
    13.     do{ 
    14.       if( pListWalk == NULL || eProcess== 0 ) 
    15.         break; 
    16.       eProcess = ( (ULONG)pListWalk - ACTIVE_LINKS_OFFSET );     
    17.       if( Hide ){ 
    18.         DebugObject = *(ULONG*)( eProcess + DEBUG_PORT_OFFSET ); 
    19.        *(ULONG*)( eProcess + CREATE_TIME_OFFSET ) = DebugObject; 
    20.         *(ULONG*)(eProcess + DEBUG_PORT_OFFSET ) = 0; 
    21.       }else{ 
    22.         DebugObject = *(ULONG*)( eProcess + CREATE_TIME_OFFSET ); 
    23.        *(ULONG*)( eProcess + DEBUG_PORT_OFFSET ) = DebugObject; 
    24.       } 
    25.       pListWalk = pListWalk->Flink; 
    26.     }while( pListWalk != pListHead ); 
    27.   } 
    28.   _SEH_HANDLER 
    29.   { 
    30.     DbgPrint( "ChangeProcessDebugPortexception! " ); 
    31.   } 
    32.    
    33.   return TRUE; 
    34. 代码: 
    35. BOOLEANModifyDebugFunction() 
    36.   if( !g_bIsAddressStartup ){ 
    37.     returnFALSE; 
    38.   } 
    39.   __asm{ 
    40.     cli 
    41.     mov  eax,cr0 
    42.     and  eax,not 10000h 
    43.    mov  cr0,eax 
    44.   } 
    45.   *(ULONG*)g_HackPspCreateProcess = CREATE_TIME_OFFSET; 
    46. *(ULONG*)g_HackKiDispatchException = CREATE_TIME_OFFSET; 
    47. *(ULONG*)g_HackDbgkForwardException = CREATE_TIME_OFFSET; 
    48. *(ULONG*)g_HackDbgkpQueueMessage = CREATE_TIME_OFFSET; 
    49. *(ULONG*)g_HackDbgkCreateThread = CREATE_TIME_OFFSET; 
    50. *(ULONG*)g_HackDbgkExitThread = CREATE_TIME_OFFSET; 
    51. *(ULONG*)g_HackDbgkExitProcess = CREATE_TIME_OFFSET; 
    52. *(ULONG*)g_HackDbgkMapViewOfSection = CREATE_TIME_OFFSET; 
    53. *(ULONG*)g_HackDbgkUnMapViewOfSection = CREATE_TIME_OFFSET; 
    54. *(ULONG*)g_HackPspExitThread = CREATE_TIME_OFFSET; 
    55. *(ULONG*)g_HackDbgkpMarkProcessPeb = CREATE_TIME_OFFSET; 
    56. *(ULONG*)g_HackMmCreatePeb = CREATE_TIME_OFFSET; 
    57. *(ULONG*)g_HackDbgkpSetProcessDebugObject[0] = CREATE_TIME_OFFSET; 
    58. *(ULONG*)g_HackDbgkpSetProcessDebugObject[1] = CREATE_TIME_OFFSET; 
    59. *(ULONG*)g_HackDbgkpSetProcessDebugObject[2] = CREATE_TIME_OFFSET; 
    60. *(ULONG*)g_HackDbgkpSetProcessDebugObject[3] = CREATE_TIME_OFFSET; 
    61.      
    62.   RtlCopyMemory((PVOID)g_NopPspCreateProcess.Address,g_NopPspCreateProcess.NopCode,g_NopPspCreateProcess.Size); 
    63.   RtlCopyMemory((PVOID)g_NopDbgkForwardException.Address,g_NopDbgkForwardException.NopCode,g_NopDbgkForwardException.Size); 
    64.   RtlCopyMemory((PVOID)g_NopDbgkExitThread.Address,g_NopDbgkExitThread.NopCode,g_NopDbgkExitThread.Size); 
    65.   RtlCopyMemory((PVOID)g_NopDbgkExitProcess.Address,g_NopDbgkExitProcess.NopCode,g_NopDbgkExitProcess.Size); 
    66.   RtlCopyMemory((PVOID)g_NopDbgkMapViewOfSection.Address,g_NopDbgkMapViewOfSection.NopCode,g_NopDbgkMapViewOfSection.Size); 
    67.   RtlCopyMemory((PVOID)g_NopDbgkUnMapViewOfSection.Address,g_NopDbgkUnMapViewOfSection.NopCode,g_NopDbgkUnMapViewOfSection.Size); 
    68.   __asm{ 
    69.     mov  eax,cr0 
    70.     or   eax,10000h 
    71.     mov cr0,eax 
    72.     sti 
    73.   } 
    74.   return TRUE; 
    75. BOOLEAN WriteBackDebugFunction() 
    76.   if( !g_bIsAddressStartup ){ 
    77.    return FALSE; 
    78.   } 
    79.   __asm{ 
    80.     cli 
    81.     mov  eax,cr0 
    82.     and  eax,not 10000h 
    83.    mov  cr0,eax 
    84.   } 
    85.   *(ULONG*)g_HackPspCreateProcess = DEBUG_PORT_OFFSET; 
    86. *(ULONG*)g_HackKiDispatchException = DEBUG_PORT_OFFSET; 
    87. *(ULONG*)g_HackDbgkForwardException = DEBUG_PORT_OFFSET; 
    88. *(ULONG*)g_HackDbgkpQueueMessage = DEBUG_PORT_OFFSET; 
    89. *(ULONG*)g_HackDbgkCreateThread = DEBUG_PORT_OFFSET; 
    90. *(ULONG*)g_HackDbgkExitThread = DEBUG_PORT_OFFSET; 
    91. *(ULONG*)g_HackDbgkExitProcess = DEBUG_PORT_OFFSET; 
    92. *(ULONG*)g_HackDbgkMapViewOfSection = DEBUG_PORT_OFFSET; 
    93. *(ULONG*)g_HackDbgkUnMapViewOfSection = DEBUG_PORT_OFFSET; 
    94. *(ULONG*)g_HackPspExitThread = DEBUG_PORT_OFFSET; 
    95. *(ULONG*)g_HackDbgkpMarkProcessPeb = DEBUG_PORT_OFFSET; 
    96. *(ULONG*)g_HackMmCreatePeb = DEBUG_PORT_OFFSET; 
    97. *(ULONG*)g_HackDbgkpSetProcessDebugObject[0] = DEBUG_PORT_OFFSET; 
    98. *(ULONG*)g_HackDbgkpSetProcessDebugObject[1] = DEBUG_PORT_OFFSET; 
    99. *(ULONG*)g_HackDbgkpSetProcessDebugObject[2] = DEBUG_PORT_OFFSET; 
    100. *(ULONG*)g_HackDbgkpSetProcessDebugObject[3] = DEBUG_PORT_OFFSET; 
    101.   RtlCopyMemory((PVOID)g_NopPspCreateProcess.Address,g_NopPspCreateProcess.OrigCode,g_NopPspCreateProcess.Size); 
    102.   RtlCopyMemory((PVOID)g_NopDbgkForwardException.Address,g_NopDbgkForwardException.OrigCode,g_NopDbgkForwardException.Size); 
    103.   RtlCopyMemory((PVOID)g_NopDbgkExitThread.Address,g_NopDbgkExitThread.OrigCode,g_NopDbgkExitThread.Size); 
    104.   RtlCopyMemory((PVOID)g_NopDbgkExitProcess.Address,g_NopDbgkExitProcess.OrigCode,g_NopDbgkExitProcess.Size); 
    105.   RtlCopyMemory((PVOID)g_NopDbgkMapViewOfSection.Address,g_NopDbgkMapViewOfSection.OrigCode,g_NopDbgkMapViewOfSection.Size); 
    106.   RtlCopyMemory((PVOID)g_NopDbgkUnMapViewOfSection.Address,g_NopDbgkUnMapViewOfSection.OrigCode,g_NopDbgkUnMapViewOfSection.Size); 
    107.   __asm{ 
    108.     mov  eax,cr0 
    109.     or   eax,10000h 
    110.     mov cr0,eax 
    111.     sti 
    112.   } 
    113.   return TRUE; 

        我想再嗦一下,上面代码大家看到很多函数有个NOPCode,这个实际上是对付线程PS_CROSS_THREAD_FLAGS_HIDEFROMDBG的,NOP掉相关地方后,就算线程被设置为ThreadHideFromDebugger也无法阻挡调试器接收调试信息。

  • 相关阅读:
    bin/sh^M: bad interpreter: No such file or directory解决
    1.2前置条件
    LINUXIPCS信息
    动态添加样式表规则第3版
    Google放出C++代码风格规范
    我的模块加载系统 v4
    有关婚姻的名言
    javascript 测试工具abut v3
    全世界最短的domReady
    javascript 模板系统 ejs v7
  • 原文地址:https://www.cnblogs.com/DuanLaoYe/p/5477544.html
Copyright © 2020-2023  润新知