40HEX_6_002 SEGMENT PUBLIC 'code' ORG 100H ASSUME CS:CODE,DS:CODE,SS:CODE,ES:CODE ;****************************************************************************** Concealment: Keep Your Code Hidden From Prying Eyes by Demogorgon/PHALCON/SKISM Recently, I have been experimenting with a few new programming techniques that should be of great interest to the virus writing community. It is always our top priority to keep our code out of the hands of lamers in order to prevent the dreaded 'text change' and above all, to cause the anti-virus community as much grief as possible. In order to do this, we must put a great deal of effort into concealing our code. That is the focus of this article. This file is divided into two parts. The first part is devoted to developing 'debug resistant' code, and the second part deals with defeating disassemblers. I will not cover encryption, because methods of encryption are commonly known and there is really not much further I can go with that. For a complete review of self encryption methods, take a look at Dark Angel's Funky Virus Writing Guide (number three, the one that hasn't been released yet.) Part_I: The debugger is NOT your friend The basic idea behind writing debug ressistant code is finding a way to make your code behave differently when it runs under a debugger. With a real mode debugger, this is simplicity itself. All that is necessary is a little knowledge of how a debugger works. A debugger, such as debug or TD traces through a program by setting handlers to int 1 and int 3. These are called after every instruction is executed. A virus that wishes to avoid being debugged can simply replace the handlers for these interrupts, and the results will be just about whatever you want. Here is some code to do this: eat_debug: push cs pop ds mov dx, offset eat_int mov ax,2501h int 21h mov al,03h int 21h ... ; rest of code eat_int: iret As you can see, this requires minimal space in your code, and is certainly worth the effort. You can experiment by placing something else at 'eat_int'. Another commonly used tactic is to disable the keyboard interrupt while certain parts of the code are being executed. This will surely keep lamers baffled, though a pro would recognize what was going on immediately. I am sure McAfee's programmer's scoff at code such as this. Also note that while this will defeat the average real mode debugger, any protected mode debugger will step through this as if it weren't there. Playing with interrupts will not help you when your program will be running in a virtual cpu anyway. One method I found which will work nicely against td386 is to throw in a hlt instruction. This will give TD an exception 13 error, and terminate the program. Anyone who is aware of this will just step over a hlt instruction, so therefore methods must be used to conceal its presence, or to make it a necessary part of the code. This will be covered in part II. Another trick you can play is to call int3 within your program. If someone tries to run your program under a debugger, it will stop each time int3 is called. It is possible to trace through it, but it will be annoying if there are many int3's thrown in. Part_2: Kill your disassembler No matter how well you mess up debuggers, your program is entirely at the mercy of a programmer armed with a good disassembler. Unless, of course, you use techniques that will confuse disassemblers. My favorite method for baffling them is to create code that overlaps. Overlapping code may seem a little bit too complicated for most of us at first, but with the knowledge of a few instruction hex translations, you too can make effective overlapping code without sacrificing too much code size. Overlapping code can get as complex as you would like, but this file will only deal with the simplest examples. eat_sr: mov ax,02EBh jmp $-2 ; huh? ... ; rest of code This may confuse you at first, but it is fairly simple. The first instruction moves a dummy value into ax. The second instruction jmps into the value that was just moved into ax. '02EB' translates into 'jmp $+2' (remember that words are stored in reverse). This jump goes past the first jmp, and continues on with the code. This will probably not be sufficient to defeat a good disassembler like Sourcer, but it does demonstrate the technique. The problem with this is that Sourcer may or may not just pick up the code after commenting out the 'jmp $-2'. It is difficult to predict how Sourcer will respond, and it usually depends on the bytes that appear directly after the jmp. To severely baffle Sourcer, it is necessary to do some stranger things. Take a look at this example. erp: mov ax,0FE05h jmp $-2h add ah,03Bh ... ; rest of code This code is quite a bit more useful than the previous listing. Let us simulate what would happen if we were to trace through this code, showing a hex dump at each step to clarify things. B8 05 FE EB FC 80 C4 3B mov ax,0FE05h ; ax=FE05h ^^ ^^ ^^ B8 05 FE EB FC 80 C4 3B jmp $-2 ; jmp into '05 FE' ^^ ^^ B8 05 FE EB FC 80 C4 3B add ax,0EBFEh ; 05 is 'add ax' ^^ ^^ ^^ B8 05 FE EB FC 80 C4 3B cld ; a dummy instruction ^^ B8 05 FE EB FC 80 C4 3B add ah,3Bh ; ax=2503h ^^ ^^ ^^ The add ah,03Bh is there simply to put the value 2503h into ax. By adding five bytes (as opposed to simply using 'mov ax,2503h') this code will confuse disassemblers pretty well. Even if the instructions are disassembled properly, the value of ax will not be known, so every int call after this point will not be commented properly, as long as you never move a value into ax. You can conceal the value from the disassembler by using 'add ax' or 'sub ax' whenever possible. If you examine this closely, you can see that any value can be put into ax. Two of the values can be changed to whatever you want, namely the FE in the first line, and the 3B in the last line. It is helpful to debug through this chunk of code to determine what values should be placed here in order to make ax what you would like it to be. Back to the subject of killing debuggers, it is very sneaky to hide something like a hlt instruction inside another instruction, such as a jmp. For example, take a look at this: glurb: mov cx,09EBh mov ax,0FE05h ;-\ jmp $-2 ; >--this should look familiar to you add ah,03Bh ;-/ jmp $-10 ... ; rest of code The three lines in the middle are a repeat of the previous example. The important part of this code is the first line and the 'jmp $-10'. What happens is, the jmp goes back into the 'mov cx' instruction. The '09EB' translates into 'jmp $+9'. This lands in the '$-10' part of the first jmp. The $-10 just happens to be stored as 0F4h, the hlt instruction. By making the hlt part of another instruction, it is not visible when it is being traced through by td386. It is also not possible to remove it without altering the code. The purpose of this article is not to supply code to be thrown into your own programs. The purpose is to get you to think about new ways to avoid having your code looked at and modified by others. The most important thing is to be original. It is pointless for you to simply duplicate this code, because anyone else who has read this file will already know what you are trying to do. code ENDS END concealment