0,0 → 1,234 |
.386p |
WIN40COMPAT = 1 |
include vmm.inc |
include v86mmgr.inc |
DECLARE_VIRTUAL_DEVICE LDKLBR,1,0,LDKLBR_Control,UNDEFINED_DEVICE_ID,1 |
|
;Begin_control_dispatch LDKLBR |
;Control_Dispatch w32_DeviceIoControl, OnDeviceIoControl |
;Control_Dispatch Sys_Dynamic_Device_Exit, OnExit |
;End_control_dispatch LDKLBR |
|
VxD_LOCKED_DATA_SEG |
VkdControlProc dd 0 |
vkdddb dd 0 |
diskinfobuf: |
db 10h,0,0,0FFh |
db 0Ch dup (0) |
|
oldidt label fword |
dw 03FFh |
dd 0 |
|
include mtldr.inc |
|
imgname dd 0 |
|
VxD_LOCKED_DATA_ENDS |
|
VxD_LOCKED_CODE_SEG |
|
BeginProc NewControlProc |
cmp eax, Reboot_Processor |
jz short MyReboot |
jmp [VkdControlProc] |
EndProc NewControlProc |
|
BeginProc MyReboot |
VMMCall _MapPhysToLinear,<0D000h,2000h,0> |
push eax |
VMMCall _MapPhysToLinear,<0,1000h,0> |
xchg eax, ebx |
cli |
lea esi, [ebx+53Ch] |
lodsd |
mov [ebx+413h], ax |
shr eax, 10h |
mov [ebx+40Eh], ax |
; restore BIOS IDT - vectors 00..1F |
mov edi, ebx |
mov ecx, 20h |
rep movsd |
; int 19 |
mov eax, [ebx+810h] |
mov [ebx+64h], eax |
; vectors 40,41,42,43,46,4B,4F |
lea edi, [ebx+40h*4] |
movsd |
movsd |
movsd |
movsd |
scasd |
scasd |
movsd |
add edi, 10h |
movsd |
add edi, 0Ch |
movsd |
; vectors 70..77 |
; lea esi, [ebx+5DCh] |
lea edi, [ebx+70h*4] |
mov ecx, 8 |
rep movsd |
|
; reboot to mtldr |
mov dword ptr [ebx+467h], 0D000007h ; 0D00:0007 |
mov al, 0Fh |
out 70h, al |
jecxz $+2 |
jecxz $+2 |
mov al, 5 |
out 71h, al |
; copy mtldr code |
mov esi, offset mtldr |
; mov edi, 0D000h |
pop edi |
push edi |
mov ecx, mtldr_size |
rep movsb |
; copy mtldr parameters |
mov esi, [imgname] |
mov edi, esi |
mov al, 0 |
xor ecx, ecx |
dec ecx |
repnz scasb |
pop edi |
not ecx |
movzx eax, word ptr [edi+5] |
add edi, eax |
rep movsb |
; load old IDT |
lidt [oldidt] |
; reboot |
mov al, 0FEh |
out 64h, al |
hlt |
EndProc MyReboot |
|
BeginProc LDKLBR_Control |
cmp eax, w32_DeviceIoControl |
jz short OnDeviceIoControl |
cmp eax, Sys_Dynamic_Device_Exit |
jz short OnExit |
cmp eax, Reboot_Processor |
jz MyReboot |
clc |
ret |
|
OnExit: |
; allow unload if and only if we are not hooking |
cmp [VkdControlProc], 1 |
cmc |
ret |
|
OnDeviceIoControl: |
cmp dword ptr [esi+12], DIOC_Open |
jz @@open |
cmp dword ptr [esi+12], 0Fh |
jnz _exit |
; request to set path of image |
mov ecx, [esi+20] ; cbInBuffer |
cmp ecx, 300 |
ja short @@paramerr |
test ecx, ecx |
jnz short @@param1ok |
@@paramerr: |
xor eax, eax |
inc eax |
@@errret: |
mov ecx, [vkdddb] |
mov edx, [VkdControlProc] |
mov [ecx + VxD_Desc_Block.DDB_Control_Proc], edx |
mov [VkdControlProc], 0 |
ret |
@@param1ok: |
mov eax, [esi+16] ; lpvInBuffer |
; set drive |
mov dl, [eax] |
or dl, 20h |
sub dl, 60h |
jz short @@paramerr |
cmp dl, 'z'-60h |
ja short @@paramerr |
push esi |
Push_Client_State Uses_edi |
mov ecx, 10h |
stc |
push ds |
pop fs |
mov esi, offset diskinfobuf |
VMMCall Get_Cur_VM_Handle |
VxDCall V86MMGR_Allocate_Buffer |
VMMCall Begin_Nest_V86_Exec |
assume ebp:ptr Client_Reg_Struc |
mov [ebp.Client_AX], 440Dh |
mov [ebp.Client_BL], dl |
mov [ebp.Client_CX], 086Fh |
mov [ebp.Client_DX], di |
mov eax, edi |
shr eax, 10h |
mov [ebp.Client_DS], ax |
mov eax, 21h |
VMMCall Exec_Int |
VMMCall End_Nest_Exec |
mov ecx, 10h |
stc |
push ds |
pop fs |
VxDCall V86MMGR_Free_Buffer |
Pop_Client_State Uses_esi |
pop esi |
mov al, byte ptr [diskinfobuf+3] |
cmp al, 0FFh |
jz @@errret |
cmp al, 80h |
jb @@paramerr |
mov byte ptr [mtldr+4], al |
mov eax, dword ptr [diskinfobuf+8] |
mov dword ptr [mtldr], eax |
; set path |
mov ecx, [imgname] |
jecxz @f |
VMMCall _HeapFree, <ecx,0> |
@@: |
mov ecx, [esi+20] |
dec ecx |
push ecx |
VMMCall _HeapAllocate, <ecx,0> |
pop ecx |
mov [imgname], eax |
xchg edi, eax |
mov esi, [esi+16] |
inc esi |
@@1: |
lodsb |
cmp al, 'A' |
jb short @f |
cmp al, 'Z' |
ja short @f |
or al, 20h |
@@: |
stosb |
loop @@1 |
xor eax, eax |
ret |
@@open: |
; don't hook if already hooked |
cmp [VkdControlProc], 0 |
jnz short @f |
mov eax, 0Dh |
VMMCall Get_DDB |
mov [vkdddb], ecx |
mov eax, [ecx + VxD_Desc_Block.DDB_Control_Proc] |
mov [VkdControlProc], eax |
mov [ecx + VxD_Desc_Block.DDB_Control_Proc], NewControlProc |
@@: |
xor eax, eax |
_exit: |
ret |
EndProc LDKLBR_Control |
|
VxD_LOCKED_CODE_ENDS |
|
end |