From:
                                                                       08:18
Subject: Re: HackStop Unpacking!To: RalphRoth@gmx.de

>masterball@crosswinds.net wrote:
>> seem that you have not proven GTR 1.90 with HackStop, well, I send you
the

>
>I know that GTR can unpack HS - and I see no way currently to prevent
>this, any ideas? btw, you dont need to send unpacked hs.exe - i believe
>you.
>
>How did you do it?
>
>--
>Sincerely,              mailto:RalphRoth@gmx.de
>   Ralph Roth           http://come.to/rose_swe
>--
>
>
>
i'am recommend to see INSIDER.FAQ complete and iluvatar (ilucrypt)
modules...

    ---------------------------------------------------------------------



            
                        
                           
               
                                INSIDER - FAQ
                             Edition #9 Complete
                             by Christoph Gabler
                           Release Date : 01.10.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 an ASM support like C++ or Pascal.
  Furthermore is the INSIDER - FAQ meant for those who are interested in
  anti debugging tricks against realmode or pmode debuggers/unpackers.
  Finally might the INSIDER - FAQ also be helpful for protector writers or
  crackers which want to learn how anti debugging tricks look like or how to
  bypass them with debuggers.
   Ŀ
    About Anti Debugging Code 
   
  Before I start listing anti debugging code against the different unpacking
  methods and debuggers, I would first like to describe the following
  topics : "What is anti debugging code?", "How can I use it in the
            most effective way?" and "Security against Compatibilty"
   What is anti debugging code?
  If we want to understand more about the working of a program, the
internals
  and the machine code it is made of, we have to "debug" the program with
  a "debugger". This is another program which uses one of different methods
  to trace back the whole program you want to debug by setting breakpoints
  after every single machine code instruction, so that we can follow the
  programs execution step by step. The only problem for the debugger is,
  that the code which is traced in the program, controls the debuggger and
  not vice versa, which means that if the author of the program has put
  tricky code (anti debugging code) to crash/detect our debugger into the
  program, the debugger might not be able to automatically trace the whole
  program.
  The best chance for a debugger to be able to trace as much anti debugging
  tricks as possible, is to react as "CPU-like" (without debugger in
background)
  as possible. Anti debugging code is based on the "search the difference"
  game between CPU-only and debugger. Which means, if an instruction or a
  value is different traced from debugger to CPU-only, we could use this
  to create anti debugging and to make the debugger crash.
  If you want to create anti debugging code your own, you'll first have
  to know how the different debugging systems work and were their faults
are.
   How can I use it in the most effective way?
  It is also very important to make anti debugging code as invisible and
  difficult to bypass manually with a debugger.
  For hindering automatic tracing/unpacking of most realmode debuggers, the
  following code is enough :
  CLI
  MOV AX, SP
  MOV SP, 3     ; Crashs rm debuggers which do not keep their own stack.
  MOV SP, AX
  STI
  But, of course, it is pretty easy to either NOP out the code or simply
  jump over it with a debugger. Much more difficult would be to use the
  stack (SP) as an used value in a decryptor :
  CLI
  Mov Ax, Sp
  Decryptor:
  Xor CS:byte ptr [Bx], 99h
  Inc Sp
  Mov Bx, Sp
  Loop Decryptor
  Mov Sp, Ax
  STI
  Of course this is also not very difficult to bypass, but we cannot
  simply jump over the code, because we have to trace decryptors, because
  otherwise, we would later run into encrypted code.
  Remember : Decryptors *only* need to be traced by the debugger, which
  means, put most of your antidebugging into it in an intelligent way,
  so that the decryptor would *not* work without the antidebugging
  instructions!
   Security against Compatibilty
  The reason why many of the protection systems out there are incompatible
and
  unstable is the anti debugging code they use. Anti debugging code is
  the most system based code that exists. To stop advanced debuggers,
  you need to have a good knowledge about the different CPU's, memory
  managers and so on... that exist, because they might crash as well by
  the anti debugging code you just invented.
  Which means, if you invent new anti debugging code, do the following :
   - Make sure it runs on every memory manager and operation system you've
     installed on your computer
   - Let other people as well test it on their machines (IRC...)
   - Make sure you know 100% what the anti debugging code does and why
     the debugger can't trace it
  It is of course very sad, that the different CPU's... react different
  in many things, so that you can never be sure that your program works
  everywhere if it uses tricky code. That's why many protector author
  got sick of it and stopped the developement of their protector because
they
  simply cannot hear bug reports like "doesn't work here" and
  "doesn't work there" any longer.
  Remember : If you are not sure that your anti debugging code is *very*
  compatible, don't use it!
   Ŀ
    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)        
ͼ

Realmode debugger trace using the trap flag which causes an INT1 after every
single instruction. So, if we would modify the INT1 pointer at 0000:0004,
we could crash rm debuggers - if they don't use their own IDT like CUP386
/1.
Crashs : TD, IUP, TR INT1, DEBUG...

        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    
ͼ

Nearly all realmode tracer use a "PUSH/POP" instruction in their INT1
handler,
which modifies SS:SP. If we now let SS point to an invalid area we would
make
these instructions crash the tracer when the INT1 eccours.
The best example can be shown with these two instructions :
Mov Sp, 3
Push Eax
The computer will now crash because of a stack underflow because the "PUSH"
instruction tries to write to an overlapped area (SS:0003).
The reason why we should always better clear the interrupt flag with "CLI"
before doing stack modifications like the one below is that interrupts might
also "PUSH" in our invalid area - and as you might know, the timer interrupt
eccours pretty often if "STI" is set, which means that our stack-modify
could also crash the computer without a debugger beeing tracing in the
background.

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 2     
  by Christoph Gabler    
ͼ

This stack trick is able to detect all debuggers which trace step by step
and use a "PUSH" instruction in the eccouring unpacking handler.
If at least one byte gets pushed onto the stack it will modify our "0FFFFh"
string we put to the current stack pointer and we are able to detect the
debugger.

Cli               ; Important, now no hw ints will eccour anymore
Mov Bx, Sp
Mov SS:word ptr [BX-2], -1   ; Write "0FFFFh" onto stack
Cmp SS:word ptr [BX-2], -1   ; Check if still there or if a "PUSH" eccoured
Jne $                        ; If so, a debugger is in background
Sti               ; Turn hw ints back on
ͷ
  Nice stack-trick 3     
  by Christoph Gabler    
ͼ

The last nice possibility to use the stack to crash INT1 tracing, points the
stack to CS:IP+2 in order that neccassary instructions get modified with the
"PUSH" in the INT1 handler.
Please remember that in .EXE files SS is not equel to CS, so that you need
to
modify SS either.

Cli                    ; Turn hw ints off
Mov Dx, Sp             ; Save SP
Mov Sp, offset $+4     ; Point SS:SP to CS:IP+2
Jmp $+4                ; Jump if CS:IP not changes (pushed)
db 0EAh, 0EAh          ; Otherwise crash tru crap instructions
Mov Sp, Dx             ; Restore SP
Sti                    ; Turn hw ints on

Very common method to detect realmode tracers - often found in protectors.
It stops: Debug, Turbo Debug, 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.
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_Dump_If_Found ;)

MOV CX,9000h                 ; Fake the entrypoint 9000h times.
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.
This time JMP method used.

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:WORD PTR [100h],0E2FFh; Write the jump command to 100h.
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.
ͷ
 Change CodeSegement Trick   
 by Hit-BBS Programmers Crew 
ͼ

A very interesting but also dangerous trick was used in BinLock 1.0 by
the Hit-BBS Programmers Crew in 1994. They simply moved all the .COM image
code into another segment area. Always to 4100h:100h, instead of leaving it
at the current CS:100h. A very effective trick because I don't know any
debugger which is able to find the right entrypoint because they expect
the code to be at CS:...! The problem is that I think this is also very
dangerous because a few thousand KB of main memory is simply not used, which
might cause trouble with some programs and then might there also be drivers
or other resident progs in these areas because they weren't reserved at the
execution entry of the .COM file.
Stops automatic unpacking with : CRKCOM, DUMPCOM, LTR, CUP386...
Manual unpacking is still easy of course.

Mov Ax, 4100h   ; The value they used, I would use CS+10h or something...!?
Mov Es, Ax
Mov Si, Offset COM_FILE  ; Should be 100h if you used in a .COM protector
Mov Di, 100h             ; Must be 100h, because offsets are wrong otherwise
Mov Cx, END_COM_FILE - COM_FILE
REPZ
MOVSB                    ; Move CX bytes from DS:SI to ES:DI
Mov Bx, Offset COM_FILE
Mov Cx, END_COM_FILE - COM_FILE
ClearMem:
Mov DS:byte ptr [Bx], 00 ; Wipe the old .COM data from memory
Inc Bx
Loop ClearMem
Xor Si, Si
Xor Di, Di
Mov Cx, 00FFh
REPZ
MOVSB                    ; Move CX bytes from DS:SI to ES:DI
CLI
Push Ax Ax               ; 4100h=DS=ES=SS=CS
Pop Ds Ss                ;
MOV SP, -12h             ; Resize stack
STI
; The PSP should also be set to the 4100h... (not done yet)
Push Ax                  ; Push CS
Mov Si, 100h
Push Si                  ; Push IP
RetF                     ; Jump to AX:SI (4100h:100h)
COM_FILE:
Nop                      ; Example .COM file.
Nop                      ;
Mov Ax, 4C00h            ; INT 20h would crash, still buggy! :)
Int 21h                  ;
END_COM_FILE:
ͷ
 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 - because it uses it's own interrupt
table.

PUSH ES                    ; Save ES
CLI
Xor Ax, Ax
Mov Es, Ax                 ; Point to 0000
Neg Es:word ptr [1*4]      ; 4*INT1 = Adress of INT1
Neg Es:word ptr [3*4]      ; 4*INT3 = Adress of INT3
Neg Es:word ptr [1*4]      ; Restore INT1
Neg Es:word ptr [3*4]      ; Restore INT3
STI
POP ES                     ; Restore 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 too. ;)
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 tracing. Of course only useful 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 #1 
 by Rose             
ͼ

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.
Rose showed us his 'famous' nebelbombs everywhere in HS, how do they
actually
look like?

; Small Nebelbomb
mov ax,03EBh
jmp short $-2               ; Jump into "0EBh, 03h"
db 0EAh                     ; Irritation opcode
; Medium Nebelbomb
push bx                     ; Save BX
mov bx,04EBh
pop bx                      ; Restore BX
jmp short $-3               ; Jumps straight into the "0EBh, 04h" jump
db 9Ah                      ; Irritation opcode
; Large Nebelbomb
push dx                     ; Save DX
mov dx,05EBh
pop dx                      ; Restore DX
jmp short $-3               ; Jump into "0EBh, 06h"
db 66h,069h                 ; 8 byte opcode irritation
ͷ
 Irritation macro #2 
 by Christoph Gabler 
ͼ

For better demonstration of when to use irritation macros like the
ones found above. The best thing you can put them into are decryption loops
or antidebugging code. They make the code a little bit noughtier and worse
to read.
Example decryptor follows.

; Pretty fucked up to follow. Better debug it to get out what it looks like.
DECRYPTION:
JMP OVER_1
DB 0EAh                         ; 5 byte opcode irritation
OVER_1:
Add CS:byte ptr [Bx], 99h       ; Do decryption command
JMP OVER_2
db 66h,069h                     ; 8 byte opcode irritation
OVER_2:
CALL OVER_3
Xor CS:byte ptr [Bx], 88h       ; Do decryption command
CALL OVER_4
JMP OVER_6
DB 0EAh                         ; 5 byte opcode irritation
OVER_4:
RET
OVER_6:
Sub CS:byte ptr [Bx], 77h       ; Do decryption command
JMP OVER_5
DB 00,00,0EAh                   ; 5 byte opcode irritation
OVER_3:
RET
DB 00,00,00,09Ah                ; 5 byte opcode irritation
OVER_5:
LOOP DECRYPTION
ͷ
 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
   Ŀ
    PMode Debugger/Interpreter AntiDebugging 
   
These kind of debuggers/unpackers use nonstandard ways in order to trace.
Mostly hardware breakpoints (DRx) are used to set breakpoint in order to
trace the program. This method works as follows :
(1) DR7 is used as Control Debug Register for the condition like 'on memory
    area read/write' or 'on execution'...
(2) If a condition is true, the debugger will gain back control over
    INT1 -> breakpoint.
(3) One of the debugregisters DR0 till DR4 is used to contain the linear
    adress of the place where the INT1 should eccour.
Example debuggers : DG, CUP386 /3, GTR
Avoiding of this tracing method is pretty easy :
(1) Clearing of DR0-7
(2) Pointing INT1 to another area
But, debbugger authors are pretty intelligent ;) and know how to make these
things worthless by using own INT-tables (redirection) and emulating
certain mnomenics like DRx instructions, flaggs...
The other possibility of debugging in a nonstandard way is the interpreting
method :
No breakpoints are used, the program is simply red into memory and then
emulated there. The debugger which use interpreting as tracing have full
control over the program. The problem is, that every instruction has to be
emulated like DRx actions.
Examples : TR, LTR, CUP386 /7
Methods of detecting/crashing interpreting deuggers :
(1) Finding wrong emulations and using these for antidebugging
(2) Playing with hardware breakpoints, because some can't emulate them
Btw, DRx debuggers often trace in protected mode and can only run from
realmode. If a debugger emulates realmode but is in reality in pmode then
we can easily use priviliged instructions in order to crash the debugger.
Simply jump over these instructions when already in V86, pmode like under
EMM386, QEMM.
ͷ
 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.
Yeah, INT's again and again, what's about these patched versions of Winice
which are immune against such tricks? Would anybody send me some NON-INT
detections of SICE or WINICE, please?

; 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

Another INT related detection, this time a backdoor command using int3.

Call SICE_Catch
Iret
SICE_Catch: Pop Dx       ; DX=delta offset to "IRET"
Push DS
Push Cs                  ; DS=CS
Pop Ds
Mov Ax, 2503h
Int 21h                  ; INT3 points to "IRET"
Mov Ah, 4
Mov Ebp, 4243484bh
Int 3                    ; Backdoor cmd
Cmp Ah, 4                ; If AH changed, SICE in background
Je  Ok_SICE
Jmp $                    ; Crash SICE
Ok_SICE: Pop DS
ͷ
 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                 ; Opcode 66h
CLI
STI
ͷ
 Overflow trick #1   
 by Christoph Gabler 
ͼ

Interesting and strange at the same time is the following trick.
It behaves completely different if executed in realmode or in v86 mode.
CMPSD increases DI by 4, but what happens if DI has already reached the
largest value 0FFFFh? An INT 0Dh is caused, or atleast only in realmode.
EMM managers like EMM386 and QEMM will halt the system because they fear
a general protection fault.
GTR, LTR... execute INTD also if we are in realmode.

MOV DI, -1        ; Can also be set to -2 or -3 of course. ;)
CWD               ; Increase, not decrease
CMPSD
ͷ
 Overflow trick #2   
 by Christoph Gabler 
ͼ

Here comes a little demonstration of the trick we discussed before, using
another way to overflow the valid segment range. Using the more simple way
with "MOV".
This trick will detect every debugger/unpacker operating in realmode because
debugger which use/simulate V86 mode simply jump over the routine because
it isn't compatible to V86 mode at all.

Smsw Ax                ; Check if CPU in realmode or not.
Test Al,1
Jne  Not_Realmode
Mov Dx, Offset Hooked
Mov Ax, 250Dh
Int 21h
Mov Di, -1                 ; DI must be 0FFFFh
Mov Ax, CS:word ptr [Di]   ; Will cause a INT0D if in realmode.
Cmp Di, 1234h              ; If not DI=1234h, no INT0D eccoured.
Jne $                      ; Crash system, debugger found.
Not_Realmode:
; Further code....
Int 20h
Hooked:
Pop Dx
Add Dx, 3
Push Dx
Mov Di, 1234h
IRet
ͷ
 Commandline trick #1 
 by Christoph Gabler  
ͼ

We can use the faulty commandline presets of a few debuggers to detect
tracing. Btw, test this piece of code under every OS before using it!
Detects: CUP386 /1 /3 /7, IUP and more

Cmp DS:byte ptr [80h], 01h   ; Cmdline might be *spacebar/return* key, so,
Je Ok                        ; avoid wrong detection.
Cmp DS:byte ptr [82h], 0Dh   ; Check for possible fault.
Jne Ok
Jmp $                        ; -> Debugger is running in background.
Ok:
ͷ
 Commandline trick #2 
 by Christoph Gabler  
ͼ

LTR 1.0 uses another fault in the commandline. This one will detect LTR
if no additional syntax was used.

Cmp DS:word ptr [80h], 2001h
Jne Not_LTR
Mov DS:word ptr [82h], 000Dh
Jne Not_LTR
Jmp $                            ; LTR is now detected, crash it.
Not_LTR:
ͷ
 Timer exception trick #1 
 by unknown               
ͼ

Old trick found in HS, CS, Mess, Ciphator and many other protectors...
Useful against lame interpreters. But TR and LTR can emulate it without
problems.

Push Ds                            ; Save DS
Push 0000
Pop Ds                             ; Point to 0000
Mov Ax, DS:word ptr [046Ch]        ; Store the current timer value
TimeTrick:
Cmp DS:word ptr [046Ch], Ax        ; Compare till changed by timer (int8)
Je TimeTrick                       ; Produces endless jumps if not emulated.
Pop Ds                             ; Restore DS
ͷ
 Timer exception trick #2 
 by Dark Angel            
ͼ

Another funny trick which is also very often used in many protectors I
discovered is Dark Angel's lame so called "Overlap trick" which can also
be found in the RADFAQ. The only thing that is done by these crappy bytes
is explained below:

; Original overlap trick :
Mov Cx, 09EBh               ; W
Mov Ax, 0FE05h              ; A
Jmp $-2                     ; S  of bytes. :)
Add Ah, 03Bh                ; T
Jmp $-10                    ; E
; The trick does nothing else then :
Sti                         ; If the interrupt flag is set, the CPU will
lock
Hlt                         ; Do the exception trick. :)
ͷ
 Timer exception trick #3 
 by Christoph Gabler      
ͼ

Similar but a little bit naughtier then the timer tricks above is the
following routine which is also an old idea.
Instead of waiting for int8 modifying the timer value, this trick hooks
int8 and waits till our hooked interrupt eccours and jumps over the
endless loop.

Push Ds Es                 ; Save segment regs for later
Cli                        ; Turn of int8 eccourance...
Mov Ax, 3508h
Int 21h                    ; Get old int8 and save for later
Push Es Bx
Mov CS:word ptr [CallFar+1], Bx  ; Write to CallFar, for hook
Mov CS:word ptr [CallFar+3], Es  ; Write to CallFar, for hook
Mov Dx, Offset int8new
Mov Ax, 2508h
Int 21h                    ; Set hooked int8 vector
sti                        ; Turn int8 on now
jmp $                      ; Endless jump till int8 eccours
okint8:                    ; Should continue here if int8 eccoured
cli
Pop Dx Ds
Mov Ax, 2508h
Int 21h                    ; Set old int8
Pop Es Ds                  ; Restore segment regs
; further code ...
Int 20h
; new int8 handler, must be placed out of code range
int8new:
Cmp CS:byte ptr [int8already], 1  ; Check if alreay int8 eccoured
Je donormalint8                   ; for extra crash prevention
Mov CS:byte ptr [int8already], 1
Pop Ax                            ; Get IP return adress
Mov Ax, Offset okint8             ; Fix IP return
Push Ax                           ; Onto stack
donormalint8:
PushF
CallFar: db 09Ah,0,0,0,0          ; Call old int8
Iret                              ; Back to caller
int8already db 00
ͷ
 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, protected mode or
the operation system Windows 3.xx/95/98/NT.

; 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.
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,1je Protected_Mode_Found
; V86 (Windows 3.x and Windows 95) detection by Christoph Gabler.
mov eax,cr0cmp ax,0000            ; CPU is in Virtual 8086 mode if CR0 is
0000.
je V86_Mode_Found
; Windows Detection detection by Christoph Gabler.
Mov Ebx, 12341234h     ; Value doesn't matter.
Mov Ebx, Edx
Mov Edx, Dr7           ; DR7 and DR6 are not readable under Windows
Cmp Edx, Ebx           ; if we aren't in dpmi pm.
Je Windows_Found       ; Edx wasn't changed.
; Windows Detection detection by unknown
mov ax, 01600h
int 02fh               ; Check if Windows present.
or  al,al
jne Windows_Found
ͷ
 Opcode Trick against TR 1.xx 
 by Szaszi                    
ͼ

TR 1.97 wasn't able to emulate the 32 bit opcode when 8 bit instructions
followed and crashed, since 1.98, TR is able to emulate them also, but, here
comes another TR bug for every version since now.

DB 66h            ; 32 bit opcode
PUSH FS           ; Works with PUSH FS/GS, POP FS/GS
DB 66h            ; 32 bit opcode
POP FS            ; Works with PUSH FS/GS, POP FS/GS
ͷ
 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
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+
ͷ
 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 files or TEU.COM? 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  Load module memory size in 32 bit
DX     Set to DS  (EDX is CPU dependent)
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                  
ͼ

I already wrote about the debug registers (DRx) above, describing the
hardwarebreakpoint tracing method. The following small section will
introduce both control- and debug registers and their functions.

(1) - The following "enhanced" 32 Bit registers exist :
   [CRx] Control Registers
   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 place 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) - 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.DF   =  Better usage now and nice tracing engine.
                 Clever HW breakpoint tracing method in protected mode and
                 is trying to claim that we are in RM. ;)
   IceUnp     =  Very strong IUP rip, using the TF, yes the TF!
                 Own stack, INT1/3 emulation, DRx tracing.
   TR 2.03    =  Interpreter with the best usage, no DRx hardware brkpoint
                 emulating. 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 I    =  Uses the Windows dpmi functions for gaining access of hw
                 breakpoints. Very strong.
   EDUMP II   =  Same method as EDUMP I, small changes like other working
API
                 then INT3 & magic EBP.
   LTR 1.0    =  Mighty interpreter, full DRx hardware breakpoint
possibility.
                 Only a few bugs left and no PM instr. interpreting.
    Ŀ
     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.
ͷ
 UPC/XPACK -UX FakeCode  
 By Christophe M. Vallat 
ͼ

This time fakecode against UPC and XPack's "UltraFileExpander" with the
switch -UX. Thanx to Iosco for sending this nice routine some time ago.
Also visit Christophe M. Vallat's homepage at www.mygale.org/10/miodrag

        push ds
        pop ax
        mov ah,30h
        int 21h
        jmp short skip
                db 8Bh,5Eh,04h,82h,37h,00h
                mov     ax,4C01h
                int     21h                     ; Exit with Errorlevel=01
                push    es
                pop     ds
                push    ss
                pop     es
                mov     si,080h
                cld                             ; Clear direction
                lodsb                           ; String [si] to al
                xor     ah,ah
                mov     cx,0CD2h
                mov     di,2000h
skip:

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! 
                              
 The following section includes some interesting sources.
   I hope they'll help you out. Greetings to everyone reading. :)
ͷ
 AntiRM Debugging trick  
 by Christoph Gabler (C) 
ͼ

There is no RM Debugger which is able to bypass this.

MOV CX,1234h
DECRYPTOR_LOOP:
MOV AX,SP
PUSH CX
POP SP
MOV SP,AX
LOOP DECRYPTOR_LOOP
ͷ
 TR 1.97 & CUP386 /7 detection routine!    
 by Christoph Gabler                       
ͼ

Here is a nice routine to detect TR 1.97! With my famous 32B method. =8]

; [-]  Anti TR 1.97  [-]
.386p           ; Get priviliged 386 support.
cli             ; Nonsense but wastes space! =8]
mov ebx,fs      ; Save FS
mov eax,10000h  ; 10001 would be FS=1
mov fs,eax
mov eax,fs      ; Write it quickly back.
mov fs,ebx      ; Restore FS
cmp eax,10000h  ; FS and GS can only be fulled with 4 byte large values!
je FUCK_TR      ; Found TR let's kick his ass.
sti
jmp NO_TR_THERE
FUCK_TR:
Cli
Jmp $
NO_TR_THERE:
ͷ
 CUP386 3.x /3 detection!      
 by Christoph Gabler           
ͼ

A nice routine to detect CUP386 /3.

.386p           ; Activate 32 Bit registers
; [-]  Anti CUP386 /3  [-]
mov ecx,500h    ; Prepare EBX
mov ebx,dr7     ; Save DR7 to EAX
mov dr7,ecx     ; Clear DR7
mov eax,dr7     ; Write DR7 back to EDX
cmp eax,400h    ; If EAX is 400h CUP386 /3 is tracing.
je DIE_CUP      ; Hehe.
mov dr7,ebx     ; Restore DR7
jmp I_M_FREE
DIE_CUP:
Cli
Jmp $
I_M_FREE:
ͷ
 GTR 1.90 Detection!      
 by Christoph Gabler      
ͼ

And here is the famous anti GTR routine. I'm not using a hangup like
db 0FFFFh or JMP $ this time because there might be problems on some
systems,
so I'm using a method to make GTR display an error message which is still
compatible to the CPU.

; [-]  Anti GTR 1.90  [-]
.386p
xor edx,edx
AgainGTR1:
add edx,+1
mov eax,0100h
mov ebx,dr5
mov dr5,eax
mov ecx,dr5
mov dr5,ebx
cmp ecx,0400h    ; GTR, are you out there?
jne GTR_OK1
mov ecx,cr0
cmp ecx,11h      ; GTR, are you really tracing??
jne GTR_OK1
mov ecx,dr7
cmp ecx,400h     ; REALLY?
jne GTR_OK1
mov ecx,2000h
mov dr5,ecx      ; Ok, we found him, now kick him with DR5=2000h
mov dr5,ebx
GTR_OK1:
cmp edx,0010h
jne AgainGTR1
ͷ
 Deglucker Detection 
 by Christoph Gabler 
ͼ

And another nice detection. This time to find DG.

; New Anti Deglucker Routine!
; Realmode detection by ELiCZ.
SMSW AX                ; Get Machine Status Word and store in AX.
TEST AL,1
JE  OK_RM2             ; Jump if CPU in Real Mode.
; Check for WiNDOWS
Mov Ax, 0160Ah
Int 02Fh
Or  Ax, Ax
Je  OK_RM2      ; Windows found...
Mov Eax, Cr0    ; HW brkpoint fault
Cmp Eax,0
Jne OK_RM2
Mov Eax, 100h
Mov Dr7, Eax
Mov Eax, Dr5    ;
Mov Ebx, Dr7    ; DR5 redirects DR7, which means, always DR5=DR7
Cmp Eax, Ebx    ;
Jne DG_DETECTED ; Crash Deglucker now.
Xor Eax, Eax
Mov Dr7, Eax
OK_RM2:
ͷ
 TR 1.97 CrashUp!     
 by Christoph Gabler  
ͼ

The following lines are to crash TR 1.97. As you have maybe already
found out it crashs TR with the opcode '66h' and uses an Anti INT01
trick to get TR 1.97 with 'TT' (Int1).

; TR 1.97 - LOCKUP
CLI
MOV DX,SP         ; Save SP to BX
DB 66h,67h        ; Kicks TR 1.97
MOV SP,03h        ; Kicks TR 1.97 with INT 01 (Is automatically traced!)
XOR DI,DI
MOV SP,DX         ; Restore SP
STI
ͷ
 EXE/COM Fake Entry point!   
 by Christoph Gabler         
ͼ

Against CUP386 /1, /3 and /7 for both EXE and COM files and against DECAY05.
Including a INT10h kill routine and restore.

; Corrupt INT10 so CUP and DECAY will crash if they find an entrypoint.
pUSH dS
xor ax,ax
mov ds,ax
mov bx,ds:word ptr [0040h]
push bx
mov bx,ds:word ptr [0042h]
push bx
mov ds:word ptr [0040h],0FFFFh
mov ds:word ptr [0042h],0FFFFh
; FAKE - ENTRYPOiNT
MOV CX,100h                  ; Fake the entrypoint 100h 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_ENTRY1:
CALL AX                      ; Call 100h.
LOOP FAKE_ENTRY1
MOV CS:BYTE PTR [100h],DL    ; Restore the byte we overwrote before.
; [EXE] ENTRYPOiNT FAKE
pUSH ES
Push Ds
Pop Es
Mov Bx,100h
Mov Dl,Es:byte ptr [BX]
Mov Es:byte ptr [BX],0CBh
CLI
Call $+3
Pop Ax
Add Ax, GO_ON_TRICK - $ + 1
Push Cs ; Return CS
Push Ax ; Return IP
Push Es ; Call CS
Push Bx ; Call IP
STI
RETF
GO_ON_TRICK:
Mov Es:byte ptr [BX],dL
pOP ES
; Restore INT10h.
pop ax
pop bx
mov ds:word ptr [0040h],bx
mov ds:word ptr [0042h],ax
pop ds
ͷ
 Tight and nice CUP386 detection  
 by Christoph Gabler              
ͼ

This routine is able to detect CUP386 /1, /3 and /7 !
Based on CUP's always FS=GS=CS.

PUSH 0000
POP [FS:0004]
CMP Cs:Word ptr [04],0000
JE CUP_FOUND
ͷ
 Anti LTR trick      
 by Christoph Gabler 
ͼ

Funny trick against LTR, 'cause LTR does not clear the cmd line and so we
can detect it if no syntax was entered.
The Anti LTR tricks found in TRAP 1.24 will not be released to the public
because I have no reason to give everything away. ;)

; Anti LTR - Syntax Trick
Mov Ax, DS:word ptr [80h]
Cmp Ax, 2001h
Jne Over_Lame
Mov Ax, DS:word ptr [82h]
Cmp Ax, 000Dh
Jne Over_Lame
Jmp $
Over_Lame:
ͷ
 TR 1.xx LockUp routine!  
 by Christoph Gabler      
ͼ

Against TR 2.52 and lower/higher. TR will simply crash if it traces this.
Important: 4 bytes are pushed/poped from the stack if the prefix was used.

db 66h         ; 32bit prefix for TR irritation.
Push FS        ; Will cause to push 4 byte from stack.
db 66h         ; 32bit prefix for TR irritation.
Pop FS         ; Will cause to pop 4 byte from stack.
ͷ
 Detect *EVERY* debugger! 
 idea by Ady              
ͼ

Detects the following: INT1 debugger (CUP386 /1, CV, IUP....), HW Breakpoint
debugger (CUP386 /3, DG, GTR 1.C1...), Interpreter (LTR, TR...)
only CUP386 /7 is able to bypass this!
The problem is that this routine is a little bit strange and should be
tested before usage because it uses some unfair/unclean methods to detect
tracing.
It uses a Pentium compatible prefetch trick which is very strong but might
be also incompatible to some excotic computers.

Mov Ax, 1234h                 ; Prefetch clearing (not able to be first
instr)
Xor CS:byte ptr [Here+1], 93h ; Do prefetch trick
Here: Mov Ax, 4321h           ; Modified or not, this is the question. ;)
Cmp Ax, 4321h                 ; If modified, than crash the CPU.
Jne DETECTED
--------------------------------------------------------------------
That's it - I'm too lazy to include more. Hope you found anything
interesting.
If not I'm sorry. :)
If you use any of the Uncovered tricks you'll have to credit me in your
protector. If you got any further questions or whatever I'll be glad to
try to help you out : It is never a waste of time to help a friend.
Btw, the other tricks that are used by TRAP will not get released to the
public.
With best regards, Christoph in 1999
Email to : ChristophG1@Hotmail.Com
--------------------------------------------------------------------
(C)opright by Christoph Gabler between 1998 and 1999
Routines are licensed for free usage





    ---------------------------------------------------------------------
                   Name: ilucry19.zip
   ilucry19.zip    Type: Zip Compressed Data (application/x-zip-compressed)
               Encoding: base64
