⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmd_trace.asm

📁 Cracker终结者——提供最优秀的软件保护技术
💻 ASM
📖 第 1 页 / 共 4 页
字号:

	VMMCall	_FreeThreadDataSlot, dword [TDS]

	call	UnhookW32GetSetThreadContext

	call	UnhookGetSetThreadContext

	call	UnhookPMFaults

	pop	edi
	pop	ecx
	pop	ebx
	clc
	retn


;-------------------------------------------------------------------------------
; init TDS in new thread
; check if it belongs to a process one of whose threads is already being traced
; if so and multithread tracing is enabled, trace this guy as well
;
; EDI: R0TCB
;-------------------------------------------------------------------------------
TracerThreadInit:
	push	ebx
	push	ecx
	push	edx
	push	esi
	push	edi
	push	ebp

	mov	ecx,[TDS]
	and	dword [ecx+edi],byte 0

	mov	esi,edi				; save current R0TCB
	mov	ebp,[edi+TCB_ClientPtr]

	call	IsThreadWin32
	jc	near .ret

	VMMCall	Get_Sys_VM_Handle
	VMMCall	Get_Initial_Thread_Handle
	mov     ebx,edi

.loop:
	mov	ebp,[edi+TCB_ClientPtr]		; R0TCB.CRS
	test	byte [ebp+CRS.EFlags+2],2	; is client in V86 mode?
	jnz	.next

	call	ShallTraceIt
	jnc	.trace

.next:
	VMMCall	Get_Next_Thread_Handle
	cmp	ebx,edi
	jnz	.loop
	jmp	short .ret

.trace:
	xchg	edi,esi
	mov	ebp,[edi+TCB_ClientPtr]
	mov	ebx,[edi+TCB_VMHandle]

	cmp	byte [OT.OBreaknew],'D'
	jz	@F

	call	BreakIn.ignore_range
	jmp	short .ret

@@
	call	TracerAlloc
	jnc	@F

	debug_start sdata+DebugFlags, ICEDUMP_DEBUG_TRACE
	Trace_Out "ICEDUMP: ThreadInit: failed to allocate TraceInfo, R0TCB: #edi"
	debug_end

	jmp	short .ret

@@
	push	edi
	mov	esi,[ecx+esi]
	mov	edi,[ecx+edi]
	mov	ecx,TraceInfo_size
	rep	movsb
	pop	edi

	mov	esi,[TDS]
	mov	esi,[esi+edi]
	call	TrReinforce

.ret:
	pop	ebp
	pop	edi
	pop	esi
	pop	edx
	pop	ecx
	pop	ebx
	clc
	retn


;-------------------------------------------------------------------------------
; decide if the new thread should be traced or not
;
; ESI: R0TCB of new thread, cannot be in V86 mode
; EDI: R0TCB of an already existing thread
;
; clc: trace it
;-------------------------------------------------------------------------------
ShallTraceIt:
	push	ebx
	push	ecx
	push	edx

	cmp	byte [OT.OTracethread],'D'
	jz	.check_parent

	mov	cx,[esi+TCB_PMPSPSelector]
	cmp	[edi+TCB_PMPSPSelector],cx	; same process?
	jnz	.check_parent

	mov	ecx,[TDS]
	cmp	dword [edi+ecx],byte 0		; already tracing?
	jz	near .no_trace

	debug_start sdata+DebugFlags, ICEDUMP_DEBUG_TRACE
	Trace_Out "ICEDUMP: detected new thread in process, R0TCB: #esi"
	debug_end

	jmp	short .trace

.check_parent:
	cmp	byte [OT.OTraceprocess],'D'
	jz	.no_trace

	mov	ebx,[esi+TCB_VMHandle]
	mov	eax,[esi+TCB_ClientPtr]
	movzx	eax,word [eax+CRS.FS]
	VMMCall	_SelectorMapFlat, ebx, eax, byte 0

	cmp	eax,0x80000000
	jb	.no_trace

	cmp	eax,0xC0000000
	jae	.no_trace

	mov	eax,[eax+0x30]			; PDB
	push	dword [eax+0x48]		; parent PDB

	mov	ebx,[edi+TCB_VMHandle]
	mov	eax,[edi+TCB_ClientPtr]
	movzx	eax,word [eax+CRS.FS]
	VMMCall	_SelectorMapFlat, ebx, eax, byte 0
	pop	ecx

	cmp	eax,0x80000000
	jb	.no_trace

	cmp	eax,0xC0000000
	jae	.no_trace

	mov	eax,[eax+0x30]			; PDB
	cmp	eax,ecx				; child/parent?
	jnz	.no_trace

	debug_start sdata+DebugFlags, ICEDUMP_DEBUG_TRACE
	Trace_Out "ICEDUMP: detected new thread in child process, R0TCB: #esi"
	debug_end

.trace:
	pop	edx
	pop	ecx
	pop	ebx
	clc
	retn

.no_trace:
	pop	edx
	pop	ecx
	pop	ebx
	stc
	retn


;-------------------------------------------------------------------------------
; stop tracing thread
;
; EDI: R0TCB
;-------------------------------------------------------------------------------
TracerThreadNotExecuteable:
	mov     eax,[TDS]
	mov	eax,[edi+eax]		; TraceInfo
	cmp	eax,byte 0
	jz	@F

	debug_start sdata+DebugFlags, ICEDUMP_DEBUG_TRACE
	push	edx
	mov	edx,[eax+TraceInfo.TickCount+4]
	mov	eax,[eax+TraceInfo.TickCount]
	Trace_Out "ICEDUMP: thread died, instruction count: #edx:#eax, R0TCB: #edi"
	pop	edx
	debug_end

	call	TracerFree

@@
	clc
	retn


;-------------------------------------------------------------------------------
; alloc tracer's structure
;
; EDI: R0TCB
;
; stc on error
;-------------------------------------------------------------------------------
TracerAlloc:
	mov     eax,[TDS]
	mov	eax,[edi+eax]
	or	eax,eax
	jz	@F

	debug_start sdata+DebugFlags, ICEDUMP_DEBUG_TRACE
	Trace_Out "ICEDUMP: thread is already being traced, R0TCB: #edi"
	debug_end

	stc
	retn

@@
	push	ecx
	push	edx
	VMMCall	_HeapAllocate, dword TraceInfo_size, byte HEAPZEROINIT
	pop	edx
	pop	ecx
	or	eax,eax
	jnz	@F

	debug_start sdata+DebugFlags, ICEDUMP_DEBUG_TRACE
	Trace_Out "ICEDUMP: failed to allocate TraceInfo for thread, R0TCB: #edi"
	debug_end

	stc
	retn

@@
	push	eax
	mov     eax,[TDS]
	add	eax,edi
	pop	dword [eax]

; set up fake IDT: int32 gates to a simple iretd
	push	ebx
	push	ecx
	push	edx

	mov	ecx,0x60
	mov	eax,[eax]		; TraceInfo
	lea	edx,[eax+TraceInfo.IRETD]
	mov	ebx,0x00280000
	mov	bx,dx
	mov	dx,0x8E00		; int32, dpl=0
	
@@
	mov	[eax+8*ecx-8+TraceInfo.IDT],ebx
	mov	[eax+8*ecx-8+TraceInfo.IDT+4],edx
	loop	@B

	mov	byte [eax+TraceInfo.IRETD],0xCF
	and	dword [eax+TraceInfo.TickCount],byte 0

	pop	edx
	pop	ecx
	pop	ebx

	clc
	retn


;-------------------------------------------------------------------------------
; free tracer's structure if thread was traced
;
; EDI: R0TCB
;-------------------------------------------------------------------------------
TracerFree:
	push	ecx
	push	edx

	mov     ecx,[TDS]
	xor	eax,eax
	xchg	eax,[edi+ecx]
	or	eax,eax
	jz	@F

	VMMCall	_HeapFree, eax, byte 0

@@
	pop	edx
	pop	ecx
	clc
	retn


;-------------------------------------------------------------------------------
; try to set EFLAGS.T in thread's context
;
; EDI: R0TCB
;-------------------------------------------------------------------------------
StartTracing:
	push	ebp

	mov	ebp,[edi+TCB_ClientPtr]
	bts	word [ebp+CRS.EFlags],8		; set single step flag
	jnc	@F

	debug_start sdata+DebugFlags, ICEDUMP_DEBUG_TRACE
	Trace_Out "ICEDUMP: StartTracing: EFLAGS.T was already set, R0TCB: #edi"
	debug_end

@@
	pop	ebp
	clc
	retn


;-------------------------------------------------------------------------------
; try to reset EFLAGS.T in thread's context
;
; EDI: R0TCB
;-------------------------------------------------------------------------------
StopTracing:
	push	ebp

	mov	ebp,[edi+TCB_ClientPtr]
	btr	word [ebp+CRS.EFlags],8		; reset single step flag
	jc	@F

	debug_start sdata+DebugFlags, ICEDUMP_DEBUG_TRACE
	Trace_Out "ICEDUMP: StopTracing: EFLAGS.T was not set, R0TCB: #edi"
	debug_end

@@
	debug_start sdata+DebugFlags, ICEDUMP_DEBUG_TRACE
	Trace_Out "ICEDUMP: stopped tracing thread, R0TCB: #edi"
	debug_end

	pop	ebp
	clc
	retn


;-------------------------------------------------------------------------------
; eax: client EIP, skip over known prefixes
;
; eax: first non-prefix byte (real opcode)
; ecx: max length for real opcode (considering the 15 byte limit)
;-------------------------------------------------------------------------------
SkipPrefixes:
	push	esi
	mov	esi,eax

	mov	ecx,15		; max instruction length

.loop:

.protect_start:
	movzx	eax,byte [esi]
.protect_end:

	bt	[Prefixes],eax
	jc	@F

	mov	eax,esi
	pop	esi
	clc
	retn

@@
	inc	esi
	loop	.loop

.EH:
	mov	eax,esi
	pop	esi
	stc
	retn


;segment _LDATA
; prefixes:	db 0x26,0x2E,0x36,0x3E,0x64,0x65,0x66,0x67,0xF0,0xF2,0xF3
	align 4
Prefixes: ;11111111111111110000000000000000
	  ;FEDCBA9876543210FEDCBA9876543210
	dd 00000000000000000000000000000000b ; 1F-00
	dd 01000000010000000100000001000000b ; 3F-20
	dd 00000000000000000000000000000000b ; 5F-40
	dd 00000000000000000000000011110000b ; 7F-60
	dd 00000000000000000000000000000000b ; 9F-80
	dd 00000000000000000000000000000000b ; BF-A0
	dd 00000000000000000000000000000000b ; DF-C0
	dd 00000000000011010000000000000000b ; FF-E0
	dd 0


segment _LTEXT

;-------------------------------------------------------------------------------
; TRACEX <EIP low> [<EIP high>]
;-------------------------------------------------------------------------------
Parse_TraceX:
	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_BadEIPlow
	call	ParseExpression			; parse <EIP low>
	jb	near Parser.errorMsg

	mov	[.EIPlow],eax

	call	[pSkipWhiteSpace]		; skip to <EIP high>
	mov	eax,[.EIPlow]
	jz	@F

	mov	edi,Error_BadEIPhigh
	call	ParseExpression			; parse <EIP high>
	jb	near Parser.errorMsg

@@
	mov	[.EIPhigh],eax

; save client EAX/CS/EIP
	mov	ebp,[dClient_EAX]
	push	dword [ebp]
	pop	dword [.EAX]

	mov	ebp,[dClient_CS]
	push	dword [ebp]
	pop	dword [.CS]

	mov	ebp,[dClient_EIP]
	push	dword [ebp]
	pop	dword [.EIP]

; set up registers for service
	push	byte SERVICE_TRACEX
	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
.CS:		dd 0
.EIP:		dd 0
.EIPlow:	dd 0
.EIPhigh:	dd 0


segment _LTEXT

Service_TraceX:
	VMMCall	Get_Cur_VM_Handle
	VMMCall	Get_Cur_Thread_Handle
	call	TracerFree
	call	TracerAlloc
	jnc	@F

	debug_start sdata+DebugFlags, ICEDUMP_DEBUG_TRACE
	Trace_Out "ICEDUMP: TRACEX failed to allocate TraceInfo"
	debug_end

	jmp	short .ret

@@
	mov	esi,[TDS]
	mov	esi,[esi+edi]			; TraceInfo

	push	dword [Parse_TraceX.EIPlow]
	pop	dword [esi+TraceInfo.EIPlow]

	push	dword [Parse_TraceX.EIPhigh]
	pop	dword [esi+TraceInfo.EIPhigh]

	push	dword [Parse_TraceX.EAX]
	pop	dword [ebp+CRS.EAX]

	push	dword [Parse_TraceX.CS]
	pop	dword [ebp+CRS.CS]

	push	dword [Parse_TraceX.EIP]
	pop	dword [ebp+CRS.EIP]

	call	TrReinforce

.ret:
	popfd
	popad
	retn


;-------------------------------------------------------------------------------
; TRACE [<R0TCB> [<EIP low> [<EIP high>]]]
;-------------------------------------------------------------------------------
Parse_Trace:
	push	byte SERVICE_TRACE
	mov	ebp,[dClient_EAX]
	pop	dword [ebp]

	and	dword [.R0TCB],byte 0
	or	dword [.EIPlow],byte -1
	and	dword [.EIPhigh],byte 0

	call	ParseExpression			; parse <R0TCB>
	jc	.setCB

	mov	[.R0TCB],eax

	call	[pSkipWhiteSpace]		; skip to <EIP low>
	jz	.setCB

	mov	edi,Error_BadEIPlow
	call	ParseExpression			; parse <EIP low>
	jb	near Parser.errorMsg

	mov	[.EIPlow],eax

	call	[pSkipWhiteSpace]		; skip to <EIP high>
	mov	eax,[.EIPlow]
	jz	@F

	mov	edi,Error_BadEIPhigh
	call	ParseExpression			; parse <EIP high>
	jb	near Parser.errorMsg

@@
	mov	[.EIPhigh],eax

.setCB:
	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


segment _LDATA
	align 4
.R0TCB:		dd 0
.EIPlow:	dd 0
.EIPhigh:	dd 0


segment _LDATA
Error_BadEIPlow:	db 'invalid EIP low',0
Error_BadEIPhigh:	db 'invalid EIP high',0


segment _LTEXT
;-------------------------------------------------------------------------------
; prepare for tracing the specified thread, take care of self-tracing guys too
;-------------------------------------------------------------------------------
Service_Trace:
	cmp	[Parse_Trace.R0TCB],byte 0		; print trace info?
	jnz	.trace

	Trace_Out "ICEDUMP: threads under trace:"

	VMMCall	Begin_Critical_Section

	VMMCall	Get_Sys_VM_Handle
	VMMCall	Get_Initial_Thread_Handle
	mov     ebx,edi
	mov     ecx,[TDS]

@@
	cmp	[edi+ecx],byte 0

	Trace_OutNZ "#edi"

	VMMCall	Get_Next_Thread_Handle
	cmp	ebx,edi
	jnz	@B

	VMMCall	End_Critical_Section

.ret1:
	popfd
	popad
	retn

.trace:
	VMMCall	Get_Cur_VM_Handle
	VMMCall	Get_Cur_Thread_Handle

	cmp	[Parse_Trace.R0TCB],edi		; trace current thread?
	jnz	near .trace_notcurrent

	mov	esi,[TDS]
	mov	esi,[esi+edi]			; TraceInfo
	cmp	esi,byte 0			; tracing current thread?
	jnz	@F

	debug_start sdata+DebugFlags, ICEDUMP_DEBUG_TRACE
	Trace_Out "ICEDUMP: use TRACEX to trace the current thread"
	debug_end

	jmp	short .ret1

@@
	debug_start sdata+DebugFlags, ICEDUMP_DEBUG_TRACE
	Trace_Out "ICEDUMP: you shot yourself in the foot, use TRACEX to reactivate tracing the current thread"
	debug_end

	call	TracerFree
	jmp	short .ret1

.trace_notcurrent:
	mov	edi,[Parse_Trace.R0TCB]
	VMMCall	Validate_Thread_Handle
	jnc	@F

	Trace_Out "ICEDUMP: invalid thread handle, R0TCB: #edi"

	jmp	.ret2

@@
	mov	esi,[TDS]
	mov	esi,[esi+edi]

	mov	ecx,[Parse_Trace.EIPlow]
	mov	edx,[Parse_Trace.EIPhigh]
	cmp	ecx,edx
	jbe	.start

	cmp	esi,byte 0
	jnz	@F

	debug_start sdata+DebugFlags, ICEDUMP_DEBUG_TRACE
	Trace_Out "ICEDUMP: thread was not traced, R0TCB: #edi"
	debug_end

	jmp	short .ret2

@@
	cmp	dword [esi+TraceInfo.State0],byte ST0_SELFTRACEON
	jz	@F

	call	StopTracing

@@
	call	TracerFree
	jmp	short .ret2

.start:
	cmp	esi,byte 0			; already tracing?
	jnz	.update_range

	mov	ebp,[edi+TCB_ClientPtr]
	test	byte [ebp+CRS.EFlags+2],2	; is client in V86 mode?
	jz	@F

;	call	IsThreadWin32
;	jnc	@F

	debug_start sdata+DebugFlags, ICEDUMP_DEBUG_TRACE
	Trace_Out "ICEDUMP: thread is in V86 mode, R0TCB: #edi"
	debug_end

	jmp	short .ret2

@@
	call	TracerAlloc
	jnc	@F

	debug_start sdata+DebugFlags, ICEDUMP_DEBUG_TRACE
	Trace_Out "ICEDUMP: TRACE failed to allocate TraceInfo, R0TCB: #edi"
	debug_end

	jmp	short .ret2

@@
	mov	esi,[TDS]
	mov	esi,[esi+edi]
	call	TrReinforce

.update_range:
	mov	dword [esi+TraceInfo.EIPlow],ecx
	mov	dword [esi+TraceInfo.EIPhigh],edx

.ret2:
	popfd
	popad
	retn

%endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -