WARNING: Wiki content is an archive, no promise about quality!
Please choose a tutorial page:
- Fundamentals -- Information about C
- Tools
- Registers
- Simple Instructions
- Example 1 -- SC CDKey Initial Verification
- Example 2 -- SC CDKey Shuffle
- Example 2b -- SC CDKey Final Decode
- The Stack
- Functions
- Example 3 -- Storm.dll SStrChr
- Assembly Summary
- Machine Code
- Example 4 -- Smashing the Stack
- Cracking a Game
- Example 5 -- Cracking a game
- Example 6 -- Writing a keygen
- .dll Injection and Patching
- Memory Searching
- Example 7 -- Writing a cheat for Starcraft (1.05)
- Example 7 Step 1 -- Displaying Messages
- Example 7 Step 1b -- Above, w/ func ptrs
- Example 7 Final
- Example 8 -- Getting IX86.dll files
- 16-bit Assembly
- Example 9 -- Keygen for a 16-bit game
- Example 10 -- Writing a loader
This is the third (and, basically, final) part of the Starcraft CDKey Decode. I'm going to present the code and the final answer, but not the interim steps. This may cover things we haven't talked about (like a function call and local variables, for example).
As usual, esi is a pointer to the cdkey.
mov ebp, 13AC9741h
mov ebx, 0Bh
top:
movsx eax, byte ptr [ebx+esi]
push eax ; Parameter to toupper()
call _toupper ; Call toupper()
add esp, 4 ; Fix the stack (don't worry about this)
cmp al, 37h
mov byte ptr [ebx+esi], al
jg short body1
mov ecx, ebp
mov dl, cl
and dl, 7
xor dl, al
shr ecx, 3
mov byte ptr [ebx+esi], dl
mov ebp, ecx
jmp short body2
body1:
cmp al, 41h
jge short body2
mov cl, bl
and cl, 1
xor cl, al
mov byte ptr [ebx+esi], cl
body2:
dec ebx
jns short top
C Code
void getFinalValue(char *key) {
char *esi;
int eax, ebp, ebx, ecx, edx;
esi = key;
ebp = 0x13AC9741;
ebx = 0x0b;
for(ebx = 0x0b; ebx > 0; ebx--)
{
eax = *(ebx+esi);
*(ebx+esi) = eax;
if(eax <= 0x37)
{
ecx = ebp;
edx = ecx & 0xFF;
edx = edx & 7;
edx = edx ^ eax;
ecx = ecx >> 3;
*(ebx+esi) = edx;
ebp = ecx;
}
else if (eax < 0x41)
{
ecx = ebx;
ecx = ecx & 1;
ecx = ecx ^ eax;
*(ebx+esi) = ecx;
}
}
}
Cleaned up C Code
void getFinalValue(char *key) {
int eax, ebp, ebx;
ebp = 0x13AC9741;
for(ebx = 0x0b; ebx > 0; ebx--)
{
eax = key[ebx];
if(eax <= 0x37)
{
key[ebx] = (ebp & 7) ^ eax;
ebp = ebp >> 3;
}
else if (eax < 0x41)
{
key[ebx] = (ebx & 1) ^ eax;
}
}
}
Finished Code
Here is the resulting code, in Java
/** Gets the final CDKey values. */
protected void getFinalValue()
{
int hashKey = 0x13AC9741;
byte[] key = cdkey.getBytes();
for (int i = (cdkey.length() - 2); i >= 0; i--)
{
if (key[i] <= '7')
{
key[i] ^= (byte) (hashKey & 7);
hashKey = hashKey >>> 3;
}
else if (key[i] < 'A')
{
key[i] ^= (byte)(i & 1);
}
}
}
This will produce a new numeric string, sub-strings of which are sent to Battle.net as integers (the first two characters are the product, the next 7 are "Val1", and the next three are "Val2".
I'm afraid I don't have any sample values for this one.