⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dao31e.asm

📁 破解很多程序的序列号算法程序
💻 ASM
字号:




;-----------------------------------------------------------------------------

; 100% keygenerator for CDR-Win 3.1e/DAO 16/32 3.1e

; coded 06/26/97

; full credits go to the guy who localised the hidden check.

; do_what_you_want_with_it_source

; compile : tasm dao31e-k

;           tlink /t /3 dao31e-k

;-----------------------------------------------------------------------------



; some notes on the registration check by the guy mentioned above ;)

;

; the registration algorithm works this way:

; 1.1 compute 32 bit hash value from user name (must be at least 6 chars)

; 1.2 swap upper and lower 16 bits of this hash value

; 1.3 compute 32 bit hash value from company name (must be at least 6 chars)

; 1.4 XOR 32 bit numbers computed in step.1.2 and step.1.3 with each other

; 1.5 convert registration number (which is an ascii string) to a 32 bit number

;     by calling atol() (this is a C library function)

; 1.6 compare 24 bits of the two numbers we got in step.1.4 and step.1.5

; 1.7 if they match (in those 24 bit positions) then accept registration

;

; wow, now we know how to compute the registration number!

;

; well, at least this is what all crackers thought when they were tracing

; through the registration code. it seems that nobody had a second thought

; about the fact that only 24 bits were checked/compared, 8 bits were simply

; ignored, thus making key generators where those 8 bits were chosen randomly

; (usually taken from the number computed in step.1.4)

;

; however, later people noticed that certain types of CDs were fucked up

; 'cos apparently some random data was written into some sectors (which

; made the CD unusable). rumour went around stating that there was a second

; or hidden check in the program.

;

; well, as you probably found out by now this hidden check does exist indeed!

; to find it i used IDA, probably one of the best disassemblers ever made.

; (i didn't use WINICE at all)

;

; this is how i approached the problem: first, i had to find out what those

; 24 bits were that were checked during registration. this was easy, however

; i'd like to point out that the checking algorithm is extremly lame (well,

; maybe it was intentional to confuse the crackers) 'cos instead of using

; a bitmask to mask out the uninteresting 8 bits and then doing a simple cmp,

; the author wrote a for loop in which he compared 24 of 32 bits, one by one.

;

; the bits to be compared were determined by a table of 32 entries, where each 

; entry (a 0 or 1) corresponded to a bit position, namely a 1 caused a bit 

; position to be compared (i.e. there are 24 1s and 8 0s in that table).

; btw, the effective bitmask in the comparison is 0xFB39DEBF.

;

; after learning this, i assumed that in the hidden check only the remaining

; 8 bits were checked, either by using the table of 1s and 0s mentioned above

; (which was not the case, as IDA didn't find any more references to it) or

; by using the more effective masking method (which turned out to be the case).

;

; now, the masking method basically could have been implemented in two ways:

; either using 0xFB39DEBF or its binary complement 0x04C62140. a quick search

; revealed that the first value was used, as it was stored in the data area

; of the program (you can find it in the executable if you search for it).

; now, all i had to do was to find the code that referenced this value (which

; IDA did for me automatically) and see how it was used.

;

; so, the hidden check works this way:

;

; 2.1 read 0xFB39DEBF from the data area and then NOT it

; 2.2 AND the registration number and the mask computed in step.2.1

; 2.3 substract 0x822040 from the number computed in step.2.2

; 2.4 if the result is not zero, then set a variable to 0x930 in the data area

; 2.5 later, during burning, check whether that variable mentioned in the

;     previous step is equal to 0x930 or not. if it is then write some random

;     data into the current sector being written

;

; so, all we have to make sure is that the substraction done in step.2.3 will

; result in 0 (in this case that memory variable will contain a 0 by default).

; i guess, from this point on it is very trivial what those 8 bits have to be

; set to. if not then have a look at the code below ;).

;-----------------------------------------------------------------------------



.model tiny

.code

.386

org 100h

main:



        push cs

        pop ds

        mov dx,offset(presentation)

        mov ah,09h

        int 21h



        mov ah,0ah

        mov dx,offset(keyb_buffer)

        int 21h



        cmp byte ptr [string_length],06h

        jb not_enough_char_4_name



        mov esi,offset(DAO_REG_TABLE)

        call magic_num_calc

        push eax



        mov esi,offset(CDRWIN_REG_TABLE)

        call magic_num_calc



        rol eax,10h

        mov dword ptr [offset(magic1)],eax



        mov dx,offset(ask_company)

        mov ah,09h

        int 21h



        mov ah,0ah

        mov dx,offset(keyb_buffer)

        int 21h



        cmp byte ptr [string_length],06h

        jb not_enough_char_4_company



        mov esi,offset(DAO_REG_TABLE)

        call magic_num_calc

        push eax



        mov esi,offset(CDRWIN_REG_TABLE)

        call magic_num_calc

        xor eax,dword ptr [offset(magic1)]



;------------Fixing Calculated key in order to make it real-----------

        and eax,0FB39DEBFh

        or  eax,00822040h

;---------------------------------------------------------------------



        mov bx,offset(CDRWIN31eRegCode)+9

        call hex2dec



        mov ah,09h

        mov dx,offset(HereisCDRWIN31e)

        int 21h



        pop ebx

        pop eax

        rol eax,10h

        xor eax,ebx

;------------Fixing Calculated key in order to make it real-----------

        and eax,0FB39DEBFh

        or  eax,00822040h

;---------------------------------------------------------------------



        mov bx,offset(DAO31eRegCode)+9

        call hex2dec



        mov ah,09h

        mov dx,offset(HereisDAO31e)

        int 21h



prog_ends_ok:

        mov ax,4C00h

        int 21h



hex2dec proc near

        mov ecx,000ah

        xor edx,edx

        div ecx

        add dl,30h

        mov [BX],dl

        dec bx

        or eax,eax

        jnz hex2dec



        ret

        endp



not_enough_char_4_name:

        mov dx,offset(toofew4name)

        jmp print_error

not_enough_char_4_company:

        mov dx,offset(toofew4cie)

print_error:

        mov ah,09h

        int 21h

        mov ax,4Cffh

        int 21h



MAGIC_NUM_CALC PROC NEAR

        xor eax,eax

        mov ebx,offset(string)



        push word ptr string_length

keep_calc:

        xor edx,edx

        mov DL,[EBX]

        INC EBX

        mov ECX,EDX

        shr edx,02h

        xor ecx,eax

        shr eax,04h

        and ecx,0000000fh

        mov ecx,[ecx*4+esi]

        xor ecx,eax

        lea eax,[ecx*4+0]

        shr ecx,04h

        xor eax,edx

        and eax,3ch

        mov eax,[esi+eax]

        xor eax,ecx

        DEC byte ptr [offset(string_length)]

        jnz keep_calc

        pop word ptr string_length

        ret

        endp



CDRWIN_REG_TABLE:

        DB 000h,000h,000h,000h,07Eh,088h,03Eh,01Ch,0FCh,010h,07Dh,038h,082h,098h,043h,024h

        DB 0F8h,021h,0FAh,070h,086h,0A9h,0C4h,06Ch,004h,031h,087h,048h,07Ah,0B9h,0B9h,054h

        DB 0F0h,043h,0F4h,0E1h,08Eh,0CBh,0CAh,0FDh,00Ch,053h,089h,0D9h,072h,0DBh,0B7h,0C5h

        DB 008h,062h,00Eh,091h,076h,0EAh,030h,08Dh,0F4h,072h,073h,0A9h,08Ah,0FAh,04Dh,0B5h



DAO_REG_TABLE:

        DB 000h,000h,000h,000h,0C0h,0ADh,055h,019h,080h,05Bh,0ABh,032h,040h,0F6h,0FEh,02Bh

        DB 000h,0B7h,056h,065h,0C0h,01Ah,003h,07Ch,080h,0ECh,0FDh,057h,040h,041h,0A8h,04Eh

        DB 000h,06Eh,0ADh,0CAh,0C0h,0C3h,0F8h,0D3h,080h,035h,006h,0F8h,040h,098h,053h,0E1h

        DB 000h,0D9h,0FBh,0AFh,0C0h,074h,0AEh,0B6h,080h,082h,050h,09Dh,040h,02Fh,005h,084h



magic1: DB 00h,00h,00h,00h



presentation:

        DB 0ah,0dh

        DB ' 100% Key-Generator for DAO 3.1e/CDR-Win 3.1e, hidden check supported 26-06-97',0ah,0dh

        DB ' ---[Brought to you by #cracking]---------------------------------------------',0ah,0dh,0ah,0dh

        DB ' Produces original keys, you won''t fuck CDs with it! CDRWIN/DAO both tested.',0ah,0dh

        DB ' Thanks to Midi-Man for testing with his rewritable.',0ah,0dh,0ah,0dh



ask_name:

        DB 'Enter your name (min 6 char): $'



ask_company:

        DB 0ah,0dh

        DB 'Enter your company (min 6 char): $'



toofew4name:

        DB 0dh,0ah,0dh,0ah

        DB 'At least 6 characters for name needed$'



toofew4cie:

        DB 0dh,0ah,0dh,0ah

        DB 'At least 6 characters for company needed$'



HereisCDRWIN31e:

        DB 0dh,0ah,0dh,0ah

        DB 'CDRWIN 3.1e : '



CDRWIN31eRegCode:

        db '          $'



HereisDAO31e:

        DB 0dh,0ah

        DB 'DAO 3.1e    : '



DAO31eRegCode:

        db '          $'



keyb_buffer:

        DB 80h

string_length:

        DB 00h

string:        

        end     main

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -