Outside of debugger and tracer.
Code:
.686
.model flat, stdcall
option casemap :none
include \masm32\include\ntdll.inc
.code
OS_VERSION_ID_2000 equ 0
OS_VERSION_ID_XP equ 1
OS_VERSION_ID_2003 equ 2
OS_VERSION_ID_VISTA equ 3
OS_VERSION_ID_7 equ 4
; +
;
QueryVersion proc C
push eax
push edx
assume fs:nothing
mov ecx,fs:[TEB.Peb]
assume ecx:PPEB
mov eax,[ecx].NtMajorVersion
mov edx,[ecx].NtMinorVersion
cmp eax,5
je v_5_x_
cmp eax,6
jne err_ver_
; 6.X
test edx,edx
mov ecx,OS_VERSION_ID_VISTA
jz end_ver_ ; 6.0
inc ecx ; OS_VERSION_ID_7
dec edx
jz end_ver_ ; 6.1
jmp err_ver_
v_5_x_:
xor ecx,ecx ; OS_VERSION_ID_2000
test edx,edx
jz end_ver_ ; 5.0
inc ecx ; OS_VERSION_ID_XP
dec edx
jz end_ver_ ; 5.1
inc ecx ; OS_VERSION_ID_2003
dec edx
jz end_ver_
err_ver_:
mov ecx,0
end_ver_:
pop edx
pop eax
ret
QueryVersion endp
; +
;
SystemCall proc C
; [Esp]:
; + 00 Eax
; + 04 Return1 <- Esp
; + 08 ServiceList1
; + 0C ServiceList2
; + 10 ServiceList3
; + 14 NumberParameters
; + 18 Return2
; + 1C Parameter1
; + 20 ParameterN <- Return
; + XX ...
Call QueryVersion
.if Zero?
lea edx,[esp + 14H]
movzx eax,word ptr [esp + ecx*2 + 4]
.else
mov eax,esp
.endif
mov ecx,esp
sub esp,300H ; sizeof(CONTEXT)
assume ecx:PCONTEXT
mov CONTEXT.ContextFlags[esp],CONTEXT_CONTROL or CONTEXT_INTEGER or CONTEXT_DEBUG_REGISTERS
mov CONTEXT.regEsp[esp],ecx
mov CONTEXT.regEFlags[esp],EFLAGS_IF or 2
mov word ptr CONTEXT.regSegSs[esp],ss
mov word ptr CONTEXT.regSegCs[esp],cs
mov CONTEXT.regDr7[esp],0
mov CONTEXT.regEbp[esp],ebp
mov CONTEXT.regEax[esp],Eax
mov CONTEXT.regEdx[esp],Edx
mov CONTEXT.regEbx[esp],Ebx
mov CONTEXT.regEsi[esp],esi
mov CONTEXT.regEdi[esp],edi
Call GetGraphEntry
mov CONTEXT.regEip[esp],ecx
push FALSE
push esp
push dword ptr 3CH ; Aligned.
add dword ptr [esp + 4],4
push 3722201CH
Call QueryVersion
jnz @f
lea edx,[esp + 8]
movzx eax,byte ptr [esp + ecx]
Int 2EH
DB 0CCH ; Int3
@@:
add esp,308H
jmp CallService
GetGraphEntry:
Call GetGraphReturn
CallService:
Int 2EH
ServiceExit:
push eax
mov eax,dword ptr [esp + 14H]
push dword ptr [esp + 4]
lea eax,[eax*4 + esp + 18H]
pop dword ptr [eax]
mov dword ptr [esp + 4],eax
pop eax
pop esp
inc dword ptr [esp]
ret
GetGraphReturn:
pop ecx
ret
SystemCall endp
$SYSCALL macro VT1:REQ, VT2:REQ, VT3:REQ, NumberParameters:REQ, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10
FOR Arg, <p10,p9,p8,p7,p6,p5,p4,p3,p2,p1>
IFNB <Arg>
push Arg
ENDIF
ENDM
push NumberParameters
push VT3
push VT2
push VT1
Call SystemCall
endm
ProcessDebugObjectHandle equ 30
STATUS_PORT_NOT_SET equ 0C0000353H
OutsideOfDebugger proc C
push esp
mov eax,esp
push NULL
push sizeof(HANDLE)
push eax
push ProcessDebugObjectHandle ; 0x1E
push NtCurrentProcess
push 5
push 000000EAH
push 00E400A1H
push 009A0086H
Call SystemCall ; NtQueryInformationProcess(ProcessDebugObjectHandle)
nop
test eax,eax
jnz @f
push dword ptr [esp]
push NtCurrentProcess
push 2
push 00000121H
push 010A00C7H
push 00BFFFFFH
Call SystemCall ; NtRemoveProcessDebug
nop
push eax
push dword ptr [esp + 4]
push 1
push 00000032H
push 0030001BH
push 00190018H
Call SystemCall ; NtClose
nop
pop eax
@@:
add esp,sizeof(HANDLE)
inc dword ptr [esp] ; test.
ret
OutsideOfDebugger endp
Entry proc
Local Response:ULONG
invoke OutsideOfDebugger
nop
invoke ZwRaiseHardError, STATUS_SUCCESS, 1, 0, 0, OptionOkCancel, addr Response
ret
Entry endp
end Entry