📄 util.asm
字号:
%include "util.mac"
%include "icedump.inc"
%include "vxdn.inc"
%include "wiat.inc"
global GetAPIs
global GetK32Info
global IsPageCommitted
global IsPagePresent
global SaveRegs
global RestoreRegs
global ParseAddress
global ParseExpression
global IsThreadWin32
global GetVideoMem
global API.oGetCurrentProcessID
global API.oFindWindowA
global API.oSendMessageA
global API.oOpenProcess
global API.oResumeThread
global API.oSuspendThread
global API.oExitThread
;global API.oExitProcess
;global API.oTerminateThread
;global API.oTerminateProcess
global API.oORD_0017
global API.oGetTickCount
global R3PID
global R3TID
global R3TCB.Flags
global R3TCB.R0TCB
global R3TCB.SuspendCount
global oMTEList
global Error_V86
global Error_PM16
global Error_PMR0
global Error_NoID
extern sdata
extern entryPMR0
bits 32
segment _LTEXT
;-------------------------------------------------------------------------------
GetAPIs:
push esi
push ecx
push eax
or ecx,byte -1
.loop:
inc ecx
cmp dword [8*ecx+API+4],byte 0
jnz @F
pop eax
pop ecx
pop esi
clc
retn
@@
cmp dword [8*ecx+API],byte 0
jnz .loop
mov esi,[8*ecx+API+4]
call ParseAddress
jnb @F
pop eax
pop ecx
pop esi
stc
retn
@@
mov [8*ecx+API],eax
jmp short .loop
segment _LDATA
align 4
API:
.oGetCurrentProcessID: dd 0, .GetCurrentProcessID
.oFindWindowA: dd 0, .FindWindowA
.oSendMessageA: dd 0, .SendMessageA
.oOpenProcess: dd 0, .OpenProcess
.oResumeThread: dd 0, .ResumeThread
.oSuspendThread: dd 0, .SuspendThread
.oExitThread: dd 0, .ExitThread
;.oExitProcess: dd 0, .ExitProcess
;.oTerminateThread: dd 0, .TerminateThread
;.oTerminateProcess: dd 0, .TerminateProcess
.oORD_0017: dd 0, .ORD_0017
.oGetTickCount: dd 0, .GetTickCount
; null record, do not remove
dd 0, 0
.GetCurrentProcessID: db 'GetCurrentProcessID',0
.FindWindowA: db 'FindWindowA',0
.SendMessageA: db 'SendMessageA',0
.OpenProcess: db 'OpenProcess',0
.ResumeThread: db 'ResumeThread',0
.SuspendThread: db 'SuspendThread',0
.ExitThread: db 'ExitThread',0
;.ExitProcess: db 'ExitProcess',0
;.TerminateThread: db 'TerminateThread',0
;.TerminateProcess: db 'TerminateProcess',0
.ORD_0017: db 'KERNEL32!ORD_0017',0
.GetTickCount: db 'GetTickCount',0
segment _LTEXT
;------------------------------------------------------------------------------
GetK32Info:
push eax
push ecx
push edi
; get the IDs first
cmp dword [R3PID],byte 0
jnz .flags
mov ecx,64
mov edi,[API.oOpenProcess]
mov al,0x38 ; cmp byte [eax],PID
.1:
repnz scasb
jecxz .error
cmp byte [edi-2],0x80 ; cmp byte [eax],PID
jz .1a
cmp byte [edi-2],0x83 ; cmp dword [eax],PID
jnz .1
.1a:
cmp word [edi+3],0x576A ; push 0x57
jnz .1
movzx eax,byte [edi]
mov [R3PID],eax
inc al
mov [R3TID],eax
; get R3TCB.SuspendCount and R3TCB.Flags
.flags:
cmp dword [R3TCB.Flags],byte 0
jnz .r0tcb
mov ecx,64
mov edi,[API.oResumeThread]
mov al,0x8B ; mov eax,[edi+R3TCB.SuspendCount]
.2:
repnz scasb
jecxz .3
cmp byte [edi],0x87 ; mov eax,[edi+R3TCB.SuspendCount]
jnz .2
cmp word [edi+5],0xC085 ; test eax,eax
jnz .2
push dword [edi+1]
pop dword [R3TCB.SuspendCount]
movzx eax,byte [edi+11]
mov [R3TCB.Flags],eax
jmp short .5
.error:
pop edi
pop ecx
pop eax
stc
retn
.3:
mov ecx,64
mov edi,[API.oResumeThread]
mov al,0x8D ; lea edi,[eax+R3TCB.SuspendCount]
.4:
repnz scasb
jecxz .error
cmp byte [edi],0xB8 ; lea edi,[eax+R3TCB.SuspendCount]
jnz .4
cmp word [edi+5],0x0F8B ; mov ecx,[edi]
jnz .4
push dword [edi+1]
pop dword [R3TCB.SuspendCount]
movzx eax,byte [edi+13]
mov [R3TCB.Flags],eax
.5:
; get R3TCB.R0TCB, VWIN32_W32_SuspendThread and VWIN32_W32_ResumeThread
.r0tcb:
cmp dword [R3TCB.R0TCB],byte 0
jnz .omtelist
mov ecx,64
mov edi,[API.oSuspendThread]
mov al,0x83 ; cmp eax,0xFFFFFFFF
.6:
repnz scasb
jecxz .error
cmp word [edi],0xFFF8 ; cmp eax,0xFFFFFFFF
jnz .6
dec edi
mov eax,[edi-4] ; get call's destination
add edi,eax
mov ecx,64
mov al,0x8B ; mov eax,[eax+R3TCB.R0TCB]
.7:
repnz scasb
jecxz .error
cmp byte [edi],0x40 ; mov eax,[eax+R3TCB.R0TCB]
jnz .7
cmp word [edi+2],0xC085 ; test eax,eax
jnz .7
movzx eax,byte [edi+1]
mov [R3TCB.R0TCB],eax
.omtelist:
cmp dword [oMTEList],byte 0
jnz .success
mov ecx,48
mov edi,[API.oORD_0017]
mov al,0x8B ; mov ecx,oMTEList
.8:
repnz scasb
jecxz .error2
cmp byte [edi],0x0D ; mov ecx,oMTEList
jnz .8
push dword [edi+1]
pop dword [oMTEList]
.success:
pop edi
pop ecx
pop eax
clc
retn
.error2:
pop edi
pop ecx
pop eax
stc
retn
segment _LDATA
align 4
R3PID: dd 0
R3TID: dd 0
R3TCB:
.Flags: dd 0
.R0TCB: dd 0
.SuspendCount: dd 0
oMTEList: dd 0
;------------------------------------------------------------------------------
; in: EAX: page number,
; out: ZF set on error, cleared otherwise
; ------------------------------------------------------------------------------
; the following piece of code directly accesses the page tables and directories
; to figure out if a specific page has been committed or not. credits go to
; LiuTaoTao for the short code to calculate the offsets into the tables.
; ------------------------------------------------------------------------------
segment _LTEXT
IsPageCommitted:
push edi
push edx
mov edi,0xFF800000 ; linear start address of page tables
lea edx,[edi+4*eax] ; EAX: current page number
shr edx,12 ; EDX: current directory number
test byte [edi+4*edx],0x1 ; is page directory present?
jz @F
test byte [edi+4*eax+1],0x2 ; is page committed?
@@
pop edx
pop edi
retn
;------------------------------------------------------------------------------
; in: EAX: page number,
; out: ZF set on error, cleared otherwise
; ------------------------------------------------------------------------------
IsPagePresent:
push edi
push edx
mov edi,0xFF800000 ; linear start address of page tables
lea edx,[edi+4*eax] ; EAX: current page number
shr edx,12 ; EDX: current directory number
test byte [edi+4*edx],0x1 ; is page directory present?
jz @F
test byte [edi+4*eax],0x1 ; is page present?
@@
pop edx
pop edi
retn
;------------------------------------------------------------------------------
SaveRegs:
push edi
push esi
push ecx
mov esi,[dClient_EAX]
mov edi,[pINT3_CleanupForPAGEIN]
%if WINICE_VERSION <= 0x405
mov edi,[edi+0xC]
%else
%error please validate version WINICE_VERSION
%endif
mov ecx,0x48
rep movsb
pop ecx
pop esi
pop edi
retn
;------------------------------------------------------------------------------
RestoreRegs:
push edi
push esi
push ecx
mov edi,[dClient_EAX]
mov esi,[pINT3_CleanupForPAGEIN]
%if WINICE_VERSION <= 0x405
mov esi,[esi+0xC]
%else
%error please validate version WINICE_VERSION
%endif
mov ecx,0x48
rep movsb
pop ecx
pop esi
pop edi
retn
;------------------------------------------------------------------------------
ParseAddress:
push eax
mov eax,[fExp2Int_08]
mov byte [eax],0
mov eax,[fExp2Int_10]
mov byte [eax],0
mov eax,[fExp2Int_04]
mov byte [eax],1
pop eax
call [pExpression2Integer]
retn
;------------------------------------------------------------------------------
ParseExpression:
push eax
mov eax,[fExp2Int_40]
mov byte [eax],1
pop eax
call [pExpression2Integer]
push eax
mov eax,[fExp2Int_40]
mov byte [eax],0
pop eax
retn
;-------------------------------------------------------------------------------
; EDI: R0TCB
; EBP: Client Registers
;
; clc: win32
;-------------------------------------------------------------------------------
IsThreadWin32:
push eax
test byte [ebp+CRS.EFlags+2],2 ; is client in V86 mode?
jnz .non_win32
mov eax,[selKernel32Code] ; is it win32?
movzx eax,word [eax]
cmp ax,[ebp+CRS.CS]
jnz .non_win32
mov eax,[selKernel32Data] ; is it win32?
movzx eax,word [eax]
cmp ax,[ebp+CRS.SS]
jnz .non_win32
pop eax
clc
retn
.non_win32:
pop eax
stc
retn
;-------------------------------------------------------------------------------
; eax: linear address of the video memory as used by winice
;-------------------------------------------------------------------------------
GetVideoMem:
mov eax,[oVideoMem]
mov eax,[eax]
%if WINICE_VERSION <= 0x324
push ebx
mov ebx,[oLinAddrPhysical_0_MAXPHYS]
add eax,[ebx]
pop ebx
%endif
retn
segment _LDATA
;------------------------------------------------------------------------------
; global error messages (used at more than one place)
;------------------------------------------------------------------------------
Error_V86: db 'EFLAGS.VM=1, only win32 clients are supported.',0
Error_PM16: db 'CS.D=0, only win32 clients are supported.',0
Error_PMR0: db 'CS.DPL=0, only win32 clients are supported.',0
Error_NoID: db 'specify PID/TID.',0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -