Welcome to cheekey's Cracking Tutorial #1! Blind Angel asks why i don't write tut's ? so here is one: Target: Disk Archie 1.1 (http://software.freepage.de/hjensen/diskarc.htm) Protection: Serial Solution: KeyGen Toolz: Softice 4.x Ok i hope you know how to use softice (setting breakpoints, etc.) so let's start - start disk archie click "enter register data" and enter some register data ... - set a breakpoint (bpx hmemcpy ; why hmemcpy ? bcz it mostly workx ;) - click ok and when softice pops trace through the code until you see this : (i often read "press xx times F12 to get back to the proggie", sorry i dunno how often you've to press F12 bcz my softice is always at the right point ;) :00448548 E8ABB0FBFF call 004035F8 //get the length of name :0044854D 83F809 cmp eax, 00000009 //compare with 9 :00448550 0F8E64010000 jle 004486BA //if less or equal jump to bad cracker if not ... go on :00448556 8B45F0 mov eax, dword ptr [ebp-10] // do some fucking shit to prepare for ... :00448559 E81EDBFBFF call 0040607C // ... getting the fake serial :0044855E 8945E4 mov dword ptr [ebp-1C], eax // save the fake serial for later comparing with the real one (type "? eax" to get your fake serial) :00448561 8B45F4 mov eax, dword ptr [ebp-0C] // do some fucking shit to prepare for ... :00448564 E88FB0FBFF call 004035F8 // getting the length of the name again (see :00448548 ) :00448569 8945EC mov dword ptr [ebp-14], eax // save the lenght of name for later :0044856C 33C0 xor eax, eax // eax = 0 :0044856E 8945E0 mov dword ptr [ebp-20], eax // ebp-20 = 0 :00448571 8B45EC mov eax, dword ptr [ebp-14] // gets the length see :00448569 :00448574 85C0 test eax, eax // if length = 0 then ... :00448576 7E27 jle 0044859F // ... jump to :0044859F :00448578 8945D8 mov dword ptr [ebp-28], eax // saves the length ... :0044857B C745E801000000 mov [ebp-18], 00000001 //ebp-18 = 1 :00448582 8B45F4 mov eax, dword ptr [ebp-0C] - + preparing some shit :00448585 8B55E8 mov edx, dword ptr [ebp-18] | edx = counter every time the routine is called again edx = edx +1 (see :00448597) :00448588 8A4410FF mov al, byte ptr [eax+edx-01] | al = ascii code of current char :0044858C 8845DF mov byte ptr [ebp-21], al | save it for two lines down :0044858F 33C0 xor eax, eax | eax = 0 :00448591 8A45DF mov al, byte ptr [ebp-21] | al = ascii code of current char (see two lines higher) :00448594 0145E0 add dword ptr [ebp-20], eax | save it for 4 lines down :00448597 FF45E8 inc [ebp-18] | ebp-18 = ebp-18 + 1 :0044859A FF4DD8 dec [ebp-28] | if length of name = ebp-18 (means that the shit is calculated for every char; example: name: "cheekey [l2c]" so it does this routine 13 times ) then ... :0044859D 75E3 jne 00448582 - + ... it goes on with the code (no jump back to start of the routine) :0044859F 8B45E0 mov eax, dword ptr [ebp-20] // eax = all the ascii codes of the chars (see 4 lines higher) added together :004485A2 F76DEC imul [ebp-14] // eax = eax * length of name :004485A5 8945E0 mov dword ptr [ebp-20], eax // eax * length of name :004485A8 8B45EC mov eax, dword ptr [ebp-14] // gets the length of the name (see :00448569 ) :004485AB 0145E0 add dword ptr [ebp-20], eax // adds to (eax * length of name) the length; so: eax = all ascii codes * length of name + length of name :004485AE 8B45F4 mov eax, dword ptr [ebp-0C] // does some shit to get ... :004485B1 8A4001 mov al, byte ptr [eax+01] // ... the ascii value of the second char (example: name: "cheekey [l2c]" ; type "? al" and you get the ascii code of the "h" ... 104 ) :004485B4 8845DF mov byte ptr [ebp-21], al // saves al for later using (see :004485B9; :004485C4 and :004485CC ) :004485B7 33C0 xor eax, eax // eax = 0 :004485B9 8A45DF mov al, byte ptr [ebp-21] // gets al back ... now eax = ascii value of second char :004485BC F76DE0 imul [ebp-20] // eax = (all ascii codes * length of name + length of name) * ascii value of second char :004485BF 8945E0 mov dword ptr [ebp-20], eax // save it for later using :004485C2 33C0 xor eax, eax // eax = 0 :004485C4 8A45DF mov al, byte ptr [ebp-21] // gets ascii code of second char ... you now have to know it ;) :004485C7 0145E0 add dword ptr [ebp-20], eax // adds al (eax=al because of :004485C "xor eax, eax" ) ... :004485CA 33C0 xor eax, eax // eax = 0 :004485CC 8A45DF mov al, byte ptr [ebp-21] // whatta you think ? ;) :004485CF F76DEC imul [ebp-14] // second char * length :004485D2 0145E0 add dword ptr [ebp-20], eax // add it again so that ... :004485D5 8B45E0 mov eax, dword ptr [ebp-20] // ... eax = (all ascii codes added together * length of name + length of name) * ascii value of second char + ascii value of second char + ascii value of second char * length of name :004485D8 3B45E4 cmp eax, dword ptr [ebp-1C] //serial compare (see :0044855E ) :004485DB 7574 jne 00448651 //if not equal jump to badcracker so what it does ? it checks whether the name got at least 10 chars ( cmp eax, 00000009 and test eax, eax ) and then calculates the serial: serial = (all ascii codes added together * length of name + length of name) * ascii value of second char + ascii value of second char + ascii value of second char * length of name Example: name: cheekey [l2c] serial = ( 1207 * 13 + 13 ) * 104 + 104 + 104 * 13 = 1634672 ok here is the VB code for a keygen (create two textboxes and one button) ... --------------------------------------------------------------------------------------------------------------------------------------------------------------- Private Sub Command1_Click() If Len(Text1.Text) <= 9 Then MsgBox prompt:="you have to enter at least 10 chars !" Else For i = 1 To Len(Text1.Text) serial = serial + Asc(Mid(Text1.Text, i, 1)) Next serial = (serial * Len(Text1.Text) + Len(Text1.Text)) * Asc(Mid(Text1.Text, 2, 1)) + Asc(Mid(Text1.Text, 2, 1)) + Asc(Mid(Text1.Text, 2, 1)) * Len(Text1.Text) Text2.Text = serial End If End Sub --------------------------------------------------------------------------------------------------------------------------------------------------------------- and here is the c++ (i use the BCB 4 ) code-snippet for a keygen (create two textboxes and one button) ... --------------------------------------------------------------------------------------------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { AnsiString strSerial = Edit1->Text; int iFertig = 0; if (strSerial.Length() > 9) { for (int i = 1; i <= strSerial.Length(); i++) { iFertig += static_cast(strSerial[i]); } iFertig = iFertig * strSerial.Length() + strSerial.Length(); iFertig = iFertig * static_cast(strSerial[2]) + static_cast(strSerial[2]) + static_cast(strSerial[2]) * strSerial.Length(); Edit2->Text = iFertig; } else { Edit2->Text = "You have to enter at least 10 chars"; } } --------------------------------------------------------------------------------------------------------------------------------------------------------------- for those who thinks "to keygen the prog" is too difficult for them: ok you see "cmp eax, dword ptr [ebp-1C]" this is the serial compare, enter "? eax" and not down what eax contains ... disable bpx hmemcpy ("bc*") and enter the value of eax as serial ... =) it's your code ! ... so the "jne 00448651" at :004485DB jumps if the serial is incorrect to "bad cracker" and if it's the right one nothing happens and the proggie goes on ... and says "good cracker". Example: name: cheekey [l2c] Key: 1634672 you registered the prog and wanna unregister it ? edit the "diskarc.ini" in your windows dir ! ok thats @ll folks ... how contact me: mail:cheekey99@hotmail.com efnet: #learn2crack #gwa #kraecker WWW: http://www.learn2crack.org Greetz: Gizmo, cg!, MooLoK, lord natas (your script r0x), [Ra], Apophis, adenozin, b00m, Shi, Lazarus, ultraschall, controller, confuse PC, s0nyk, Ridlexx, BlindAngel, abex, Lady Die, Tapete CrazyKnight, DiGiB0y, Cardenal Mendoza, MikeVD, PeeGee, PhatAzz, berserk4, si0nide, sn00pe(thx for fxping me the x-mas present for my mother ;), and all the ppl i forgot ... and look out for my learn2crackme #3 !