=================== Keygenning Resource Builder (Update Pack 1) =================

 

                a tutorial by j!m published by +Tsehp October 2001

 

---------------------------------------------------------------------------------

Target: resource builder (update pack 1) from SiComponents.

Where : www.votum.md/sicmps/

tools : softice, borland C++, Hedit.

 

A word about the protection:

the shareware version works without any limitations, no time limits or annoying

things except a little message box when you launch the program, asking you for registering.

 

This tutorial is for newbies, it will explain you how to register this program in

two ways:

 

first method: computing a valid serial

 

second method: patching the program

---------------------------------------------------------------------------------

ok let's go!

 

***********************

1-Enter the cave...   *

***********************

 

launch resource builder 1.0, enter the help menu and choose register...

Enter a serial into the registratio

n key field : 12345678 for example.

ctrl+D to enter softice and put a breakpoint: bpx hmemcpy, ctrl+D to

go back to windows.

Press the OK button, softice should pop up!

 

*******************

2-Light a torch...*

*******************

 

play with F12 (about 5 or 6 times) until you enter Resbldr code, and then trace into (F8 key) until you reach

the following instructions:

 

              mov eax, dword ptr [ebp-04]

              call 49D260

              mov esi, eax

              lea edx, dword ptr [ebp-08]

              mov eax, dword ptr [ebx+000002D4]

              call 436AF8

              mov eax, dword ptr [ebp-08]

              call 49D260

              xor eax, dword ptr [004C4198]

              sub esi, eax

              jne bad_serial

 

press F8 one more time to execute the first mov and type: d eax, you should see in the

data window the serial you have entered.

 

***************************

3-Dislodge the monster... *

***************************

 

press F8 to enter the Call 4

9D260.

the code of the function is given here after, i have put comments in front of the interesting lines:

 

:00000000 CC                      push ebp

:00000001 8BEC                    mov ebp, esp

:00000003 83C4F4                  add esp, FFFFFFF4

:00000006 56                      push esi

:00000007 57                      push edi

:00000008 8945FC                  mov dword ptr [ebp-04], eax

:0000000B 8B45FC                  mov eax, dword ptr [ebp-04]

:0000000E E8A56DF6FF              call 404018

:00000013 33C0                    xor eax, eax

:00000015 55                      push ebp

:00000016 68F5D24900              push 0049D2F5

:0000001B 64FF30                  push dword ptr fs:[eax]

:0000001E 648920                  mov dword ptr fs:[eax], esp

:00000021 33C0                    xor eax, eax

:00000023 8945F8                  mov dword ptr [ebp-08], eax

:00000026 8B45FC                  mov eax, dword ptr [ebp-04]

:00000029 E8D66BF6FF              call 403E64                     ;get length

:000000

2E 83F808                  cmp eax, 00000008                ;must be 8 chars!!

:00000031 754C                    jne finished

:00000033 8B45FC                  mov eax, dword ptr [ebp-04]

:00000036 E8C96BF6FF              call 403E64

:0000003B 8BF8                    mov edi, eax

:0000003D 85FF                    test edi, edi

:0000003F 7E3E                    jle finished

 

:00000041 BE01000000              mov esi, 00000001               ;first char in string

:00000046 C745F418414C00          mov [ebp-0C], 004C4118          ;serial table address

 

one_more_car:                     xor edx, edx                    ;edx = 0

:0000004F 8B45F4                  mov eax, dword ptr [ebp-0C]           ;serial table address

 

still_check:                      mov ecx, dword ptr [ebp-04]           ;string address

:00000055 8A4C31FF                mov cl, byte ptr [ecx+esi-01]         ;get byte

:00000059 3A08                    cmp cl, byte ptr [eax]          ;compare

:0000005B 7513                    jne next_car

 

:0000005D 8BC6                    mov eax, esi                    ;which char is it (f

irst, second ...) ?

:0000005F 48                      dec eax                   ; - 1

:00000060 8BC8                    mov ecx, eax

:00000062 C1E102                  shl ecx, 02                     ; * 4

:00000065 33C0                    xor eax, eax                    ;eax = 0

:00000067 8AC2                    mov al, dl                      ;which index in serial tab

:00000069 D3E0                    shl eax, cl                     ;shift

:0000006B 0145F8                  add dword ptr [ebp-08], eax           ;compute value   

:0000006E EB07                    jmp next_car2

 

next_car:                         inc edx                   ;one more char checked

:00000071 40                      inc eax                   ;next char in table

:00000072 80FA10                  cmp dl, 10                      ;16 chars checked?

:00000075 75DB                    jne still_check

 

next_car2:                        inc esi                   ;next char in string

:00000078 8345F410                add dword ptr [ebp-0C], 00000010      ;next entry in the serial table

:0000007C 4F                      dec edi                   ;still some chars to check?

:0000007D 75CE           

         jne one_more_car

 

finished:                         xor eax, eax

:00000081 5A                      pop edx

:00000082 59                      pop ecx

:00000083 59                      pop ecx

:00000084 648910                  mov dword ptr fs:[eax], edx

:00000087 68FCD24900              push 0049D2FC

:0000008C 8D45FC                  lea eax, dword ptr [ebp-04]

:0000008F E8D468F6FF              call 403BC8

:00000094 C3                      ret

 

trace with F8 and F10 (skip the calls) until you reach the mov [ebp-0C], 004C4118 and type d 4c4118 to show

the data at this address.

You should see a weird sequence of characters! go on tracing into the algorithm and try to understand it ;-),

until you are back in the main piece of code.

 

The algorithm is quite simple:

------------------------------

The table at address 4C4118 is an array of 8 lines and 16 columns:

 

aABW0xL9DsdfrvS4

HcZD2nJ3eh5SkVwg

JSz3fCN4EHeA5G0W

rsW6kL37RP1Q8p05

Yxv2uK58twXgkm3y

iGN8Ua39cWOXpH2k

IjmP4s82TeLK9dh

O

OplL8Q01t25fu37w

 

for each character in the string you typed, the function searches this char in the table

according to its position in the string (first char will be searched in the first line of the table...)

and puts the index found in eax ,

the index is a 4 bit value (0-15) and eax is a 32 bits register, 32/4 = 8, the 8 indexes fit in the word!.

 

for example, If you type 4gW5ykOw as registration key, eax should be FFFFFFFF because index of '4' is 0xF, index of 'g' is 0xF...

 

before the call 42D260, eax = @string you entered

after the call, eax=40060340 (if you typed 12345678)

so, f(12345678) = 40060340

 

go on tracing,

before the second call 42D260, eax = @reg_id (d eax gives fVCskaTl for me but it should be different in your version)

after the call, eax = 285C15DB (different for you but it doesn't matter)

f(fVCskaTl) = 285C15DB (0xB is index of 'f', 0xD is index of 'V', and so on...)

 

after that the program tests :

 

f(reg_ID) xor Internal_key == f(registration key)

 

Internal_ke

y = 0xCFFF34BC (dword ptr [004C4198])

 

*********************

4-Kill the beast!!  *

*********************

 

so all we have to do is to compute f(-1)( f(reg_ID) xor Internal_key ),

 

here is the C implementation for this

<----------------------------------------------------------------------------->

//resource builder 1.0 keygen by j!m

//04-10-2001

 

#include <stdio.h>

#include <string.h>

#include <conio.h>

 

int main() {

      char c;

      char regID[8];

      char vserial[8];

      char table[8][16] = { "aABW0xL9DsdfrvS4",

                       "HcZD2nJ3eh5SkVwg",

                       "JSz3fCN4EHeA5G0W",

                       "rsW6kL37RP1Q8p05",

                         "Yxv2uK58twXgkm3y",

                         "iGN8Ua39cWOXpH2k",

                       "IjmP4s82TeLK9dhO",

                       "OplL8Q01t25fu37w" };

     

      unsigned int i,j;

      unsigned int k = 0xcfff34bc;

 

      printf("Enter your Reg ID [8 chars] : ");

      gets(regID);

     

      for (i=0; i<8; i++) {

            c = regID[i];

            for (j=0; table[i][j] != c; j++);

            j = (j ^ k) & 0xf;

            k >>= 4;

            vserial[i] = table[i][j];

      }

        vseria

l[8] = '\0';

      printf("Computed serial: %s\nPress any key to quit", vserial);

      c = getch();

      return 0;

 

}

<----------------------------------------------------------------------->

 

********************

5- The Lazy way... *

********************

 

the decision function is:

 

f(reg_ID) xor 0xCFFF34BC == f(registration key)

 

this 0xCFFF34BC value is annoying me!, if i put 0 instead the decision function becomes f(reg_ID) == f(registration key)

 

and one trivial solution for this equation is registration key = reg_ID!!

 

so take your hex editor, search into resbldr.exe for bytes BC 34 FF CF and replace them with 00 00 00 00,

launch resource builder, register, enter the reg_ID into the registration key field and press OK!!

That's good, isn't it?

 

**************

6-Conclusion *

**************

 

The beast is not as strong as you think and there are many ways to kill her!!

Greets to all Fravias,

don't hesitate to contact me if you have any suggestions or comments (don't ask me for serials or c

racks try astalavista instead).

 

To finish, all the informations given here are for educational purposes only, if you find this software usefull, buy it!

 

j!m