MatrixxxMadness 1  -- a tutorial on ripping a valid matrix for your name...

Tutorial by : R!SC -- risc@notme.com -- http://csir.cjb.net 
Date : 11th june 1999 (heh, the day the film gets released(well, in england anyway))

Cracking a Matrix (using soft-ice and good luck)

Right, we have an 8*8 Matrix of check boxes and a place to enter our name..

Theory, every three seconds, the crackme takes our name and our matrix entry, it
then uses our name to work out the correct matrix, and compares this to our fake
matrix entry. All we have to do is find the compare, and decode the matrix
information so we can use it. 8*8 matrix = 64 check boxes, how to represent this in
memory? too many ways, lets just crack this mother :)

i have two ways to crack this program, the first is real easy to follow..

Method #1:

Load MatrixxxMadness, and also load it into WDasm...While its running in the
background, study the code in WDasm, after about 15-20 minutes, go back to
matrixxxmadness, and its registered, showing you the congratulations screen..
simple enough?? (for this method, WDasm is not required, but it helps to pass the
time)

Method #2:

More complicated... run matrixxxmadness, enter your nick, i choose 'R!SC & notme'.
Randomly check some boxes(i made a big 'X' with the ticks) ... Enter softice, and
put a breakpoint on hmemcpy 'bpx hmemcpy', exit softice, and wait...

when softice breaks, you have to hit F11 to return to caller, then F12 several
times to exit out of USER code back into mm1!code (i had to hit F12 6 times..)

you should end up here...

015F:00431D81  E8368C0000          CALL    0043A9BC
015F:00431D86  5E                  POP     ESI          <-- YOU ARE HERE!!!
015F:00431D87  5B                  POP     EBX
015F:00431D88  C3                  RET

trace with F8 or F10(can still use F12 if you like) until you get to some proper
code.. after 6 ret's, you end up after the call that called the call that called
the call(etc..) that copied your name into memory

015F:00457B22  E8A9F4FDFF          CALL    00436FD0
015F:00457B27  8D558C              LEA     EDX,[EBP-74] <-- YOU ARE HERE!!!

okay, this code looks normal enough, lets trace through this, and see whats
happening :)

015F:00457B27  8D558C              LEA     EDX,[EBP-74]
015F:00457B2A  8B45F8              MOV     EAX,[EBP-08] <-- address of name (BC21C4)
015F:00457B2D  E816FBFAFF          CALL    00407648     <-- copies it to BC21E0
015F:00457B32  837D8C00            CMP     DWORD PTR [EBP-74],00
015F:00457B36  0F84D9000000        JZ      00457C15


015F:00457B3C  8D45A0              LEA     EAX,[EBP-60]
015F:00457B3F  E80CE9FFFF          CALL    00456450
015F:00457B44  8B45F8              MOV     EAX,[EBP-08] <-- address of name (again)
015F:00457B47  E88CBFFAFF          CALL    00403AD8     <-- get length
015F:00457B4C  83F840              CMP     EAX,40       <-- is it 0x40 (64 decimal)
015F:00457B4F  7D18                JGE     00457B69


015F:00457B51  8D45F8              LEA     EAX,[EBP-08] - this bit gets name, and 
015F:00457B54  8B55F8              MOV     EDX,[EBP-08] - copies it onto the end of
015F:00457B57  E884BFFAFF          CALL    00403AE0     - itself, into a buffer at
015F:00457B5C  8B45F8              MOV     EAX,[EBP-08] - BC21FC, so keeps doubling
015F:00457B5F  E874BFFAFF          CALL    00403AD8     - the size, until it is
015F:00457B64  83F840              CMP     EAX,40       - greater than 0x40..
015F:00457B67  7EE8                JLE     00457B51


015F:00457B69  8B45F8              MOV     EAX,[EBP-08]
015F:00457B6C  E867BFFAFF          CALL    00403AD8
015F:00457B71  83F840              CMP     EAX,40
015F:00457B74  7E24                JLE     00457B9A

015F:00457B76  8B45F8              MOV     EAX,[EBP-08] <-- new >0x40 char name :)
015F:00457B79  E85ABFFAFF          CALL    00403AD8     <-- get length
015F:00457B7E  8BD0                MOV     EDX,EAX      <-- save it
015F:00457B80  8D45F8              LEA     EAX,[EBP-08] <-- guess..
015F:00457B83  B901000000          MOV     ECX,00000001 <-- hmmm
015F:00457B88  E88FC1FAFF          CALL    00403D1C     <-- trim 1 char off the end
015F:00457B8D  8B45F8              MOV     EAX,[EBP-08] <-- buffer to big name
015F:00457B90  E843BFFAFF          CALL    00403AD8     <-- get length
015F:00457B95  83F840              CMP     EAX,40       <-- if its not 0x40
015F:00457B98  75DC                JNZ     00457B76       - carry on chopping


015F:00457B9A  33D2                XOR     EDX,EDX
015F:00457B9C  8D45B0              LEA     EAX,[EBP-50] <-- a new Buffer (69FBFC)
015F:00457B9F  8B4DF8              MOV     ECX,[EBP-08] <-- truncted big name
015F:00457BA2  8A4C11FF            MOV     CL,[EDX+ECX-01]
015F:00457BA6  8808                MOV     [EAX],CL     <-- copy it byte by byte
015F:00457BA8  42                  INC     EDX            - into the new buffer,
015F:00457BA9  40                  INC     EAX            - missing the last char
015F:00457BAA  83FA40              CMP     EDX,40
015F:00457BAD  75F0                JNZ     00457B9F     <-- loop until its finished


015F:00457BAF  8D55A0              LEA     EDX,[EBP-60] - gets complicated here
015F:00457BB2  8D45B0              LEA     EAX,[EBP-50]
015F:00457BB5  E8FEE8FFFF          CALL    004564B8
015F:00457BBA  8D75A0              LEA     ESI,[EBP-60]
015F:00457BBD  8D7D90              LEA     EDI,[EBP-70]
015F:00457BC0  B904000000          MOV     ECX,00000004
015F:00457BC5  F3A5                REPZ MOVSD
015F:00457BC7  8D5590              LEA     EDX,[EBP-70]
015F:00457BCA  8D45B0              LEA     EAX,[EBP-50]
015F:00457BCD  E8E6E8FFFF          CALL    004564B8
015F:00457BD2  8B45A0              MOV     EAX,[EBP-60] - but this bit was
015F:00457BD5  2B45A4              SUB     EAX,[EBP-5C] - very interesting
015F:00457BD8  2B45A8              SUB     EAX,[EBP-58] - sub this off that
015F:00457BDB  0345AC              ADD     EAX,[EBP-54] - add this to that
015F:00457BDE  8945A0              MOV     [EBP-60],EAX - move it here...
015F:00457BE1  8B4590              MOV     EAX,[EBP-70]
015F:00457BE4  2B4594              SUB     EAX,[EBP-6C]
015F:00457BE7  2B4598              SUB     EAX,[EBP-68]
015F:00457BEA  03459C              ADD     EAX,[EBP-64] - using some strange numbers
015F:00457BED  894590              MOV     [EBP-70],EAX - aswell....
015F:00457BF0  8D55F0              LEA     EDX,[EBP-10]
015F:00457BF3  8D45F4              LEA     EAX,[EBP-0C] - all the sub's and mov's
015F:00457BF6  E8B1F8FFFF          CALL    004574AC     - caught my eye :)


015F:00457BFB  8B45F0              MOV     EAX,[EBP-10] <-- VERY NICE
015F:00457BFE  50                  PUSH    EAX
015F:00457BFF  8B4DF4              MOV     ECX,[EBP-0C] <-- JUST AS NICE
015F:00457C02  8B5590              MOV     EDX,[EBP-70] <-- MAGIC
015F:00457C05  8B45A0              MOV     EAX,[EBP-60] <-- EXCELLENT!!
015F:00457C08  E8AFFEFFFF          CALL    00457ABC     <-- hmm, dont care no more..
015F:00457C0D  8945FC              MOV     [EBP-04],EAX
015F:00457C10  8B45FC              MOV     EAX,[EBP-04]
015F:00457C13  FFD0                CALL    EAX



after all this? do you know what i know? look at the last section of code.. 

MOV     EAX,[EBP-10] <-- this put '18244281' into EAX
MOV     ECX,[EBP-0C] <-- this put '81422418' into ECX

which i thought could be my matrix entry (in binary..) look, convert it byte by byte
into binary..

EAX...
18= 00011000
24= 00100100
42= 01000010
81= 10000001

hmm? the bottom  half of an 'X' eh? so i killed the 'bpx hmemcpy', and set a
breakpoint on 00457BFB . exited softice, and checked a few more boxes, sure enough,
EAX & ECX seemed to change as the boxes did...

going on a hunch, as you do when you havent reversed the code, and have no source to
go with, i decided that these lines revealed the correct matrix code..

MOV     EDX,[EBP-70] <-- EDX = '15BB7346'
MOV     EAX,[EBP-60] <-- EAX = '6866D0DC'

okay, using logic

MOV     EAX,[EBP-10] <-- bottom half?
MOV     ECX,[EBP-0C] <-- top half?

er, do you see the logic? bottom half of fake is epb-10, so maybe epb-70 is bottom
half of real matrix ? if they were sorted into descending order? 

70..60  bottom..top
10..0C  bottom..top

name 'R!SC & notme'

eax..6866D0DC  (00457C05  8B45A0              MOV     EAX,[EBP-60])
01101000
01100110
11010000
11011100

edx..15BB7346  (00457C02  8B5590              MOV     EDX,[EBP-70])
00010101
10111011
01110011
01000110

make it look pretty...

     1 2 3 4 5 6 7 8
  
  a: 0 1 1 0 1 0 0 0 :a
  b: 0 1 1 0 0 1 1 0 :b
  c: 1 1 0 1 0 0 0 0 :c   my name 'R!SC & notme'
  d: 1 1 0 1 1 1 0 0 :d
  e: 0 0 0 1 0 1 0 1 :e
  f: 1 0 1 1 1 0 1 1 :f
  g: 0 1 1 1 0 0 1 1 :g
  h: 0 1 0 0 0 1 1 0 :h

     1 2 3 4 5 6 7 8
     
 
     
name 'NiCKY BLaCKMaRKeT'

eax...
B37B90C0
edx...
5F33EC07

10110011 : B3
01111011 : 7B
10010000 : 90
11000000 : C0


01011111 : 5F
00110011 : 33
11101100 : EC
00000111 : 07

make it look pretty...

     1 2 3 4 5 6 7 8
  
  a: 1 0 1 1 0 0 1 1 :a
  b: 0 1 1 1 1 0 1 1 :b
  c: 1 0 0 1 0 0 0 0 :c   my name 'NiCKY BLaCKMaRKeT'
  d: 1 1 0 0 0 0 0 0 :d
  e: 0 1 0 1 1 1 1 1 :e
  f: 0 0 1 1 0 0 1 1 :f
  g: 1 1 1 0 1 1 0 0 :g
  h: 0 0 0 0 0 1 1 1 :h

     1 2 3 4 5 6 7 8
     


Time taken to crack, about 30 minutes, good job luck was on my side... time taken to
compose tutorial, and recrack several times, about 2.5 hrs..

Personal difficulty rating, er, a fair 4/10.. it could have been a lot harder, damn,
it could have been impossible, like duelists crackme #3 :)

Greets to all crackers / reversers (except yoshi), thanks to The AntiXrysT for some
entertainment (please dont make another Matrix crackme.....)


oh, and thanks for reading.. did you learn anything??

R!SC -- risc@notme.com  11th june '99