Copy Link
Add to Bookmark
Report

Xine - issue #4 - Phile 106

eZine's profile picture
Published in 
Xine
 · 6 months ago

 
/-----------------------------\
| Xine - issue #4 - Phile 106 |
\-----------------------------/


Win32 Anti-Debugging tricks
a.k.a. protect your own ass



Here i will list some tricks that could be used for the purpose of self-
protect your viruses and/or your programs againist debuggers (of all levels,
application and system). I hope you will like it.

[ Win98/NT: Detecting Application level debuggers with IsDebuggerPresent ]

This API is not present in Win95, so you will have to test for its presence,
and works with application level debuggers only (such as TD32). And it works
fine. Let's see what it's written about it in the Win32 API reference list.

-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú

The IsDebuggerPresent function indicates whether the calling process is
running under the context of a debugger. This function is exported from
KERNEL32.DLL.

BOOL IsDebuggerPresent(VOID)

- Parameters

This function has no parameters.

- Return Value

þ If the current process is running in the context of a debugger, the return
value is nonzero.
þ If the current process is not running in the context of a debugger, the
return value is zero.
-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú

So, an example for demonstrate this is very simple. Here it goes.

;---[ CUT HERE ]-------------------------------------------------------------

.586p
.model flat

extrn GetProcAddress:PROC
extrn GetModuleHandleA:PROC

extrn MessageBoxA:PROC
extrn ExitProcess:PROC

.data
szTitle db "IsDebuggerPresent Demonstration",0
msg1 db "Application Level Debugger Found",0
msg2 db "Application Level Debugger NOT Found",0
msg3 db "Error: Couldn't get IsDebuggerPresent.",10
db "We're probably under Win95",0

@IsDebuggerPresent db "IsDebuggerPresent",0
K32 db "KERNEL32",0

.code

antidebug1:
push offset K32 ; Obtain KERNEL32 base address
call GetModuleHandleA
or eax,eax ; Check for fails
jz error

push offset @IsDebuggerPresent ; Now search for the existence
push eax ; of IsDebuggerPresent. If
call GetProcAddress ; GetProcAddress returns an
or eax,eax ; error, we assume we're in
jz error ; Win95

call eax ; Call IsDebuggerPresent

or eax,eax ; If it's not 0, we're being
jnz debugger_found ; debugged

debugger_not_found:
push 0 ; Show "Debugger not found"
push offset szTitle
push offset msg2
push 0
call MessageBoxA
jmp exit

error:
push 00001010h ; Show "Error! We're in Win95"
push offset szTitle
push offset msg3
push 0
call MessageBoxA
jmp exit

debugger_found:
push 00001010h ; Show "Debugger found!"
push offset szTitle
push offset msg1
push 0
call MessageBoxA

exit:
push 00000000h ; Exit program
call ExitProcess

end antidebug1

;---[ CUT HERE ]-------------------------------------------------------------

Ain't it nice? Micro$oft did the job for us :) But, of course, don't expect
this method to work with SoftICE, the g0d ;)

[ Win32: Another way of know if we're under the context of a debugger ]

If you take a look into the article "Win95 Structures and Secrets", that was
written by Murkry/iKX, and published in the Xine-3, you'll realize that the-
re is a very cool structure in the FS register. Take a look into the field
FS:[20h]... It's 'DebugContext'. Just make the following:

mov ecx,fs:[20h]
jecxz not_being_debugger
[...] <--- do whatever, we're being debugged :)

So, if FS:[20h] is zero, we're not being debugged. Just enjoy this little
and simple method for detect debuggers! Of course, this can't be applied to
SoftICE...

[ Win32: Stopping Application level debuggers with SEH ]

I still don't know why, but the application level debuggers die simply if
the program uses SEH. And also the code emulators, if we make faults, die
too :) The SEH, as i published in my article in DDT#1 is used for many inte-
resting purposes. Well, as i don' t want to tell you all SEH stuff again, i
will cut'n'paste my old description :)

--[DDT#1.2_6]---------------------------------------------------------------

Well, this is a very simple tutorial about the Structured Exception Handler.
When i saw SEH implemented in a virus, i thought "Well, it does a lot. Must
be very hard to implement". So i simple skipped its use. But, as my Destiny
made General Protection Faults running under NT, as i read in 0BFF70000h, i
realized that i had to do something. And SEH was the only way. Well, we can
do it very complex to understand, or very easy. Of course, i prefer to do it
more easy :)

% Setting up the SEH frame %
----------------------------

Firstly we save it for our own safety with a simple text line.

push dword ptr fs:[0]

And now it's time to make the thingy to point to our handler (for example,
imagine that we used a call for call the setup of the SEH, and our handler
is just after that call instructions: we can use the offset of ret for make
it point there)

push offset SEH_Handler
mov fs:[0],esp

Well, as easy as it gets. What about restore the original SEH? More easy.
Simply do the opposite of the first instruction.

pop dword ptr fs:[0]


It's surprising that that very simple thing for implement if our Windoze vi-
ruses could do for us. For me (as it was the use of SEH i was searching) the
most important one is that i can help us to avoid all that goddamn blue
screens when we run our Win95 virus under NT enviroments. That goddamn blue
screen appears everytime we try to make comparisons over our hardcoded Win95
kernel under NT.

% Example of SEH use %
----------------------

Well, you can compile this with:

tasm32 /m3 /ml sehtest,,;
tlink32 /Tpe /aa sehtest,sehtest,,import32.lib

;---[ CUT HERE ]-------------------------------------------------------------

.386p
.model flat ; Good good... 32 bit r0x0r

extrn MessageBoxA:PROC ; Defined APIs
extrn ExitProcess:PROC

.data

szTitle db "Structured Exception Handler example",0
szMessage db "Intercepted General Protection Fault!",0

.code

start:
call setupSEH ; The call pushes the offset
; past it in the stack rigth?
; So we will use that :)
exceptionhandler:
mov esp,[esp+8] ; Error gives us old ESP
; in [ESP+8]

push 00000000h ; Parameters for MessageBoxA
push offset szTitle
push offset szMessage
push 00000000h
call MessageBoxA

push 00000000h
call ExitProcess ; Exit Application

setupSEH:
push dword ptr fs:[0] ; Push original SEH handler
mov fs:[0],esp ; And put the new one (located
; after the first call)

mov ebx,0BFF70000h ; Try to write in kernel (will
mov eax,012345678h ; generate an exception)
xchg eax,[ebx]

end start
;---[ CUT HERE ]-------------------------------------------------------------

[...]

--[DDT#1.2_6]---------------------------------------------------------------

Well, i hope you understood that. If not... Erhm, forget it :) Also, as the
other methods presented before, this cannot be applied to SoftICE

[ Win9X: Detect SoftICE (I) ]

Well, i must greet here Super/29A, because he was the one that told me about
this method. I broke this into two parts: in this one we will see how to
do it from a Ring-0 virus. I won't put a whole example program because it
would fill unnecessary lines, but you must know that this method must be
executed in Ring-0, and the VxDCall must be restored because the call-back
problem (do you remember?).

Well, we are gonna use the Virtual Machine Manager (VMM) service Get_DDB,
so the service will be 00010146h (VMM_Get_DDB). Let's see the information
about this service on the SDK.

-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú

mov eax, Device_ID
mov edi, Device_Name
int 20h ; VMMCall Get_DDB
dd 00010146h
mov [DDB], ecx

- Determines whether or not a VxD is installed for the specified device and
returns a DDB for that device if it is installed.

- Uses ECX, flags.

- Returns a DDB for the specified device if the function succeeds;
- otherwise, returns zero.

þ Device_ID: The device identifier. This parameter can be zero for name-
based devices.
þ Device_Name: An eight-character device name that is padded with blank
characters. This parameter is only required if Device_ID is zero. The
device name is case-sensitive.

-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú

Well, you are wondering why all this shit. Very simple, the Device_ID field
of SoftICE VxD is constant for all programs, as it's registered in Micro$oft
so we have a weapon again the marvelous SoftICE. It's Device_ID is 202h al-
ways. So we should use code like this:

mov eax,00000202h
VxDCall VMM_Get_DDB
xchg eax,ecx
jecxz NotSoftICE
jmp DetectedSoftICE

Where NotSoftICE should be the continuation of virus code, and the label
DetectedSoftICE should handle the action to perform, as we know that our
enemy is alive :) I don't suggest anything destructive because, for example,
would hurt my computer, as i always have SoftICE active :)

[ Win9X: Detect SoftICE (II) ]

Well, here goes another method for detect the presence of my beloved SoftICE
but based in the same concept of before: the 202h ;) Again i must greet to
Super :) Well, in the Ralph Brown Interrupt list we can see a very cool
service in the interrupt 2Fh (multiplex), the 1684h

-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú
Inp.:
AX = 1684h
BX = virtual device (VxD) ID (see #1921)
ES:DI = 0000h:0000h
Return:ES:DI -> VxD API entry point, or 0:0 if the VxD does not support an
API
Note: some Windows enhanced-mode virtual devices provide services that
applications can access. For example, the Virtual Display Device
(VDD) provides an API used in turn by WINOLDAP.
-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú

So, you put in BX a 202h, and execute this function. And you then say...
"Hey Billy... How the fuck i can use interrupts?". My answer is... USE THE
VxDCALL0!!!

[ Win32: Detect SoftICE (III) ]

The definitive and wonderful trick that you was waiting... The global solu-
tion of finding SoftICE in both Win9x and WinNT enviroments! It's very easy,
100% API based, and without "dirty" tricks that go againist compatibility.
And the answer isn't as hidden as you can think... the key is in an API that
you've surely used before: CreateFile. Yes, that API... ain't it charming?
Well, we have to try to open the following:

+ SoftICE for Win9x : "\\.\SICE"
+ SoftICE for WinNT : "\\.\NTICE"

If the API returns us something different than -1 (INVALID_HANDLE_VALUE),
SoftICE is active! Here follows a demonstration program:

;---[ CUT HERE ]-------------------------------------------------------------

.586p
.model flat

extrn CreateFileA:PROC
extrn CloseHandle:PROC
extrn MessageBoxA:PROC
extrn ExitProcess:PROC

.data

szTitle db "SoftICE detection",0

szMessage db "SoftICE for Win9x : "
answ1 db "not found!",10
db "SoftICE for WinNT : "
answ2 db "not found!",10
db "(c) 1999 Billy Belcebu/iKX",0

nfnd db "found! ",10

SICE9X db "\\.\SICE",0
SICENT db "\\.\NTICE",0

.code

DetectSoftICE:
push 00000000h ; Check for the presence of
push 00000080h ; SoftICE for Win9x envirome-
push 00000003h ; nts...
push 00000000h
push 00000001h
push 0C0000000h
push offset SICE9X
call CreateFileA

inc eax
jz NoSICE9X
dec eax

push eax ; Close opened file
call CloseHandle

lea edi,answ1 ; SoftICE found!
call PutFound
NoSICE9X:
push 00000000h ; And now try to open SoftICE
push 00000080h ; for WinNT...
push 00000003h
push 00000000h
push 00000001h
push 0C0000000h
push offset SICENT
call CreateFileA

inc eax
jz NoSICENT
dec eax

push eax ; Close file handle
call CloseHandle

lea edi,answ2 ; SoftICE for WinNT found!
call PutFound
NoSICENT:
push 00h ; Show a MessageBox with the
push offset szTitle ; results
push offset szMessage
push 00h
call MessageBoxA

push 00h ; Terminate program
call ExitProcess

PutFound:
mov ecx,0Bh ; Change "not found" by
lea esi,nfnd ; "found"; address of where
rep movsb ; to do the change is in EDI
ret

end DetectSoftICE

;---[ CUT HERE ]-------------------------------------------------------------

This really works, believe me :) The same method can be applied to other
"hostile" drivers, just research a bit on it.

[ Final Words ]

Well, some simple antidebugging tricks. I hope you can use them in your
virus without problems. See ya!

Breaking the law,
Billy Belcebu/iKX.



← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT