[转] hook PsCreateSystemThread

hook PsCreateSystemThread

很多RootKit在ring0下利用PsCreateSystemThread来创建系统线程做某些WS的事情,我们平时不利用ARK工具的话,是很难发现这些线程,在某些情况下,需要anti一些特定的rootkit,这里给出一个简单的示例:

.h:
#pragma once

#include 
< ntddk.h >  

typedef 
long  LONG;
typedef unsigned 
char   BOOL,  * PBOOL;
typedef unsigned 
char   BYTE,  * PBYTE;
typedef unsigned 
long   DWORD,  * PDWORD;
typedef unsigned 
short  WORD,  * PWORD;

typedef 
void    * HMODULE;
typedef 
long  NTSTATUS,  * PNTSTATUS;
typedef unsigned 
long  DWORD;
typedef DWORD 
*  PDWORD;
typedef unsigned 
long  ULONG;
typedef unsigned 
long  ULONG_PTR;
typedef ULONG 
* PULONG;
typedef unsigned 
short  WORD;
typedef unsigned 
char  BYTE; 
typedef unsigned 
char  UCHAR;
typedef unsigned 
short  USHORT;
typedef 
void   * PVOID;
typedef BYTE BOOLEAN;
#define  SEC_IMAGE    0x01000000

NTSTATUS
  PsLookupProcessByProcessId(
    IN HANDLE ProcessId,
    OUT PEPROCESS 
* Process
    );

.c:
#include  " HookPsThread.h "
/**/ /******************************************************************************

    Hook PsCreateSystemThread
    out adress

*****************************************************************************
*/


// =============================================================================
//         Version Define
// =============================================================================
#define  EPROCESS_SIZE            1
#define  PEB_OFFSET                2   
#define  FILE_NAME_OFFSET        3   
#define  PROCESS_LINK_OFFSET     4   
#define  PROCESS_ID_OFFSET       5 
#define  EXIT_TIME_OFFSET        6 
// =============================================================================
//         Logic Define
// =============================================================================
ULONG PsCreateSystemThreadAddr  =   0 ;
char  PsCreateSystemThreadData[ 5 =   {0} ;

DWORD  ProcessNameOffset;

// -----------------------------------------------------------------------------
//         GetPlantformDependentInfo
// -----------------------------------------------------------------------------
DWORD GetPlantformDependentInfo( DWORD dwFlag )    
{     
    DWORD current_build;     
    DWORD ans 
= 0;     
   
    PsGetVersion(NULL, NULL, 
&current_build, NULL);     
   
    
switch ( dwFlag )    
    
{     
    
case EPROCESS_SIZE:     
        
if (current_build == 2195) ans = 0 ;        // 2000,当前不支持2000,下同    
        if (current_build == 2600) ans = 0x25C;     // xp    
        if (current_build == 3790) ans = 0x270;     // 2003    
        break;     
    
case PEB_OFFSET:     
        
if (current_build == 2195)  ans = 0;     
        
if (current_build == 2600)  ans = 0x1b0;     
        
if (current_build == 3790)  ans = 0x1a0;    
        
break;     
    
case FILE_NAME_OFFSET:     
        
if (current_build == 2195)  ans = 0;     
        
if (current_build == 2600)  ans = 0x174;     
        
if (current_build == 3790)  ans = 0x164;    
        
break;     
    
case PROCESS_LINK_OFFSET:     
        
if (current_build == 2195)  ans = 0;     
        
if (current_build == 2600)  ans = 0x088;     
        
if (current_build == 3790)  ans = 0x098;    
        
break;     
    
case PROCESS_ID_OFFSET:     
        
if (current_build == 2195)  ans = 0;     
        
if (current_build == 2600)  ans = 0x084;     
        
if (current_build == 3790)  ans = 0x094;    
        
break;     
    
case EXIT_TIME_OFFSET:     
        
if (current_build == 2195)  ans = 0;     
        
if (current_build == 2600)  ans = 0x078;     
        
if (current_build == 3790)  ans = 0x088;    
        
break;     
    }
     
    
return ans;     
}



// -----------------------------------------------------------------------------
//         GetFunctionAddr
// -----------------------------------------------------------------------------
ULONG GetFunctionAddr( IN PCWSTR FunctionName)
{
    UNICODE_STRING UniCodeFunctionName;
    RtlInitUnicodeString( 
&UniCodeFunctionName, FunctionName );
    
return (ULONG)MmGetSystemRoutineAddress( &UniCodeFunctionName );   
}


// -----------------------------------------------------------------------------
//         _PsCreateSystemThread
// -----------------------------------------------------------------------------
NTSTATUS _PsCreateSystemThread(IN PKSTART_ROUTINE  StartRoutine)
{
    ULONG RAddr 
= (ULONG)StartRoutine;  //Routine Address
    
//Get Process Info
    LPTSTR   CurProc;
    PEPROCESS EProcess;
    PsLookupProcessByProcessId(PsGetCurrentProcessId(), 
&EProcess);
    CurProc 
=(LPTSTR)EProcess;
    CurProc 
=CurProc+ProcessNameOffset;

    
if (strncmp((char*)CurProc,"System",6!= 0)
    
{
        DbgPrint(
"Current Process : %s, StartRoutine : %X\n", (char *)CurProc, StartRoutine);
    }

    
return 0;
}


// -----------------------------------------------------------------------------
//         MyPsCreateSystemThread
// -----------------------------------------------------------------------------
__declspec (naked) void  MyPsCreateSystemThread()
{
    _asm
    
{
        pushad
        push [esp
+20h+18h]
        call _PsCreateSystemThread
        popad
        
        mov edi,edi
        push ebp
        mov ebp,esp
        jmp PsCreateSystemThreadAddr
    }

}


// -----------------------------------------------------------------------------
//         Install Hook
// -----------------------------------------------------------------------------
VOID InHook()
{
    PsCreateSystemThreadAddr 
= GetFunctionAddr(L"PsCreateSystemThread");

    __asm
    
{
        push    eax
        mov        eax, CR0
        and        eax, 0FFFEFFFFh
        mov        CR0, eax
        pop        eax
    }


    
//Save asmCode
    memcpy(PsCreateSystemThreadData, (PVOID)PsCreateSystemThreadAddr, 5);
    (ULONG)PsCreateSystemThreadAddr 
+= 5;

    
//Inline PsCreateSystemThread
    __asm
    
{
        mov esi, PsCreateSystemThreadAddr
        sub esi, 
5
        mov 
byte ptr[esi], 0xE9
        lea eax, [MyPsCreateSystemThread]
        sub eax, esi
        sub eax, 
5
        mov dword ptr [esi
+1],eax
    }


    __asm
    
{
        push    eax
        mov        eax, CR0
        or        eax, NOT 0FFFEFFFFh
        mov        CR0, eax
        pop        eax
    }


    DbgPrint(
"Hooked OK.\n");
    
return;
}


// -----------------------------------------------------------------------------
//         Uninstall Hook
// -----------------------------------------------------------------------------
VOID UnHook()
{
    __asm
    
{
        push    eax
        mov        eax, CR0
        and        eax, 0FFFEFFFFh
        mov        CR0, eax
        pop        eax
    }

    (ULONG)PsCreateSystemThreadAddr 
-= 5;
    memcpy((PVOID)PsCreateSystemThreadAddr, PsCreateSystemThreadData, 
5);
    __asm
    
{
        push    eax
        mov        eax, CR0
        or        eax, NOT 0FFFEFFFFh
        mov        CR0, eax
        pop        eax
    }

    DbgPrint(
"UnHook OK.\n");
    
return;
}


// -----------------------------------------------------------------------------
//         Driver UnLoad
// -----------------------------------------------------------------------------
void  OnUnload(PDRIVER_OBJECT pDriverObj)
{
    UnHook();
    DbgPrint(
"UnLoading Driver");
}


// -----------------------------------------------------------------------------
//         Driver LoadEntry
// -----------------------------------------------------------------------------
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
{
    pDriverObj
->DriverUnload = OnUnload;

    DbgPrint(
"Loading Driver");
    ProcessNameOffset 
= GetPlantformDependentInfo(FILE_NAME_OFFSET);
    InHook();
    
return STATUS_SUCCESS;
}
很多RootKit在ring0下利用PsCreateSystemThread来创建系统线程做某些WS的事情,我们平时不利用ARK工具的话,是很难发现这些线程,在某些情况下,需要anti一些特定的rootkit,这里给出一个简单的示例:

.h:
#pragma once

#include 
< ntddk.h >  

typedef 
long  LONG;
typedef unsigned 
char   BOOL,  * PBOOL;
typedef unsigned 
char   BYTE,  * PBYTE;
typedef unsigned 
long   DWORD,  * PDWORD;
typedef unsigned 
short  WORD,  * PWORD;

typedef 
void    * HMODULE;
typedef 
long  NTSTATUS,  * PNTSTATUS;
typedef unsigned 
long  DWORD;
typedef DWORD 
*  PDWORD;
typedef unsigned 
long  ULONG;
typedef unsigned 
long  ULONG_PTR;
typedef ULONG 
* PULONG;
typedef unsigned 
short  WORD;
typedef unsigned 
char  BYTE; 
typedef unsigned 
char  UCHAR;
typedef unsigned 
short  USHORT;
typedef 
void   * PVOID;
typedef BYTE BOOLEAN;
#define  SEC_IMAGE    0x01000000

NTSTATUS
  PsLookupProcessByProcessId(
    IN HANDLE ProcessId,
    OUT PEPROCESS 
* Process
    );

.c:
#include  " HookPsThread.h "
/**/ /******************************************************************************

    Hook PsCreateSystemThread
    out adress

*****************************************************************************
*/


// =============================================================================
//         Version Define
// =============================================================================
#define  EPROCESS_SIZE            1
#define  PEB_OFFSET                2   
#define  FILE_NAME_OFFSET        3   
#define  PROCESS_LINK_OFFSET     4   
#define  PROCESS_ID_OFFSET       5 
#define  EXIT_TIME_OFFSET        6 
// =============================================================================
//         Logic Define
// =============================================================================
ULONG PsCreateSystemThreadAddr  =   0 ;
char  PsCreateSystemThreadData[ 5 =   {0} ;

DWORD  ProcessNameOffset;

// -----------------------------------------------------------------------------
//         GetPlantformDependentInfo
// -----------------------------------------------------------------------------
DWORD GetPlantformDependentInfo( DWORD dwFlag )    
{     
    DWORD current_build;     
    DWORD ans 
= 0;     
   
    PsGetVersion(NULL, NULL, 
&current_build, NULL);     
   
    
switch ( dwFlag )    
    
{     
    
case EPROCESS_SIZE:     
        
if (current_build == 2195) ans = 0 ;        // 2000,当前不支持2000,下同    
        if (current_build == 2600) ans = 0x25C;     // xp    
        if (current_build == 3790) ans = 0x270;     // 2003    
        break;     
    
case PEB_OFFSET:     
        
if (current_build == 2195)  ans = 0;     
        
if (current_build == 2600)  ans = 0x1b0;     
        
if (current_build == 3790)  ans = 0x1a0;    
        
break;     
    
case FILE_NAME_OFFSET:     
        
if (current_build == 2195)  ans = 0;     
        
if (current_build == 2600)  ans = 0x174;     
        
if (current_build == 3790)  ans = 0x164;    
        
break;     
    
case PROCESS_LINK_OFFSET:     
        
if (current_build == 2195)  ans = 0;     
        
if (current_build == 2600)  ans = 0x088;     
        
if (current_build == 3790)  ans = 0x098;    
        
break;     
    
case PROCESS_ID_OFFSET:     
        
if (current_build == 2195)  ans = 0;     
        
if (current_build == 2600)  ans = 0x084;     
        
if (current_build == 3790)  ans = 0x094;    
        
break;     
    
case EXIT_TIME_OFFSET:     
        
if (current_build == 2195)  ans = 0;     
        
if (current_build == 2600)  ans = 0x078;     
        
if (current_build == 3790)  ans = 0x088;    
        
break;     
    }
     
    
return ans;     
}



// -----------------------------------------------------------------------------
//         GetFunctionAddr
// -----------------------------------------------------------------------------
ULONG GetFunctionAddr( IN PCWSTR FunctionName)
{
    UNICODE_STRING UniCodeFunctionName;
    RtlInitUnicodeString( 
&UniCodeFunctionName, FunctionName );
    
return (ULONG)MmGetSystemRoutineAddress( &UniCodeFunctionName );   
}


// -----------------------------------------------------------------------------
//         _PsCreateSystemThread
// -----------------------------------------------------------------------------
NTSTATUS _PsCreateSystemThread(IN PKSTART_ROUTINE  StartRoutine)
{
    ULONG RAddr 
= (ULONG)StartRoutine;  //Routine Address
    
//Get Process Info
    LPTSTR   CurProc;
    PEPROCESS EProcess;
    PsLookupProcessByProcessId(PsGetCurrentProcessId(), 
&EProcess);
    CurProc 
=(LPTSTR)EProcess;
    CurProc 
=CurProc+ProcessNameOffset;

    
if (strncmp((char*)CurProc,"System",6!= 0)
    
{
        DbgPrint(
"Current Process : %s, StartRoutine : %X\n", (char *)CurProc, StartRoutine);
    }

    
return 0;
}


// -----------------------------------------------------------------------------
//         MyPsCreateSystemThread
// -----------------------------------------------------------------------------
__declspec (naked) void  MyPsCreateSystemThread()
{
    _asm
    
{
        pushad
        push [esp
+20h+18h]
        call _PsCreateSystemThread
        popad
        
        mov edi,edi
        push ebp
        mov ebp,esp
        jmp PsCreateSystemThreadAddr
    }

}


// -----------------------------------------------------------------------------
//         Install Hook
// -----------------------------------------------------------------------------
VOID InHook()
{
    PsCreateSystemThreadAddr 
= GetFunctionAddr(L"PsCreateSystemThread");

    __asm
    
{
        push    eax
        mov        eax, CR0
        and        eax, 0FFFEFFFFh
        mov        CR0, eax
        pop        eax
    }


    
//Save asmCode
    memcpy(PsCreateSystemThreadData, (PVOID)PsCreateSystemThreadAddr, 5);
    (ULONG)PsCreateSystemThreadAddr 
+= 5;

    
//Inline PsCreateSystemThread
    __asm
    
{
        mov esi, PsCreateSystemThreadAddr
        sub esi, 
5
        mov 
byte ptr[esi], 0xE9
        lea eax, [MyPsCreateSystemThread]
        sub eax, esi
        sub eax, 
5
        mov dword ptr [esi
+1],eax
    }


    __asm
    
{
        push    eax
        mov        eax, CR0
        or        eax, NOT 0FFFEFFFFh
        mov        CR0, eax
        pop        eax
    }


    DbgPrint(
"Hooked OK.\n");
    
return;
}


// -----------------------------------------------------------------------------
//         Uninstall Hook
// -----------------------------------------------------------------------------
VOID UnHook()
{
    __asm
    
{
        push    eax
        mov        eax, CR0
        and        eax, 0FFFEFFFFh
        mov        CR0, eax
        pop        eax
    }

    (ULONG)PsCreateSystemThreadAddr 
-= 5;
    memcpy((PVOID)PsCreateSystemThreadAddr, PsCreateSystemThreadData, 
5);
    __asm
    
{
        push    eax
        mov        eax, CR0
        or        eax, NOT 0FFFEFFFFh
        mov        CR0, eax
        pop        eax
    }

    DbgPrint(
"UnHook OK.\n");
    
return;
}


// -----------------------------------------------------------------------------
//         Driver UnLoad
// -----------------------------------------------------------------------------
void  OnUnload(PDRIVER_OBJECT pDriverObj)
{
    UnHook();
    DbgPrint(
"UnLoading Driver");
}


// -----------------------------------------------------------------------------
//         Driver LoadEntry
// -----------------------------------------------------------------------------
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
{
    pDriverObj
->DriverUnload = OnUnload;

    DbgPrint(
"Loading Driver");
    ProcessNameOffset 
= GetPlantformDependentInfo(FILE_NAME_OFFSET);
    InHook();
    
return STATUS_SUCCESS;
}

你可能感兴趣的:([转] hook PsCreateSystemThread)