Tutorial #SLS02
mIRC 5.71 (C) by mIRC Co. Ltd.
7 Dec.
2000 
by Skizo
7 Dec.
2000 
* SkiZo^ Lost Soul * member of Da Breaker Crew *

About mIRC

This program is a chat, and is very good!! I often use it, but... something doesn't work:
it should be registered. OK, let's register our chat!! ;-)

PS (19/05/2001): the keygen done with this tutorial works fine with the last version of mIRC too (5.9) so I suppose that the algorythm is the same, but the addresses may change

In the cold of the night, in the warmth of the breeze,
I'll come cracking around, with tutorials like this! ;-)

Skill Level
[  ] None - [  ] Easy - [X] Medium - [  ] Hard - [  ] Punishment 
Skill Level
HUMANITAS IUSTITIAM NOSQUAM RENUIT
GRANDEM MALIGNITATEM COGNOSCENDO



Introduction 

Cracking this program, I've learned something that I'll explain during the essay, but I want to say that for me it was an hard work. While I was doing this keygen, I was thinking that it should be an hard work for all the newbies, but I was wrong: I discovered that for someone it's impossible to do in a week of cracking activity. Anyway I did it, and I want you to be happy like me: nothing is impossible, there is only an hard work to do. So follow me in this essay and be ready to learn a lot from this hard battle.
Let me tell you that [...] means that I haven't copyed that part of code, because it was useless.



Required Tools 
 - Soft Ice (You can find it on http://www.crackstore.com/)


Program's URL 
 http://www.mirc.co.uk/


The Essay 


Here we go...
Start mIRC, click on Help and then on Register. There are two input boxes, one for the user name and one for the registration number. Write Skizo and 12345-123456, then enter in Sice with CTRL+D and set the breakpoint for the boxes reading (bpx getdlgitemtexta). Press F5 to enter mIRC and then click on register. Failed. Shit. Back in Sice, and then we'll try with bpx getwindowtexta. Failed again. What the fuck. Back in Sice again, but this time we won't make mistakes: bpx hmemcpy. Click Register and Sice pops up, then press one time F11, 5 times F12 and 56 times F10 to skip the libraries and go directly to the source fie. When we are in the source file, we can see a call to SENDDLGITEMMESSAGEA. For first we must write down this call, then we can go ahead with F10. After some lines, we will see this:

   CS:004A33B2   CALL   004A2F9C
   CS:004A33B7   TEST   EAX, EAX            ; Typical test
   CS:004A33B9   JZ     004A345A            ; and typical jump

Step over the call and the test (with F10), and when you are on the jump, switch the zero flag off (the zero flag activated is represented by the Z in capital letter, so you must put the cursor on the Z and press Ins to switch it off). Press F5 and your registration will be accepted. Easily, isn't it? Nope. You can see that on the Help menu there isn't the Registration submenu anymore, but when u close and load again mIRC it will tell you that you have an unlicensed version. That's because on every mIRC start it checks the registration number. There are now two solutions: the first is to leave PC on for all the day, but I don't think that your parents will be happy of this; the second one is to make a Keygen. I prefer the last one. So: go back on CS:004A33B2, and this time step into the call (with F8). When I was at this point, I've started checking every single routine, and I will tell you the addresses of the most important (the ones that can teach you something), while I'll rewrite the ones that are needed for the keygen. Where we were? Oh, yeah. Press some times F10 until you'll fly here:

  CS:004A2FF4   PUSH   005425DC            ; Stores the Registration number
  CS:004A2FF9   PUSH   005A24DC            ; Stores the User name
  CS:004A2FFE   CALL   004A2EA4

Something was telling me that that call should give me the right serial number. To check the addresses you can write d 005425DC, or right click on the address and click on display. Step into the call and go ahead until you can see this:

  CS:004A2EAD   MOV    ESI, [EBP+0C]       ; Moves the serial number in ESI
  CS:004A2EB0   MOV    EAX, [EBP+08]       ; Moves the user name in EAX
                [...]
  CS:004A2EC6   PUSH   2D                  ; Ascii char of -
  CS:004A2EC8   PUSH   ESI                 ; Stores Serial 12345-123456
  CS:004A2EC9   CALL   00401278            ; Puts in EAX the address of -123456
  CS:004A2ECE   ADD    ESP, 08
  CS:004A2ED1   MOV    EBX, EAX            ; Moves in EBX the address of -123456
  CS:004A2ED3   TEST   EBX, EBX            ; Checks it
  CS:004A2ED5   JNZ    004A2EDE            ; And jumps to 004A2EDE if EBX is not 0
                [...]
  CS:004A2EDE   MOV    BYTE PTR [EBX], 00  ; Puts 00 in the place of -
  CS:004A2EE1   PUSH   ESI                 ; ESI contains the address of 12345_123456
                                           ; where the _ is the char 00. EBX is a pointer to
                                           ; the char -, of the string putted in ESI, so
                                           ; changing the first char of EBX it changes ESI
  CS:004A2EE2   CALL   0040C50C            ; This routine, puts in EAX the first part's value
  CS:004A2EE7   POP    ECX
  CS:004A2EE8   MOV    [EBP-04], EAX       ; Stores the first part's value
  CS:004A2EEB   MOV    BYTE PTR [EBX], 2D  ; Replace the char 00 with the char -
  CS:004A2EEE   INC    EBX
  CS:004A2EEF   CMP    BYTE PTR [EBX], 00
  CS:004A2EF2   JNZ    004A2EFB            ; If there is a second part then jump
                [...]
  CS:004A2EFB   PUSH   EBX
  CS:004A2EFC   CALL   0040A500
  CS:004A2F01   POP    ECX
  CS:004A2F02   MOV    [EBP-08], EAX       ; Stores the second part's value
  CS:004A2F05   MOV    EDX, [EBP+O8]       ; Puts in EDX the user name
  CS:004A2F08   PUSH   EDX
  CS:004A2F09   CALL   401318              ; Puts in EAX the length of the user name
  CS:004A2F0E   POP    ECX
  CS:004A2F0F   MOV    [EBP-0C], EAX       ; Stores the length of user name
  CS:004A2F12   XOR    EAX, EAX
  CS:004A2F14   XOR    EBX, EBX
  CS:004A2F16   MOV    EDX, 00000003
  CS:004A2F1B   MOV    ECX, [EBP+08]
  CS:004A2F1E   MOV    ECX, 03
  CS:004A2F21   CMP    EDX, [EBP-0C]
  CS:004A2F24   JGE    004A2F42            ; Jumps if the lenght of user name is 3 or less
  CS:004A2F26   MOVZX  ESI, BYTE PTR [ECX]
  CS:004A2F29   IMUL   ESI, [EAX*4+0052158C]
  CS:004A2F31   ADD    EBX, ESI
  CS:004A2F33   INC    EAX
  CS:004A2F34   CMP    EAX, 26             ; The array has 26h values, so if the letters to
                                           ; read are more than 26h, at the 27h resets EAX
  CS:004A2F37   JLE    004A2F3B
  CS:004A2F39   XOR    EAX, EAX
  CS:004A2F3B   INC    EDX
  CS:004A2F3C   INC    ECX
  CS:004A2F3D   CMP    EDX, [EBP-0C]       ; Is ended the reading of the user name?
  CS:004A2F40   JL     004A2F26
  CS:004A2F42   CMP    EBX, [EBP-04]       ; EBX contains the right first part of our reg #
  CS:004A2F45   JZ     004A2F4B

Now we must look at the address 004A2F29. WHAT'S THAT??? I've taken some hour to understand what it was: is an array, an array of DWORDS. The multiplication is between the ascii char and the EAX value of the array. It takes the first ascii code, it multiplicates for Array[0], then takes the second ascii code and it multiplicates for Array[1]. The sum of this multiplications is stored in EBX. So at the address 004A2F42, in EBX is contained the right first part of our registration number. You can see the array values in the VB keygen that I have done for you.
When u'll arrive on 004A2F42, write down the ebx value (7DB, 2008), set here a breakpoint and then press F5.
Reload the Registration dialog box, write Skizo and 2008-123456 and click Registration. Sice pops up and the value of EBX is the same of [EBP-04]: everything is ok now, and we can look for the second part of our registration code. The source is the following:

  CS:004A2F4B   XOR    EAX, EAX
  CS:004A2F4D   XOR    EBX, EBX
  CS:004A2F4F   MOV    EDX, 00000003
  CS:004A2F54   MOV    ECX, [EBP+08]       ; Moves in ECX the user name
  CS:004A2F57   ADD    ECX, 03             ; Starts from the fourth char
  CS:004A2F5A   CMP    EDX, [EBP-0C]
  CS:004A2F5D   JGE    004A2F82            ; Jumps if the reading of the user name is ended
  CS:004A2F5F   MOVZX  ESI, BYTE PTR [ECX]
  CS:004A2F62   MOVZX  EDI, BYTE PTR [ECX-1]
  CS:004A2F66   IMUL   ESI, EDI
  CS:004A2F69   IMUL   ESI, [EAX*4+0052158C]
  CS:004A2F71   ADD    EBX, ESI
  CS:004A2F73   INC    EAX
  CS:004A2F74   CMP    EAX, 26
  CS:004A2F77   JLE    004A2F7B
  CS:004A2F79   XOR    EAX, EAX
  CS:004A2F7B   INC    EDX
  CS:004A2F7C   INC    ECX
  CS:004A2F7D   CMP    EDX, [EBP-0C]       ; Is finished the reading of chars?
  CS:004A2F80   JL     004A2F5F
  CS:004A2F82   CMP    EBX, [EBP-08]       ; EBX contains the right second part of our reg #
  CS:004A2F85   JZ     004A2F8B

What does this routine? Takes a char (starting from the fourth) and his precedent, multiplicates them ascii codes, and then multiplicates the result with a value of the array. And oviously stores the final results in EBX, so standing on 004A2F82, we can wee the last part of our registration number, that is 363D2h (222162).
So: delete all breakpoint, press F5 and will appear the failing message (of course, we are only trying ;-) ). Reload for the last time the Registration dialog box and write Skizo and 2008-222162.
Everything is OK and the registration is regular.
Now using RegEdit.EXE or something similar, you must find the mIRC folder, look for the user name and change it. Why? Because I don't think that you want Skizo as user name :)
Changing it the mIRC will show again the registration dialog box, so you will be able to Keygen it and insert whatever you want. If you want to check the array, you should write under Sice and when u are inside the keygen routine (for example at 004A2F69) d 0052158C. You will be able to see 26h DWORDS, write it down and do the array like I did in the following VB Keygen.



The VB Keygen 
 Private Sub ShowKey()
   'Text1.Text = Username       | Min 4 chars |
   Static Already As Boolean, MyTable(&H26)
   If Already = False Then
     MyTable(0) = 11:   MyTable(1) = 6:    MyTable(2) = 17:   MyTable(3) = 12
     MyTable(4) = 12:   MyTable(5) = 14:   MyTable(6) = 5:    MyTable(7) = 12
     MyTable(8) = 16:   MyTable(9) = 10:   MyTable(10) = 11:  MyTable(11) = 6
     MyTable(12) = 14:  MyTable(13) = 14:  MyTable(14) = 4:   MyTable(15) = 11
     MyTable(16) = 6:   MyTable(17) = 14:  MyTable(18) = 14:  MyTable(19) = 4
     MyTable(20) = 11:  MyTable(21) = 9:   MyTable(22) = 12:  MyTable(23) = 11
     MyTable(24) = 10:  MyTable(25) = 8:   MyTable(26) = 10:  MyTable(27) = 10
     MyTable(28) = 16:  MyTable(29) = 8:   MyTable(30) = 4:   MyTable(31) = 6
     MyTable(32) = 10:  MyTable(33) = 12:  MyTable(34) = 16:  MyTable(35) = 8
     MyTable(36) = 10:  MyTable(37) = 4:   MyTable(38) = 16
   End If
   If Len(Text1.Text) < 4 Then Text2.Text = "": Exit Sub
   CL = 0
   For C = 4 To Len(Text1.Text)
      Valore = Asc(Mid$(Text1.Text, C, 1)) * MyTable(CL)
      FirstPart = FirstPart + Valore
      CL = CL + 1
      If CL > &H26 Then CL = 0
   Next
   CL = 0: Valore = 0
   For C = 4 To Len(Text1.Text)
      Valore = Asc(Mid$(Text1.Text, C - 1, 1)) * Asc(Mid$(Text1.Text, C, 1))
      SecondPart = SecondPart + Valore * MyTable(CL)
      CL = CL + 1
      If CL > &H26 Then CL = 0
   Next
   Text2.Text = LTrim$(Str$(FirstPart)) + "-" + LTrim$(Str$(SecondPart))
 End Sub

 Private Sub Text1_Change()
    ShowKey
 End Sub


Final Notes 

So we have finally did the Keygen. I'm hoping that you have learned something more, because is what I did: I've learned a lot cracking this program. If you like this tutorial contact me, because I want to know if my tutorials are read and if it's a real help for newbies like me (I've started my cracking activity from two weeks) ;)
Oh, that's something funny: open the About dialog box and then write "ARNIE", doesn't matter if in small or capital letters. The author will change himself in a sweet sweet peluche.

PEACE ON EARTH




E-Mail: Skizo@DBC2000.ORG
URL: http://kickme.to/skizo