Lesson 6.1: Funny tricks (1)

LESSON 6 (1) - Funny tricks.  Xoring, Junking, Sliding
EXERCISE 01: [LARRY in search of the King]
     Before the next step let's resume what you have learned in
the lessons 3-5, beginning with a very simple crack exercise
(again, we'll use the protection scheme of a game, for the
reasons explained in lesson 1): SEARCH FOR THE KING (Version
1.1.). This old "Larry" protection sequence, is a "paper
protection" primitive. It's a very widespread (and therefore easy
to find) program, and one of the first programs that instead of
asking meaningful passwords (which offer us the possibility to
immediately track them down in memory) asked for a random number
that the good buyer could find on the manual, whereby the bad
cracker could not. (Here you choose -with the mouse- one number
out of 5 possible for a "gadget" choosen at random). I don't need
any more to teach you how to find the relevant section of code
(-> see lesson 3). Once you find the protection, this is what you

 :C922 8E0614A3       MOV     ES,[A314]
 :C952 50 0E          PUSH    AX & CS
 :C954 E81BFF         CALL    C872      <- call protection scheme
 :C957 5B             POP     BX twice
 :C959 8B76FA         MOV     SI,[BP-06] <- prepare store_room
 :C95C D1E6           SHL     SI,1       <- final prepare
 :C95E 8942FC         MOV     [BP+SI-04],AX  <- store AX
 :C961 837EFA00       CMP     Word Ptr [BP-06],+00  <- good_guy?
 :C965 75BB           JNZ     C922           <- loop, bad guy
 :C967 8E0614A3       MOV     ES,[A314]
 :C96B 26F606BE3501   TEST    Byte Ptr ES:[35BE],01  <- bad_guy?
 :C971 74AF           JZ C922                <- loop, bad guy
 :C973 8B46FC         MOV     AX,[BP-04]...  <- go on good guy

Let's see now the protection scheme called from :C954
 :C872 55             PUSH    BP
 :C8F7 90             NOP
 :C8F8 0E             PUSH    CS
 :C8F9 E87234         CALL    FD6E <- call user input
 :C8FC 5B             POP     BX
 :C8FD 5B             POP     BX
 :C8FE 8B5E06         MOV     BX,[BP+06]
 :C901 D1E3           SHL     BX,1
 :C903 39872266       CMP     [BX+6622],AX  <- right answer?
 :C907 7505           JNZ     C90E      <- no, beggar_off
 :C909 B80100         MOV     AX,0001   <- yes, AX=1
 :C90C EB02           JMP     C910
 :C90E 2BC0           SUB     AX,AX     <- beggar_off with AX=0
 :C910 8BE5           MOV     SP,BP
 :C912 5D             POP     BP
 :C913 CB             RETF              <- back to main

Here follow 5 questions, please answer all of them:
1)   Where in memory (in which locations) are stored the "right"
     passnumbers? Where in memory is the SEGMENT of this
     locations stored? How does the scheme get the OFFSET?
2)   Would setting NOPs instructions at :C965 and :C971 crack?
     Would it be a good idea?
3)   Would changing :C907 to JZ crack? Would it be a good idea?
4)   Would changing :C907 to JNZ C909 crack? Would it be a good
5)   Write down (and try) at least 7 OTHER different patches to
     crack this scheme in spades (without using any NOP!).
Uff! By now you should be able to do the above 5 exercises in
less than 15 minutes WITHOUT USING THE DEBUGGER! Just look at the
data above and find the right answers feeling them... (you 'll
now which one are the right one checking with your debugger...
score as many points as you like for each correct answer and sip
a good Martini-Wodka... do you know that the sequence should
ALWAYS be 1) Ice cubes 2) Martini Dry 3) Wodka Moskovskaja 4)
olive 5) lemon 6) Schweppes Indian tonic?

Let's now come to the subject of this lesson:
-----> [Xoring] (Simple encryption methods)
     One easy way to encrypt data is the XOR method. XOR is a bit
manipulation instruction that can be used in order to cipher and
decipher data with the same key:
 Byte to encrypt                   key            result
     FF                  XOR       A1               5E
     5E                  XOR       A1               FF
As you can see XOR offers a very easy way to encrypt or to
decrypt data, for instance using the following routine:
     mov  bx, offset_where_encryption/decryption_starts
     mov  ah, [bx]            <-   get current byte
     xor  ah, encrypt_value   <-   engage/disengage xor
     mov [bx], ah             <-   back where you got it
     inc  bx                  <-   ahead one byte
     cmp  bx, offset_start_+_size  <- are we done?
     jle  xor_loop            <-   no, then next cycle
     ret                      <-   back where we came from

The encrypt_value can be always the same (fixed) or chosen at
random, for instance using INT_21, service 2Ch (get current time)
and choosing as encrypt_value the value reported in DL (but
remembering to discard the eventual value 0, coz otherwise it
would not xor anything at all!)
     mov  ah,2Ch
     int  21h
     cmp  dl,0
     je   random_value
     mov  encrypt_value,dl
     The problem with XORing (and with many other encryption
methods), is that the part of the code that calls the encryption
routine cannot be itself encrypted. You'll somewhere have, "in
clear" the encryption key.

     The protectionist do at times their best to hide the
decrypting routine, here are some common methods:

  These are the more common protection method for the small
decryption part of the program code. This methods, originally
devised to fool signature virus scanners, have been pinched from
the polymorphic virus engines of our fellows viriwriters, and are
still in use for many simple decryption protection schemes. For
parts of the following many thanks go to the [Black Baron], it's
a real pity that so many potential good crackers dedicate so much
time to useless (and pretty repetitive) virus writing instead of
helping in our work. This said, virus studying is VERY important
for crackers coz the code of the viri is

Let's show as example of the abovementioned protection tactics
the following ultra-simple decryptor:
          MOV      SI,jumbled_data     ;Point to the jumbled data
          MOV      CX,10               ;Ten bytes to decrypt
mn_loop:  XOR      BYTE PTR [SI],44    ;XOR (un_scramble!) a byte
          INC      SI                  ;Next byte
          LOOP     mn_loop             ;Loop the 9 other bytes

This small program will XOR the ten bytes at the location pointed
to by SI with the value 44.  Providing the ten bytes were XORed
with 44 prior to running this decryptor the ten bytes will be
restored to their original state.
In this very simple case the "key" is the value 44. But there are
several tricks involving keys, the simplest one being the use of
a "sliding" key: a key that will be increased, or decreased, or
multiplied, or bit-shifted, or whatever, at every pass of the

A possible protection can also create a true "Polymorph"
decryptor, a whole decryptor ROUTINE that looks completely
different on each generation. The trick is to pepper totally
random amounts of totally random instructions, including JUMPS
and CALLS, that DO NOT AFFECT the registers that are used for the
decryption. Also this kind of protection oft uses a different
main decryptor (possibly from a selection of pre-coded ones) and
oft alters on each generation also all the registers that the
decryptor uses, invariably making sure that the JUNK code that
it generates doesn't destroy any of the registers used by the
real decryptor!  So, with these rules in mind, here is our simple
decryptor again:

         MOV      DX,10              ;Real part of the decryptor!
         MOV      SI,1234            ;junk
         AND      AX,[SI+1234]       ;junk
         CLD                         ;junk
         MOV      DI,jumbled_data    ;Real part of the decryptor!
         TEST     [SI+1234],BL       ;junk
         OR       AL,CL              ;junk
mn_loop: ADD      SI,SI              ;junk instr, but real loop!
         XOR      AX,1234            ;junk
         XOR      BYTE PTR [DI],44   ;Real part of the decryptor!
         SUB      SI,123             ;junk
         INC      DI                 ;Real part of the decryptor!
         TEST     DX,1234            ;junk
         AND      AL,[BP+1234]       ;junk
         DEC      DX                 ;Real part of the decryptor!
         NOP                         ;junk
         XOR      AX,DX              ;junk
         SBB      AX,[SI+1234]       ;junk
         AND      DX,DX              ;Real part of the decryptor!
         JNZ      mn_loop            ;Real part of the decryptor!

As you should be able to see, quite a mess! But still executable
code. It is essential that any junk code generated by the
Polymorph protection is executable, as it is going to be peppered
throughout the decryptor. Note, in this example, that some of the

junk instructions use registers that are actually used in the
decryptor! This is fine, providing the values in these
registers aren't destroyed. Also note, that now we have random
registers and random instructions on each generation. So, a
Polymorph protection Engine can be summed up into three major
  1 .. The random number generator.
  2 .. The junk code generator.
  3 .. The decryptor generator.
There are other discrete parts but these three are the ones where
most of the work goes on!

How does it all work?  Well a good protection would
*    choose a random selection of registers to use for the
decryptor and leave the remaining registers as "junk" registers
for the junk code generator.
*    choose one of the compressed pre-coded decryptors.
*    go into a loop generating the real decryptor, peppered with
junk code.
From the protectionist's point of view, the advantages of this
kind of method are mainly:
*    the casual cracker will have to sweat to find the decryptor.
*    the casual cracker will not be able to prepare a "patch" for
the lamers, unless he locates and patches the generators, (that
may be compressed) coz otherwise the decryptor will vary every

To defeat this kind of protection you need a little "zen" feeling
and a moderate knowledge of assembler language... some of the
junk instructions "feel" quite singular when you look at them
(->see lesson B). Besides, you (now) know what may be going on
and memory breakpoints will immediately trigger on decryption...
the road is open and the rest is easy (->see lessons 3-5).

-----> Starting point number magic
For example, say the encrypted code started at address 10h, the
following could be used to index this address:
 MOV   SI,10h         ;Start address
 MOV   AL,[SI]        ;Index from initial address
But sometimes you'll instead find something like the following,
again based on the encrypted code starting at address 10h:

 MOV   DI,0BFAAh      ;Indirect start address
 MOV   AL,[DI+4066h)  ;4066h + 0BFAAh = 10010h (and FFFF = 10h)!!
The possible combinations are obviously infinite.

[BIG KEYS] (Complicated encryption methods)
     Prime number factoring is the encryption used to protect
sensible data and very expensive applications. Obviously for few
digit keys the decoding is much easier than for, say, 129 or 250
digit keys. Nevertheless you can crack those huge encryption too,
using distributed processing of quadratic sieve equations (which
is far superior for cracking purpose to the sequential processing
methods) in order to break the key into prime numbers. To teach
you how to do this sort of "high" cracking is a little outside
the scope of my tutorial: you'll have to write a specific short
dedicated program, linking together more or less half a thousand
PC for a couple of hours, for a 250 bit key, this kind of things
have been done quite often on Internet, were you can also find
many sites that do untangle the mysteries (and vagaries) of such
  As References I would advocate the works of Lai Xueejia, those
swiss guys can crack *everything*. Begin with the following:
Xuejia Lai, James Massey, Sean Murphy, "Markov Ciphers and
     Differential Cryptanalysis", Advances in Cryptology,
     Eurocrypt 1991.
Xuejia Lai, "On the Design and Security of Block Ciphers",
     Institute for Signal and Information Processing,
     ETH-Zentrum, Zurich, Switzerland, 1992
Factoring and primality testing is obviously very important for
this kind of crack. The most comprehensive work I know of is:
(300 pages with lengthy bibliography!)
    W. Bosma & M. van der Hulst
    Primality Testing with Cyclotomy
    Thesis, University of Amsterdam Press.
A very good old book you can incorporate in your probes to build
very effective crack programs (not only for BBS accesses :=) is
*the* "pomerance" catalog:
Pomerance, Selfridge, & Wagstaff Jr.
    The pseudoprimes to 25*10^9
    Math. Comp. Vol 35 1980 pp. 1003-1026

Anyway... make a good search with Lykos, and visit the relevant
sites... if encryption really interests you, you'll be back in
two or three (or thirty) years and you'll resume cracking with
deeper erudite knowledge.
  The study of the patented enciphering methods is also *quite*
interesting for our aims :=) Here are some interesting patents,
if you want to walk these paths get the complete texts:
     [BEST]    USPat 4168396 to Best discloses a microprocessor
for executing enciphered programs. Computer programs which have
been enciphered during manufacture to deter the execution of the
programs in unauthorized computers, must be decrypted before
execution. The disclosed microprocessor deciphers and executes
an enciphered program one instruction at a time, instead of on
a continuous basis, through a combination of substitutions,
transpositions, and exclusive OR additions, in which the address
of each instruction is combined with the instruction. Each unit
may use a unique set of substitutions so that a program which can
be executed on one microprocessor cannot be run on any other
microprocessor. Further, Best cannot accommodate a mixture of
encrypted and plain text programs.
     [JOHNSTONE]    USPat 4120030 to Johnstone describes a
computer in which the data portion of instructions are scrambled
and in which the data is of necessity stored in a separate
memory. There is no disclosure of operating with instructions
which are completely encrypted with both the operation code and
the data address portion being unreadable without a corresponding
key kernel.
     [TWINPROGS]    USPat 4183085 describes a technique for
protecting software by providing two separate program storages.
The first program storage is a secure storage and the second
program storage is a free storage. Security logic is provided to
check whether an output instruction has originated in the secure
store and to prevent operation of an output unit which receives
output instructions from the free storage. This makes it
difficult to produce information by loading a program into free
     [AUTHENTICATOR]     USPat 3996449 entitled "Operating System
Authenticator," discloses a technique for authenticating the
validity of a plain text program read into a computer, by
exclusive OR'ing the plain text of the program with a key to
generate a code word which must be a standard recognizable code
word which is successfully compared with a standard corresponding
code word stored in the computer. If there is a successful
compare, then the plain text program is considered to be
authenticated and is allowed to run, otherwise the program
is not allowed to run.

In order to try to crack PGP, you need to understand how these
public/private keys systems work. Cracking PGP seems extremely
difficult, though... I have a special dedicated "attack" computer
that runs 24 hours on 24 only to this aim and yet have only begun
to see the light