Created
August 31, 2014 14:34
-
-
Save mrexodia/4ed6a40b37628804486b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdint.h> | |
#include <windows.h> | |
const char * ALPHABET32 = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789\0"; | |
int MAGIC = 91717; | |
int g_dwSeed = 0; | |
int8_t getCharIndex(char c) | |
{ | |
char *p = (char *)ALPHABET32; | |
do | |
{ | |
if ( *p == c ) | |
return p - ALPHABET32; | |
++p; | |
} | |
while ( *p ); | |
return -1; | |
} | |
void RandomizeSeed() | |
{ | |
if ( !g_dwSeed ) | |
g_dwSeed = 0x74D99E; | |
g_dwSeed = (0x41A7 * g_dwSeed % 0x1F31D) - (0xB14 * g_dwSeed / 0x1F31D); | |
if ( g_dwSeed <= 0 ) | |
g_dwSeed += 0x7FFFFFFFu; | |
printf("seed: %.8X\n", g_dwSeed); | |
} | |
bool make_bits_array(char bits_array[12], const uint8_t *arKey) | |
{ | |
memset(bits_array, 0, 12); | |
int64_t offset = 0; | |
/* Make the bits array ==> array of 5 bits */ | |
for (int i = 0; i < 18; ++i ) | |
{ | |
uint8_t pos = offset & 7; | |
uint8_t idx = getCharIndex(arKey[i]); | |
if ( idx == 255 ) | |
return false; | |
bits_array[offset / 8] |= idx << pos; | |
bits_array[offset / 8 + 1] |= idx >> (8 - pos); | |
offset += 5; | |
} | |
return true; | |
} | |
void print_bits_array(const char* title, char bits_array[12]) | |
{ | |
puts(title); | |
for(int i=0; i<12; i++) | |
printf("%.2X ", (uint8_t)bits_array[i]); | |
puts("\n"); | |
} | |
const uint8_t get_expected_checksum(int seed) | |
{ | |
uint8_t expected_chk = 0; | |
for (int i = 0; i < 8; ++i ) | |
expected_chk ^= seed >> 4 * i; | |
expected_chk &= 0x0F; | |
return expected_chk; | |
} | |
void brute(int seed) | |
{ | |
printf("possible bytes with seed %.8X:\n", seed); | |
const uint8_t expected_checksum = get_expected_checksum(seed); | |
for(int i=0,count=0; i<0x100; i++) | |
for(int j=0; j<0x100; j++) | |
{ | |
uint8_t computed_chk = (i >> 6) | ((j & 3) << 2); | |
if(computed_chk == expected_checksum) | |
{ | |
count++; | |
if(!(count % 8)) | |
puts(""); | |
printf("%.2X,%.2X=%.2X ", i, j, computed_chk); | |
} | |
} | |
puts("\n"); | |
} | |
bool KeyCheck(int seed, const uint8_t *arKey) | |
{ | |
char bits_array[12]; | |
if(!make_bits_array(bits_array, arKey)) | |
{ | |
puts("invalid characters in key!"); | |
return false; | |
} | |
print_bits_array("bits_array:", bits_array); | |
g_dwSeed = seed + 0x2B8ECCB; | |
for (int i = 0; i < 12; ++i ) | |
{ | |
RandomizeSeed(); | |
g_dwSeed ^= bits_array[i]; | |
bits_array[i] ^= g_dwSeed >> 16; | |
} | |
print_bits_array("\nrandomized:", bits_array); | |
/* Compute the expected checksum */ | |
uint8_t expected_chk = get_expected_checksum(seed); | |
printf("Expected Checksum=%x\n", expected_chk); | |
uint8_t computed_chk = (bits_array[10] >> 6) | ((bits_array[11] & 3) << 2); | |
printf("Computed Checksum=%x\n", computed_chk); | |
return (computed_chk == expected_chk); | |
} | |
int main(int argc, const char *argv[]) | |
{ | |
//brute(MAGIC); | |
/* entered key: xxxxxx-xxxxxx-xxxxxx and then to upper string */ | |
const uint8_t *szKey = (const uint8_t*)"22222233333344444Z\0"; | |
if(!KeyCheck(MAGIC, szKey)) | |
printf("\n==> Invalid Key (checksum mismatch) !\n"); | |
else | |
puts("\nyou win!"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment