📄 icedump.asm
字号:
%include "util.mac"
%include "vxdn.inc"
%include "icedump.inc"
%include "wiat.inc"
%ifndef MAKEDEP
global sdata
global ICEDUMP_Control
global StaticEntryV86CB
global StaticEntryPMCB
global TempBuffer
extern TracerSysDynamicDeviceInit
extern TracerSysDynamicDeviceExit
extern TracerThreadInit
extern TracerThreadNotExecuteable
extern GetAPIs
extern GetK32Info
extern Parser
extern AllocCallBacks
extern MP3MainHook
extern entryV86CB
extern entryPMCB
bits 32
segment _LDATA
Declare_Virtual_Device ICEDUMP_DDB_NAME, ICEDUMP_DEVICE_NAME, ICEDUMP_VERSION_MAJOR, ICEDUMP_VERSION_MINOR1
segment _SDATA
;-------------------------------------------------------------------------------
; stuff here will be initialized once only, even thru multiple loads/unloads
;-------------------------------------------------------------------------------
align 4
sdata:
istruc StaticData
at loadcount, dd 0
at oWinice, dd 0
at oOld_CMD_INVALID, dd Parser
at s_fWiniceIsActive, dd 0
at s_pSendSpecificEOI, dd 0
at PMCB, istruc CallBack
at CallBack.offset, dw 0
at CallBack.segment, dw 0
iend
at V86CB, istruc CallBack
at CallBack.offset, dw 0
at CallBack.segment, dw 0
iend
at V86IDT, istruc HookedInts
at HookedInts.VMCB, dd 0
at HookedInts.cAPP, dd 0
iend
at MP3.PlayerPresent, db 0
at MP3.nIRQ, db 0xFF
at OldSoundCardIntProc.off, dd 0
at OldSoundCardIntProc.sel, dd 0
; at DebugFlags, times (ICEDUMP_DEBUG_FLAG_COUNT+31)/32 dd 0
at DebugFlags, dd (1 << ICEDUMP_DEBUG_PEDUMP) + (1 << ICEDUMP_DEBUG_TASKMOD) + (1 << ICEDUMP_DEBUG_COMMON) + (1 << ICEDUMP_DEBUG_TRACE)
times (ICEDUMP_DEBUG_FLAG_COUNT+31)/32-1 dd 0
iend
segment _LTEXT
;-------------------------------------------------------------------------------
; SysControl message dispatcher
;
; ebx: VMCB
;-------------------------------------------------------------------------------
Begin_Control_Dispatch ICEDUMP
Control_Dispatch SYS_DYNAMIC_DEVICE_INIT,OnSysDynamicDeviceInit
Control_Dispatch SYS_DYNAMIC_DEVICE_EXIT,OnSysDynamicDeviceExit
Control_Dispatch VM_INIT,OnVmInit
Control_Dispatch BEGIN_PM_APP,OnBeginPMApp
Control_Dispatch END_PM_APP,OnEndPMApp
Control_Dispatch VM_NOT_EXECUTEABLE,OnVmNotExecuteable
Control_Dispatch THREAD_INIT,OnThreadInit
Control_Dispatch THREAD_NOT_EXECUTEABLE,OnThreadNotExecuteable
End_Control_Dispatch
segment _LDATA
align 4
TempBuffer: dd 0
segment _LTEXT
;-------------------------------------------------------------------------------
; find winice base address by not using VMM functions
; relocate WIAT
; allocate callbacks used by certain new commands
; patch winice and hook IDTs of existing VMs
;
; ebx: VMCB
;-------------------------------------------------------------------------------
OnSysDynamicDeviceInit:
debug_start sdata+DebugFlags, ICEDUMP_DEBUG_SYSCTRL
mov eax,[sdata+loadcount]
Trace_Out "ICEDUMP: SYS_DYNAMIC_DEVICE_INIT #eax"
debug_end
cmp dword [sdata+loadcount],byte 0 ; don't load twice
jnz near .error
VMMCall _HeapAllocate, dword TempBuffer_size, byte HEAPZEROINIT
or eax,eax
jz .error
mov [TempBuffer],eax
call FindWiniceBase
cmp dword [sdata+oWinice],byte 0
jz .error_free
call RelocIAT
call AllocCallBacks
cmp dword [sdata+PMCB],byte 0
jz .error_free
cmp dword [sdata+V86CB],byte 0
jz .error_free
call HookInts
jb .error_free
call ApplyWinicePatches
cmp dword [WiniceMainHookSource],byte 0
jz .error_removepatches
cmp dword [INT41015034HookSource],byte 0
jz .error_removepatches
call TracerSysDynamicDeviceInit
jb .error_removepatches
inc dword [sdata+loadcount]
clc
retn
.error_removepatches:
call RemoveWinicePatches
call UnhookInts
.error_free:
VMMCall _HeapFree, dword [TempBuffer], byte 0
.error:
stc
retn
;-------------------------------------------------------------------------------
; remove all patches/hooks from winice and IDTs
;
; ebx: VMCB
;-------------------------------------------------------------------------------
OnSysDynamicDeviceExit:
debug_start sdata+DebugFlags, ICEDUMP_DEBUG_SYSCTRL
mov eax,[sdata+loadcount]
Trace_Out "ICEDUMP: SYS_DYNAMIC_DEVICE_EXIT #eax"
debug_end
call TracerSysDynamicDeviceExit
call RemoveWinicePatches
call UnhookInts
VMMCall _HeapFree, dword [TempBuffer], byte 0
dec dword [sdata+loadcount]
clc
retn
;-------------------------------------------------------------------------------
; hook vectors in the IDT if it's the first time we see a V86 IDT
; (which is the same for all VMs, so we patch it once only)
;
; ebx: VMCB
;-------------------------------------------------------------------------------
OnVmInit:
debug_start sdata+DebugFlags, ICEDUMP_DEBUG_SYSCTRL
mov eax,[ebx]
Trace_Out "ICEDUMP: VM_INIT VMCB: #ebx, VMSTATUS: #eax"
debug_end
pushfd ; necessary since our list is LF_Async
cli ; and we're tweaking the IDT after all
call HookIntsInVM
popfd
clc
retn
;-------------------------------------------------------------------------------
; hook vectors in PM IDT if it is the first PM app in the given VM
; (can happen more than once during the lifetime of a VM)
;
; ebx: VMCB
;-------------------------------------------------------------------------------
OnBeginPMApp:
debug_start sdata+DebugFlags, ICEDUMP_DEBUG_SYSCTRL
mov eax,[ebx]
Trace_Out "ICEDUMP: BEGIN_PM_APP VMCB: #ebx, VMSTATUS: #eax"
debug_end
pushfd ; necessary since our list is LF_Async
cli ; and we're tweaking the IDT after all
mov esi,[HooksList]
VMMCall List_Get_First
jz .hook
.next:
cmp [eax+HookedInts.VMCB],ebx
jnz @F
inc dword [eax+HookedInts.cAPP]
jmp short .ret
@@
VMMCall List_Get_Next
jnz .next
.hook:
debug_start sdata+DebugFlags, ICEDUMP_DEBUG_SYSCTRL
Trace_Out "ICEDUMP: first PM APP VMCB: #ebx"
debug_end
call HookIntsInVM
.ret:
popfd
clc
retn
;-------------------------------------------------------------------------------
; find/free list element if it is the last PM app in the given VM,
; do nothing to IDT (it's been freed already)
; (can happen more than once during the lifetime of a VM)
;
; ebx: VMCB
;-------------------------------------------------------------------------------
OnEndPMApp:
debug_start sdata+DebugFlags, ICEDUMP_DEBUG_SYSCTRL
mov eax,[ebx]
Trace_Out "ICEDUMP: END_PM_APP VMCB: #ebx, VMSTATUS: #eax"
debug_end
pushfd
cli
mov esi,[HooksList]
VMMCall List_Get_First
jz .ret
.next:
cmp [eax+HookedInts.VMCB],ebx
jnz @F
dec dword [eax+HookedInts.cAPP]
jz .free
debug_start sdata+DebugFlags, ICEDUMP_DEBUG_SYSCTRL
mov eax,[eax+HookedInts.cAPP]
Trace_Out "ICEDUMP: not last PM APP VMCB: #ebx, apps: #eax"
debug_end
jmp short .ret
@@
VMMCall List_Get_Next
jnz .next
debug_start sdata+DebugFlags, ICEDUMP_DEBUG_SYSCTRL
Trace_Out "ICEDUMP: END_PM_APP in unknown VMCB: #ebx"
debug_end
jmp short .ret
.free:
debug_start sdata+DebugFlags, ICEDUMP_DEBUG_SYSCTRL
Trace_Out "ICEDUMP: last PM APP VMCB: #ebx"
debug_end
call UnhookIntsInVM
.ret:
popfd
clc
retn
;-------------------------------------------------------------------------------
; find/free list element, do nothing to IDT (it's been freed already)
;
; ebx: VMCB
;-------------------------------------------------------------------------------
OnVmNotExecuteable:
debug_start sdata+DebugFlags, ICEDUMP_DEBUG_SYSCTRL
mov eax,[ebx]
Trace_Out "ICEDUMP: VM_NOT_EXECUTEABLE VMCB: #ebx, VMSTATUS: #eax"
debug_end
pushfd
cli
mov esi,[HooksList]
VMMCall List_Get_First
jz .ret
@@
cmp [eax+HookedInts.VMCB],ebx
jz .free
VMMCall List_Get_Next
jnz @B
debug_start sdata+DebugFlags, ICEDUMP_DEBUG_SYSCTRL
Trace_Out "ICEDUMP: VM_NOT_EXECUTEABLE in unknown VMCB: #ebx"
debug_end
jmp short .ret
.free:
push eax
VMMCall List_Remove
pop eax
VMMCall List_Deallocate
.ret:
popfd
clc
retn
;-------------------------------------------------------------------------------
;
;-------------------------------------------------------------------------------
OnThreadInit:
call TracerThreadInit
retn
;-------------------------------------------------------------------------------
;
;-------------------------------------------------------------------------------
OnThreadNotExecuteable:
call TracerThreadNotExecuteable
clc
retn
;-------------------------------------------------------------------------------
; find base address of winice by not using VMM services (so that we don't
; need to know how winice has been protected against detection - but please,
; not yet another cat/mouse game...)
;-------------------------------------------------------------------------------
FindWiniceBase:
cmp dword [sdata+oWinice],byte 0
jnz .exit
pushfd
cli
cld
push eax
push eax
sgdt [esp+2] ; store GDT limit and start address
pop ecx ; get GDT limit
shr ecx,16+3 ; compute number of descriptors
pop esi ; get GDT start address
@@
lodsd ; read first dword of descriptor
mov edi,eax ; save it
lodsd ; read second dword of descriptor
cmp ah,0xFF ; is it Winice's special code segment?
loopnz @B ; if not, search further
popfd
jecxz .exit ; did we find what we were looking for?
rol eax,8 ; compute start address of code segment
xchg ah,al
shrd edi,eax,16
cmp [edi],edi ; 1st check
jnz .exit
; compute Winice base, using NON relocated addresses...
sub edi,[wSelector_WINICE_Code]
add edi,byte 4
mov eax,[c_PCI_]
add eax,edi
cmp dword [eax],0x83EC8B55 ; push ebp/mov ebp,esp/sub esp,30
jnz .exit
mov [sdata+oWinice],edi
.exit:
retn
;-------------------------------------------------------------------------------
RelocIAT:
mov eax,[sdata+oWinice]
mov ecx,[wiat_size]
mov esi,wiat
@@
add [esi],eax
add esi,byte 4
loop @B
mov eax,[fWiniceIsActive]
mov [sdata+s_fWiniceIsActive],eax
mov eax,[pSendSpecificEOI]
mov [sdata+s_pSendSpecificEOI],eax
retn
;-------------------------------------------------------------------------------
ApplyWinicePatches:
call Swap_CMD_INVALID
call HookWiniceMain
call HookINT41015034
retn
;-------------------------------------------------------------------------------
RemoveWinicePatches:
call Swap_CMD_INVALID
call UnhookWiniceMain
call UnhookINT41015034
retn
;-------------------------------------------------------------------------------
Swap_CMD_INVALID:
mov eax,[tCommands]
xchg [sdata+oOld_CMD_INVALID],edx
xchg [eax+4*CMD_INVALID],edx
xchg [sdata+oOld_CMD_INVALID],edx
retn
segment _LDATA
align 4
VMCB:
.oPMIDT: dd 0
HooksList: dd 0
IntHandlers: dd Handler_Int00
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -