📄 cmd_thread.asm
字号:
%include "util.mac"
%include "icedump.inc"
%include "vxdn.inc"
%include "wiat.inc"
%ifndef MAKEDEP
global Parse_SuspendX
global Parse_Suspend
global Parse_Resume
global Parse_Kill
global Service_SuspendResumeKill
extern sdata
extern Parser.error
extern Parser.errorMsg
extern Error_V86
extern Error_PM16
extern Error_NoID
extern SetCB
extern GetK32Info
extern IsPageCommitted
extern R3TID
extern R3PID
extern R3TCB.SuspendCount
extern R3TCB.R0TCB
extern R3TCB.Flags
extern VWIN32_W32_ResumeThread
extern VWIN32_W32_SuspendThread
extern VWIN32W32ServiceTable
extern ParseExpression
bits 32
;-------------------------------------------------------------------------------
; SUSPEND <PID>|<TID>
; SUSPENDX <PID>|<TID>
; RESUME <PID>|<TID>
; KILL <PID>
;-------------------------------------------------------------------------------
segment _LTEXT
Parse_SuspendX:
mov edi,Error_V86
mov ebp,[dClient_EFLAGS]
test byte [ebp+2],2 ; is client in V86 mode?
jnz near Parser.errorMsg
mov edi,Error_PM16
mov ebp,[dClient_CS]
lar eax,[ebp] ; is client 32 bit?
bt eax,22
jnc near Parser.errorMsg
mov edi,Error_NoID
call ParseExpression ; parse <pid>|<tid>
jb near Parser.errorMsg
; save client EAX/ESI/CS/EIP
mov ebp,[dClient_EAX]
push dword [ebp]
pop dword [.EAX]
mov ebp,[dClient_ESI]
push dword [ebp]
pop dword [.ESI]
mov ebp,[dClient_CS]
push dword [ebp]
pop dword [.CS]
mov ebp,[dClient_EIP]
push dword [ebp]
pop dword [.EIP]
mov ebp,[dClient_ESI] ; store pid or tid
mov [ebp],eax
; set up registers for service
push byte SERVICE_SUSPENDX
mov ebp,[dClient_EAX]
pop dword [ebp]
call SetCB
jc near Parser.error
mov ebp,[fExecuteMoreCommands] ; set internal Winice flag to 0
mov byte [ebp],0
popad
retn
segment _LDATA
align 4
.EAX: dd 0
.ESI: dd 0
.CS: dd 0
.EIP: dd 0
segment _LTEXT
Parse_Suspend:
push byte SERVICE_SUSPEND
jmp short @F
Parse_Resume:
push byte SERVICE_RESUME
jmp short @F
Parse_Kill:
push byte SERVICE_KILL
@@
mov ebp,[dClient_EAX]
pop dword [ebp]
mov edi,Error_V86
mov ebp,[dClient_EFLAGS]
test byte [ebp+2],2 ; is client in V86 mode?
jnz near Parser.errorMsg
mov edi,Error_PM16
mov ebp,[dClient_CS]
lar eax,[ebp] ; is client 32 bit?
bt eax,22
jnc near Parser.errorMsg
mov edi,Error_NoID
call ParseExpression ; parse <pid>|<tid>
jb near Parser.errorMsg
mov ebp,[dClient_ESI] ; store pid or tid
mov [ebp],eax
call SetCB
jc near Parser.error
xor eax,eax
inc eax
mov ebp,[fPAGEIN_InProgress] ; set internal Winice flag to 1
mov [ebp],eax
mov ebp,[fExecuteMoreCommands] ; set internal Winice flag to 0
mov [ebp],ah
popad
retn
Service_SuspendResumeKill:
mov eax,[ebp+CRS.ESI] ; get xID
cmp eax,0xF0000000
jb .is_dbase
mov ecx,[dK32XOR] ; ECX: obfuscator
mov ecx,[ecx]
cmp ecx,byte 0 ; is obfuscator initialized?
mov ebx,.Obf_Error
jz .error
xor eax,ecx ; EAX: Thread or Process Database
.is_dbase:
push eax ; save it for later use
shr eax,12 ; convert it to page number
mov ebx,.Mem_Error
call IsPageCommitted ; can we access the corresponding page?
pop eax ; back to linear address
jz .error
mov ebx,.Obj_Error
; cmp eax,0x80000000 ; PDB/TDB are above private arena
; jb .error
bt eax,31
jnc .error
xor ecx,ecx
mov bl,[R3TID]
cmp [eax],bl
jnz @F
mov ebx,.Kill_Error
cmp dword [ebp+CRS.EAX],byte SERVICE_KILL
jz .error
jmp short .handle_thread
@@
mov bl,[R3PID]
cmp [eax],bl
mov ebx,.Obj_Error
jnz .error
cmp dword [ebp+CRS.EAX],byte SERVICE_KILL
jnz @F
call KillProcess
jc .error
jmp short .return
@@
mov ecx,[eax+0x50] ; get ThreadList
mov ecx,[ecx] ; get Thread_Ref pointer
.more_threads:
mov eax,[ecx+8] ; get Thread Database
mov ecx,[ecx] ; prefetch next Thread_Ref
.handle_thread:
call SuspendResumeThread
jnc .continue
push dword .Sch_Error
VMMCall _Trace_Out_Service
.continue:
jecxz .return ; was it last/only thread to deal with?
jmp short .more_threads
.error:
push ebx
VMMCall _Trace_Out_Service
.return:
cmp dword [ebp+CRS.EAX],byte SERVICE_SUSPENDX
jnz .done
; restore client EAX/ESI/CS/EIP
push dword [Parse_SuspendX.EAX]
pop dword [ebp+CRS.EAX]
push dword [Parse_SuspendX.ESI]
pop dword [ebp+CRS.ESI]
push dword [Parse_SuspendX.CS]
pop dword [ebp+CRS.CS]
push dword [Parse_SuspendX.EIP]
pop dword [ebp+CRS.EIP]
.done:
popfd
popad
retn
segment _LDATA
align 4
;------------------------------------------------------------------------------
.K32_Error db 'unsupported Windows version, failed to determine Kernel32 info.',CRLF0
.Sch_Error db 'failed to suspend/resume thread #EAX.',CRLF0
.Kill_Error db 'cannot kill object #EAX, it is not a process object.',CRLF0
.Obj_Error db 'object #EAX is not a valid thread or process object.',CRLF0
.Obf_Error db 'obfuscator is not yet initialized.',CRLF0
.Mem_Error db 'page #EAX is not committed. verify command line.',CRLF0
;------------------------------------------------------------------------------
segment _LTEXT
;------------------------------------------------------------------------------
; in: EAX: thread, EBP: Client registers
; out: clc: ok, stc: error
;------------------------------------------------------------------------------
segment _LTEXT
SuspendResumeThread:
pushad
cmp eax,0xF0000000 ; check if it's ThreadId
jb .is_dbase
mov esi,[dK32XOR]
xor eax,[esi] ; EAX = Thread Database
.is_dbase:
mov edx,.sfClient ; get fake client regs
mov edi,[VWIN32W32ServiceTable]
mov ebx,[R3TCB.SuspendCount]
mov ecx,[R3TCB.R0TCB]
.select:
cmp dword [ebp+CRS.EAX],byte SERVICE_SUSPENDX
jz .suspendx
cmp dword [ebp+CRS.EAX],byte SERVICE_SUSPEND
jz .suspend
cmp dword [ebp+CRS.EAX],byte SERVICE_RESUME
jz .resume
.error:
stc
popad
retn
.success:
clc
popad
retn
.suspend:
test byte [ebp+CRS.CS],3 ; skip this test if called from ring-0
jz .suspendx
push edi
VMMCall Get_Cur_Thread_Handle
cmp edi,[eax+ecx] ; do not suspend the current one
pop edi
jz .error
.suspendx:
; cmp dword [eax+ebx],byte 0 ; test suspension counter
; jnz .success ; already suspended?
mov esi,[R3TCB.Flags]
test byte [eax+esi],0x40 ; thread created suspended?
jnz .s_update_r3
mov esi,[R3TCB.Flags]
test byte [eax+esi+3],0x10
jnz .error
push ebx ; save suspension counter index
push eax ; save TDB, EAX will get trashed
push dword [eax+ecx] ; ring0TCB
push byte 0 ; fake VM handle
push edx ; Client Regs
mov esi,[VWIN32_W32_SuspendThread]
lea esi,[edi+esi*8+8]
call [esi]
cmp eax,byte -1
pop eax ; restore EAX
pop ebx ; restore suspension counter index
jz .error
.s_update_r3:
inc dword [eax+ebx] ; increment suspension counter
jmp short .success
.resume:
cmp dword [eax+ebx],byte 0 ; test suspension counter
jz .success ; already running?
mov esi,[R3TCB.Flags]
test byte [eax+esi],0x40 ; thread created suspended?
jnz .r_update_r3
mov esi,[R3TCB.Flags]
test byte [eax+esi+3],0x10
jnz near .error
push ebx
push eax
push dword [eax+ecx] ; Ring0 Thread handle
push byte 0 ; fake VM handle
push edx ; fake Client Registers
mov esi,[VWIN32_W32_ResumeThread]
lea esi,[edi+esi*8+8]
call [esi]
cmp eax,byte -1 ; error?
pop eax
pop ebx
jz near .error
.r_update_r3:
dec dword [eax+ebx] ; decrement suspension counter
clc
popad
retn
segment _LDATA
align 4
.sfClient TIMES 8 db 'SGER'
segment _LTEXT
KillProcess:
mov ecx,eax
VxDCall VWIN32_GetCurrentProcessHandle
test eax,eax
jnz @F
mov ebx,.Err_NoCurrProc
stc
retn
@@
cmp eax,ecx ; don't kill current process
jnz @F
mov ebx,.Err_Current
stc
retn
@@
mov ecx,[ecx+0x50] ; get ThreadList
mov ecx,[ecx] ; get Thread_Ref pointer
mov ecx,[ecx+8] ; get Thread Database
add ecx,[R3TCB.R0TCB]
mov edi,[ecx]
VxDCall VWIN32_TerminateApp
clc
retn
segment _LDATA
.Err_NoCurrProc db 'no current process',CRLF0
.Err_Current db 'cannot kill current process',CRLF0
%endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -