www.pudn.com > Kgensrcs.zip > ID3-SER.ASM
; Serial Number generator by Lord Soth. Version 1.0 ; for ID crackme number 3. ; Any comments are welcome, but will be ignored :) ;----------------------------------------------------------------- model compact .data querystr db 'Enter your soon to be registered name: $' headline db 'Immortal Descendants CrackMe 3 serial number generator!$' sernumstr db 'Your serial number is: $' creditstr db 'Cracked and brought to you by Lord Soth!!$' zerostr db 'ERROR: Zero length string.$' username db 256 DUP (0) ; max length of string that can be brought by a dialog box str_out db 12 DUP (0) ; length of final serial ser_len dw 0000 .code .startup .386C MOV AH,0 MOV AL,3 INT 10h ; set normal text video mode. MOV AX,0625h ; set 25 lines to scroll up MOV BH,1Fh ; set color attribute for blank chars MOV CX,0000 ; set upper-left corner of window MOV DX,184Fh ; set lower-right corner of window INT 10h ; fill screen with blue death :) push ds pop es mov ah,13h mov al,1 mov bh,0 mov bl,0eh mov cx,37h mov dx,0 mov ebp,offset es:headline ; this will print the headline string.. int 10h MOV Ah,3 MOV BH,0 INT 10h ; get cursor position ADD DH,2 ; go down 2 lines MOV AH,2 MOV DL,0 PUSH DX MOV BH,0 INT 10h ; set cursor on new position POP DX MOV AH,13h MOV AL,1 MOV BX,1Fh MOV CX,27h ; 39 chars to print MOV EBP,offset ES:querystr ; load offset of string INT 10h ; print the damn string :) ; get the user name from the user, of course.. who did u think? :) MOV CX,0FFh ; counter from 255 to 0 (bytes read) mov bx,0 ; pointer for memory LEA DI,username KBread: MOV AH,0 INT 16h ; get char from keyboard MOV BX,CX OR BX,0FF00h NOT BX ; BX will be used to point to the memory where char is stored CMP AH,1Ch ; check for Enter pressed JZ CreateUserName ; Bug outa here CMP AH,0Eh ; check for backspace JNZ store CALL delchar JMP Kbread store: MOV [DI+BX],AL ; store ASCII byte in username buffer MOV AH,0Ah MOV BX,0 PUSH CX ; store counter on stack MOV CX,1 INT 10h ; print the char on screen MOV AH,3 INT 10h ; get cursor position INC DL ; increase X pos by 1 MOV AH,2 MOV BH,0 INT 10h ; set on new pos POP CX LOOP KBread ; get another char (CX decreases) ; Create the REAL username the program has to calculate the serial from CreateUserName : NOT CL ; reversing CX makes it the string length CMP CL,0 ; if no chars, get outa here :) JNZ contuser ; JMP out_of_prog ; this is a fixed JMP, if your calculation routine is long ; this might be needed contuser: MOV AX,0 ; initailize to 0 LEA SI,username ; pointer to the username we entered MOV CX,5 ; 5 chars to process MOV BX,0 ; set BX to 0 LEA DI,str_out ; load target string offset into EDI :) ;Calculation of the serial number , those 4 little lines :) calc: MOV AL,[SI+BX] ; get char CALL num2str ; turn it into an ASCII digit INC BX ; next char LOOP calc ; all over again.. ;Get string length and check against 10, which is max LEA SI,str_out MOV DI,SI not_end: INC SI CMP BYTE PTR [SI],0 ; check for end of string JNZ not_end SUB SI,DI ; substract will give the length CMP SI,0Ah ; compare to 10 JLE good_num ; if 10 or less, continue, this is a good number MOV SI,0Ah ; if more than 10, set to 10, coz 10 is the max the prog uses.. good_num: MOV WORD PTR [ser_len],SI ; store length of serial number MOV AH,3 MOV BX,0 INT 10h ; get cursor position ADD DH,2 MOV DL,0 MOV AX,1301h MOV BX,1Fh MOV CX,17h ; 23 chars to print - "Your serial number...." MOV EBP,offset sernumstr INT 10h MOV AH,3 MOV BX,0 INT 10h ; get cursor position MOV CX,WORD PTR [ser_len] ; get serial length MOV AX,1301h MOV BX,1Fh MOV EBP,offset str_out INC EBP INT 10h ; print serial number MOV AH,3 MOV BX,0 INT 10h ; get cursor position ADD DH,3 ; increase Y pos by 3 MOV DL,0 ; X pos = 0, start of line MOV AX,1301h MOV BX,1Fh MOV CX,29h MOV EBP,offset creditstr INT 10h ; print my name POP BP MOV AX,4C00h INT 21h ; get da fuck outa here :) out_of_prog : MOV AH,3 MOV BX,0 INT 10h ; get cursor position MOV AX,1301h MOV DL,0 ADD DH,3 MOV BX,1Fh MOV CX,1Ah ; 26 chars to print, "ERROR: Zero length..." MOV EBP,offset ES:zerostr INT 10h POP BP MOV AX,4C00h INT 21h ; get outa here, no chars in username delchar PROC near PUSH CX PUSH AX CMP BX,0 JZ nochars MOV BYTE PTR [DI+BX],0 ; store null char on the buffer DEC BX ; reduce memory pointer by 1 PUSH BX MOV BH,0 MOV AH,3 INT 10h ; get cursor position DEC DL MOV AH,2 MOV BH,0 INT 10h ; set it on X-1 pos MOV AX,0A20h ; store "space" on screen pos MOV BX,0 MOV CX,1 INT 10H ; write space on screen POP BX POP AX POP CX INC CX ; increase CX, coz it normally decreases ; and we want to go back 1 char RET ; return to caller nochars:MOV BX,0 ; zero out BX, no chars to del POP AX POP CX ; free stack MOV CX,0FFh ; zero out counter, intial value is FFh RET delchar ENDP num2str PROC near ; AX assumed to hold the 3 digit number ; BX used in indirection to put the ASCII in memory ; CX used to divide by 100, 10 etc..... PUSH CX MOV CX,64h ; to divide by 100, find hundreds-digit CWD IDIV CX CMP AX,0 JZ zero_dig ADD AX,30h ; add 30h to make it ASCII MOV [EDI],AL SUB AX,30h ; return me to normal numbers INC EDI zero_dig:MOV CX,0Ah MOV AX,DX CWD IDIV CX ADD AX,30h ADD DX,30h MOV [EDI],AL INC EDI MOV [EDI],DL INC EDI POP CX RET num2str ENDP .exit END