
                    File Protectors Tutorial 1 - CryptCom
                       Written By Aphex Twin [Vandals]

This is the first of many tutorials  that I will write on the subject of exec-
utable  file deprotection,  I hope that someone finds  this useful and is able
to learn something from it,  I myself am still quite new  to this scene and as
I learn more, I'll pass along my knowledge.  In this first installment I'll be
covering CRYPTCOM by Nowhere Man of Nuke,  it's a bit of an oldie, but I think
that it's a good protector to start off  with due to its simplicity.  CRYPTCOM
can be found in the Nowhere Utilities 2.0,  search the various  virus sites on
the Web to find it, it shouldn't be too hard.  For these and future tutorials,
you'll need a couple of utilities they are: a debugger (SoftIce, Super Program
Trace , etc..),  for this tutorial DEBUG will work fine,  you'll need a binary
file editor (hex editor) (HexWorkshop,  XTGold, Hacker's View,  etc..) and fi-
nally  if you decide to write an  unprotector you'll need  a compiler (duh!!).

CRYPTCOM is a COM only protector, before we begin to operate on CRYPTCOM,  let
us go over some info on COM files.

COM files, have a maximum size of 65535 bytes (64KB), execution begins at off-
set CS:100, and it is limited to the use of only one segment thus the 64KB li-
mit (FFFF hex).  In case your wondering why  the execution of COM files begins
at CS:100,  it's because the area from CS:0 to CS:FF is reserved  for the PSP,
I won't go into the explanation of the PSP in this tutorial,  to get more info
on it consult HelpPC,  but it's not really important at this moment.  I try to
explain everything as best as I can,  please read everything carefully, in fu-
ture tutorials I'll be going at a faster pace, and I won't be repeating things
already explained in this tutorial.

CRYPTCOM works like many other COM cryptors and viruses, it replaced the first
three original bytes  with a jump to the end of the file where the protector's
code is located,  this is the area where all  the decryption instructions  and
debugger traps are usually located, CRYPTCOM just has a decryption routine and
thankfully  no debugger traps,  after it's finished executing  the protector's
appended code,  it restores the original three  bytes at the beginning  of the
file, returns back to the beginning of the file, and runs the original program
which is now decrypted. In these tutorials I'll be making references to a file
offset and a memory offset,  the file offset is a reference  to a location in-
side a file, a memory offset is a reference to a location in memory.

Lets now look at the complete CRYPTCOM routine:

CS:0100  E9????    JMP <Marker1>
CS:0103  ????      ............ \
CS:0105  ????      ............  > Just random bullshit
CS:0107  ????      ............ /

Marker1:
CS:????  BE0001    MOV SI,0100
CS:????  56        PUSH SI
CS:????  B9????    MOV CX,<number of bytes to decrypt>
CS:????  C704????  MOV [Word SI], <Original Byte 1 & 2>
CS:????  C64402??  MOV [Byte SI+0002], <Original Byte 3>

Marker2:
CS:????  8134????  XOR [Word SI], <Decryption Key>
CS:????  46        INC SI
CS:????  46        INC SI
CS:????  E2F8      Loop <Marker2>

CS:????  31F6      XOR SI,SI
CS:????  31C9      XOR CX,CX
CS:????  C3        RET


The (?)s  and (<>)s are  variables  that don't have constant  values  (they're
never the same),  print  the above  and go  into debug with a  test file  (ex:
DEBUG  test.com),  trace  through it  using the 'p'  option  (proceed) or  't'
(trace) the difference between trace and proceed is that trace will trace into
subroutines like INTs,  CALLs, REPs and LOOPs, most of the time you'll want to
use proceed.  Now lets go over each instruction step by step:

CS:0100  E9????    JMP <Marker1>

This is the first instruction,  it's at memory offset CS:100h and  file offset
01h, it takes up three bytes,  this instruction will force the program to jump
to the CRYPTCOM routine, later on, the memory offset of these three bytes will
be overwritten by the original three bytes.  The first byte (E9h) is constant,
the second and third byte point to the memory offset of  the CRYPTCOM routine,
the two bytes make up a word, what this means is that the two bytes have to be
reversed for you to understand them, if you make an unprotector,  don't forget
to use the right variables for the right job,  you can't use BYTE variables to
read and write variables which were meant to be read and written as a WORD and
likewise for using WORD variables instead of BYTE variables. Here's an example
of how the WORD works (nibble reversing):

CS:0100  E90802    JMP 030B

Where did the 030Bh come from?  Do the following, reverse byte 2 and 3, so in-
stead of having 0802h you have 0208h, now add 100h (remember,  COM files start
at CS:100h) and you've got 30Bh.

Continuing on, the JMP takes us inside the CRYPTCOM routine, let's look at the
following:

CS:????  BE0001    MOV SI,0100
CS:????  56        PUSH SI
CS:????  B9????    MOV CX,<number of bytes to decrypt>

There are 5 constant bytes (BE 00 01 56 B9),  you can use these bytes as a way
to detect if a file is protected by CRYPTCOM, in your program,  move your file
read/write pointer to the following  location: FileSize(File.com)-29, this po-
sition never changes, read the five bytes at this file offset into an array or
variables and compare them to the above five bytes,  if they match it's likely
the file has been  protected by CRYPTCOM.  Ok,  the first line above,  sets SI
(special pointer) to 100h (the address where the original bytes  will be writ-
ten to),  the second instruction 'pushes' the  SI address into the stack,  and
'activates it' (I don't know  how to explain this any better),  the third  in-
struction  moves the original file size to  CX (CX is a special  register used
for counting and looping operations),  it's in WORD format,  this is also  the
number of words which will be decrypted.  Example:

CS:030F  B90601    MOV CX,0106

This tells that there is going to be 106h words (20Ch bytes) to decrypt,  each
word contains two bytes.  The number  of words  to decrypt is  located at file
offset FileSize(File)-24, read it into a WORD variable.

Next we see:

CS:????  C704????  MOV [Word SI], <Original Byte 1 & 2>
CS:????  C64402??  MOV [Byte SI+0002], <Original Byte 3>

These  two instructions move the original  3 bytes to their original position,
the first instruction uses a word, we know that SI=0100h so the first instruc-
tion will write the two original bytes to memory offset 100h and 101h, the se-
cond instruction only writes one byte to memory offset SI+0002,  since SI=100,
SI=100+2, it'll  write the byte at 103h.  Byte 1 and 2 are located at the file
offset  filesize(file)-20  read  it  as  a word,  byte 3  is  at  file  offset
filesize(file)-15,  read it as a byte.   These three bytes that have just been
written  are the original bytes  from the program,  but they are still  in en-
crypted form. Ex:

CS:0312  C7049788  MOV [Word SI], 8897
CS:0316  C6440299  MOV [Byte SI+0002], 99

The old three bytes at memory offset CS:100h are now changed to 97 88 99.

Now we arrive at the most important part of the CRYPTCOM routine,  the decryp-
tion:

Marker2:
CS:????  8134????  XOR [Word SI], <Decryption Key>
CS:????  46        INC SI
CS:????  46        INC SI
CS:????  E2F8      Loop <Marker2>

The first line is the decryption instruction,  as we see here,  it uses XOR to
decrypt the word, XOR is regularly used in encryption schemes,  here it'll XOR
the word at the memory offset SI (SI=100h,  remember?) with a  special decryp-
tion  key  (another  word),  the  decryption  key is located  at  file  offset
filesize(file)-12, read it as a word, example of how XOR works:

SI=100
CS:100=97 88
XOR 8897, 8123 = 09B4   (B409, reversing nibbles)

8123h was the special decryption key,  8897 is the reversed  word that was  at
memory offset SI.

The following two INC SI,  will increment the  value (position) of SI,  so in-
stead of SI pointing to 100h,  it is now pointing to 102h.  The LOOP will make
the program return to the location  of Marker2 (the XOR instruction),  the XOR
now decrypts the word at memory offset 102h (the current value of SI),  and SI
is once again  incremented by two,  now, do you  remember the  MOV CX,???? in-
struction earlier on?   The variable CX holds  the number of  words to  be de-
crypted,  each time the LOOP instruction is executed,  the value of  CX is de-
cremented by one,  until CX equals 0,  the LOOP will keep returning to the XOR
to decrypt all the bytes, when CX=0 the program will continue on.  In your de-
bugger,  use the trace command and see how the loop works, keep looking at the
values  of the variables CX and SI,  you will see  them change,  after use the
proceed command to get out of the loop.

Once you are  out of the loop and  at the instruction XOR SI,SI,  the file has
been completely decrypted in memory.  The program is now ready to run the ori-
ginal program,  but first it's got to do  some clean up work,  that's what the
following two instructions do:

CS:????  31F6      XOR SI,SI
CS:????  31C9      XOR CX,CX

Whenever you see a XOR with the same parameters, the value will equal zero, so
XOR SI,SI, will write the value zero to the SI variable, same with the CX var-
iable, which should already be set at zero.

We finally arrive at the end:

CS:????  C3        RET

This is the last instruction  in the CRYPTCOM routine,  and tells the  program
to  return the  last position  saved on the stack,  remember the  instructions
MOV SI,0100  and PUSH SI, earlier on?  It saved  the position 0100h  into  the
stack, now the RET is retrieving that position.

After the RET is executed,  you will be at memory offset CS:100, and you'll be
at the beginning  of your original program,  if you wish,  you may now use the
DEBUG command 'w' to write the decrypted memory content to a file.

Well, that's it,  I hope this has been useful,  look out for future tutorials.

Lastly the greetings and thanks:

Megadevil (How's everything there in mainland Portugal?)
Scorch (Thanks for keeping me connected)
Morbid Mind (Thanks for lending me your CDs)
Extacy (Garbage rules the Azores demo scene)
All the dudes on the EXE mailing list
All the small cracking groups and independent crackers
Red Bull (The best damn drink in the world)

                 Peace Ya'll, say a prayer for today's youth...

                                               -- Aphex Twin [Vandals]

