home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Quantico / km / dao31e.asm.txt < prev    next >
Encoding:
Text File  |  2000-05-25  |  9.2 KB  |  269 lines

  1.  
  2.  
  3.  
  4.  
  5. ;-----------------------------------------------------------------------------
  6.  
  7. ; 100% keygenerator for CDR-Win 3.1e/DAO 16/32 3.1e
  8.  
  9. ; coded 06/26/97
  10.  
  11. ; full credits go to the guy who localised the hidden check.
  12.  
  13. ; do_what_you_want_with_it_source
  14.  
  15. ; compile : tasm dao31e-k
  16.  
  17. ;           tlink /t /3 dao31e-k
  18.  
  19. ;-----------------------------------------------------------------------------
  20.  
  21.  
  22.  
  23. ; some notes on the registration check by the guy mentioned above ;)
  24.  
  25. ;
  26.  
  27. ; the registration algorithm works this way:
  28.  
  29. ; 1.1 compute 32 bit hash value from user name (must be at least 6 chars)
  30.  
  31. ; 1.2 swap upper and lower 16 bits of this hash value
  32.  
  33. ; 1.3 compute 32 bit hash value from company name (must be at least 6 chars)
  34.  
  35. ; 1.4 XOR 32 bit numbers computed in step.1.2 and step.1.3 with each other
  36.  
  37. ; 1.5 convert registration number (which is an ascii string) to a 32 bit number
  38.  
  39. ;     by calling atol() (this is a C library function)
  40.  
  41. ; 1.6 compare 24 bits of the two numbers we got in step.1.4 and step.1.5
  42.  
  43. ; 1.7 if they match (in those 24 bit positions) then accept registration
  44.  
  45. ;
  46.  
  47. ; wow, now we know how to compute the registration number!
  48.  
  49. ;
  50.  
  51. ; well, at least this is what all crackers thought when they were tracing
  52.  
  53. ; through the registration code. it seems that nobody had a second thought
  54.  
  55. ; about the fact that only 24 bits were checked/compared, 8 bits were simply
  56.  
  57. ; ignored, thus making key generators where those 8 bits were chosen randomly
  58.  
  59. ; (usually taken from the number computed in step.1.4)
  60.  
  61. ;
  62.  
  63. ; however, later people noticed that certain types of CDs were fucked up
  64.  
  65. ; 'cos apparently some random data was written into some sectors (which
  66.  
  67. ; made the CD unusable). rumour went around stating that there was a second
  68.  
  69. ; or hidden check in the program.
  70.  
  71. ;
  72.  
  73. ; well, as you probably found out by now this hidden check does exist indeed!
  74.  
  75. ; to find it i used IDA, probably one of the best disassemblers ever made.
  76.  
  77. ; (i didn't use WINICE at all)
  78.  
  79. ;
  80.  
  81. ; this is how i approached the problem: first, i had to find out what those
  82.  
  83. ; 24 bits were that were checked during registration. this was easy, however
  84.  
  85. ; i'd like to point out that the checking algorithm is extremly lame (well,
  86.  
  87. ; maybe it was intentional to confuse the crackers) 'cos instead of using
  88.  
  89. ; a bitmask to mask out the uninteresting 8 bits and then doing a simple cmp,
  90.  
  91. ; the author wrote a for loop in which he compared 24 of 32 bits, one by one.
  92.  
  93. ;
  94.  
  95. ; the bits to be compared were determined by a table of 32 entries, where each 
  96.  
  97. ; entry (a 0 or 1) corresponded to a bit position, namely a 1 caused a bit 
  98.  
  99. ; position to be compared (i.e. there are 24 1s and 8 0s in that table).
  100.  
  101. ; btw, the effective bitmask in the comparison is 0xFB39DEBF.
  102.  
  103. ;
  104.  
  105. ; after learning this, i assumed that in the hidden check only the remaining
  106.  
  107. ; 8 bits were checked, either by using the table of 1s and 0s mentioned above
  108.  
  109. ; (which was not the case, as IDA didn't find any more references to it) or
  110.  
  111. ; by using the more effective masking method (which turned out to be the case).
  112.  
  113. ;
  114.  
  115. ; now, the masking method basically could have been implemented in two ways:
  116.  
  117. ; either using 0xFB39DEBF or its binary complement 0x04C62140. a quick search
  118.  
  119. ; revealed that the first value was used, as it was stored in the data area
  120.  
  121. ; of the program (you can find it in the executable if you search for it).
  122.  
  123. ; now, all i had to do was to find the code that referenced this value (which
  124.  
  125. ; IDA did for me automatically) and see how it was used.
  126.  
  127. ;
  128.  
  129. ; so, the hidden check works this way:
  130.  
  131. ;
  132.  
  133. ; 2.1 read 0xFB39DEBF from the data area and then NOT it
  134.  
  135. ; 2.2 AND the registration number and the mask computed in step.2.1
  136.  
  137. ; 2.3 substract 0x822040 from the number computed in step.2.2
  138.  
  139. ; 2.4 if the result is not zero, then set a variable to 0x930 in the data area
  140.  
  141. ; 2.5 later, during burning, check whether that variable mentioned in the
  142.  
  143. ;     previous step is equal to 0x930 or not. if it is then write some random
  144.  
  145. ;     data into the current sector being written
  146.  
  147. ;
  148.  
  149. ; so, all we have to make sure is that the substraction done in step.2.3 will
  150.  
  151. ; result in 0 (in this case that memory variable will contain a 0 by default).
  152.  
  153. ; i guess, from this point on it is very trivial what those 8 bits have to be
  154.  
  155. ; set to. if not then have a look at the code below ;).
  156.  
  157. ;-----------------------------------------------------------------------------
  158.  
  159.  
  160.  
  161. .model tiny
  162.  
  163. .code
  164.  
  165. .386
  166.  
  167. org 100h
  168.  
  169. main:
  170.  
  171.  
  172.  
  173.         push cs
  174.  
  175.         pop ds
  176.  
  177.         mov dx,offset(presentation)
  178.  
  179.         mov ah,09h
  180.  
  181.         int 21h
  182.  
  183.  
  184.  
  185.         mov ah,0ah
  186.  
  187.         mov dx,offset(keyb_buffer)
  188.  
  189.         int 21h
  190.  
  191.  
  192.  
  193.         cmp byte ptr [string_length],06h
  194.  
  195.         jb not_enough_char_4_name
  196.  
  197.  
  198.  
  199.         mov esi,offset(DAO_REG_TABLE)
  200.  
  201.         call magic_num_calc
  202.  
  203.         push eax
  204.  
  205.  
  206.  
  207.         mov esi,offset(CDRWIN_REG_TABLE)
  208.  
  209.         call magic_num_calc
  210.  
  211.  
  212.  
  213.         rol eax,10h
  214.  
  215.         mov dword ptr [offset(magic1)],eax
  216.  
  217.  
  218.  
  219.         mov dx,offset(ask_company)
  220.  
  221.         mov ah,09h
  222.  
  223.         int 21h
  224.  
  225.  
  226.  
  227.         mov ah,0ah
  228.  
  229.         mov dx,offset(keyb_buffer)
  230.  
  231.         int 21h
  232.  
  233.  
  234.  
  235.         cmp byte ptr [string_length],06h
  236.  
  237.         jb not_enough_char_4_company
  238.  
  239.  
  240.  
  241.         mov esi,offset(DAO_REG_TABLE)
  242.  
  243.         call magic_num_calc
  244.  
  245.         push eax
  246.  
  247.  
  248.  
  249.         mov esi,offset(CDRWIN_REG_TABLE)
  250.  
  251.         call magic_num_calc
  252.  
  253.         xor eax,dword ptr [offset(magic1)]
  254.  
  255.  
  256.  
  257. ;------------Fixing Calculated key in order to make it real-----------
  258.  
  259.         and eax,0FB39DEBFh
  260.  
  261.         or  eax,00822040h
  262.  
  263. ;---------------------------------------------------------------------
  264.  
  265.  
  266.  
  267.         mov bx,offset(CDRWIN31eRegCode)+9
  268.  
  269.         call hex2dec
  270.  
  271.  
  272.  
  273.         mov ah,09h
  274.  
  275.         mov dx,offset(HereisCDRWIN31e)
  276.  
  277.         int 21h
  278.  
  279.  
  280.  
  281.         pop ebx
  282.  
  283.         pop eax
  284.  
  285.         rol eax,10h
  286.  
  287.         xor eax,ebx
  288.  
  289. ;------------Fixing Calculated key in order to make it real-----------
  290.  
  291.         and eax,0FB39DEBFh
  292.  
  293.         or  eax,00822040h
  294.  
  295. ;---------------------------------------------------------------------
  296.  
  297.  
  298.  
  299.         mov bx,offset(DAO31eRegCode)+9
  300.  
  301.         call hex2dec
  302.  
  303.  
  304.  
  305.         mov ah,09h
  306.  
  307.         mov dx,offset(HereisDAO31e)
  308.  
  309.         int 21h
  310.  
  311.  
  312.  
  313. prog_ends_ok:
  314.  
  315.         mov ax,4C00h
  316.  
  317.         int 21h
  318.  
  319.  
  320.  
  321. hex2dec proc near
  322.  
  323.         mov ecx,000ah
  324.  
  325.         xor edx,edx
  326.  
  327.         div ecx
  328.  
  329.         add dl,30h
  330.  
  331.         mov [BX],dl
  332.  
  333.         dec bx
  334.  
  335.         or eax,eax
  336.  
  337.         jnz hex2dec
  338.  
  339.  
  340.  
  341.         ret
  342.  
  343.         endp
  344.  
  345.  
  346.  
  347. not_enough_char_4_name:
  348.  
  349.         mov dx,offset(toofew4name)
  350.  
  351.         jmp print_error
  352.  
  353. not_enough_char_4_company:
  354.  
  355.         mov dx,offset(toofew4cie)
  356.  
  357. print_error:
  358.  
  359.         mov ah,09h
  360.  
  361.         int 21h
  362.  
  363.         mov ax,4Cffh
  364.  
  365.         int 21h
  366.  
  367.  
  368.  
  369. MAGIC_NUM_CALC PROC NEAR
  370.  
  371.         xor eax,eax
  372.  
  373.         mov ebx,offset(string)
  374.  
  375.  
  376.  
  377.         push word ptr string_length
  378.  
  379. keep_calc:
  380.  
  381.         xor edx,edx
  382.  
  383.         mov DL,[EBX]
  384.  
  385.         INC EBX
  386.  
  387.         mov ECX,EDX
  388.  
  389.         shr edx,02h
  390.  
  391.         xor ecx,eax
  392.  
  393.         shr eax,04h
  394.  
  395.         and ecx,0000000fh
  396.  
  397.         mov ecx,[ecx*4+esi]
  398.  
  399.         xor ecx,eax
  400.  
  401.         lea eax,[ecx*4+0]
  402.  
  403.         shr ecx,04h
  404.  
  405.         xor eax,edx
  406.  
  407.         and eax,3ch
  408.  
  409.         mov eax,[esi+eax]
  410.  
  411.         xor eax,ecx
  412.  
  413.         DEC byte ptr [offset(string_length)]
  414.  
  415.         jnz keep_calc
  416.  
  417.         pop word ptr string_length
  418.  
  419.         ret
  420.  
  421.         endp
  422.  
  423.  
  424.  
  425. CDRWIN_REG_TABLE:
  426.  
  427.         DB 000h,000h,000h,000h,07Eh,088h,03Eh,01Ch,0FCh,010h,07Dh,038h,082h,098h,043h,024h
  428.  
  429.         DB 0F8h,021h,0FAh,070h,086h,0A9h,0C4h,06Ch,004h,031h,087h,048h,07Ah,0B9h,0B9h,054h
  430.  
  431.         DB 0F0h,043h,0F4h,0E1h,08Eh,0CBh,0CAh,0FDh,00Ch,053h,089h,0D9h,072h,0DBh,0B7h,0C5h
  432.  
  433.         DB 008h,062h,00Eh,091h,076h,0EAh,030h,08Dh,0F4h,072h,073h,0A9h,08Ah,0FAh,04Dh,0B5h
  434.  
  435.  
  436.  
  437. DAO_REG_TABLE:
  438.  
  439.         DB 000h,000h,000h,000h,0C0h,0ADh,055h,019h,080h,05Bh,0ABh,032h,040h,0F6h,0FEh,02Bh
  440.  
  441.         DB 000h,0B7h,056h,065h,0C0h,01Ah,003h,07Ch,080h,0ECh,0FDh,057h,040h,041h,0A8h,04Eh
  442.  
  443.         DB 000h,06Eh,0ADh,0CAh,0C0h,0C3h,0F8h,0D3h,080h,035h,006h,0F8h,040h,098h,053h,0E1h
  444.  
  445.         DB 000h,0D9h,0FBh,0AFh,0C0h,074h,0AEh,0B6h,080h,082h,050h,09Dh,040h,02Fh,005h,084h
  446.  
  447.  
  448.  
  449. magic1: DB 00h,00h,00h,00h
  450.  
  451.  
  452.  
  453. presentation:
  454.  
  455.         DB 0ah,0dh
  456.  
  457.         DB ' 100% Key-Generator for DAO 3.1e/CDR-Win 3.1e, hidden check supported 26-06-97',0ah,0dh
  458.  
  459.         DB ' ---[Brought to you by #cracking]---------------------------------------------',0ah,0dh,0ah,0dh
  460.  
  461.         DB ' Produces original keys, you won''t fuck CDs with it! CDRWIN/DAO both tested.',0ah,0dh
  462.  
  463.         DB ' Thanks to Midi-Man for testing with his rewritable.',0ah,0dh,0ah,0dh
  464.  
  465.  
  466.  
  467. ask_name:
  468.  
  469.         DB 'Enter your name (min 6 char): $'
  470.  
  471.  
  472.  
  473. ask_company:
  474.  
  475.         DB 0ah,0dh
  476.  
  477.         DB 'Enter your company (min 6 char): $'
  478.  
  479.  
  480.  
  481. toofew4name:
  482.  
  483.         DB 0dh,0ah,0dh,0ah
  484.  
  485.         DB 'At least 6 characters for name needed$'
  486.  
  487.  
  488.  
  489. toofew4cie:
  490.  
  491.         DB 0dh,0ah,0dh,0ah
  492.  
  493.         DB 'At least 6 characters for company needed$'
  494.  
  495.  
  496.  
  497. HereisCDRWIN31e:
  498.  
  499.         DB 0dh,0ah,0dh,0ah
  500.  
  501.         DB 'CDRWIN 3.1e : '
  502.  
  503.  
  504.  
  505. CDRWIN31eRegCode:
  506.  
  507.         db '          $'
  508.  
  509.  
  510.  
  511. HereisDAO31e:
  512.  
  513.         DB 0dh,0ah
  514.  
  515.         DB 'DAO 3.1e    : '
  516.  
  517.  
  518.  
  519. DAO31eRegCode:
  520.  
  521.         db '          $'
  522.  
  523.  
  524.  
  525. keyb_buffer:
  526.  
  527.         DB 80h
  528.  
  529. string_length:
  530.  
  531.         DB 00h
  532.  
  533. string:        
  534.  
  535.         end     main
  536.  
  537.