|
Posted on 2009-09-17 21:59 S.l.e!ep.¢% 阅读(780) 评论(0) 编辑 收藏 引用 所属分类: Windows WDM
很多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, ¤t_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, ¤t_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; }
|