Hide your debugport in ring0

Source: Internet
Author: User

Title: [original] Hide Your debugport in ring0
Author: wowelf
Time: 2009-01-26, 11: 00: 30
Chain: http://bbs.pediy.com/showthread.php? T = 80971

When a program is debugged by the ring3 debugger, many debugging features can be detected. This forum also has a special post for details, however, there is a very fundamental identifier ring3 that few people can detect, namely _ eprocess. debugport. Debugport is very important for the ring3 debugger. Without its normal ring3 debugging, it cannot be performed. Of course, the premise for detecting this flag is that the program can read ring0 memory. A very simple method for systems above XP is to use the sysdbgreadvirtualmemory method of zwsystemdebugcontrol. We can also map physicalmemory for operations. Before checking debugport, you must first obtain the eprocess address of the process, which can be obtained through the systemhandleinformation method of zwquerysysteminformation, or you can directly search for the eprocess structure of ring0 memory.

For ring3 to directly detect debugport, we can prevent this process from accessing the ring0 memory. However, once the target uses a driver for detection, this is very troublesome. The following describes a hidden _ eprocess. debugport method. The basic idea of this method is to set the debugport of a normal debugging process to zero and correct all affected functions so that our debugger can proceed normally. These functions are as follows:
Pspcreateprocess, mmcreatepeb Process Creation, set debugport
Dbgkcreatethread refers to debugging information created by the sending thread or process.
Kidispatchexception, dbgkforwardexception, and dbgkpqueuemessage send exception debugging information
Debugging information about pspexitthread, dbgkexitthread, and dbgkexitprocess sending thread exit and process exit
Dbgkmapviewofsection and dbgkunmapviewofsection send image loading/unloading debugging information
Dbgkpsetprocessdebugobject and dbgkpmarkprocesspeb set debugport when the debugger attaches a process

There are a lot of such functions. If they are all handled by hook, It would be terrible. Here we use a very simple method: steal dragon and convert it into a Phoenix. We can see that the code used by the system to access debugport is like this (XP)
8b89bc000000 mov ECx, dword ptr [ECx + 0bch] // 0bch is the offset of debugport

We can transfer the debugport to another location of _ eprocess. For example, if I use + 0x070 createtime, it records the process creation time. After the process is created, the system does not modify the process before it exits, and The modification does not affect the system or process. In this way, we can change the above Code to this
8b8970000000 mov ECx, dword ptr [ECx + 070 H] // point to createtime, the actual debugport has been moved here
You only need to modify one byte, which is very simple.

Of course, the most troublesome part of this method is to locate the function that references debugport (I have exhausted all the signatures created for different XP systems). These functions are not exported. If they are specific systems, the simplest method is windbg-> UF ***. It takes only a few minutes to find the hard-coded IP address.

Code:
BOOLEAN InitHackAddress(){  _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( "InitHackAddress Exception!\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 );}

Code:

// Modify the debugport location of the running process Boolean changeprocessdebugport (Boolean hide) {ulong eprocess = (ulong) psinitialsystemprocess; plist_entry plisthead, plistwalk; ulong debugobject; If (! G_bisaddressstartup) {return false;} 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 {dbuplint ("changeprocessdebugport exception! \ N ") ;}return true ;}

Code:

BOOLEAN ModifyDebugFunction(){  if( !g_bIsAddressStartup ){    return FALSE;  }  __asm{    cli    mov  eax,cr0    and  eax,not 10000h    mov  cr0,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{    mov  eax,cr0    or   eax,10000h    mov  cr0,eax    sti  }  return TRUE;}BOOLEAN WriteBackDebugFunction(){  if( !g_bIsAddressStartup ){    return FALSE;  }  __asm{    cli    mov  eax,cr0    and  eax,not 10000h    mov  cr0,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{    mov  eax,cr0    or   eax,10000h    mov  cr0,eax    sti  }  return TRUE;}

I want to give it a bit again. The code above shows that many functions have a nopcode, which is actually used to deal with the thread ps_cross_thread_flags_hidefromdbg. After NOP drops the relevant content, even if the thread is set to threadhidefromdebugger, the debugger cannot be blocked from receiving debugging information.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.