home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Mendoza / ASMTUT.TXT < prev    next >
Text File  |  2000-05-25  |  16KB  |  390 lines

  1. Welcome to XLogic's Assembly KeyGen tutorial.
  2.  
  3. What you will need:
  4. TASM 3.0 or higher (Comes with TD).
  5. A Good Text Editor (EDIT.COM).
  6. A Good Dos Debugger (I will use TD, S-ICE and DG are also Acceptable).
  7. A File access monitor (SCANF is included).
  8. An ASM Command Listing (go buy a book).
  9. A GOOD (intermediate) knowledge of ASM. <-- Don't bug me for help.
  10. X-Tract 1.51 (included).
  11.  
  12. 1. Introduction.
  13. This was the first key generator I ever wrote.  It taught me more about
  14. assembly than any book I've read, considering that I originally
  15. learned assembly from debugging stuff.
  16.  
  17. This is a very easy keygen to do, but you use the same process to write
  18. other much more complex keygens.
  19.  
  20. The best way of writing a keygen in my experience is:
  21. 1.  Debug, dissasemble, do whatever is necessary to UNDERSTAND what the hell
  22.     the program is doing.
  23. 2.  Extract the relevant code, reverse it or whatever needs doing to make it
  24.     ready for the keygen.
  25. 3.  Write the keygen.
  26. 4.  Use a key you made, debug the program, and make sure it works 101%.
  27.  
  28. 2. Let's Get Started!
  29. Ok, look at the program, how it runs. See if it prompts for a reg number,
  30. if it looks for a key file, any way it gets registration in.
  31.  
  32. With X-Tract, there are no prompts for reg numbers, or anything.
  33. Ok, so now you run a file access monitor, to check if it looks for a reg
  34. key.  (I have included a good file access monitor with the package, SCANF.
  35. To make it put file access up on the screen, use "scanf con" to run it)
  36. Bingo.  It looks for X-TRACT.KEY.
  37.  
  38. Now the debugging starts.  First create a file called X-TRACT.KEY in the
  39. same directory as X-Tract, and load your debugger.  Step through with the
  40. file access montior loaded to see where it opens the key file. 
  41.  
  42. You trace over the following call, and the file monitor tells you that the
  43. key has been opened.
  44.  
  45.   cs:366B 2EA27908       mov    cs:[0879],al
  46.   cs:366F 9C             pushf
  47.   cs:3670 E8D71A         call   514A
  48.  
  49. Now you restart debugging and trace one instruction into that function call.
  50. You trace over the first function call, and notice that it displays the
  51. startup banner:
  52. X-TRACT (tm)   Executable File Extractor  Version 1.51  7-26-95
  53. Copyright 1994-95 by Pablo Carboni. All Rights Reserved.
  54.  
  55. The next block of code uses an Int 21h call.
  56. You notice that this is what opens the file.
  57. Int 21h's usage is as follows:
  58. ah = 3D                 ; Open file Handle for file access
  59. al = 02                 ; file access code
  60. dx = filename offset    ; Where the filename is in memory
  61. Int 21h                 ; Try to open the file
  62. jnb ok                  ; If the file exists, and has been opened, jump
  63. jmp error               ; If the file hasn't been opened, jump.
  64.  
  65. So what this block of code does is try and open the file.
  66.   cs:5150 B8023D         mov    ax,3D02
  67.   cs:5153 BAFC21         mov    dx,21FC
  68.   cs:5156 CD21           int    21
  69.   cs:5158 7303           jnb    515D
  70.   cs:515A E9ED00         jmp    524A
  71.  
  72. Since you made a file called X-TRACT.KEY before you started debugging
  73. it should jump on the first jump.
  74. You then end up here:
  75.   cs:515D 2EA3D805       mov    cs:[05D8],ax
  76.   cs:5161 B43F           mov    ah,3F
  77.   cs:5163 2E8B1ED805     mov    bx,cs:[05D8]
  78.   cs:5168 B99B00         mov    cx,009B
  79.   cs:516B BABD00         mov    dx,00BD
  80.   cs:516E CD21           int    21
  81.   cs:5170 3D9B00         cmp    ax,009B
  82.   cs:5173 7303           jnb    5178
  83.   cs:5175 E9D200         jmp    524A
  84.  
  85. The first line stores the files handle for future access from AX to
  86. memory location 05D8h.
  87.  
  88. Now, we see another Int 21h call coming up.  This time it is as follows:
  89. ah = 3Fh                ; Read Data from the open filehandle in BX
  90. bx = [05D8h]            ; get the file handle we saved just before.
  91. cx = 9Bh                ; How many bytes we want to try and read.
  92. dx = 0BDh               ; Where we want to put the read bytes.
  93. Int 21h                 ; Do the deed
  94.  
  95. When this returns, AX will be the actual number of bytes read from the file.
  96. So what is this next piece of code doing?
  97.   cs:5170 3D9B00         cmp    ax,009B
  98.   cs:5173 7303           jnb    5178
  99.   cs:5175 E9D200         jmp    524A
  100. Its checking if it could read 9Bh bytes from the file, and if it could,
  101. continue.
  102.  
  103. As you should have noticed, if any of the previous tests have failed, they
  104. jump to location 524Ah. Keep this in mind when you are debugging the code.
  105.  
  106. Now you hit this big lump of code:
  107.   cs:5178 BEBD00         mov    si,00BD
  108.   cs:517B BF5521         mov    di,2155
  109.   cs:517E B99A00         mov    cx,009A
  110.   cs:5181 0E             push   cs
  111.   cs:5182 1F             pop    ds
  112.   cs:5183 0E             push   cs
  113.   cs:5184 07             pop    es
  114.   cs:5185 FC             cld
  115.   cs:5186 F3A6           rep cmpsb
  116.   cs:5188 7403           je     518D
  117.   cs:518A E9BD00         jmp    524A
  118. rep cmpsb....... hmmm, a byte-by-byte compare statement.
  119. how this is called is:
  120. cx = Number of bytes to compare
  121. DS:DI = First lot of bytes to compare
  122. ES:SI = Second lot of bytes to compare
  123. rep cmpsb       ; do the compare
  124. je continue     ; jump here it the same
  125. jmp error       ; jump here if not the same
  126.  
  127. So what should be at the start of the rego key?
  128. Whatever is at ES:DI.  The other location has what was in the rego key
  129. that you created.
  130.  
  131. Now you get to this:
  132.   cs:518D AC             lodsb
  133.   cs:518E 3CE0           cmp    al,E0
  134.   cs:5190 741B           je     51AD
  135. And a few more with different compares.  It is checking if one of these
  136. is equal to the byte it loaded from DS:DI (its there from after the 1st
  137. compare).
  138.  
  139. Could it be checking for the type of registration?  Lets continue and see.
  140.   cs:51AD 2EA28008       mov    cs:[0880],al
  141.   cs:51B1 B43F           mov    ah,3F
  142.   cs:51B3 2E8B1ED805     mov    bx,cs:[05D8]
  143.   cs:51B8 B92A00         mov    cx,002A
  144.   cs:51BB BABD00         mov    dx,00BD
  145.   cs:51BE CD21           int    21
  146.   cs:51C0 3D2A00         cmp    ax,002A
  147.   cs:51C3 7403           je     51C8
  148.   cs:51C5 E98200         jmp    524A
  149.  
  150. It saves the byte it just checked to cs:880h.
  151. Then it does what it did before with Int 21h, it reads 2Ah bytes from the
  152. file to ds:00BDh.  If it could read 2Ah bytes, it continues on, otherwise
  153. it quits.
  154.  
  155. Now would be a good time to get out of the debugger and make the key file.
  156. 9Bh + 2Ah bytes (add the two cx vaules from the file read Int 21h's) is
  157. equal to 197 bytes, so now would be a good time to get out, make a file of
  158. size 197 bytes, With the first lot of data it compared (that string of
  159. bytes), then either a E0h, E1h, E2h or E3h, which it looked for.  I will
  160. use a E0h.
  161.  
  162. You've got your registration key half done.  After making it, you
  163. should be able to pass all of the tests it performs to the point where we
  164. left off.  If you had problems, have a look at the key that I provided
  165. called XLOGIC.REG to get some hints.
  166.  
  167. Now you hit this:
  168.   cs:51C8 BEBD00         mov    si,00BD
  169.   cs:51CB 8BFE           mov    di,si
  170.   cs:51CD B92A00         mov    cx,002A
  171.   cs:51D0 2E8A1E8008     mov    bl,cs:[0880]
  172.   cs:51D5 AC             lodsb
  173.   cs:51D6 32C3           xor    al,bl
  174.   cs:51D8 AA             stosb
  175.   cs:51D9 80EB22         sub    bl,22
  176.   cs:51DC E2F7           loop   51D5
  177.  
  178. Now before i tell you, try and work out what this does.
  179.  
  180. Here is what it is doing:
  181. 1. si = 0BDh    ;the location to start from
  182. 2. di = si      ;set the second location to start from
  183. 3. cx = 2Ah     ;how many times to loop
  184. 4. bl = cs:880h ;get that byte that it checked for earlier
  185. 5. lodsb        ;load a byte from ES:SI into al, increment si by 1
  186. 6. xor al,bl    ;xor al by bl
  187. 7. stosb        ;store al to DS:DI, increment di by 1
  188. 8. sub bl,22    ;decrement bl by 22h
  189. 9. loop 5       ;loop cx times.
  190.  
  191. Now, step through this, watching what this does.
  192. What does it do?
  193. It decripts the data after the 0E0h, in the keyfile, using the above process.
  194.  
  195. If you can't understand this, just keep watching it and debugging it,
  196. because if you can't understand this, you won't be able to write a keygen.
  197.  
  198. Now it has tried to decrypt your name, and what we're about to look at.
  199.  
  200. Check this code out:
  201.   cs:51DE BEBD00         mov    si,00BD
  202.   cs:51E1 8BFE           mov    di,si
  203.   cs:51E3 B92800         mov    cx,0028
  204.   cs:51E6 2E8A1E8008     mov    bl,cs:[0880]
  205.   cs:51EB 33D2           xor    dx,dx
  206.   cs:51ED 33C0           xor    ax,ax
  207.   cs:51EF AC             lodsb
  208.   cs:51F0 03D0           add    dx,ax
  209.   cs:51F2 E2FB           loop   51EF
  210.   cs:51F4 2E3B14         cmp    dx,cs:[si]
  211.   cs:51F7 7551           jne    524A
  212.  
  213. Whats it doing?
  214. You should understand the first 7 lines, actually, you should understand
  215. the whole thing if you have a good grasp of Assembly.
  216.  
  217. It adds all the bytes together of what "Should" be you name, into dx.
  218. Then it compares dx to the number stored at cs:si.  This is what is called
  219. a CRC check.  This is only a simple one, and all it does is check if any
  220. of the bytes in the string have changed.
  221.  
  222. If it is the same, it is ok, and continues, otherwise it quits.
  223.  
  224. Now it sets cs:2220 to 01h, to tell the program it is registered.
  225.   cs:51FC 2EC606202201   mov    cs:byte ptr [2220]
  226. Then it checks the 0E0h byte.  This is where we find out what it does.
  227.   cs:5202 2E803E8008E0   cmp    cs:byte ptr [0880]
  228.   cs:5208 7424           je     522E
  229. So we let it jump:
  230.   cs:522E BA9B22         mov    dx,229B
  231.   cs:5231 E81D00         call   5251
  232.   cs:5234 C3             ret
  233. And it prints on the screen "REGISTERED VERSION".
  234. So what do the other "0E?h" values do?
  235. Go back and try the others to find out for yourself.
  236.  
  237. IMPORTANT.
  238. If you don't understand all of the above, go over and over it until you do.
  239.  
  240.  
  241. 2. Writing The KeyGen.
  242.  
  243. Now I am going to get lazy.  I will tell you what the steps are,
  244. give you my commented source file, and leave you go from there.
  245.  
  246. Here is what it is doing:
  247. 1. Open the Rego File.
  248. 2. Read the Header.
  249. 3. Check it.
  250. 4. Read the Rego Name and CRC.
  251. 5. Decrypt them.
  252. 6. Calculate the CRC.
  253. 7. Check the CRC.
  254. 8. Display the Rego type.
  255. 9. Continue on with the program.
  256.  
  257. Here is what you have to do:
  258. 1. Read the Rego Name.
  259. 2. Calculate the CRC.
  260. 3. Encript the Rego name and CRC.
  261. 3. Store the Rego type.
  262. 4. Write the whole block (including the header) to the Rego file.
  263.  
  264. Now for the assembly file:
  265. -------------------------------------------------------------------------------
  266. .386p
  267. seg_a        segment    byte public use16
  268.         assume    cs:seg_a, ds:seg_a
  269.  
  270.         org    100h
  271.  
  272. xtract_keygen   Proc Far
  273. start:
  274.                 mov     dx,offset title_text       ;load the startup banner
  275.                 call    print_text                 ;print it on the screen
  276.                 mov     dx,offset max_ent_length   ;load the text entry offset
  277.                 mov     ah,0Ah                     ;function=get text string
  278.                 int     21h                        ;get the text
  279.                 cmp     byte ptr entry_length,01h  ;check if mor than 1
  280.                                                    ;character was entered
  281.                 jae     short reg_type_sel         ;jump if 1 or more
  282.                 mov     dx,offset no_entry         ;not enough was entered
  283.                 jmp     short exit                 ;jump to exit
  284.  
  285. reg_type_sel:
  286.                 mov     dx,offset reg_type_text    ;load rego type selection
  287.                 call    print_text                 ;display it
  288.                 xor     ax,ax                      ;clear ax
  289.                 int     16h                        ;get a char from the keybd 
  290.                 int     29h                        ;display it
  291.                 cmp     al,31h                     ;check if its 1
  292.                 jl      reg_type_sel               ;jmp if lower than
  293.                 cmp     al,34h                     ;check if its 4
  294.                 ja      reg_type_sel               ;jmp if above 
  295. continue:
  296.                 add     al,0AFh                    ;add 0AFh to input, to get
  297.                                                    ;"E" value.
  298.                 mov     reg_type,al                ;store it in the rego type
  299.                 mov     dl,0Ah                     ;1 These lines store
  300.                 mov     dh,al                      ;2 the rego type
  301.                 mov     bx,offset max_ent_length   ;3
  302.                 mov     [bx],dx                    ;4
  303.                 call    make_key                   ;make the key
  304.                 mov     dx,offset done_text        ;load done text
  305. exit:
  306.                 call    print_text                 ;display the output result
  307.                 retn                               ;exit to dos/windoze
  308. xtract_keygen   endp
  309.  
  310. print_text      proc    near                       ;put text up on the
  311.                 mov     ah,9                       ;screen
  312.                 int     21h
  313.                 retn
  314. print_text      endp
  315.  
  316. make_key        proc    near                       
  317.                 mov     si,offset name_input       ;this should look
  318.                 mov     dx,si                      ;familiar :)
  319.                 mov     cx,28h                     ;
  320.                 mov     bl,reg_type                ;
  321.                 xor     dx,dx                      ;
  322.                 xor     ax,ax                      ;
  323. crc_loop:                                          ;
  324.                 lodsb                              ;
  325.                 add     dx,ax                      ;
  326.                 loop    crc_loop                   ;
  327.                 mov     bx,offset checksum_dat     ;
  328.                 mov     [bx],dx                    ;store the crc
  329.  
  330.                 mov     si,offset name_input       ;this should also look
  331.                 mov     di,si                      ;familiar :)
  332.                 mov     cx,2Ah                     ;
  333.                 mov     bl,reg_type                ;
  334. encription_loop:                                   ;
  335.                 lodsb                              ;
  336.                 xor     al,bl                      ;
  337.                 stosb                              ;
  338.                 sub     bl,22h                     ;
  339.                 loop    encription_loop            ;
  340.  
  341.                 mov     ah,3Ch                     ;open the file to write
  342.                 mov     dx,offset key_name         ;
  343.                 int     21h                        ;
  344.                 xchg    bx,ax                      ;put filehand in bx
  345.                 mov     ah,40h                     ;write the key to disk
  346.                 mov     dx,offset key_data         ;
  347.                 mov     cx,0C5h                    ;
  348.                 int     21h                        ;
  349.                 mov     ah,3Eh                     ;close the file handle
  350.                 int     21h                        ;
  351.                 retn
  352. make_key        endp
  353.  
  354. title_text      db 'X-Tract 1.51 Key File Generator by XLogic', 0Dh, 0Ah
  355. name_prompt     db 'Enter your name: $'
  356. reg_type_text   db 0Dh,0Ah,'Please Choose Registration Type:',0Dh,0Ah
  357.                 db '1. Registered Version',0Dh,0Ah
  358.                 db '2. Beta-Test Version',0Dh,0Ah
  359.                 db '3. Distro-Site Version',0Dh,0Ah
  360.                 db '4. Special Version',0Dh,0Ah
  361.                 db 'Enter the number corresponding to the type: $'
  362. no_entry        db 0Dh,0Ah,'You must enter a name.$'
  363. done_text       db 0Dh,0Ah,'Key file X-TRACT.KEY created.$'
  364. key_name        db 'X-TRACT.KEY',0
  365. reg_type        db 0
  366. key_data        dd 073696854h,020736920h,072756F79h,067657220h,072747369h,06F697461h,0656B206Eh,06F662079h
  367.                 dd 02D582072h,043415254h,050202E54h,07361656Ch,064202C65h,06F6E206Fh,069642074h,069727473h
  368.                 dd 065747562h,021746920h,063280A0Dh,039312029h,062203439h,06F572079h,02C79646Fh,065754220h
  369.                 dd 020736F6Eh,065726941h,041202C73h,04E454752h,0414E4954h,06150202Eh,0206F6C62h,06576694Ch
  370.                 dd 06F532073h,06877656Dh,020657265h,054206E49h,054206568h,02E656D69h
  371.                 db 0Dh 
  372. max_ent_length  db 26h
  373. entry_length    db 0
  374. name_input      db 40 dup ('$')
  375. checksum_dat    db 2 dup (0)
  376. seg_a        ends
  377.         end    start
  378. -------------------------------------------------------------------------------
  379.  
  380. Ok, there it is in all its glory.  I hope you've learned something from this,
  381. and if you did, let me know.  If you didn't, good for you.  Tell me how to
  382. improve this tutorial.
  383.  
  384. I can be contacted in #PC97 or #cracking on EFNET.
  385.  
  386. Cya Round.
  387.  
  388. XLogic.
  389.  
  390.