Support GM61a
This commit is contained in:
parent
11c4b7a3ef
commit
2056d68f44
|
@ -18,9 +18,9 @@
|
|||
<datafile>
|
||||
<name>UGP.dll</name>
|
||||
<filename>UGP.dll</filename>
|
||||
<origname>C:\Users\User\Documents\git\UGP\UGP.gmx\\\datafiles\UGP.dll</origname>
|
||||
<origname>C:\Users\User\Documents\git\UGP\UGP.gmx\datafiles\UGP.dll</origname>
|
||||
<exists>-1</exists>
|
||||
<size>93696</size>
|
||||
<size>97280</size>
|
||||
<exportAction>2</exportAction>
|
||||
<exportDir></exportDir>
|
||||
<overwrite>0</overwrite>
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -95,7 +95,7 @@
|
|||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;UNIVERSALGAMEMAKERPATCHERDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
|
|
|
@ -2,5 +2,12 @@
|
|||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerCommand>C:\Users\User\Desktop\UGP\UGP\UGP.exe</LocalDebuggerCommand>
|
||||
<LocalDebuggerWorkingDirectory>C:\Users\User\Desktop\UGP\UGP</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LocalDebuggerCommand>C:\Users\User\Desktop\UGP\UGP\UGP.exe</LocalDebuggerCommand>
|
||||
<LocalDebuggerWorkingDirectory>C:\Users\User\Desktop\UGP\UGP</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -24,11 +24,8 @@ GMSTR GetMachineGuid(void)
|
|||
|
||||
GMSTR GenerateGM6Key(char* name) {
|
||||
uint8_t out_key[KEY_LEN];
|
||||
|
||||
keygen_gm6(name, out_key);
|
||||
|
||||
key_to_string(out_key, gm6key, sizeof(gm6key));
|
||||
|
||||
return gm6key;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,9 +3,33 @@
|
|||
static char key_name[6];
|
||||
|
||||
// The Mark Overmas Sequence.
|
||||
const uint8_t mark_overmars_seq[0x29] = { 0x01, 0x07, 0x11, 0x17, 0x19, 0x1b, 0x24, 0x27, 0x2b, 0x31, 0x33, 0x3d, 0x3f, 0x4d, 0x53, 0x59, 0x5e, 0x63, 0x68, 0x69, 0x76, 0x7f, 0x89, 0x8b, 0x97, 0x9b, 0x9e, 0xA6, 0xB9, 0xBD, 0xBF, 0xC6, 0xC9, 0xD3, 0xD6, 0xDE, 0xE5, 0xEA, 0xEB, 0xF5, 0xF9 };
|
||||
const uint8_t mark_overmars_seq[0x30] = { 0x01,0x07,0x11,0x17,0x19,0x1b,0x24,0x27,0x2b,0x31,0x33,0x3d,0x3f,0x4d,0x53,0x59,0x5e,0x63,0x68,0x69,0x76,0x7f,0x89,0x8b,0x95,0x97,0x9b,0x9e,0xa6,0xb9,0xbd,0xbf,0xc6,0xc9,0xd3,0xd6,0xde,0xe5,0xea,0xeb,0xf5,0xf9 };
|
||||
|
||||
const uint8_t blacklisted_keys[0x6][0x8] = {
|
||||
{0xFF, 0xDF, 0x0A, 0xFF, 0xD3, 0x05, 0x7F, 0x24},
|
||||
{0x04, 0x22, 0xDA, 0xEE, 0x19, 0x79, 0xEE, 0x61},
|
||||
{0x24, 0xB4, 0x48, 0x5C, 0x5B, 0xDB, 0x29, 0x22},
|
||||
{0xB6, 0x15, 0xEA, 0x32, 0xBC, 0x16, 0xFB, 0xAF},
|
||||
{0x1E, 0x9E, 0xCE, 0x56, 0x12, 0xAD, 0x9D, 0x48},
|
||||
{0x9E, 0x6E, 0x3F, 0x8C, 0xD4, 0x36, 0x22, 0xEA}
|
||||
};
|
||||
|
||||
int is_blacklisted(uint8_t* key) {
|
||||
for (int i = 0; i < 0x6; i++) {
|
||||
if (memcmp(blacklisted_keys[i], key, 0x8) == 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (key[0x00] == 0xE3 &&
|
||||
key[0x05] == 0x7A &&
|
||||
key[0x06] == 0xD9 &&
|
||||
key[0x07] == 0xE3 &&
|
||||
key[0x08] == 0x06) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int add_multiply(uint8_t* key_arr) {
|
||||
int sum = 0;
|
||||
|
@ -65,7 +89,6 @@ void gen_checksum(uint8_t* key_arr) {
|
|||
int curchk = key_arr[KEY_LEN - 1];
|
||||
int chksum = add_multiply(key_arr);
|
||||
if (curchk != chksum) {
|
||||
//printf("Updating checksum, %x -> %x\n", curchk, chksum);
|
||||
key_arr[KEY_LEN - 1] = (uint8_t)chksum;
|
||||
|
||||
}
|
||||
|
@ -202,6 +225,7 @@ char* decode_name(int encoded_name)
|
|||
|
||||
void sanitize_name(char* namein, char* nameout) {
|
||||
memset(nameout, 0, 6);
|
||||
memcpy(nameout, namein, 5);
|
||||
|
||||
if (strlen(namein) != 5) {
|
||||
int sz = strlen(namein);
|
||||
|
@ -232,6 +256,11 @@ void sanitize_name(char* namein, char* nameout) {
|
|||
|
||||
}
|
||||
|
||||
int get_current_date_delphi() {
|
||||
double t = (((((double)time(0)) + 0.5) / 86400.0) + 25569.0);
|
||||
return (int)t;
|
||||
}
|
||||
|
||||
int encode_name(char* name) {
|
||||
int total = 0;
|
||||
int multi = 1;
|
||||
|
@ -258,13 +287,22 @@ int final_key_check(uint8_t* key_arr, char* name, uint8_t chk2, uint8_t chk1, ui
|
|||
encoded_time += 0x8EAE;
|
||||
|
||||
if (timed) {
|
||||
if (encoded_time != (exp_date + 0x8EAE)) {
|
||||
if (encoded_time != exp_date + 0x8EAE) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (encoded_time - 0xA > get_current_date_delphi()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_timed = key_arr[0x2];
|
||||
|
||||
if (!(is_timed >= 0x1 && is_timed <= 0x20)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (is_timed >= 0xA && is_timed <= 0xF) {
|
||||
if (!timed) {
|
||||
return 0;
|
||||
|
@ -341,6 +379,11 @@ void obfuscate_key(uint8_t* key_arr, uint8_t* out_key, int chk2, int chk1) {
|
|||
}
|
||||
|
||||
int check_key_6(uint8_t* key_arr, char* name, uint32_t exp_date, uint32_t timed) {
|
||||
// Did we win the lottery?
|
||||
if (is_blacklisted(key_arr)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (check_checksum(key_arr)) {
|
||||
|
||||
uint8_t chk1;
|
||||
|
@ -355,7 +398,7 @@ int check_key_6(uint8_t* key_arr, char* name, uint32_t exp_date, uint32_t timed)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void gen_key_6(char* name, uint8_t chk1, uint8_t chk2, uint32_t exp_date, uint32_t timed, uint8_t* out_key) {
|
||||
void gen_key_6(char* name, uint8_t chk1, uint8_t chk2, uint16_t exp_date, uint32_t timed, uint8_t* out_key) {
|
||||
|
||||
uint8_t keydata[KEY_LEN];
|
||||
|
||||
|
@ -374,7 +417,7 @@ void gen_key_6(char* name, uint8_t chk1, uint8_t chk2, uint32_t exp_date, uint32
|
|||
|
||||
|
||||
|
||||
int encoded_time = exp_date - 0x8EAE;
|
||||
uint16_t encoded_time = exp_date;
|
||||
keydata[0x1] = ((uint8_t*)(&encoded_time))[0];
|
||||
keydata[0x0] = ((uint8_t*)(&encoded_time))[1];
|
||||
|
||||
|
@ -383,9 +426,9 @@ void gen_key_6(char* name, uint8_t chk1, uint8_t chk2, uint32_t exp_date, uint32
|
|||
is_timed = (rand() % 0x6) + 0xA;
|
||||
}
|
||||
else {
|
||||
is_timed = rand() % 0x100;
|
||||
if (is_timed >= 0xA && is_timed <= 0xF)
|
||||
is_timed += 0x10;
|
||||
do {
|
||||
is_timed = (rand() % 0x20) + 1;
|
||||
} while (is_timed >= 0xA && is_timed <= 0xF);
|
||||
}
|
||||
|
||||
keydata[0x2] = is_timed;
|
||||
|
@ -401,40 +444,59 @@ void key_to_string(uint8_t* key, char* out_str, int buffer_sz) {
|
|||
snprintf(out_str, buffer_sz, "%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X", key[0x0], key[0x1], key[0x2], key[0x3], key[0x4], key[0x5], key[0x6], key[0x7], key[0x8], key[0x9], key[0xA], key[0xB]);
|
||||
}
|
||||
|
||||
void bruteforce_mark_seq(void* name) {
|
||||
char checked_name[6];
|
||||
sanitize_name(name, checked_name);
|
||||
uint8_t keybuf[KEY_LEN];
|
||||
|
||||
for (int chk1 = 0; chk1 < 0xFF; chk1++) {
|
||||
int chk1_valid = 0;
|
||||
|
||||
for (int chk2 = 0; chk2 < 0xFF; chk2++) {
|
||||
uint32_t exp_date = (get_current_date_delphi() - 0xA) - 0x8EAE;
|
||||
|
||||
gen_key_6(checked_name, chk1, chk2, exp_date, 0, keybuf);
|
||||
if (check_key_6(keybuf, checked_name, exp_date, 0)) {
|
||||
chk1_valid++;
|
||||
}
|
||||
}
|
||||
if (chk1_valid == 0xFF)
|
||||
printf("found part of seq; 0x%x c = 0x%x\n", chk1, chk1_valid);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void keygen_gm6(char* name, uint8_t* out_key) {
|
||||
char checked_name[6];
|
||||
sanitize_name(name, checked_name);
|
||||
uint8_t keybuf[KEY_LEN];
|
||||
|
||||
// the key data must survive the obfuscation step, while placing the chk1 and chk2 into the correct places
|
||||
// in the obfuscation steps, and the final checksum byte as well,
|
||||
// for this reason, key generation does not always work
|
||||
// so i simply retry forever until we find a key that does work.
|
||||
int chk1 = mark_overmars_seq[rand() % sizeof(mark_overmars_seq)];
|
||||
int chk2 = rand() % 0xFF;
|
||||
uint32_t exp_date = (get_current_date_delphi() - 0xA) - 0x8EAE;
|
||||
|
||||
while (1) {
|
||||
int chk1 = mark_overmars_seq[rand() % sizeof(mark_overmars_seq)];
|
||||
int chk2 = rand() % 0x100;
|
||||
int exp_date = rand() % 0xFFFF;
|
||||
|
||||
gen_key_6(checked_name, chk1, chk2, exp_date, 0, keybuf);
|
||||
if (check_key_6(keybuf, checked_name, exp_date, 0)) {
|
||||
break;
|
||||
}
|
||||
gen_key_6(checked_name, chk1, chk2, exp_date, 0, keybuf);
|
||||
|
||||
// Sanity check ...
|
||||
if (check_key_6(keybuf, checked_name, exp_date, 0)) {
|
||||
memcpy(out_key, keybuf, KEY_LEN);
|
||||
}
|
||||
else {
|
||||
keygen_gm6(name, out_key);
|
||||
}
|
||||
|
||||
memcpy(out_key, keybuf, KEY_LEN);
|
||||
}
|
||||
#ifdef STANDALONE
|
||||
int main(int argc, char* argv[]) {
|
||||
srand(time(0));
|
||||
|
||||
char keystr[31];
|
||||
uint8_t out_key[KEY_LEN];
|
||||
keygen_gm6(argv[1], out_key);
|
||||
key_to_string(out_key, keystr, sizeof(keystr));
|
||||
printf("Key found: %s", keystr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -10,6 +10,6 @@
|
|||
|
||||
|
||||
int check_key_6(uint8_t* key_arr, char* name, uint32_t exp_date, uint32_t timed);
|
||||
void gen_key_6(char* name, uint8_t chk1, uint8_t chk2, uint32_t exp_date, uint32_t timed, uint8_t* out_key);
|
||||
void gen_key_6(char* name, uint8_t chk1, uint8_t chk2, uint16_t exp_date, uint32_t timed, uint8_t* out_key);
|
||||
void keygen_gm6(char* name, uint8_t* out_key);
|
||||
void key_to_string(uint8_t* key, char* out_str, int buffer_sz);
|
Loading…
Reference in New Issue