📄 icedump.asm
字号:
dd Handler_Int01
dd Handler_Int03
dd Handler_Int04
dd Handler_Int05
dd Handler_Int06
dd Handler_Int0D
dd Handler_Int41
dd 0 ; end of table marker
; we redirect ints 00,01,03,04,05,06,0D,41 - set the corresponding bits
IntHandlerMask:
; 11111111111111110000000000000000
; FEDCBA9876543210FEDCBA9876543210
dd 00000000000000000010000001111011b ; 1F-00
dd 00000000000000000000000000000000b ; 3F-20
dd 00000000000000000000000000000010b ; 5F-40
segment _LTEXT
;-------------------------------------------------------------------------------
; find the IDTR in the VMCB and then hook all IDTs in all existing VMs
;-------------------------------------------------------------------------------
HookInts:
VMMCall Get_Sys_VM_Handle ; figure out VMCB.oPMIDT
mov edi,ebx ; by looking for 0x2FF (IDT limit)
mov ecx,0x30 ; *below* a VMCB (that of the SysVM
mov eax,0x2FF ; since it must have a PM IDT by now)
std
repnz scasw
jecxz .error
sub edi,ebx
add edi,byte 4
mov [VMCB.oPMIDT],edi
cld
mov eax,LF_ALLOC_ERROR + LF_ASYNC
mov ecx,HookedInts_size
VMMCall List_Create
jnc @F
.error:
stc
retn
@@
mov [HooksList],esi
pushfd
cli
.nextVM:
push ebx
call HookIntsInVM
pop ebx
jnc @F
call UnhookInts
popfd
stc
retn
@@
VMMCall Get_Next_VM_Handle
VMMCall Test_Sys_VM_Handle
jnz .nextVM
popfd
clc
retn
;-------------------------------------------------------------------------------
; hook vectors in a V86 (once in a life) or PM (in each VM) IDT
;
; ebx: VMCB
;-------------------------------------------------------------------------------
HookIntsInVM:
test dword [ebx],VMSTAT_PM_APP | VMSTAT_PM_EXEC
jnz .hookPM
mov eax,sdata+V86IDT
cmp dword [eax+HookedInts.VMCB],byte 0
jz @F
clc
retn
@@
mov [eax+HookedInts.VMCB],ebx
add ebx,[VMCB.oPMIDT]
mov esi,[ebx] ; esi: V86 IDT, same in all VMs
debug_start sdata+DebugFlags, ICEDUMP_DEBUG_HOOKS
mov ebx,[eax+HookedInts.VMCB]
Trace_Out "ICEDUMP: hooking V86 ints in VM: #ebx, IDT: #esi"
debug_end
jmp short .hookInts
.hookPM:
mov esi,[HooksList]
VMMCall List_Allocate
jnc @F
.error:
debug_start sdata+DebugFlags, ICEDUMP_DEBUG_HOOKS
Trace_Out "ICEDUMP: failed to hook ints in VM: #ebx"
debug_end
stc
retn
@@
VMMCall List_Attach
mov [eax+HookedInts.VMCB],ebx
mov dword [eax+HookedInts.cAPP],1
add ebx,[VMCB.oPMIDT]
mov esi,[ebx] ; esi: IDT
debug_start sdata+DebugFlags, ICEDUMP_DEBUG_HOOKS
mov ebx,[eax+HookedInts.VMCB]
Trace_Out "ICEDUMP: hooking ints in VM: #ebx, IDT: #esi"
debug_end
.hookInts:
mov edi,eax ; edi: hooks
or ecx,byte -1 ; ecx: int counter
mov edx,IntHandlers
.nextINT:
mov ebx,[edx] ; get Handler_IntX offset
add edx,byte 4
or ebx,ebx ; table is 0-terminated
jnz @F
clc
retn
@@
inc ecx
cmp ecx,byte 0x60 ; max 0x60 ints, safety measure in case
jae .nextINT ; someone screwed up the bitmasks ;-)
lodsd ; get current handler
shl eax,16
lodsw
lodsw
ror eax,16
bt [IntHandlerMask],ecx ; check if we redirect this INT
jnc @B ; no bit shifted into CF
add ebx,edi ; ebx: edi+Handler_IntX
mov dword [ebx],0x25FF36 ; jmp dword [ss:off32]
mov [ebx+3],ebx
sub dword [ebx+3],byte 4
mov [ebx-4],eax
mov [esi-8],bx
shr ebx,16
mov [esi-2],bx
jmp short .nextINT
;-------------------------------------------------------------------------------
; unhook all vectors in all IDTs then free our list
;-------------------------------------------------------------------------------
UnhookInts:
pushfd
cli
cmp dword [HooksList],byte 0
jnz @F
debug_start sdata+DebugFlags, ICEDUMP_DEBUG_HOOKS
mov ebx,[eax+HookedInts.VMCB]
Trace_Out "ICEDUMP: UnhookInts: empty list"
debug_end
jmp short .ret
@@
mov esi,[HooksList]
VMMCall List_Get_First
jz @F
call UnhookIntsInVM
jmp short @B
@@
xor esi,esi
xchg esi,[HooksList]
VMMCall List_Destroy
.ret:
popfd
retn
;-------------------------------------------------------------------------------
; unhook all vectors and free list element
;
; eax: ptr to hooks
;-------------------------------------------------------------------------------
UnhookIntsInVM:
mov ebx,[eax+HookedInts.VMCB]
debug_start sdata+DebugFlags, ICEDUMP_DEBUG_HOOKS
Trace_Out "ICEDUMP: unhooking ints in VM: #ebx"
debug_end
push eax
add ebx,[VMCB.oPMIDT]
mov edi,[ebx] ; edi: IDT
mov edx,eax
or ecx,byte -1 ; ecx: int counter
mov esi,IntHandlers
.nextINT:
lodsd ; get Handler_IntX offset
or eax,eax ; table is 0-terminated
jnz @F
mov eax,[esp]
mov esi,[HooksList]
VMMCall List_Remove
pop eax
VMMCall List_Deallocate
retn
@@
inc ecx
cmp ecx,byte 0x60 ; max 0x60 ints, safety measure in case
jae .nextINT ; someone screwed up the bitmasks ;-)
add edi,byte 8
bt [IntHandlerMask],ecx ; check if we redirect this INT
jnc @B ; no bit shifted into CF
add eax,edx ; eax: edx+Handler_IntX
mov eax,[eax-4] ; get original handler
mov [edi-8],ax
shr eax,16
mov [edi-2],ax
jmp short .nextINT
;-------------------------------------------------------------------------------
HookWiniceMain:
; hook pWiniceMain at pDisableAllIRQs call
mov ebx,[pDisableAllIRQs] ; absolute adjusted call addr
sub ebx,byte 4
mov edi,[pWiniceMain]
mov ecx,0x400 ; look thru 1k of code
mov al,0xE8 ; search for 'call rel32'
.again:
repnz scasb
jecxz .exit
push ebx
sub ebx,edi ; rel32 offset of call
cmp ebx,[edi] ; is it our call ?
pop ebx
jne .again
; found location of call, now hook
mov [WiniceMainHookSource],edi
mov ebx,WiniceMainHook-4
sub ebx,edi
xchg [edi],ebx
mov [WiniceMainHookTarget],ebx
.exit:
retn
;-------------------------------------------------------------------------------
UnhookWiniceMain:
mov eax,[WiniceMainHookSource]
or eax,eax
jz @F
mov ebx,[WiniceMainHookTarget]
mov [eax],ebx
@@
retn
segment _LDATA
align 4
WiniceMainHookSource dd 0
WiniceMainHookTarget dd 0
segment _LTEXT
;-------------------------------------------------------------------------------
WiniceMainHook:
pushad
call GetAPIs
jnc @F
debug_start sdata+DebugFlags, ICEDUMP_DEBUG_HOOKS
Trace_Out "ICEDUMP: GetAPIs failed"
debug_end
jmp short .hook
@@
call GetK32Info
jnc .hook
debug_start sdata+DebugFlags, ICEDUMP_DEBUG_HOOKS
Trace_Out "ICEDUMP: GetK32Info failed"
debug_end
.hook:
; we hooked the call to this func - we have to call it ourselves
call [pDisableAllIRQs]
debug_start sdata+DebugFlags, ICEDUMP_DEBUG_HOOKS
mov esi,.msgHookCalled
call [pPrintToCommandWindow]
debug_end
call MP3MainHook
popad
retn
segment _LDATA
.msgHookCalled: db 'WiniceMainHook called',0
%if WINICE_VERSION <= 0x405
segment _LTEXT
;-------------------------------------------------------------------------------
; hook into a function which places a BP on the entry point of a module
; (used by loader32/wldr) and fix the problem with win32 modules not having
; their first section marked as executable (and thus winice not breaking at
; all)
;-------------------------------------------------------------------------------
HookINT41015034:
mov edi,[pINT_41_0150_3_4]
mov ecx,64
mov al,0x0F ; lar ecx,eax
@@
repnz scasb
jecxz .ret
cmp word [edi],0xC802 ; lar ecx,eax
jnz @B
cmp byte [edi+2],0x75 ; jnz .nobp
jnz .ret
movsx eax,byte [edi+3] ; eax: rel32 .nobp
mov [INT41015034Hookrel8],al
lea eax,[eax+edi+4]
sub eax,INT41015034Hook.nobp+5
mov [INT41015034Hook.nobp+1],eax ; jmp .nobp
lea eax,[edi+0x10] ; eax: rel32 .bp
sub eax,INT41015034Hook.bp+5
mov [INT41015034Hook.bp+1],eax ; jmp .bp
mov byte [edi-1],0xE9 ; jmp INT41015034Hook
mov eax,INT41015034Hook-4 ; eax: rel32 INT41015034Hook
sub eax,edi
mov [edi],eax
lea edi,[edi+3]
mov [INT41015034HookSource],edi
.ret:
retn
;-------------------------------------------------------------------------------
; remove hook from winice (enjoy the bug again ;-)
;-------------------------------------------------------------------------------
UnhookINT41015034:
mov edi,[INT41015034HookSource]
or edi,edi
jz @F
mov dword [edi-4],0x75C8020F
mov al,[INT41015034Hookrel8]
mov [edi],al
@@
retn
segment _LDATA
align 4
INT41015034HookSource: dd 0
INT41015034Hookrel8: db 0
%else
%error please validate version WINICE_VERSION
%endif
segment _LTEXT
;-------------------------------------------------------------------------------
; hook simulates what winice does then fixes the bug
;-------------------------------------------------------------------------------
INT41015034Hook:
lar ecx,eax
jnz .nobp
and cx,0x1800
cmp cx,0x1800
jz .bp
cmp word [ebx+WiniceDeviceParams.LogicalSeg],byte 1
jnz .nobp
mov ecx,[selKernel32Data] ; bug to be triggered?
cmp ax,[ecx]
jnz .nobp
mov ecx,[selKernel32Code] ; check for CS:EIP will succeed
mov ax,[ecx] ; in the INT3 handler now
.bp:
jmp $
.nobp:
jmp $
; nasm bug:
; intersegment relocs in same file don't work properly
; that's why we had to split the static/non-static parts
; of the callbacks into two files, the linker does it right at least
segment _STEXT
;-------------------------------------------------------------------------------
StaticEntryV86CB:
cmp dword [sdata+loadcount],byte 0
jnz near entryV86CB
retn
;-------------------------------------------------------------------------------
StaticEntryPMCB:
cmp dword [sdata+loadcount],byte 0
jnz near entryPMCB
retn
%endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -