
*** IMPORTANT ***
Disclaimer: Use this program at your own risc!

*** IMPORTANT TOO ***
The source is included in seperate files may be slightly different to
the source in this file. The source in this file is more vigurously commented


How to use this program:
I'm one lazy mofo so there is no user interface in this program - besides
it would be outta thread with the purpose of this program, I'll explain that 
later. So what you do it you take your .com file, put it in the directory
with comcrypt.exe renames it to input.com - then you run comcrypt.exe and
the output will be stored as output.com. Simple and annoying - I know!
Also remember this was'nt meant for actual use, it's not well suited for
anything but enlightenment and as the very basic for building your own 
comcrypter.

Why did I write this program:
Well because I wanted to educate myself, early in my programming I decieded
that you might aswell benefit from my "work". This changed the process a 
little - I decieded to make it as simple as possible to make it earsier for
a novice to understand. So sitting here after having done the program I
decieded that anyone that could read my source could also write his own 
anyways and that kinda defeated the educating you part of why. So this txt
file explaining everything real slowly was made in my boredom....

While I was sitting thinking about this program, I decieded that my rusty
pascal needed a brush up and pascal is easier to read than raw assembler
so I went for a pascal program!

Tech stuff:
So far so good, time for some technical stuff - if you already know how
to make com-encryptors, don't read this it would be a waste of time.

First I wanted to deciede on an decryption/encryption scheme. Since I already
decieded to keep it simple I choose the simplest scheme that came to mind.
This scheme is remarkably similar to the one I used when passing around love
notes in a distant past. The scheme is to exchange each letter with the next
in the alphabet - the computer equivalence is ofcouse to add 1 to each your
encrypting. Decrypting is then just subtracting one from each byte. Very simple
I think you'll have to agree on that!

Next I had to deciede on what kinda structure my encrypted com file should have.
The two restrictions on how to build it was: The first to run must be the
decryption routine. The second was that the decrypted code must start at 
the memory offset 100h. (where all .com files start naturally) The reason
why you just cannot put the code anywhere in the memory is that pointers
are absolute, not relative as jmps and calls. Placing the code anywhere but at
100h would fuck up all reading and writing data the program may do!
The 2nd made me wanna place the original code as close to the begining 
of the output program. The first would force me to place atleast some code
at the absolute beginning. So the structure chosen was something like this:

Offset       Code part
  100h       Jump to decryption algorith
 100h+Xh     The encrypted code - where X is the bytes spend on the jump part
 100h+Xh+Yh  Decryption - where Y is the bytes spend on the encrypted code
 ????h       A procedure to move the code back X bytes so it will start at 100h
 ????h       Jump back to 100h where the now-decrypted code is.

In order for me to add the code parts in the code of the output file I would
have to know what to add. So I the Jmp to the decryption algorith, 
the decryption algorithm, the move procedure and the jmp back to 100h in
assembler and assembled it with TASM 3.2 (UGH.. I should really consider
updating ehh?). The code looked like this:

mov ax, offset decryption          ; I would want a jmp that could point 
                                   ; to anywhere.
jmp ax                             ; this construction was my choice

encrypted_code_here:
mov ax,0000                        ; I need some bogus to pass as encrypted bytes
                                   ; This is of no importance.

decrypt:                           ; Decryption starts here!
mov bx, offset encrypted_code_here ; Let bx point to my encrypted stuff  (105h)
mov cx,04                          ; this moves the length of the encrypted
                                   ; the 4 part will be altered in our
                                   ; pascal code so it fits with the com
                                   ; file we're working on
xor ax,ax                          ; This is a left over from a crc I had going
                                   ; at a time - so ignore it!
loopme:
sub byte ptr cs:[bx],1             ; BX decrypt the byte that bx points to
inc bx                             ; move on to the next byte
loop loopme                        ; do it for a total of CX bytes
                                   ; Moving it all to 100h starts here
mov bx, offset encrypted_code_here ; Let bx point to the now decrypted code
mov cx, 04                         ; Same as last mov cx,4
loopme2:               
mov ax,[bx]                        ; fetch the now decrypted byte
mov word ptr[bx-5], ax             ; move it 5 spaces back - jmp part is 5 bytes 
                                   ; in total
loop loopme2                       ; do it for all bytes in the now decrypted code

mov ax,0100h                       ; now run the sucker like it was supposed to
jmp ax                             ; and action!

Compiling this and tearing it apart I found the bytes I need to add to my 
output file. 5 bytes to the start of the file (the jmp part) and 34 
bytes to the end doing the actual decryption. Our mov cx,04 should be 
mov length_of_the_com_file_were_encrypting and the mov ax, offset decryption
will be mov ax, length_of_the_com_file_were_encrypting +5h (the jmp header)
This we patch in our pascal program.

Excuse my rusty pascal - I hav'nt done anything over 20 lines in 2 years and
the pascal I learned was on VAX/VMS and it does things a little different than
Turbo Pascal. Not to mention.. I never had the need to use byte and word 
operators in pascal before. So basically the program is not, neet, nice and
efficient, but slow, ugly and working.


Program Stonescomcrypt;

var

i :  integer;
flaffer : byte;
infil : file of byte;
outfil : file of byte;
decryptor : array [1..40] of byte;
start     : array [1..5] of byte;
filelen   : word;

begin;
Writeln('ComCrypt (C) Stone 1996');
{Initial call to our decryption routine}
start[1]:=$b8;    {mov ax, 102 (2 get's changed to length of code+5 later}
start[2]:=$02;
start[3]:=$01;
start[4]:=$FF;    {jmp ax}
start[5]:=$E0;

{Decryption code}
decryptor[1]:=$0BB; {mov bx,105 (org 100 + 5 bytes for our jmp ax}
decryptor[2]:=$05;
decryptor[3]:=$01;
decryptor[4]:=$B9;  {mov cx,8 - 8 get's changed later to lenght of code}
decryptor[5]:=$08;
decryptor[6]:=$00;
decryptor[7]:=$33;  {xor ax,ax - not really neasesary left over from old code}
decryptor[8]:=$C0;
decryptor[9]:=$2E;   {sub byte ptr cs:[bx],1}
decryptor[10]:=$80;
decryptor[11]:=$2F;
decryptor[12]:=$01;
decryptor[13]:=$43;  {inc bx}
decryptor[14]:=$E2;  {loop last 2 instructions}
decryptor[15]:=$F9;

{move back the now-decrypted shit 5 bytes}
decryptor[16]:=$bb;     {mov bx,105 (org 100 + 5 bytes for our jmp ax)}
decryptor[17]:=$05;
decryptor[18]:=$01;
decryptor[19]:=$b9;     {mov cx,0025}
decryptor[20]:=$25;
decryptor[21]:=$00;
decryptor[22]:=$8b;     {mov ax,[bx]}
decryptor[23]:=$07;
decryptor[24]:=$89;     {mov word ptr[bx-5],ax}
decryptor[25]:=$47;
decryptor[26]:=$fb;
decryptor[27]:=$43;     {inc bx}
decryptor[28]:=$e2;     {loop last three instructions}
decryptor[29]:=$f8;

{jmp to the now decrypted code at 100h}
decryptor[30]:=$b8;      {mov ax,100}
decryptor[31]:=$00;
decryptor[32]:=$01;
decryptor[33]:=$ff;      {jmp ax}
decryptor[34]:=$e0;
{end decryption code}

{Init the files}
assign(infil, 'input.com');
reset(infil);
assign(outfil, 'output.com');
rewrite(outfil);
filelen:=0;

{Find filelength of infil}
filelen:=filesize(infil);


{see to it that mov cx,0008 becomes mov cx, lenght_of_code}
decryptor[5]:=(filelen mod $100);          {mov cx, length of code}
decryptor[6]:=(filelen div $100);

{see to it that our move it all back 5 bytes routine knows how long the code is}
decryptor[20]:=decryptor[5];      {mov cx, length of code}
decryptor[21]:=decryptor[6];

{See to it that the initial jmp get's the right length}
start[2]:=(filelen mod $100)+$5;   {mov ax, length of code+5}
start[3]:=(filelen div $100) +$1;          {^^^^^^^^^^^^^^^^}

{Write the initial mov ax and jmp - the new header}
for i:=1 to 5 do write(outfil,start[i]);

write('working ');
{encrypt and write it to the new file}
i:=0;
while not eof(infil) do begin;
inc(i);
if (i mod (filelen div 10)) = 0 then write('X'); {Does'nt matter just a stupid work bar}
read(infil, flaffer);    {fetch a byte to be encrypted}
flaffer:=flaffer+1;      {encrypt it}
write(outfil,flaffer);   {write the byte}
end;

{write our decryption routine to the end of this file}
FOR I:=1 TO 34 do write(outfil,decryptor[i]);

{clean up the mess, close the files!}
close(infil);
close(outfil);
end.

That's it and that's that!
Now as stated earlier - this code is simply to the maximum, no error checking
no user interface, no nothing. Any cracker with 3 mins of time could decrypt
this no problem! But changing the encryption algorithm to something powerful,
adding antidebug code and crc-sums should be very straight forward!!

I can be emailed as stone@ftp.one.se - I will try to answer all emails!
Greets goes to my favorite bird in the world, Winterhawk, my regular cracking
partner, landlord and friend, Patriarch. And ofcoz all my homies in masque!

This program, the sourcecode and txt file is to beconsidered beerware - meaning
that if you like it and use it you gotta gimme a beer if you ever meet me!
                                                     /Stone 1996

A last btw.. If you're looking for something to test it on.. Don't use the 
.com files in your windows. They are dectect this program and exits. And ummm
a piece of advice, don't ever encrypt command.com (especially not win.com in
95, it's really an .exe file! ;) )