************************************************
************************************************

Unfortunately, this site has restricted functionality as this browser does not support the HTML button formaction attribute.

Unfortunately, this site has restricted functionality as this browser has HTML web storage turned off.

35973 of 48,116 files

    Download INSIDER8.FAQ

    Size 42 kB

  • Browsers may flag this download as unwanted or malicious. If unsure, scan it with VirusTotal.
  • Last modified Apr 29, 1999 11:00:00 PM
     MD5 checksum d36182ee7057a75f940b2773c121d71b
        Mime type ISO-8859 text, with CRLF line terminators

1999 April 29

[+] Configuration Copy text
½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½ »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»» ▄▄▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄▄ ▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄ █▄ ▄█ █ ▀██ █ █ ▄▄▄▄█ █▄ ▄█ █ ▄▄▄▀█ █ ▄▄▄▄█ █ ▄▄▄ █ █ ▄▄▄▄█ █ ▄▄▄ █ █ ▄▄▄ █ ▄█ █▄ █ █▄▀ █ █▄▄▄▄ █ ▄█ █▄ █ ███ █ █ ▄▄▄█▄ █ ▄▄ ▄█ █ ▄▄█ █ ▄▄▄ █ █ ██▀ █ █▄▄▄█ █▄█▀█▄█ █▄▄▄▄▄█ █▄▄▄█ █▄▄▄▄█▀ █▄▄▄▄▄█ █▄██▄▄█ █▄█ █▄█ █▄█ █▄▄▄▄▄▀ INSIDER - FAQ Edition #8 UnComplete by Christoph Gabler Release Date : 01.05.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 a nice email to [email protected]! ────────────────────────────┐ │ About Anti Debugging Code │ └──────────────────────────── Before I start listing anti debugging code against the different unpacking methods and debuggers, I would first like to introduce you 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) ║ ╚══════════════════════════════╝ »» 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 ║ ╚═════════════════════════╝ »» Corrupts the main stack pointer and restores it back again in order to crash nearly every single realmode debugger existing. »» 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. »» CLI 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. STI »» 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. 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. 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: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... Anyway, 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 - uses 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*1] ; Restore INT1 Neg Es:word ptr [3*1] ; 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 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 #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? Here come the most used macros found in HS. Btw, did anyone realize that Nebelbomb is a connection between the german word "Nebel" and the english word "bomb" because Rose doesn't know that "Nebel" is "fog" in english. ;) »» ; 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 inteligent ;) and know how to make these things worthless by using own INT-tables (redirection) and interpreting (emulating) DRx instructions. 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 ╓══════════════════════════╖ ║ 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? A 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 not additional syntax was entered. »» 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 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. :) ╓══════════════════════╖ ║ 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 unknown. 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 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? 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 ║ ╚══════════════════════════════════════╝ »» 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.C1 = Still unhandy in usage ;), but 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.25 = 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 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. Corrupts INT1/3 and unloads TBSCANX. »» 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. ╓═════════════════════════╖ ║ 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 the 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! │ ──────────────── ■ Unavailable, send a nice email to [email protected] in order to get the latest uncovered version of the INSIDER.FAQ! ■ If you have coded your own anti debugging 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 »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»» »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
95x1327 Font
95