How To Register Ani Message 3.0 -------------------------------- A key generator (in asm) by Mister Legend target: AniMessage 3.0 (http://www.msinet.net/videoman/AMsg98P.EXE) tools: Softice for windows 95 (v3.22) it's really kewl! Tasm 5.0 for creating the keymaker settings: Make sure the data window and the registers window are visible in softice, you can do this by typing data 1 (for the data) and pressing F2 (for the registers). In this tut i will teach you how to make a key generator, and everything that comes with it. Okay let's start PART ONE: ANALYZING THE SERIAL CALCULATION PROCESS Run AniMessage. You'll get a nag screen. Click it away. AMsg allows you to enter your name and reg code. Enter something. I entered as name MrLegend 98, and 76543212 as my serial. You can enter any name you want, but make sure it contains a few lowercase chars and that it's unique at you computer, so don't enter Jack if all your documents contain that name....You need to follow these instructions in order to find it back in softice. Hit enter Nice error: "Whoops! Please try again." As if it knows that you are a cracker ;) Okay get into softice (ctrl-d) and set a breakpoint on GetWindowTextA and GetDlgItemTextA: >bpx getwindowtexta >bpx getdlgitemtexta Press ctrl-d again to leave softice. Back in AMsg Hit enter again and softice will break on getwindowtexta Hit f12 (go to next return) 7 times, until you are back in the right procedure. What happened: AMsg got your name. search for the entered name in memory by typing: >s 0 l ffffffff '[name]' You will find your name. I found mine at location: 0157:0079218C but that could be different for you. Don't worry if so See that call to :0040D0DA ? press F10 until the white bar is at the call. Stop there. Keep looking at your name in the data window and press F10 one more time. hey! My name changed from MrLegend 98 to MRLEGEND 98: it is uppercased in the call. Get a pen and something to write on. write: 1) Name is uppercased That's the first one. now let's go on. You'll see this: :0040B67F 8B4D00 mov ecx, dword ptr [ebp+00] ;load name location in ecx :0040B682 33F6 xor esi, esi ;esi = 0 :0040B684 33C0 xor eax, eax ;eax = 0 :0040B686 8B51F8 mov edx, dword ptr [ecx-08] ;load length of name in edx :0040B689 85D2 test edx, edx ;check if length = 0 :0040B68B 7E0B jle 0040B698 ;if so, skip the loop :0040B68D 0FBE1C08 /movsx ebx, byte ptr [eax+ecx] ;load value of char(eax) in ebx :0040B691 03F3 | add esi, ebx ;add value to esi (esi is sum) :0040B693 40 loop | inc eax ;increase eax :0040B694 3BC2 | cmp eax, edx ;is eax equal to edx? (finished?) :0040B696 7CF5 \jl 0040B68D ;no? then goto next character That's the next one, write it down: 2) The values of the characters in the name are all put together in esi What next: surprise: when you have reached 40B6A0, type >? ecx guess what: ecx contains the integer value of what you just entered as your serial! :0040B698 B800000A00 mov eax, 000A0000 ;eax = 0xA0000 (655360) :0040B69D 8B4F64 mov ecx, dword ptr [edi+64] ;ecx = integer value of entered reg code :0040B6A0 2BC6 sub eax, esi ;substract ecx from eax(0xA0000) next step: 3) the sum of all characters is substracted from 0xA0000 and substraction is put in eax write it down. Let's go on: :0040B6A2 6A00 push 00000000 ;0 on stack, only to confuse you :0040B6A4 99 cdq ;??? makes edx equal to 0 :0040B6A5 33C2 xor eax, edx ;76543212 xor 00000000 = 76543212 :0040B6A7 6A00 push 00000000 ;0 on stack, only to confuse you :0040B6A9 2BC2 sub eax, edx ;substracts 0 from eax, does nothing :0040B6AB 3BC1 cmp eax, ecx ;THE check: is eax equal to ecx? :0040B6AD 0F85EF000000 jne 0040B7A2 ;if not: BAD JUMP! :0040B6B3 68B0714100 push 004171B0 ;from this point we are registered :0040B6B8 E891180000 Call 0040CF4E ; users (if we reach it) 4) eax must be equal to the integer value of the entered registration code. Now we have the whole scheme: [ 0)AniMessage gets your name ] 1) Name is uppercased 2) The values of the characters in the name are all put together in esi 3) the sum of all characters is substracted from 0xA0000 and substraction is put in eax 4) eax must be equal to the integer value of the entered registration code. Be careful, reversing "integrization" of your code in asm is quite complicated for a newbie :) Ok. Now we know all about the serial calculation! Let's make a keygenerator... PART TWO: THE KEYGENERATOR The keygenerator must basically contain the following procedures: first part, actually a copy of the program's scheme: 1) Get Name 2) Uppercase name 3) Put values of name characters together 4) Substract sum from 0xA0000 (call the new value "CalcVal", i'll use it later) Second part, reverse now to the wanted serial, more complicated now. 5) We must reverse the integer value to an ascii string, as the output for our key generator. I made the following loop for it: start loop: divide CalcVal by 10 add 30h (48) to rest-value, new value is a character, a part of our serial put character on the stack jump to start loop to generate the next character (until CalcVal = 0) end loop 5a) for example, if CalcVal is 123: integer devide of 123 by 10 makes 12 rest 3 add 30h to 3 and we have the 3rd character, "3", put it on the stack integer devide of 12 by 10 makes 1 rest 2 add 30h to 2 and we have the 2nd character, "2", put it on the stack integer devide of 1 by 10 makes 0 rest 1 add 30h to 1 and we have the 1st character, "1", put it on the stack 5b) since we calculate the characters from right to left, as you must understand, i decided to put the char values one by one on the stack and then get them back (first one on top of stack). Picture put it on the stack get it back from the stack from right to left: from left to right "3 2 1" "1 2 3" | | | | |1| |1| | | | | | | |2| |2| |2| |2| | | |3| |3| |3| |3| |3| |3| ~~~~~~~~~~~ ~~~~~~~~~~~ And then, we have part 6 of course: 6) Print serial on the screen This is how the keygenerator would be like: ----------------------------------------key.asm----------------------------------------------- .MODEL SMALL .STACK 100h .386P .DATA input DB 22h,0 serial DB 50h dup ('$') prompt DB 'Input name : ','$' done DB 'Your serial is : ','$' lf DB 0ah,0dh,'$' intro DB 0ah,0dh, '-------------*-------------',0ah,0dh DB ' AniMessage 3.0 keymaker ',0ah,0dh DB ' by Mister Legend ',0ah,0dh DB '===========================',0ah,0dh,'$' .CODE START: MOV AX,@DATA MOV DS,AX ; just make sure DS points to data segment MOV ES,AX ; and ES :) (Corn2's words) LEA EDX,[intro] MOV AH,09h INT 21h ; show intro message LEA EDX,[prompt] MOV AH,09h INT 21h ; show prompt LEA EDX,[input] MOV AH,0Ah INT 21h ; 1) get name LEA EDX,[lf] MOV AH,09h INT 21h CMP BYTE PTR [input+1],00 ; no input? bah JE lamer ; bail. (Corn2's words) LEA EDI,input+2 XOR EAX,EAX MOVZX EBX,BYTE PTR [EDI-1] ; get length of name PUSH EBX XOR ECX,ECX upcloop: MOV AL, BYTE PTR [EDI+ECX] ; CMP AL,61h ; JB nolow ; CMP AL,7Ah ; 2) this is JA nolow ; the SUB AL,20h ; uppercase MOV BYTE PTR [EDI+ECX],AL ; loop nolow: ; INC ECX ; DEC EBX ; TEST EBX,EBX ; JNZ upcloop ; XOR EAX,EAX XOR ECX,ECX XOR ESI,ESI POP EBX firstloop: MOV CL, BYTE PTR [EDI+EAX] ; 3) get char value and ADD ESI, ECX ; add it to esi DEC EBX INC EAX TEST EBX,EBX ; finished? JNZ firstloop ; if not, get next character MOV EAX,000A0000h SUB EAX,ESI ; 4) substract sum from 0xA0000 XOR EBX,EBX LEA EDI,[serial] XOR ECX,ECX MOV ECX,0Ah secloop: XOR EDX,EDX DIV ECX ; 5a) divide CalcVal by ten ADD EDX,30h ; add 30h to rest value PUSH EDX ; put it on stack INC EBX ; counter one up TEST EAX,EAX ; is eax = 0 ? JNZ secloop ; if not, divide again XOR EDX,EDX XOR EAX,EAX thirdloop: POP EDX ; 5b) get character from stack MOV BYTE PTR [EDI+EAX],DL ; paste it to the serial INC EAX TEST EBX,EBX DEC EBX ; counter one down JNZ thirdloop ; if not finished, get next char from stack MOV BYTE PTR [EDI+EAX],'$' ; this pastes the end char to the serial LEA EDX,[done] MOV AH,09h INT 21h ; print "Your serial is :" LEA EDX,[serial] MOV AH,09h INT 21h ; 6) print serial! LEA EDX,[lf] MOV AH,09h INT 21h ; print linefeed lamer: LEA EDX,[lf] MOV AH,09h INT 21h MOV AX,4C00h INT 21h END START ----------------------------------------EOF--------------------------------------------------- For the "frame" of my generator i used some code that i got from Corn2. I want to thank him for it :) ANOTHER APPROACH: PATCHING Though I prefer a keymaker, there IS another way for cracking the program, it is patching. This is the routine where AMsg get's the entered name and code (if any. if none it takes "STILL TESTING" as you name: stupid!). Then it checks it like it does when entering the shit. Not exactly in the same way, but almost exactly in the same way :) I found this code simply by searching (in w32dasm) for the code where the program puts 000A0000 in eax. easy, huh? These are the important lines a little below that code: :00409FA0 8A10 mov dl, byte ptr [eax] :00409FA2 8ACA mov cl, dl :00409FA4 3A16 cmp dl, byte ptr [esi] :00409FA6 751A jne 00409FC2 ;1st bad jump :00409FA8 84C9 test cl, cl :00409FAA 7412 je 00409FBE :00409FAC 8A5001 mov dl, byte ptr [eax+01] :00409FAF 8ACA mov cl, dl :00409FB1 3A5601 cmp dl, byte ptr [esi+01] :00409FB4 750C jne 00409FC2 ;2nd bad jump :00409FB6 03C3 add eax, ebx :00409FB8 03F3 add esi, ebx :00409FBA 84C9 test cl, cl :00409FBC 75E2 jne 00409FA0 ;we don't want to go back :00409FBE 33C0 xor eax, eax :00409FC0 EB05 jmp 00409FC7 ;this is the place to be =) so you gotta change the three bad jne's into three je's ! i'll help you saving your precious time ;) with this: 75 stands for jne(Jump if Not Equal), 74 for je(guess what this means...) offset 00409FA6 in code is offset 93A6 in file, change 751A into 741A offset 00409FB4 in code is offset 93B4 in file, change 750C into 740C offset 00409FBC in code is offset 93BC in file, change 75E2 into 74E2 You could use any hex editor for this, that's it! I hope you enjoyed this tut, and that you could figure it out a bit. Read my next tuts too! Yours faithfully, Mister Legend/iNSiDE - '98 (contact me at #cracking4newbies or #iNSiDE)