Information of how to stop your programs from being hacked

---------------------------------------------------------------------------
This information is provided as is, and the author provides no form of
guarantee what so ever.
---------------------------------------------------------------------------
There is a better FAQ called RADFAQ. You can download it here or EMail:
****@*********.de. It is compiled by ROSE, the author of HACKSTOP. The
latest version I have is 1.02. Released 26 July 1996.

For FILE_ID.DIZ

ROSE's Anti-Debugger FAQ (rADFAQ) - All

anti-debugger tricks you can imagine.

Includes SRC and COM files too! Freeware

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

                          Overview and Objectives

This information is only really for advanced assembler programmers and it
makes the assumption that you are using one segment. It also uses 16 bit
memory addresses. All of the ideas are fundamental to this sort of
programming and could be easily adapted to other programming languages and
applications.

It's to help assembler programmers to protect their hard work from:-

   * Lamers placing their own names in your executable.
   * Crackers removing your password routines
   * Hackers removing / finding out program passwords

In other words, generally protecting your own hard work.
---------------------------------------------------------------------------

                        Rule 1 :- Encrypt your code

This will really foil any initial attempts to change the code with a simple
hex editor.
The only problem with this, is you have to write a program to encrypt your
compiled source.I.E.. You can't expect your program to modify itself and
write itself back to disk like a virus. This is because your program will
be stopped by virus checkers, because it has changed from the last time it
was executed.
A simple encryptor would be as follows :-

     .model tiny

     .RADIX  16

     .code

     org     0100

begin:

      Call Decrypt

Code_to_decrypt_Start:

Code_to_decrypt_End:

Encryption_Key: Db 0feh

Decrypt:

    Mov cx,Offset Code_to_decrpyt_End - Offset Code_to_decrypt_Start

    Mov bl,Byte ptr [Encryption_Key]

    Mov Si, 0100h                 ; The code entry point is cs:0100h

Loop_Decrypt:

    Add byte ptr [si],bl

    inc si

    Loop Loop_Decrypt

    Retn                          ; Finished carry on with program

end begin

You have to then write a program which uses the correct encryption
algorithm and key to encrypt the code.I.E. In the above example this will
need to subtract the encryption key from each byte.
The XOR command is very useful in this regard, because you can use the
identical algorithm for encryption and decryption; But it's ease of use it
perhaps it's downfall. Everybody will look for code in a program to XOR
<REG>, [WORD|BYTE] ptr [<REG>] in a little loop. So the message is get
creative. A particular Encryption / Decryption algorithm can be unique to
you.
---------------------------------------------------------------------------

                            Rule 2 :- Obscurity

Remember you want to confuse the would be hacker into giving up. Don't do
obvious things like calling documented and well known interrupts when there
are probably dozens of other methods of getting the same info. The idea of
an interrupt was to create a common platform for programmers to work off.
Many of them were documented, but many more were shrouded in mystery. Lots
of people have spend hours tracing such interrupts and they can be found in
interrupt listings on many common FTP archives. These interrupts are very
useful in the battle against hackers.
Other methods involve long methods of getting data which is always
constant. In other words instead of directly accessing a byte in memory,
you take a very long approach.
Everybody knows that the first word of the program segment prefix (PSP) is
020cdh, in reverse order lintel format. Use can use this to your advantage
in the following example.

Mov ax,0100h

Mov cx,0030h

add ax,cx

jmp short skip

GarbageBytes: db 012h,0fh,00,090h,021h

skip: Mov bx,Offset GarbageBytes      ; Point to the Garbage Table

      Mov al,03                       ; Point to db 00  which is

                                      ; at [GarbageBytes + AL]

      Xlat bx                         ; Replaces the byte AL with

                                      ; the byte from a user table

                                      ; addressed by BX. The

                                      ; original value of AL is the

                                      ; index into the translation

                                      ; table. The best way to

                                      ; describe this is

                                      ; Mov AL,[BX + AL]

      ; AL is now 00h

      mov AH,AL

      ;Ax is now 0000h

      XOR Word ptr [Next_Instruction],AX

      ; Does nothing since AX is 0000h

Next_Instruction:

Another thing regarding to obscurity is to pad your functional code with
lots of useless, but non-interfering instructions. Example :-

        Mov ax,0100h

        Mov bx,0200h

        Mov si,0300h

        Mov di, 0400h

        Mov cx,020h

        rep Lodsb

Could become

        Mov ax,0100h

        Mul bx

Nothing:Push si

        mul di

        pop dx

        Mov bx,0200h

        Mov cx, Byte ptr [Nothing]

        push ax

        mul cx

        pop ax

        Mov si,0300h

        nop

        cli

        std

        cld

        add di,ax

        add di, byte ptr [Nothing]

        "

        "

        "

        ;And so on .......

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

                     Rule 3 :- Anti - Debugging Tricks

This is a very large topic and will be covered by two subheadings. Namely
Interrupt replacement and self modifying code.

   * Self Modifying Code

Before a command is executed on the Intel processor, it is loaded into a
buffer called the Prefetch Instruction Queue (PIQ). This buffer ranges in
size from 15 to 64 bytes, depending on the power of the processor. This
buffer is designed to reduce the time the processor spends executing the
Fetch Process, by fetching more than one byte at a time. This means that
code in memory, less than 15 bytes in front of CP:IP, will not change when
executed, even if you change the bytes in physical memory.

        Mov word ptr [Dont_Change],01212h

Dont_Change: Nop ; This will still be executed as a NOP

When you run a debugger, and you Trace or Step through code, your PIQ will
always apparently be 0 bytes. So to make a debugger bomb out, all you have
to do is change the bytes a couple of instructions ahead and then wait for
disaster to strike, when the debugger encounters these changes.

This is a very useful feature of the Intel chip, but you need to remember
that the byte in memory has changed, the processor just does not know it
yet.

That is why, if you use Prefetch Instruction Queuing, as it is called, you
must replace the bytes after they are executed. Especially if it is in a
loop of some description. Insidently, Interrupt 3 will clear the PIQ
buffer.

Here is an example of PIQ in a loop:-

Mov cx,0100h

Looper: Mov word ptr [Change_This], 020cdh

        Lodsb

Changethis:stosb

        cmp al,020h

        je Anywhere

        Mov word ptr [Change_This],03CAAh

        Loop Looper

Anywhere:

   * Interrupt Replacement

The following on Interrupt replacement was cut from 40HEX Magazine. Volume
9 Article 004

1.1. Interrupt disable:

       Interrupt disable is probably the most common form of anti-debugging

     trick. It can be done in several ways:

   1.1.1. Hardware masking of interrupt:

            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. The 8259 Interrupt Controller controls the IRQ

          lines. This means that any IRQ between 0 and 7 may be disabled by

          this action. Bit 0 is IRQ0, bit 1 is IRQ1 etc. Since IRQ1 is the

          keyboard interrupt, you may disable the keyboard without the

          debugger being able to bypass it.

          Example:

          CS:0100 E421           IN     AL,21

          CS:0102 0C02           OR     AL,02

          CS:0104 E621           OUT    21,AL

            Just as a side notice, the keyboard may be also disabled by

          commanding the Programmable Perepheral Interface (PPI), port 61h.

          Example:

          CS:0100 E461           IN     AL,61

          CS:0102 0C80           OR     AL,80

          CS:0104 E661           OUT    61,AL

   1.1.2. Software masking of interrupt:

            This is quite an easy form of anti-debugging trick. All you have

          to do is simply replace the vectors of interrupts debuggers use/any

          other interrupt you will not be using or expecting to happen. Do not

          forget to restore the original vectors when you are finished.

          It is adviseable to use manual change of vector, as shown below,

          rather than to change it using interrupt 21h service 25h, because

          any debugger that has gained control of interrupt 21h may replace

          your vector with the debugger's. The example shows an interception

          of interrupt 03h - the breakpoint interrupt.

          Example:

          CS:0100 EB04           JMP    0106

          CS:0102 0000           ADD    [BX+SI],AL

          CS:0104 0000           ADD    [BX+SI],AL

          CS:0106 31C0           XOR    AX,AX

          CS:0108 8EC0           MOV    ES,AX

          CS:010A 268B1E0C00     MOV    BX,ES:[000C]

          CS:010F 891E0201       MOV    [0102],BX

          CS:0113 268B1E0E00     MOV    BX,ES:[000E]

          CS:0118 891E0401       MOV    [0104],BX

          CS:011C 26C7064C000000 MOV    Word Ptr ES:[000C],0000

          CS:0123 26C7064E000000 MOV    Word Ptr ES:[000E],0000

   1.1.3. Vector manipulation

            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. Ofcourse, during normal operation of the

          program, vectors 01h and 03h are not used, so unless you are trying

          to debug such a program, it works fine.

          Example:

          CS:0100 31C0           XOR    AX,AX

          CS:0102 8ED0           MOV    SS,AX

          CS:0104 BC0600         MOV    SP,0006

          CS:0107 8B0E0211       MOV    CX,[1102]

          CS:010B 50             PUSH   AX

          CS:010C 21C8           AND    AX,CX

          CS:010E 01C5           ADD    BP,AX

          CS:0110 58             POP    AX

          CS:0111 E2F8           LOOP   010B

   1.1.4. Interrupt replacement

            This is a really nasty trick, and it should be used ONLY if you

          are ABSOLUTELY sure that your programs needs no more debugging. What

          it does is simply copy the vectors of some interrupts you will be

          using, say 16h and 21h, onto the vectors of interrupt 01h and 03h,

          that do not occure during normal operation of the program. If the

          user wants to debug the program, he would have to search for every

          occurance of INT 01, and replace it with the appropriate INT

          instruction.

          Example:

          CS:0100 FA             CLI

          CS:0101 31C0           XOR    AX,AX

          CS:0103 8EC0           MOV    ES,AX

          CS:0105 26A18400       MOV    AX,ES:[0084]

          CS:0109 26A30400       MOV    ES:[0004],AX

          CS:010D 26A18600       MOV    AX,ES:[0086]

          CS:0111 26A30600       MOV    ES:[0006],AX

          CS:0115 B44C           MOV    AH,4C

          CS:0117 CD01           INT    01

---------------------------------------------------------------------------
There is a lot more you can do to prevent debugging, but in the end you
have to out-smart the hacker. For more information Watch this space! or
subscribe to lots of ASM newsgroups.
---------------------------------------------------------------------------
Return to Stewart Moss's Page
---------------------------------------------------------------------------
Intel is a registered trademark of the Intel corp.
              Stewart Moss <stewart.moss@saexpress.co.za> 1995
                       ------------------------------
