=================== Keygenning Resource
Builder (Update Pack 1) =================
a tutorial by j!m
---------------------------------------------------------------------------------
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