Tutorial On How To Keygen Icon Extractor 3.0
By YoKe!

1: Numega Softice 4.05
Icon Extractor 3.0
3: Some asm knowlege
4: Patience can help...

Icon extractor 3.0
Author: YoKe
Group : tCA
Level : Intermediate

In this tutorial I donít say how to code a keygen, I teach you how to find the serial code generating algorithm and how it works so if you want you can make a keygen in the preferred language of your choice!

The following information is to be used for educational purposed only!!!
Lets Get Started....  :)
Load up Softice into Windows and start Icon Extractor 3.0 Damn you see an ugly nag screen saying unregistered and other crap. Were going to fix this! When the nag screen closes, click on Help, then Register...
Now we see 3 text fields:
1: User name
2: Organisation
3: Registration

Enter in your Name: YoKe, Organisation: tCA2k and a dummy Registration: 987656789
Click OK and crap we get a "An invalid software registration code was detected!"
But then again it was obvious that would happen so Softice comes into play NOW!  hehe :)
Press CTRL+D and Softice hits your screen. We need to know how icon extractor retrieves the text in the text fields but I'm not here to teach you how do find that, instead I'll just tell you for your convenience! It uses USER32!GetDlgItemTextA, so now we must make softice break when this import function is called, so in softice type bpx getdlgitemtexta and hit enter. Now press F5 to exit softice and hit OK in the Icon Extractor registration dialog. Now softice should be back on your screen due to the breakpoint. Press F5 2 times (serial field) then press F11 to return to the caller and you should see the following:

:004074CA     lea       eax, dword ptr [esp+10]       <--  you are here..  your name is in esp+10
:004074CE     push     eax                                       <--  pointer to our name
:004074CF     call       0040CE20                           <--  do some crap checks on the info we entered
:004074D4     add      esp, 00000004                     
:004074D7     mov     ebp, eax                                <--  move our fake serial in eax to ebp stack
:004074D9     push    004186E8                             <--  useless text you see on the dialog
:004074DE     push    esi                                         <--  our name!
:004074DF    Call      [KERNEL32!lstrcmp]           <--  common in string comparisons...
:004074E5     test      eax, eax                                 <--  test the value of eax
:004074E7     jne       0040750D                             <--  and jump if not = to 0 

Woo Hoo! do you understand all that happens above? If no... don't worry I'll explain, but we haven't even got to the code that generates the real serial!
from above you see our name is put to eax and the call at 00407CF does some checks on it. Move down the lines by pressing F10 in softice, press until you are on the line 00407CE, now enter d eax you should our name. Ok press F10 until you reach the line 004074E7, this jump will be took if any info was entered so press F10 and softice takes this jump, now you should see:

:0040750D     push   ebx                                       <--  our  organisation
:0040750E     push    esi                                        <--  our  name
:0040750F     call      0040B570                          <--  generate the real code!!!
:00407514     add      esp, 00000008                    
:00407517     cmp     eax, ebp                               <--  compare ebp (fake serial) with eax (Real serial!) type ? eax to see it!
:00407519     je         00407539                            <--  jump to good code if the 2 serials are equal

I hope you can see whatís going on here, first it holds our name and organisation in ebx and esi, then calls the serial generating routine, it then compares our serial with the real one and if they are equal, it jumps to code that show the good dialog box and enter the reg info into the registry, since we are doing a keygen, finding the serial is not good enough so we must go into the call at 0040750F and see whatís happening there! Now press F10 until you are on the line: :0040750F     call  0040B570 and press F8 to enter this call, now you should see:

:0040B570    mov    eax, dword ptr [esp+04]          <--  our fake serial
:0040B574    push    esi                                           <--  our name in esi
:0040B575    mov    esi, dword ptr [00418314]         
:0040B57B    push   eax                                         <--  pointer to our name
:0040B57C   or        esi, 00000378                        <--   3976827102 is ored with 0x378 (888) to make:  3976827902
:0040B582   call      0040CA40                            <--  calculate a number from our name!!
:0040B587    add     esp, 00000004
:0040B58A   add     esi, eax                                  <--  and add it to esi (3976827902) 
:0040B58C   mov    eax, dword ptr [esp+0C]       <--  reference to our fake serial...
:0040B590   push    eax                                        <--  pointer to our organisation string!!
:0040B591  call      0040CA40                            <--  calculate a number from the organisation string (same call as above!)
:0040B596   add      esp, 00000004
:0040B599   add      eax, esi                                  <-- adds the previous result of esi to this new number from the call above
:0040B59B  pop      esi                                         <-- restore
:0040B59C  ret                                                     <-- return to the caller

I think you can see what goes on here... I'll explain anyway. First it gets our name and then does a call at: 0040CA40
Then in that call it generates a number from our name (we will look at how it does this later) and adds this number to: 3976827902. Then it does the same for the organisation, it then adds the number generated from the organisation field to the previous calculated number.
Ok you are on line: 0040B570  mov eax, dword ptr [esp+04] Now press F10 until you are at: 0040B582 and type ? esi and hit enter. Now you should see: 3976827902 This number seems to be a constant value. Keep this number in mind. What we want to do now is see how a number is calculated from our name. Hit F8. Now we are close to the serial generating code... 

note: ecx starts of at the value of 0 and increases by one at each loop, edx starts of at 1 and increased by 1 each loop until it reached the length of our name 
The texts with [] I use to show that these are variables that change and are to be evaluated  eg: get the [loop#] character of our name, so if it was the second loop then it means: get the 2nd character of our name             

There is 2 table strings that are used in the calculation. type d 0041B704 also the other enter one d 0041B73C
string1: #serB&nz|mfM1/5(!sd$Mq.{s]+sFjtKpzSdtzoXqmb^Al@dv:s?x/
string2: |b!pz*ls;rn|lf$vi^Axpe)rx5aic&9/2m5lsi4@0dmZw94cmqpfhw

Tracing down a bit I have found the code so press F10 and you should see:

:0040CA60    movsx   ebx, byte ptr [eax+ecx+0041B704]   <-- ebx = get the [length of name+loop#] character of string1
                                                                                                   and take its ascii value...
:0040CA68    movsx   ebp, byte ptr [ecx+esi]                       <-- ebp = get the [loop#] char of our name... in ascii 
:0040CA6C    lea        edx, dword ptr [ecx+01]                   <-- this increases ecx by 1 and edx by 1 
:0040CA6F    imul       ebx, ebp                                            <-- multiply the 2 ascii results got from above (ebp * ebx)
:0040CA72    movsx   ecx, byte ptr [ecx+0041B73C]          <-- ecx = get the [loop#] char of string2... in ascii
:0040CA79    imul       ebx, ecx                                            <-- multiply ecx with ebx from previous function
:0040CA7C   imul      ebx, edx                                             <-- multiply the result with edx
:0040CA7F   add       edi, ebx                                              <-- edi = 0 first loop. edi is added to ecx each loop
:0040CA81    mov      ecx, edx                                             <-- number of char of name were on (eg 1st) is moved to ecx
:0040CA83    cmp     edx, eax                                              <-- are we done with all characters of name?
:0040CA85    jl          0040CA60                                         <-- if not jump back up to 0040CA60 (loop)     else.....
:0040CA87    mov     eax, edi                                               <-- the serial generated here is moved to eax ...note this!
... more code ...
:0040CA8D   ret                                                                   <-- return back to 0040B587

Ok I'll try my best to summaries just what happens here. I hope you'll understand. 
(I find this is the hardest part in writing a tutorial is know how the protecting works but actually explaining it in text :)

Here is a (kindof) detailed analysis of the values etc. that go on in the loop: 
(take loop 1, since its loop 1, ecx will be equal to 0, eax is the name length so its 4 [YoKe])

movsx   ebx, byte ptr [eax+ecx+string1]  <-- get a character of string1, eax(4) + ecx(0), 4 + 0 = 4, so the the character after 
                                                                     the fourth character in string1 which is 'B', get its ascii value which is set to ebx,                                                                      ascii of 'B' is '66'
movsx   ebp, byte ptr [ecx+esi]                <-- get a character of our name, ecx(0), esi is our name 'YoKe', so it gets the                                                                        chararacter after char number 0 of our name which is 'Y' and set its ascii value                                                                        to ebp,  ascii of 'Y' is '89' 
lea        edx, dword ptr [ecx+01]             <-- this sets a value to edx, ecx is 0, but it sets edx to ecx+1 (0+1) so edx = 1  
imul       ebx, ebp                                     <-- multiply ebx by ebp, (66 * 89 = 5874)                      
movsx   ecx, byte ptr [ecx+string2]          <--  get a character of string2, ecx = 0 so the the character after the 0th character in                                                                        string2, so it gets '|' and the ascii of '|' is '124' and is set to ecx
imul       ebx, ecx                                     <-- multiply value of ebx by ecx, (5874 * 124 =  728376)                        
imul      ebx, edx                                      <-- multiply ebx by edx, 728376 * 1 = 728376                          
add       edi, ebx                                      <-- this adds ebx to edi, edi is 0. (728376 + 0 = 728376), the reason for this code
                                                                      here is every time it loops the value of ebx from this loop will be added to the                                                                       value of ebx on the next loop and so on...
mov      ecx, edx                                      <-- move the value of edx to ecx, this in a way increases ecx every loop as edx 
                                                                      is increased and then it is set to ecx, edx = 1, so now ecx = 1
                                                                      (note each loop edx will be set to the char number we are on, since we are on 
                                                                       'Y',  edx = 1)
cmp     edx, eax                                       <--  compare eax with edx, eax is the length of your our which is 4, edx is the                                                                        number of the character we are on which is 1 (Y)
jl          Serial_Routine                              <--  if edx is lower than eax, jump back and start loop again, this time with ecx at 1                                                                        and edx at 2, so 'o' of our name will be the main consern. And so on...
mov     eax, edi                                         <-- move the final code generated to eax and...
ret                                                             <-- ...return to the caller with this value!

This exact process is then done for the organisation string. If you remember from a good bit above, the code generated from the name is added to 3976827902 and then the result of this is then added to the code generated form the organisation.

:0040B582    call      0040CA40                           <--  calculate a number from our name!!  (7892110)
:0040B587    add     esp, 00000004
:0040B58A   add     esi, eax                                  <--  and add it to esi (3976827902 + 7892110 = 3984720012) 
:0040B58C   mov    eax, dword ptr [esp+0C]       <--  reference to our fake serial...
:0040B590   push    eax                                        <--  pointer to our organisation string!!      
:0040B591   call      0040CA40                           <--  calculate a number from the organisation string (12668212)
:0040B599   add      eax, esi                                 <-- adds the previous result of esi to this new number from the code 
                                                                                   generated from the serial to make the final working serial!!                                                                                    (3984720012 + 12668212 = 3997388224)

In other words:
1. Base serial = 3976827902
2. Add base serial code generated from our name(eax) Then the result is set to esi
3. Add the serial code generated form our organisation(eax) to esi and leave in eax - THIS IS THE FINAL SERIAL!! :)
4. Return to caller
5. Compare the real serial to the one we entered to decide whether show a good msg box or a bad one...

Name: YoKe     Code Generated From Name:          7892110                           Name: YoKe
                                                     Base Serial:    3976827902                           Organisation: tCA2k
Org:   tCA2k     Code Generated From Org   :  +    12668212                           Real Serial: 3997388224
                                      Final working Serial!:     3997388224

There you have it, I hope you have enough information here to write a keygen. Delphi, C, C++ or ASM are the most suitable
If you do, please send me your source code as my coding is not the best!
Note- if you made a keygen form this tutorial, it will work for newer versions of Icon Extractor like 3.5 and possible future release versions as the serial algorithm will be the same :)

Any questions? Mail me: yoke@tca2k.net
Visit tCA Home Page: tHE cRACKiNG aNSWER

Greetings fly out to:
ThrawN, r00t_HT, sEVanDo2k, TiVe, NaRRoW, NADA, kOBoLD666, Subzonic, kab00m, TheSilent, TheScream, Apus, Speedystep,  ZuleikaH, BlackEvil, kaggedaMC, Acid Cool 178, SnAkE, _4saken_, bOOm51, SirL, Senf, macbain2k, DArth, R!SC, M_, Master2k, TSCHENLONG, NeTSurfeR, Skycracker, The.$tar, Tapete, S\ashZer0, ScIpPeR, and whoever I forgot....