Низкоуровневая подмена результаты команды rdtsc.
- Делает инструкцию привиллегированной и путём перехвата KiUserExceptionDispatcher увеличивает регистр eip на 2 байта(размер инструкции rdtsc). Регистры edx и eax соотв-но обнуляются.
Хук(DeviceIoControl()->lpInBuffer):
Снятия хука(DeviceIoControl()->lpInBuffer):
Код:
- Делает инструкцию привиллегированной и путём перехвата KiUserExceptionDispatcher увеличивает регистр eip на 2 байта(размер инструкции rdtsc). Регистры edx и eax соотв-но обнуляются.
Хук(DeviceIoControl()->lpInBuffer):
Код:
param struct
code db ('HOOK')
handl dd ? ; Хэндл ntdll.dll
adr dd ? ; Адрес KiUserExceptionDispatcher
param ends
Снятия хука(DeviceIoControl()->lpInBuffer):
Код:
param struct
code db ('UNHO')
param ends
Код:
Код:
.586
.model flat, stdcall
option casemap:none
include \masm32\include\w2k\ntstatus.inc
include \masm32\include\w2k\ntddk.inc
include \masm32\include\w2k\ntoskrnl.inc
includelib \masm32\lib\w2k\ntoskrnl.lib
include \masm32\macros\strings.mac
.const
UNICODE = 0
ARGUMENTS = 1
.data
driver dw '\','D','e','v','i','c','e','\','f','a','k','e','r','d','t','s','c',0
symdriver dw '\','?','?','\','f','a','k','e','r','d','t','s','c',0
align 4
driver_us UNICODE_STRING <0>
sym_us UNICODE_STRING <0>
pdeviceobject dd ?
mdl dd ?
c_cr0 dd ?
ntdllbase dd ?
kiuser dd ?
.code
DriverEntry proc pDriverObject:dword, RegPath:dword
push ebx
push esi
push edi
;-------------------------------------------------------
MOV esi, RtlInitUnicodeString
push offset driver
push offset driver_us
call esi
invoke IoCreateDevice, pDriverObject, 0, offset driver_us, FILE_DEVICE_UNKNOWN,\
0, 0, offset pdeviceobject
test eax, eax
jnz __init_fail
push offset symdriver
push offset sym_us
call esi
invoke IoCreateSymbolicLink, offset sym_us, offset driver_us
test eax, eax
jnz __delete_device
mov eax, pDriverObject
mov dword ptr [eax+38h], offset RequestHandler ; DRIVER_OBJECT.PDISPATCH_IRP_MJ_CREATE
mov dword ptr [eax+40h], offset RequestHandler ; DRIVER_OBJECT.PDISPATCH_IRP_MJ_CLOSE
mov dword ptr [eax+70h], offset ServiceHandler ; DRIVER_OBJECT.PDISPATCH_IRP_MJ_DEVICE_CONTROL
mov dword ptr [eax+34h], offset DriverUnload ; DRIVER_OBJECT.PDRIVER_UNLOAD
xor eax, eax
jmp __exit
__delete_device: mov eax, pdeviceobject
push dword ptr[eax+4]
call IoDeleteDevice
__init_fail: xor eax, eax
inc eax
;-------------------------------------------------------
__exit:
pop edi
pop esi
pop ebx
ret
DriverEntry endp
RequestHandler: ;pDriverObject [esp+4], pIrp [esp+8]
mov ecx, [esp+8] ;pIrp
mov dword ptr [ecx+18h], 0; _IRP.IoStatus.IO_STATUS_BLOCK.Status < STATUS_SUCCESS
mov dword ptr [ecx+1ch], 0; _IRP.IoStatus.IO_STATUS_BLOCK.Information < nowt
xor dl, dl ;IRP_NO_INCREMENT
call IofCompleteRequest ;fast call 1st arg ecx, 2nd edx
xor eax, eax
ret 8
DriverUnload: ;pDeviceObject [esp+4]
invoke IoDeleteSymbolicLink, offset sym_us
mov eax, [esp+4]
push dword ptr [eax+4];pDriverObject.DeviceObject
call IoDeleteDevice
ret 4
;-------------------------------------------------------
ServiceHandler: ;pDriverObject [ebp+8], pIrp [ebp+0ch]
push ebp ;
mov ebp, esp ;
push ebx ; prolog
push esi ;
push edi ;
;-------------------------------------------------------
mov ebx, [ebp+0ch];pIrp
mov edx, [ebx+60h];_IRP.Tail.Overlay.CurrentStackLocation IO_STACK_LOCATION.DeviceIoControl
mov eax, [edx+0ch];DeviceIoDeviceIoControl.IoControlCode
cmp eax, 20h
jne __sh_failed
;check if user input buffer is valid
push [ebx+0ch] ;pirp.SystemBuffer (user input)
call MmIsAddressValid;not needed at all...
test al, al
jz __sh_failed
mov ebx, [ebx+0ch];prip.SystemBuffer
cmp dword ptr[ebx], 'HOOK'
je __hook
cmp dword ptr[ebx], 'UNHO'
jne __sh_failed
call unhookrdtsc
jmp __sh_oki
__hook:
mov eax, [ebx+4]
mov ntdllbase, eax
mov eax, [ebx+8]
mov kiuser, eax
call hookrdtsc
jmp __sh_oki
__sh_failed: xor dl, dl ;IRP_NO_INCREMENT
mov ecx, [ebp+0ch];pIrp
call IofCompleteRequest
xor eax, eax
inc eax ;failed
jmp __exit_sh
__sh_oki: xor dl, dl ;IRP_NO_INCREMENT
mov ecx, [ebp+0ch];pIrp
call IofCompleteRequest
xor eax, eax ;success
;-------------------------------------------------------
__exit_sh: pop edi ; epilog
pop esi ;
pop ebx ;
mov esp, ebp ;
pop ebp ;
ret 8 ;
;-------------------------------------------------------
;-------------------------------------------------------
hookrdtsc:
mov eax, cr4
or eax, 4
mov cr4, eax
invoke IoAllocateMdl, kiuser, 1000h, 0, 0, 0
test eax, eax
jz __fail
mov mdl, eax
invoke MmProbeAndLockPages, eax, 0, 0
mov eax, cr0
mov c_cr0, eax
and eax, 0FFFEFFFFh
mov cr0, eax
mov eax, ntdllbase
add eax, 300h
mov dword ptr[hook+1], eax
mov esi, offset hook
mov edi, kiuser
mov ecx, 7
cld
rep movsb
mov eax, kiuser
add eax, 7
mov dword ptr[goback+1], eax
mov esi, offset myhook
mov edi, ntdllbase
add edi, 300h
mov ecx, sizemyhook
rep movsb
mov eax, c_cr0
mov cr0, eax
invoke MmUnlockPages, mdl
invoke IoFreeMdl, mdl
__fail: ret
unhookrdtsc:
mov eax, cr4
and eax, 0FFFFFFFBh
mov cr4, eax
invoke IoAllocateMdl, kiuser, 1000h, 0, 0, 0
test eax, eax
jz __fail1
mov mdl, eax
invoke MmProbeAndLockPages, eax, 0, 0
mov eax, cr0
mov c_cr0, eax
and eax, 0FFFEFFFFh
mov cr0, eax
mov esi, offset oldkiuser
mov edi, kiuser
mov ecx, 7
cld
rep movsb
mov eax, c_cr0
mov cr0, eax
invoke MmUnlockPages, mdl
invoke IoFreeMdl, mdl
__fail1: ret
oldkiuser: mov ecx, [esp+4]
mov ebx, [esp]
hook: push 10000001h
ret
nop
myhook: mov ecx, [esp+4]
mov ebx, [esp]
cmp dword ptr[ebx], STATUS_PRIVILEGED_INSTRUCTION
jne goback
assume ecx: ptr CONTEXT
mov eax, [ecx].regEip;eip
cmp word ptr[eax], 310fh; rdtsc
jne goback
xor edx, edx
xor eax, eax
add dword ptr[ecx].regEip, 2; eip = eip + 2h (next instruction)
mov ebx, [ecx].regEbx;ebx
mov ebp, [ecx].regEbp;ebp
mov esi, [ecx].regEsi;esi
mov edi, [ecx].regEdi;edi
mov esp, [ecx].regEsp;esp
push dword ptr [ecx].regEFlags;eflags
popfd
push dword ptr[ecx].regEip;eip
mov ecx, dword ptr[ecx].regEcx; ecx
ret
goback: push 10000001h
ret
sizemyhook = $-myhook
end DriverEntry