Insider - FAQ, Edition #7 UnComplete
7 of 9 files
christoph gabler
- Browsers may flag this download as unwanted or malicious. If unsure, scan it with VirusTotal.
-
Last modified Feb 6, 1999 6:52:18 PM
MD5 checksum 53a0586c478caf5080cbbe141e661fa7
Mime type ISO-8859 text, with CRLF line terminators
Download INSIDER7.FAQ
Size 32 kB
1999 February 6
- Text / Magazine
- Christoph Gabler, writer credits
½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½
»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
▄▄▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄▄ ▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄
█▄ ▄█ █ ▀██ █ █ ▄▄▄▄█ █▄ ▄█ █ ▄▄▄▀█ █ ▄▄▄▄█ █ ▄▄▄ █ █ ▄▄▄▄█ █ ▄▄▄ █ █ ▄▄▄ █
▄█ █▄ █ █▄▀ █ █▄▄▄▄ █ ▄█ █▄ █ ███ █ █ ▄▄▄█▄ █ ▄▄ ▄█ █ ▄▄█ █ ▄▄▄ █ █ ██▀ █
█▄▄▄█ █▄█▀█▄█ █▄▄▄▄▄█ █▄▄▄█ █▄▄▄▄█▀ █▄▄▄▄▄█ █▄██▄▄█ █▄█ █▄█ █▄█ █▄▄▄▄▄▀
INSIDER - FAQ
Edition #7 UnComplete
by Christoph Gabler
Release Date : 06.02.99
½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½
»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
────── ──────
─── ───
───────────────┐
│ Introduction │
└───────────────
The INSIDER - FAQ is meant for people who want to make their programs more
secure against unpacking/viewing or modifying.
You can input the code shown below into any of your ASM source codes or
into other languages which got a ASM support like C++ or Pascal.
Furthermore is the INSIDER - FAQ meant for those who are interested in
AntiDebugging or AntiTraceCode tricks against realmode or protectedmode
debuggers/unpackers.
Last but not least might the INSIDER - FAQ also be helpful for protector
writers or crackers which want to learn how AntiDebugging tricks look like
or how to bypass them with debuggers.
Please remember that the best tricks can be found in the uncovered version
of the INSIDER - FAQ. To get such version contact me by writing an EMail
with comments about TRAP and things I could add into the next version or
AntiDebugging code which can't be found in the current INSIDER - FAQ.
──────────────────────────┐
│ Realmode Anti Debugging │
└──────────────────────────
The following chapter describes ways how to crash/detect realmode debuggers
or unpackers like TD or IUP.
If we want to crash/detect a debugger we first have to know how they work.
Most realmode tracers use INT1/3 to trace. If you point INT1 or INT3 to
a corrupt area some stupid debuggers like TD get kicked.
A better way is to insert code into INT1 and then afterwards restore it
again. But CUP386 /1 and TR (with INT1) use there own interrupt table for
these ints, so what to do against them? As ANY realmode debugger does not
use its own stack, you can corrupt it and restore it after doing some
instructions.
Due to the fact that we need the keyboard to trace but not to execute code
we can also pull the keyboard off to make realmode tracers mad.
The keyboard has two important hardware ports : 60h and 64h.
Nuking those two ports will kick most of the debuggers out.
Interrupt 9 is also used by the keyboard, so play arround with that too.
Realmode debugger use/need the following things :
- INT1,INT3 and INT10
- Keyboard (INT9, Port 60h and 64h)
- Stack (SS and SP)
- Trap Flag to be on
╓══════════════════════════════╖
║ Points INT1 to invalid area ║
║ by Piotr Warezak (C) ║
╚══════════════════════════════╝
»»
INT1 can be either reset with INT21/AX=2501h or directly with MOV.
INT1 is located at position 0000:0004.
Old method to stop some realmode debuggers.
»»
push ds ;save DS register
xor ax,ax ;zero DS register
mov ds,ax
not word ptr ds:[0004] ;cut off INT1 vector for a moment
jmp short j1
db 09ah
j1: not word ptr ds:[0004] ;restore INT1 vector
pop ds ;restore DS register
╓═════════════════════════╖
║ Nice stack-trick 1 ║
║ by Christoph Gabler ║
╚═════════════════════════╝
»»
Here is a possibility how to detect any realmode debuggers/unpacker.
It is not very tight but to make it work everywhere I used some lines
for compatibilty - they are actually not very important.
It detects : CUP386 /1, TD, TD286, DEBUG and more...
»»
CLI
MOV DX,SP ; Save SP to DX.
MOV CL,CS:BYTE PTR [00] ; Save the original 00. For 100% compatibilty. =8]
MOV BL,CS:BYTE PTR [01] ; Same as above with 01.
MOV CS:BYTE PTR [00],0CDh ; Write the normal values - just to make sure.
MOV CS:BYTE PTR [01],020h ; Same as above with 01.
MOV AX,10h ; The value 3 would crash debuggers directly.
MOV SP,AX ; Corrupt the stack, now lame debugs modify 01.
MOV SP,DX ; Restore SP.
XOR AX,AX
MOV AL,CS:BYTE PTR [01] ; Write the value back.
MOV CS:BYTE PTR [00],CL ; Write 00/01 back.
MOV CS:BYTE PTR [01],BL
CMP AX,20h ; If not 20h then a realmode debugger is there.
JNE $ ; Jump at current position.
STI
╓═════════════════════════╖
║ Nice stack-trick 2 ║
║ by Christoph Gabler ║
╚═════════════════════════╝
»»
Much tighter but much easier to find out how it works. Fills SS
with my magic number (Most other numbers do not work).
Of course only against realmode debuggers.
»»
CLI
MOV BX,SS ; Save SS to BX
MOV DX,52121d ; Preparing DX for the corruption
MOV SS,DX ; Corrupt SS with the help of DX / Hlts DEBUG
XOR DX,DX
MOV SS,BX ; Restore SS
MOV BX,DX
STI
╓═════════════════════════╖
║ Nice stack-trick 3 ║
║ by Christoph Gabler ║
╚═════════════════════════╝
»»
The following code uses the stack to jump. Most realmode debugs
get kicked at the SP-modify, to get every realmode tracer the JMP SP
is included. This routine works best in addition with a decryption loop.
»»
MOV AX,OFFSET JUMP_TO ; Get the position to jump to.
MOV BX,SP ; Save SP to BX.
MOV SP,AX ; Fill SP with the jump value.
JMP SP ; Jump to the position.
JUMP_TO:
MOV SP,BX ; Restore SP.
»»
Very common method to detect realmode tracers - often found in protectors.
It stops: Debug,Turbo Debug,Realmode Debug...
»»
PUSH AX
POP AX
DEC SP
DEC SP
POP BX ; BX should point to the pushed AX.
CMP AX,BX
JNE $ ; Kill Debugger if found.
»»
Another wellknown and oftenseen stack trick.
It stops: Debug,Turbo Debug,Realmode Debug...
»»
CLI
MOV AX,SP ; Save SP.
MOV SP,3 ; Kick realmode debugger.
NOP ; Do a cmd between corruption and restore.
MOV SP,AX ; Restore SP.
STI
╓═════════════════════╖
║ Fake entrypoint #1 ║
║ by Christoph Gabler ║
╚═════════════════════╝
»»
Almost anyone has heard about fake entrypoints. They can be found
in HS and RC to fool DECAY05 or in CS to fool CUP386. There are many
other protectors in which such a entrypoint fake can be found.
But how does it work? Pretty simple, the following code is such a
routine. CUP386 and DECAY05 get fooled.
Based on the unpackers Seek_For_IP=100h_If_So_Then_We_Are_Thru ;)
»»
MOV CX,9000h ; Fake the entrypoint 9000h times.
XOR DX,DX ; We must clear DX first.
MOV DL,CS:BYTE PTR [100h] ; Save the byte found at 100h.
MOV CS:BYTE PTR [100h],0C3h ; Write a RET to 100h.
MOV AX,100h
FAKE_ENTRY:
CALL AX ; Call 100h.
LOOP FAKE_ENTRY
MOV CS:BYTE PTR [100h],DL ; Restore the byte we overwrote before.
╓═════════════════════╖
║ Fake entrypoint #2 ║
║ by Christoph Gabler ║
╚═════════════════════╝
»»
Another possibility to fake some unpackers. This time it does not restore
100h and 101h - I think if you need to restore, you can do it yourself.
»»
MOV CX,9000h ; Fake the entrypoint 9000h times.
XOR DX,DX ; We must clear DX first.
MOV DL,OFFSET THERE - 100h ; This is to generate the correct JMP back.
ADD DX,100h ; Add 100h 'cause we jump there.
MOV CS:BYTE PTR [100h],0FFh ; Write the jump command to 100h.
MOV CS:BYTE PTR [101h],0E2h
MOV AX,100h
JMP AX ; Jump to 100h.
THERE:
CMP CX,0 ; If CX = 0 then we are done.
JE OVER_FAKE
DEC CX
JMP AX ; Do it again.
OVER_FAKE: ; Place the rest of your code here.
╓════════════════════════════╖
║ Playing with the Trap Flag ║
║ By Christoph Gabler ║
╚════════════════════════════╝
»»
INT1 tracer/unpacker have to set the Trap Flag which causes a INT1 to be
executed after every instruction, which allows the single stepping procedure.
By disabling this flag, we can disable the breakpoints from some INT1 tracers.
But, most won't loose the control, because they turn the Trap Flag back on
after every instruction and due to the fact that we need to do another instr.
after the TF is fully turned off, the tracer gets the control back.
»»
Xor Ax, Ax ; Disable all flags. (Trap Flag too, of course)
Push Ax
PopF ; After one further instr., TF should be off.
Mov Ax, 100h ; This will enable TF, by setting bit 8.
Push Ax
PopF
»»
Much better would be to turn the TF off, and then check if TF is *really*
off. If it isn't a debugger is working in the background and we can crash it.
»»
Xor Ax, Ax ; Turn TF off.
Push Ax
PopF
PushF ; Get the flag status
Pop Ax ; and put it into AX.
And Ah, 0Fh ; We only want the TF flag.
Cmp Ah, 1 ; If AH=1 then TF is still on.
Je $ ; Crash the CPU.
╓═════════════════════╖
║ Nuke Interrupt 1/3 ║
║ By Christoph Gabler ║
╚═════════════════════╝
»»
This routine kills INT1 and INT3 without using INT21. This method is
very common and a similar version can be often found in protectors.
CUP386 /1 does not loose the control - maybe it redirects INT1 and INT3.
»»
PUSH ES
CLI
xor ax,ax
mov es,ax ; Clear ES.
mov bx,4 ; Position of INT1.
mov ax,es:[bx] ; Get and save INT1.
mov es:[bx],0FFFFh ; Set INT1 to xxxx:FFFF
add bx,2 ; Position of INT3.
mov cx,es:[bx] ; Get and save INT3.
mov es:[bx],0FFFFh ; Set INT3 to xxxx:FFFF
sub bx,2
mov es:[bx],ax
add bx,2
mov es:[bx],cx
STI
POP ES
╓═════════════════════╖
║ Keyboard trick #1 ║
║ by Christoph Gabler ║
╚═════════════════════╝
»»
This will lock and then unlock the keyboard using the keyboard port 64h.
Nice against CUP, DG...
»»
; Lock keyboard.
MOV AL,0ADh
OUT 64h,AL
; Unlock keyboard.
MOV AL, 0AEh
OUT 64h,AL
╓═════════════════════╖
║ Keyboard trick #2 ║
║ by Christoph Gabler ║
╚═════════════════════╝
»»
The following trick is a generic trick, one of the unstable ones.
It is based on the fact that we have to press the ENTER key before we can
execute a program. So, hardware port 60h will be set to 1Ch which means
the ENTER key. If we debug the program, we have to press F7, F8 or F10 in
order to trace step by step. Now, if we would check if the last key pressed
is the ENTER key, we could make a generic detection routine.
The problem is that if we press another key after pressing the ENTER key,
the CPU will get detected also. ;)
BTW, I think FSE uses this (or a similar one), because it crashs if I press
another key in runtime.
»»
In Al, 60h ; Get the key which was pressed last.
Cmp Al, 1Ch ; If not ENTER key then a debugger is tracing.
Jne $ ; Hlt system.
╓═════════════════════╖
║ Irritation code ║
║ by Christoph Gabler ║
╚═════════════════════╝
»»
A stupid little routine to irritate the tracer. Of course only usefull if
you place a decryptor with a C3 in it, jump there and do other irritating
things. This is just an example.
»»
MOV DX,SP
CALL POS
JMP GO_ON
POS: POP BX ; Get current position.
CALL $+4 ; Call over the command, into C3.
DB 04h,0C3h ; MOV AL,0C3h
CALL $-1 ; Call back into C3.
MOV [CS:00],AL ; Write a C3 into CS:00.
ADD AL,03Dh ; Clear AL.
MOV [CS:20C3h],0E3FFh ; Place a JMP BX to CS:20C3.
JMP AX ; Jump to 00.
GO_ON:
MOV SP,DX
╓═════════════════════╖
║ Irritation macro ║
║ by Christoph Gabler ║
╚═════════════════════╝
»»
98% of HackStop's "AntiDebugging code" consists of lame macros.
Macro's were meant for making reading/debugging of code difficult, everyone
of course knows that they are just joke (as HS itself ;).
How do these marco's which were meant for irriatation work?
The two instructions 'CALL FAR' and 'JUMP FAR' need 5 bytes of space for
their working, that's why debuggers display the following 4 bytes as
a 'CALL FAR' or 'JUMP FAR' instruction. So, what happens if we put a
'0EAh' or a '09Ah' into our code? The following code will be displayed as
the same instruction. If we now simply jump over the oppcode byte to avoid
a crash we are done.
»»
MACRO_LOOP: ; Use a loop because this might be interesting for decryptors
JMP OVER_1 ; First fake jump over oppcode '0EAh'
DB 0EAh ; The oppcode itself.
OVER_1:
NOP ; Do a cmd, insert your code here.
JMP OVER_2 ; Second fake jump.
DB 09Ah ; The oppcode itself.
OVER_2:
CALL OVER_3 ; CALLing instead of JuMPing works better against TR.
NOP ; Do another fucky cmd.
CALL OVER_4 ; Do it again. ('cause lameness rules!)
JMP OVER_6 ; And another time.
DB 0EAh ; The oppcode itself.
OVER_4:
RET
OVER_6:
NOP
JMP OVER_5 ; Jump a last time.
DB 00,00,0EAh
OVER_3:
RET
DB 00,00,00,09Ah
OVER_5:
LOOP MACRO_LOOP
╓═══════════════════════════════╖
║ Screen AntiDebugging trick #1 ║
║ by Christoph Gabler ║
╚═══════════════════════════════╝
»»
Often seen in protectors like Ciphator,FSE05,ExeLock666,PCrypt...
Should irritate the tracer but I think it irritates the user. :)
Here's the tightest way I know - directly over hardware port 3C6h.
»»
CLI
MOV DX,3C6h ; Point to color area.
IN AX,DX ; Get old settings.
PUSH AX ; Save them.
MOV AX,100h ; Value for black.
OUT DX,AX ; Send to port.
; Place your Antidebugging Tricks here.
POP AX ; Restore old settings.
OUT DX,AX ; Send them to port.
STI
╓═══════════════════════════════╖
║ Screen AntiDebugging trick #2 ║
║ ripped out of ExeLock666 ║
╚═══════════════════════════════╝
»»
'Legandary' way to flicker the screen. Found in Ciphator and ExeLock666...
Turns whole screen off for a while.
»»
; Screen off.
mov dx,03C4h
mov al,1
out dx,al
inc dx
in al,dx
or al,20h
out dx,al
; Place your Antidebugging Tricks here.
; Screen on.
mov dx,03C4h
mov al,1
out dx,al
inc dx
in al,dx
and al,dl
out dx,al
──────────────────────────────┐
│ Protectedmode AntiDebugging │
└──────────────────────────────
Everyone knows them, every protector author fears them : PM Debuggers. ;)
Much more difficult to detect/crash then 'normal' realmode debuggers.
Number one might be Iceunp or Winice, which keep their own stack, mostly their
own interrupts and full 8086-486+ emulation.
TR 2.52 does not trace the code, it interprets every single instructions.
Unknown instructions must be traced. TR uses INT1 to trace these instructions.
Deglucker acts similar to CUP386 - full interrupt reemulation, but bad
DRx/CRx emulation.
GTR uses asskicking keyboard routines which make keyboard-offs
nearly impossible.
Protectedmode debugger use/need the following things :
- INT10
- Keyboard (INT9,Port 60h and 64h or 21h)
- Sometimes DRx (If hardware breakpoint tracing)
╓═════════════════════════╖
║ Winice recognization ║
║ by ? ║
╚═════════════════════════╝
»»
How to recognize Winice? The following routine shows how to do it.
Stonehead told me that the routine hangs sometimes - I do not know, test it.
Detects: Only Winice Win 3.1/Win95 NOT the Dos version.
»»
; Anti SoftIce trick #1
mov ax,01684h
mov bx,0202h ; VXD ID for Winice, check out Ralf Brown's INTLIST
xor di,di
mov es,di
int 2fh
mov ax,es
add di,ax
cmp di,0
jne $
»»
The four following routines were send by somebody I met on IRC. I'm sorry but
I forgot his name. Anyway, hope you enjoy the following Anti Winice tricks.
»»
; Detect Winice #1
mov ebp, 'BCHK' ; use ice BoundsChecker interface
mov ax, 04h
int 3
cmp al,4
jz winicenotdetected
; Detect Winice #2
mov ah,43h
int 68h ; winice has int 68h handler and returns following value
cmp ax,0f386h
jnz winicenotdetected
; Detect Winice #3
xor ax,ax
mov es,ax
mov bx, word ptr es:[68h*4]
mov es, word ptr es:[68h*4+2] ; checking int 68h handler
mov eax, 0f43fc80h
cmp eax, dword ptr es:[ebx]
jnz winicenotdetected
; Detect Winice #4
push cs
pop es
xor ax,ax
mov es,ax
mov bx, cs
lea dx, int41handler
xchg dx, es:[41h*4]
xchg bx, es:[41h*4+2]
in al, 40h
xor cx,cx
int 41h
xchg dx, es:[41h*4]
xchg bx, es:[41h*4+2]
cmp cl,al
jz winicenotpresent
»»
Here is another way to get Winice. Credits go to DarkStalker.
Works while executing INT41 which is used by Winice itself.
»»
cli
In Ax,40h
Mov word ptr cs:[bp+keyval],Ax
push 0
pop ds
xor ebx,ebx
mov bx,cs
shl ebx,10h
lea bx,[bp+newint2]
xchg ebx,dword ptr ds:[41h*4]
push ds cs
pop ds
Mov Ah,4Fh
Int 41h
pop ds
XChg EBx,DWord Ptr Ds:[41h*4]
Push Cs
Pop Ds
Cmp Ax,0000h
keyval Equ $-2
Jne $
sti
NewInt2:
╓══════════════════════════╖
║ Anti Deglucker 0.04 code ║
║ by Christoph Gabler ║
╚══════════════════════════╝
»»
The following routine shows a possibility of how to defeat DG with just
3 bytes. If you trace it with DG, a 'protection fault' will be displayed
and you cannot continue. The problem is that you are still able to NOP the
code out.
»»
DB 66h,0FAh,0FBh ; Opcode 66h, CLI, STI
here another little instruction which causes DG to
display 'protection fault' :
CMPSD ; Compare string or doubleword 386+
╓══════════════════════╖
║ Mode Detections ║
║ by different authors ║
╚══════════════════════╝
»»
Another nice section might be the detection of the different modes a CPU can
be switched to. Here are ways of how to detect RealMode, ProtectedMode or
Windows95.
»»
; Realmode detection by Christoph Gabler.
mov eax,cr0
cmp eax,10h ; Compare CR0 with 10h, if so, we must be in realmode.
je Real_Mode_Found
; Realmode detection by ELiCZ.
SMSW AX ; Get Machine Status Word and store in AX.
TEST AL,1
JE Real_Mode_Found ; Jump if CPU in Real Mode.
; Protected Mode (QEMM, EMM386...) detection by Christoph Gabler.
mov eax,cr0
cmp al,1
je Protected_Mode_Found
; V86 (Windows 3.x and Windows 95) detection by Christoph Gabler.
mov eax,cr0
cmp ax,0000 ; CPU is in Virtual 8086 mode if CR0 is 0000.
je V86_Mode_Found
; Windows Detection detection by tHE riDDLER
mov ax, 01600h
int 02fh ; Check for available BP.
or al,al
jne Windows_Found
╓═══════════════════════════════╖
║ Generic Anti TR 1.97 trick ║
║ by Torsten Becker ║
╚═══════════════════════════════╝
»»
Here is a nice way to stop TR. You can put the following two bytes
before any other instruction like a NOP or a XOR...
The problem is that TR is able to bypass when in INT1-mode.
You are asking yourself how to hinder tracing it with INT1? Ask me
for the uncovered INSIDER.FAQ. :)
»»
DB 66h,67h ; Kicks TR 1.97
NOP ; Or any other command.
╓══════════════════════════════════╖
║ TR - unknown instruction listing ║
║ by Christoph Gabler ║
╚══════════════════════════════════╝
»»
The following source shows a few commands which cannot be traced with
TR 1.97 without using INT1. Most instruction are unknown to TR and some
simply hang TR when trying to trace them.
Of course they are more or less useless if you can bypass them with INT1
but there are so MANY ways to get TR's INT1 - trace method :
Cut INT1 before placing these instructions or play with the stack...
»»
Instructions which are unknown to TR 1.97 :
CLTS ; Clear Task Switched Flag 286+ privileged mode
JECXZ LABEL ; Jump to LABEL if ECX zero 386+
BSR EAX,EBX ; Bit Scan Reverse 386+
BSF EAX,EBX ; Bit Scan Forward 386+
CMPXCHG EAX,EBX ; Compare and Exchange 486+
BSWAP EAX ; Byteswap 486+
╓═════════════════════════╖
║ Cheap IceUnp detection ║
║ by Christoph Gabler ║
╚═════════════════════════╝
»»
IceUnp uses good trace modes but the coder forgot one really dumb thing :
His program does always use the same temporary file that is created before
the Iceunp traced the file - a very stupid mistake because Iceunp can be
detected while just searching the temp file called '1ICEUNP'
Here is a method how to do it.
> This one is cheap too. Get a REAL IceUnp detection in the UNcovered version
of INSIDER.FAQ !
»»
mov ah,4Eh ; Find the first match
mov dx,offset ICETEMP ; Load the offset filemask dx
int 21h ; Call DOS
jnc $ ; Jump at current pos. if 1ICEUNP
found.
; Rest of your code
ICETEMP db '1ICEUNP',0 ; This must be placed out of range.
╓═════════════════════════╖
║ Startup register tricks ║
║ By Christoph Gabler ║
╚═════════════════════════╝
»»
These kind of tricks are the funny part of the antidebugging section.
Why can TR not unpack Glue'd nor ATEU'd files? Pretty simple, the decryptor
uses LODSB/STOSB for decryption which means:
LODSB = Mov Ax, DS:word ptr [SI]
INC/DEC SI
STOSB = Mov ES:word ptr [DI], Ax
INC/DEC DI
The obvious part is, that SI and DI don't get set before the decryptor:
e.g. Mov Di, xxxxh
Which means, that the values loaded at the execution of the file will be used.
Of course, every single register has its own allocation.
The following table will show to which values the registers are set by load
time.
»»
Normal CPU:
───────────
AX Contains DS:[80h] (Number of characters entered in cmd tail)
BX:CX The load module memory size in 32 bit
DX Set to DS
SI Set to IP at entrypoint (in COM always 100h)
DI Set to SP at entrypoint
SP In COM set to FFFEh, in EXE set to the SP header value
SS In COM set to CS, in EXE set to the SS header value
DS In COM set to CS, in EXE set to the DS header value
ES In COM set to CS, in EXE set to DS
CS In COM to current memory adress, in EXE to the CS header value
IP In COM to 100h, in EXE to the IP header value
TR and Deglucker:
──────────
AX Zero [Wrong]
BX:CX Zero [Wrong]
DX Set to DS
SI Always set to 100h [In EXE wrong]
DI Zero [Wrong]
SP In COM set to FFFEh, in EXE set to the SP header value
SS In COM set to CS, in EXE set to the SS header value
DS In COM set to CS, in EXE set to the DS header value
ES In COM set to CS, in EXE set to DS
CS In COM to current memory adress, in EXE to the CS header value
IP In COM to 100h, in EXE to the IP header value
╓══════════════════════════════════════╖
║ 32 Bit Control- & Debug Register FAQ ║
║ By Christoph Gabler ║
╚══════════════════════════════════════╝
»»
The following section should complain the working and function of
the 32 Bit Control and Debug registers which can used to detect nearly
ANY 80386 Debugger/GenericUnpacker. This short FAQ should describe
what the CPU and Debugger does when it executes modification on DRx/CRx.
If you know anything more about these registers please write it down
and I'll add it here!
»»
(1) - The following 'enhanced' 32 Bit registers exist :
[CRx] Control Registers (Modifications are QEMM incompatible)
CR0,CR2,CR3
[DRx] Debug Registers
DR0,DR1,DR2,DR3,DR4,DR5,DR6,DR7
[TRx] Test Registers
TR4,TR5,TR6,TR7
(2) - Description/function of the single register :
CR0 = Main Control Register
Used to switch into Protected Mode and back to Real Mode.
If already in PM mode under the OS, a crash will follow (EMM,QEMM...)
CR2-3 = Should not be modified.
DR0-4 = Breakpoint location registers
Must contain the linear adress of the adress of where to break.
DR6 = Debug status register
Sets/Disables flags to show the status of the DRx status.
DR7 = Debug Control Register
GD Avaible on 486i+ - setting it enables a breakpoint on access to
debug registers the GD bit is cleared by the processor on entry to the
exception handler.
(3) - Which values they are able to hold :
CR0 = Handles values till ca. 2000h, adds 10h to itself if modified
CR2-CR3 = Should not be accessed, values are same as they were set to
DR0-DR5 = Handles 32 bit values, the fourth position is always a zero
DR6 = Handles 32 bit values, behaves different from OS to OS
DR7 = Handles 32 bit values, adds either 400h or 00 to itself if
modified, the fourth position is always a zero
(4) - Generic Unpacker Description :
CUP386 /1 = Tracing with INT1 using the TF.
CUP386 /3 = V86 mode tracer using hw brkpoints.
CUP386 /7 = 386+ interpreter, bad debug register emulation.
GTR 1.C0 = Very unhandy in usage, but nice tracing engine.
Clever HW breakpoint tracing method.
IceUnp = Very strong IUP rip, using the TF, yes the TF!
Own stack, INT1/3 emulation, DRx tracing.
TR 2.25 = Very nice DRx,CRx emulations now! Uses interpreting mode.
INT1 tracing also available. Best DOS debugger!
AUP386 = Seems like an unstable HW breakpoint method.
DECAY05 = Uses hardware breakpoints in order to trace.
Breakpoint set to IP=100h.
EDump 1.0 = Uses the Win95 PM mode for ring tracing. Full control over
RL/SelfTracing.
LTR 1.0 = Mighty interpreter, full DRx hardware breakpoint possibility.
Only a few bugs left and no PM instr. interpreting.
┌──────────────────────
│ Anti-AntiVirus Code │
──────────────────────┘
╓═════════════════════════╖
║ Anti F-Prot Heuristic ║
║ By someone at Crypt ?? ║
╚═════════════════════════╝
»»
A very popular routine to avoid F-Prot's Heuristic Analysis. I think it's
a dumb waste of space using it - I have something better - watch at
TOP SECRETS!. Poor F-Prot, if it can be avoided by just jumping forwards
a few times. =8]
»»
call screw_fprot ; confusing f-protect's
call screw_fprot ; heuristic scanning
call screw_fprot ; Still effective as of
call screw_fprot ; version 2.10
call screw_fprot ;
call screw_fprot ; [cf] Crypt Newsletter 18
call screw_fprot ; for explanation &
call screw_fprot ; rationale
call screw_fprot ;
call screw_fprot ;
screw_fprot:
jmp $ + 2 ; Pseudo-nested calls to confuse
call screw2 ; f-protect's heuristic
call screw2 ; analysis
call screw2 ;
call screw2 ;
call screw2 ; These are straight from
ret ; YB-X.
screw2:
jmp $ + 2
call screw3
call screw3
call screw3
call screw3
call screw3
ret
screw3:
jmp $ + 2
call screw4
call screw4
call screw4
call screw4
call screw4
ret
screw4:
jmp $ + 2
ret
╓═════════════════════════╖
║ Anti TBClean routine ║
║ By someone at Crypt ??? ║
╚═════════════════════════╝
»»
Here is THE popularest routine to stop TBClean. It is very big in size
and it sucks 'cause TBClean can be stopped with 'CLI and STI'.
»»
look_4_tbclean:
mov ax, word ptr ds:[si]
xor ax, 0A5F3h
je check_it ; Jump If It's TBClean
look_again:
inc si ; Continue Search
loop look_4_tbclean
jmp not_found ; TBClean Not Found
check_it:
mov ax, word ptr ds:[si+4]
xor ax, 0006h
jne look_again
mov ax, word ptr ds:[si+10]
xor ax, 020Eh
jne look_again
mov ax, word ptr ds:[si+12]
xor ax, 0C700h
jne look_again
mov ax, word ptr ds:[si+14]
xor ax, 406h
jne look_again
mov bx, word ptr ds:[si+17] ; Steal REAL Int 1 Offset
mov byte ptr ds:[bx+16], 0CFh ; Replace With IRET
mov bx, word ptr ds:[si+27] ; Steal REAL Int 3 Offset
mov byte ptr ds:[bx+16], 0CFh ; Replece With IRET
mov byte ptr cs:[tb_here][bp], 1 ; Set The TB Flag On
mov bx, word ptr ds:[si+51h] ; Get 2nd Segment of
mov word ptr cs:[tb_int2][bp], bx ; Vector Table
mov bx, word ptr ds:[si-5] ; Get Offset of 1st Copy
mov word ptr cs:[tb_ints][bp], bx ; of Vector Table
not_found:
mov ax, 0CA00h ; Exit It TBSCANX In Mem
mov bx, 'TB'
int 2Fh
cmp al, 0
je tbcleanok
ret
tbcleanok:
────────────────────────┐
│ How to fool unpackers │
└────────────────────────
╓═════════════════════╖
║ Intruder FakeCode ║
║ By Christoph Gabler ║
╚═════════════════════╝
»»
This funny little piece of code will show the lameness of a startup code
unpacker called Intruder. Everything behind this is that Intruder hooks INT21,
than executes your program and tries to find (via INT21) if a Pascal, C or
C++ compile program was found, then reconstruct the header and dump the code.
The following few bytes will make Intruder think our program was compiled
with Pascal and then write a lot of shit to disk.
»»
Mov Ah,30h
Int 21h ; Now Intruder will get back control and will
mov bp,ds:[0002h] ; find the following few bytes so that a
mov bx,ds:[002Ch] ; wrong dump will appear.
»»
If you want to find out more such fakecode to fool TEU, UPC and similar try
the following :
(1) - Run the unpacker and specify C:\COMMAND.COM for unpacking.
(2) - Trace INT21 using a debugger like CUP386 or TR.
(3) - Try to find JE, JNE and other 7xh opcodes which might lead to the
unpacking procedure.
(4) - Rebuild the neccassary bytes which will get checked if the
INT21 function xxh will be executed and try to unpack it with your
unpacker
Good luck. ;)
»»
────────────────
│ TOP SECRETS! │
────────────────
Ehm, 'cause this is the uncomplete version of the INSIDER.FAQ this section
has been cutten - send a email in order to get a complete version.
-> If you have coded your own anti-trace/debug routine please send it to
me and it will be added here!
(C)opright by Christoph Gabler between 1998 and 1999
Routines are licensed for free usage
»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»