From dse@pacific.net Sun Aug 21 16:22:28 1994 Newsgroups: alt.lang.asm From: dse@pacific.net (DSE Software) Subject: Anti-Anti-Debugging Code Organization: Pacific Internet Date: Sun, 21 Aug 1994 04:00:35 GMT -> Anybody can tell me how to do a good anti-debugging routine -> for protecting my asm programs from curious eyes? Also, -> how can I fool Sourcer? ;; ;; Note by Uwe E. Schirm: ;; This refers to the 'Anti Debugging Tricks' by Inbar Raz ;; which is also found in the 80XXX Snippets as ANTIDBG.TXT ;; Sun 24 Jan 93 By: Michael Forrest Hi. Here's release 1 of the Anti-Anti Debugging Tricks article. > In order to avoid tracing of a code, one usually disables the > interrupt via the 8259 Interrupt Controller, addressed by > read/write actions to port 21h. This is completely ineffective against Soft-ICE, which will still break in even when the KB interrupt is disabled. I've never seen a case where SI won't break into the code without your program actually reaching out and unplugging the keyboard. > Just as a side notice, the keyboard may be also disabled by > commanding the Programmable Peripheral Interface (PPI), port 61h. That code doesn't seem to do anything at all, even to debug. > This is quite an easy form of an anti-debugging trick. > All you have to do is simply replace the vectors of interrupts > debuggers use, or any other interrupt you will not be using or > expecting to occur. Any debugger that's worth anything these days works in a virtual machine. That means that it keeps a separate interrupt table for itself. If you try to get to it, you'll get a general protection fault and you'll crash when running under QEMM, Windows, OS/2, or any other protected mode system. > This method involves manipulations of the interrupt vectors, > mainly for proper activation of the algorithm. Such action, as > exampled, may be used to decrypt a code (see also 2.1), using > data stored ON the vectors. Again, debuggers keep separate interrupt tables for themselves. > This is a really nasty trick, and it should be used ONLY if you > are ABSOLUTELY sure that your programs needs no more debugging. It IS a really nasty trick against a real-mode debugger like Debug or something else available 5-10 years ago, but completely useless against Soft-ICE, TD386, or any other protected mode debugger. > This method simply retains the value of the clock counter, updated > by interrupt 08h, and waits in an infinite loop until the value > changes. This method is usefull only against RUN actions, not > TRACE/PROCEED ones. That'll defeat DEBUG and not much else. Any other debugger has a key that'll break into the code. At that point, one could go into trace mode or just replace the JZ 0109 with a series of NOP instructions. > This is a very nice technique, that works especially and only on > those who use Turbo Debugger or its kind. What you should do is > init a jump to a middle of an instruction, whereas the real address > actually contains another opcode. I'm not really sure what you're trying to accomplish here, but it doesn't do much. A simple "U CS:IP" or its equivalent in any other debugger will show the current instruction. Anyway, the code isn't correct. IN AL,21 IN AL,21h MOV AL,FF MOV AL,0ffh JMP 0108 JMP 108 MOV Byte Ptr [21E6],00 ---> MOV BYTE PTR [21e6h],0cdh INT 20 ---> db 20h You had an extra 00 in there. > This is a nice trick, effective against almost any real mode > debugger. What you should do is simply set the trace flag off > somewhere in your program, and check for it later. Isn't it sort of silly to be trying to defeat real-mode debuggers? That's sort of like putting locks on your back door to make sure nobody gets into your house while leaving the front door wide open. > This is a technique that causes a debugger to stop the execution > of a certain program. What you need to do is to put some INT 3 > instructions over the code, at random places, and any debugger > trying to run will stop there. Assembling a NOP over the int 3 will get rid of the break. Also, many debuggers (like Soft-ICE) can be set to not break on an INT 3. > This trick is based on the fact that debuggers don't usually use a > stack space of their own, but rather the user program's stack space. I'm not sure where you're getting this, but today's debuggers keep their own stack safely hidden away in a protected segment where your program can't corrupt it. This is also only effective against real-mode debuggers if you intend to run your entire routine with interrupts cleared, since most ISR's depend on your stack being there as well. > This is a nice way to fool Turbo Debugger's V8086 module (TD386). > It is based on the fact that TD386 does not use INT 00h to detect > division by zero. Did you actually try this? It doesn't seem to have much effect at all on TD386. Soft-ICE traces through it quite happily too. > Another way of messing TD386 is fooling it into an exception. > Unfortunately, this exception will also be generated under any > other program, running at V8086 mode. Yes, and in a debugger it's _really_ easy to change the code while you're tracing through it to jump right over the offending instruction. All that you've done is eliminated compatibility with a lot of systems. > The first category is simply a code, that has been encrypted, > and has been added a decryption routine. The trick here is that > when a debugger sets up a breakpoint, it simply places the opcode > CCh (INT 03h) in the desired address, and once that interrupt is > executed, the debugger regains control of things. ANY decent debugger these days will let you use hardware breakpoints which have nothing to do with INT 3 or any other instruction replacing existing code. They'll let you set breakpoints wherever you'd like without messing up encryption routines or self-modifying code. > This is an example of a self-tracing self-modifying code, > sometimes called 'The running line'. It was presented by Serge > Pachkovsky. This is really the only effective measure in this document. It defeated every debugger I tried except for Soft-ICE. Even under Soft-ICE it was hard to trace, since Soft-ICE has a quirk to it - it disables the trace flag after each instruction. It also includes fkey macros though, so once you realize what's going on, it's pretty easy to force it to turn the trap flag back on before it executes the next instruction. With a couple of additional macros, I had it set up to trace through the code like nothing unusual was happening, except of course that the code I was looking at kept changing, but that's another matter. I had to change the routine you included since it doesn't handle multi- byte instructions very well. * DSE Online! * The Home of PB/VISION & PB/WORKSHOP for PowerBASIC 3.0 -- /\/ Daniel P. Stasinski /\/ Voice: +1-707-459-4358 /\/ /\/ DSE Software Publishing /\/ FAX/BBS: +1-707-459-4484 /\/ /\/ Post Office Box 96 /\/ Email: dse@pacific.net /\/ /\/ Willits, CA 95490-0096 /\/ FidoNet: 1:125/123 /\/