You can obtain the software from: http://www.camdevelopment.com
Run the program, choose Register, and bpx on GetDlgItemTextA.
Softice snaps, and you're tracing. If you display the contents of the registers (indirect addressing of course), you come across this:
* Possible StringData Ref from Data Obj ->"BCD5-@??????-CAM1"
We now know that our input must be 17 chars long, and is checked against the above "sample". Think about it now. What does "?" normally mean? Any value right? So then what does the "@" mean then? Probably some kinda checksum!
Anyway, we break into Softice here:
* Reference To: USER32.GetDlgItemTextA, Ord:0000h
:00492C45 E8E9470000
Call 00497433
;here
:00492C4A 8B4B19
mov ecx, dword ptr [ebx+19]
:00492C4D 51
push ecx
:00492C4E E851EDFFFF
call 004919A4
;key checking routine
:00492C53 59
pop ecx
:00492C54 85C0
test eax, eax
:00492C56 0F8EEA000000
jle 00492D46
;evil jump-but don't patch
Tracing into the key checking routine (00492C4E), we arrive here...
Note: From now,
we assume that the key we input is "BCD5-ABCDEFG-CAM1"
Remember also that the
"sample" given is
"BCD5-@??????-CAM1"
...
...skipping non-important
code...
...and going straight
into the key calculation routine...
:00491A88 8B55F8
mov edx, dword ptr [ebp-08]
:00491A8B 0FBE0A
movsx ecx, byte ptr [edx]
:00491A8E 83F940
cmp ecx, 00000040
;checking against the "sample" to see if we reached "@" (40 hex = "@")
:00491A91 7542
jne 00491AD5
;dont jump if "@" is true
:00491A93 0FBE0B
movsx ecx, byte ptr [ebx] ;ecx = B
:00491A96 0FBE4301
movsx eax, byte ptr [ebx+01] ;eax = C
:00491A9A 03C8
add ecx, eax
;ecx = B+C
:00491A9C 0FBE5302
movsx edx, byte ptr [ebx+02] ;edx = D
:00491AA0 03CA
add ecx, edx
;ecx = B+C+D
:00491AA2 0FBE4303
movsx eax, byte ptr [ebx+03] ;eax = E
:00491AA6 03C8
add ecx, eax
;ecx = B+C+D+E
:00491AA8 0FBE5304
movsx edx, byte ptr [ebx+04] ;edx = F
:00491AAC 03CA
add ecx, edx
;ecx = B+C+D+E+F
:00491AAE 0FBE4305
movsx eax, byte ptr [ebx+05] ;eax = G
:00491AB2 03C8
add ecx, eax
;ecx = B+C+D+E+F
:00491AB4 8BC1
mov eax, ecx
;eax = ecx...preparing to mod
:00491AB6 B91A000000
mov ecx, 0000001A
;1A is the quotient...1A = 26 decimal which is the spanning length of the
Alphabet (A-Z)!
:00491ABB 99
cdq
;make 64 bit
:00491ABC F7F9
idiv ecx
;division done...edx has the remainder
:00491ABE 83C241
add edx, 00000041
;0 <= edx <= 25. 41 = "A"...therefore we get an Uppercased
Alphabet!
:00491AC1 8BCA
mov ecx, edx
;ecx, the checksum, is an Uppercased Alphabet
:00491AC3 8A43FF
mov al, byte ptr [ebx-01] ;This is A
:00491AC6 84C0
test al, al
:00491AC8 7407
je 00491AD1
:00491ACA 0FBED0
movsx edx, al
:00491ACD 3BCA
cmp ecx, edx
;Compare our "first" input "A" with the correct checksum
:00491ACF 7404
je 00491AD5
;is equal...then good guy...jump
:00491AD1 33FF
xor edi, edi
;if edi = 0 then bad guy
:00491AD3 EB12
jmp 00491AE7
We see that the only
values that matters are "ABCDEFG".
Ok...lets see what the
checksum should be:
sum
= "B"+"C"+"D"+"E"+"F"+"G" = 19B
(hex addition)
remainder = 19B mod
1A = 15
checksum = 41+15
= 56 = "V" in ascii
Since "A" <>
"V", therefore we're the bad guys! Therefore...changing our
"A" to "V"
will get you regged.
Want the Reg Key to include
+HCU?
sum
= "_" + "+" + "H" + "C" + U" + "_"
= 1C9
remainder = 1C9 mod
1A = F
checksum = 41+F
= 50 = "P" in ascii
Therefore a valid Reg Code would be "BCD5-P_+HCU_-CAM1"
Wanna have "Plushm" in the Reg Code?
checksum =
"P" = 50 - 41 = F
sum
= "l"+"u"+"s"+"h"+"m" =
229
remainder = 229 mod
1A =
7
checksum - remainder
= F-7 = 8
Therefore any character in the equation 8 + 1A(n), where n is any positive integer, will be valid. Lets choose "<", since "<" = 8 + 1A(2) = 3C ascii.
Therefore another equally valid Reg Code could be "BCD5-Plushm<-CAM1"
Anyway, here's the (main)
Reg calculation code in Pascal...have fun!
Plushmm -= RiP'97 =-
Writeln('Press
<S> for something special...');
Writeln;
TemChar := ReadKey;
If UPCASE(TemChar) <> 'S' Then {Random letters used}
Repeat
i := i+1;
TemInt := Random(26)+65;
Value := Value + TemInt;
TemChar := Chr(TemInt);
RegCode[i] := TemChar;
Until i = 12
else
Repeat
{Built your own Key!}
i := i+1;
Write('What do you want your Reg Key to be :');
TemChar := ReadKey;
Writeln(TemChar);
RegCode[i] := TemChar;
TemInt := Ord(TemChar);
Value := Value + TemInt;
until i = 12;
Remainder :=
Value mod 26;
RegCode[6] :=
Chr(Remainder+65);
Writeln;
Write('Your registration
code is:');
Writeln(RegCode);