Skip to content

Commit

Permalink
mc4 decrypter
Browse files Browse the repository at this point in the history
  • Loading branch information
bucanero committed Dec 19, 2023
1 parent 76597eb commit 768c5c9
Show file tree
Hide file tree
Showing 8 changed files with 336 additions and 0 deletions.
156 changes: 156 additions & 0 deletions common/base64.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/*
* Base64 encoding/decoding (RFC1341)
* Copyright (c) 2005-2011, Jouni Malinen <[email protected]>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/


static unsigned char base64_table[65] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

void set_base64_table(const char* table)
{
memcpy(base64_table, table, sizeof(base64_table) - 1);
}

/**
* base64_encode - Base64 encode
* @src: Data to be encoded
* @len: Length of the data to be encoded
* @out_len: Pointer to output length variable, or %NULL if not used
* Returns: Allocated buffer of out_len bytes of encoded data,
* or %NULL on failure
*
* Caller is responsible for freeing the returned buffer. Returned buffer is
* nul terminated to make it easier to use as a C string. The nul terminator is
* not included in out_len.
*/
unsigned char * base64_encode(const unsigned char *src, size_t len,
size_t *out_len)
{
unsigned char *out, *pos;
const unsigned char *end, *in;
size_t olen;
int line_len;

olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
olen += olen / 72; /* line feeds */
olen++; /* nul termination */
if (olen < len)
return NULL; /* integer overflow */
out = malloc(olen);
if (out == NULL)
return NULL;

end = src + len;
in = src;
pos = out;
line_len = 0;
while (end - in >= 3) {
*pos++ = base64_table[in[0] >> 2];
*pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
*pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
*pos++ = base64_table[in[2] & 0x3f];
in += 3;
line_len += 4;
if (line_len >= 72) {
*pos++ = '\n';
line_len = 0;
}
}

if (end - in) {
*pos++ = base64_table[in[0] >> 2];
if (end - in == 1) {
*pos++ = base64_table[(in[0] & 0x03) << 4];
*pos++ = '=';
} else {
*pos++ = base64_table[((in[0] & 0x03) << 4) |
(in[1] >> 4)];
*pos++ = base64_table[(in[1] & 0x0f) << 2];
}
*pos++ = '=';
line_len += 4;
}

if (line_len)
*pos++ = '\n';

*pos = '\0';
if (out_len)
*out_len = pos - out;
return out;
}


/**
* base64_decode - Base64 decode
* @src: Data to be decoded
* @len: Length of the data to be decoded
* @out_len: Pointer to output length variable
* Returns: Allocated buffer of out_len bytes of decoded data,
* or %NULL on failure
*
* Caller is responsible for freeing the returned buffer.
*/
unsigned char * base64_decode(const unsigned char *src, size_t len,
size_t *out_len)
{
unsigned char dtable[256], *out, *pos, block[4], tmp;
size_t i, count, olen;
int pad = 0;

memset(dtable, 0x80, 256);
for (i = 0; i < sizeof(base64_table) - 1; i++)
dtable[base64_table[i]] = (unsigned char) i;
dtable['='] = 0;

count = 0;
for (i = 0; i < len; i++) {
if (dtable[src[i]] != 0x80)
count++;
}

if (count == 0 || count % 4)
return NULL;

olen = count / 4 * 3;
pos = out = malloc(olen);
if (out == NULL)
return NULL;

count = 0;
for (i = 0; i < len; i++) {
tmp = dtable[src[i]];
if (tmp == 0x80)
continue;

if (src[i] == '=')
pad++;
block[count] = tmp;
count++;
if (count == 4) {
*pos++ = (block[0] << 2) | (block[1] >> 4);
*pos++ = (block[1] << 4) | (block[2] >> 2);
*pos++ = (block[2] << 6) | block[3];
count = 0;
if (pad) {
if (pad == 1)
pos--;
else if (pad == 2)
pos -= 2;
else {
/* Invalid padding */
free(out);
return NULL;
}
break;
}
}
}

*out_len = pos - out;
return out;
}
10 changes: 10 additions & 0 deletions mc4-cheat-decrypter/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# MC4 Cheat Decrypter
# (c)2023 Damian Parrino

all: decrypter

decrypter:
gcc -D _GNU_SOURCE -o mc4-cheat-decrypter main.c

clean:
-rm -f mc4-cheat-decrypter
11 changes: 11 additions & 0 deletions mc4-cheat-decrypter/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# MC4 Cheat Decrypter

A tool to decrypt MC4 cheat files

```
USAGE: ./mc4-cheat-decrypter [option] filename
OPTIONS Explanation:
-d Decrypt File
-e Encrypt File
```
110 changes: 110 additions & 0 deletions mc4-cheat-decrypter/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
*
* MC4 Cheat Decrypter - (c) 2023 by Bucanero - www.bucanero.com.ar
*
* Keys reversed from RAN SHN-Injector 1.08 by TetzkatLipHoka (TLH)
*
*/

#define CBC 1

#include "../common/iofile.c"
#include "../common/aes.c"
#include "../common/base64.c"

const unsigned char MC4_AES256CBC_KEY[] = "304c6528f659c766110239a51cl5dd9c";
const unsigned char MC4_AES256CBC_IV[] = "u@}kzW2u[u(8DWar";


u8* decrypt_data(u8* data, size_t* size)
{
u8* bin_data;
size_t bin_size;
struct AES_ctx ctx;

printf("[*] Base64 Encoded Size: %zu bytes\n", *size);

bin_data = base64_decode(data, *size, &bin_size);
*size = bin_size;
free(data);

printf("[*] Total Decrypted Size: %zu bytes\n", bin_size);

AES_init_ctx_iv(&ctx, MC4_AES256CBC_KEY, MC4_AES256CBC_IV);
AES_CBC_decrypt_buffer(&ctx, bin_data, bin_size);

printf("[*] Decrypted File Successfully!\n\n");
return bin_data;
}

u8* encrypt_data(u8* data, size_t* size)
{
u8* b64_data;
size_t b64_size;
struct AES_ctx ctx;

printf("[*] Total XML Size: %zu bytes\n", *size);

AES_init_ctx_iv(&ctx, MC4_AES256CBC_KEY, MC4_AES256CBC_IV);
AES_CBC_encrypt_buffer(&ctx, data, *size);

b64_data = base64_encode(data, *size, &b64_size);
*size = b64_size;
free(data);

printf("[*] Total Encrypted Size: %zu bytes\n", b64_size);
printf("[*] Encrypted File Successfully!\n\n");
return b64_data;
}

void print_usage(const char* argv0)
{
printf("USAGE: %s [option] filename\n\n", argv0);
printf("OPTIONS Explanation:\n");
printf(" -d Decrypt File\n");
printf(" -e Encrypt File\n\n");
return;
}

int main(int argc, char **argv)
{
size_t len;
u8* data;
char *opt, *bak;

printf("\nMC4 Cheat Decrypter 0.1.0 - (c) 2023 by Bucanero\n\n");

if (--argc < 2)
{
print_usage(argv[0]);
return -1;
}

opt = argv[1];
if (*opt++ != '-' || (*opt != 'd' && *opt != 'e'))
{
print_usage(argv[0]);
return -1;
}

if (read_buffer(argv[2], &data, &len) != 0)
{
printf("[*] Could Not Access The File (%s)\n", argv[2]);
return -1;
}
// Save a file backup
asprintf(&bak, "%s.bak", argv[2]);
write_buffer(bak, data, len);

if (*opt == 'd')
data = decrypt_data(data, &len);
else
data = encrypt_data(data, &len);

write_buffer(argv[2], data, len);

free(bak);
free(data);

return 0;
}
1 change: 1 addition & 0 deletions mc4-cheat-decrypter/samples/CUSA32091_01.02.mc4
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
AgKHPLxZwZ+2YfYslmLUXGyUIJK0NSn6118NipwxKEwTgDtPaDO2TMpugGI9h3o9Rkx++qP4HKt8vk/4J+mtwAAQT223dPM5Njvb5dNdE/WbmMve6nBLodseDrYK7elwAGw99Igvx6qAo+DP020C2sU+4O73HwvAYeWvZ8EE/pEtCH4KeacF6OOS9HFn8t/XSSRP3+F9yuSFXmze3q/7XBh1bYqawaX7Eq3RSnsuaPbuvRihcB3+4SuSctXxKbKkSg2iAlhy/EYX89HYZPkCoTijA0NR5EKxHUwVhSwDknGMYMGQS/qyKKnD2n8Kd26BUwZQlgsA0pQuUuqi7FSFTLYfIPbIAFKABxuPeLdVGkl75XAGzkIVj98TDM5GU0vbo1oL6mmWZMpui0vRrAvHcgpHcDn/FL5vWRT5o/rlpvS9T6E5RWAX88l8pbJa03npyBMW05CIr3sjX/ZSQ6ZoELNlivQB6d1rJJyQf8PKbcyGB7dmgvoiixsbYvURVJwVDhToAfwVW/8bAJ6Vng/3Z7ItZCklqA0fMIIeqF2j44vjE7QQJMCqsZHyYjXoR+33gUOzvB3/MUvDb3wVU5NOWCacJ4uECqs0DjmPrES+zmZpux5rL/ff2Xg/jfFFcaaOHMoTtW7X/lUX9EcEq49KLx4RJ9feNsiUXqJWuwT8ePWT0EvIXiXpTzdGi0IbJtuiNb9ScRgnzmGX9NetXuc+oyq7NUafTM0l/MrhFdx4f1vTag6bjaMCeaZsYMR2b1utMI78iv+aUZ3DCr6kAbE1L61Pc9SVDJFeXV0DdZfL/59d0baYA3P2tqM1p4oDclqvRVTOZM1EMzCOtGtmAECtFcZEsxqARUbVhQznlPT5gDFkgv6mMq11NtRhcpp+X5Tdsp6njX/pPLE3+FgEIsTzvLX4ZhhaobViRBSxstQ1xZYKIJ7vzdzp3hP0kNsvvPHwuM9e/Pt44aZ51E2DMup3zwXKLhonunsbmo/QOnSu5CEqqCOlXh7S8JtYG6jsJ3vAYQ5yrwVr/cGRQ/WYHKUuasmOIZ++Obap8vNJl9jc8LColrx/hQAw3eO3HIsPwAq3ch8tUdysXyTvDth8u4b4D+CK2iogX/St0BfcDpMKud2XW3aoF+upvA76I88RkOUTlQZEw0BL2w76ITZZEsuLA+8Gzw9s+OMAOViPvabrKG8zCWvSYAsSI1TT4eYKNn+WtPwIdlx+N9HhKbM8RFv8mReSG4yXoLqTo7xktJY8QPJBtLt2PdST0u7sFVI/v2b+Mf7tIDB2berApbMwYuQs/b86sB03MWJjB9Rdl/MwrVTnUko85qMRu6IAgOfTpkSIXvuVdcthjX5ZowesSb95zizDNuwCxzESy8u3K6ve6WiGDSYNp7md6ux0v1iKWphgvI4+bf4urQl5H5v4KdPIeQQ6QLu3s89RHBeDXllClRW2ylj7OaYZKHj58LcMhEPTzTFcO0//oCGdBU/x5I+cgnAajoyfcakhfrCB7QOrClF/ytrxY42EBe29yRMekxwF0OSLvV3842KJnyLwUNi9GgoBvfsZWvnYPH8UGneixoAGki8j/z1Dh43SooLqmKq5RXpOo585JZ4qmAdwTtlfUaLU6XrPBThOPYUZbq4JiP2l3nJDtr1vYDoxDeEmYS22APFSgUjTniUxSPGiKyhfOw==
Binary file not shown.
48 changes: 48 additions & 0 deletions mc4-cheat-decrypter/samples/CUSA32091_01.02.mc4.DEC
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<Trainer xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Game="Pyramid Quest" Moder="Saso_9.00" Cusa="CUSA32091" Version="01.02" Process="eboot.bin">
<Genres Name="Action" />
<Items />
<Cheat Text="Untouchable">
<Cheatline>
<Absolute>True</Absolute>
<Section>0</Section>
<Offset>42C216</Offset>
<ValueOn>90-90-90-90-90</ValueOn>
<ValueOff>E8-05-00-00-00</ValueOff>
</Cheatline>
</Cheat>
<Cheat Text="Inf Lives">
<Cheatline>
<Absolute>True</Absolute>
<Section>0</Section>
<Offset>40F548</Offset>
<ValueOn>8B-87-14-02-00-00</ValueOn>
<ValueOff>8B-87-18-02-00-00</ValueOff>
</Cheatline>
<Cheatline>
<Absolute>True</Absolute>
<Section>0</Section>
<Offset>40F552</Offset>
<ValueOn>FF-C0</ValueOn>
<ValueOff>FF-C8</ValueOff>
</Cheatline>
</Cheat>
<Cheat Text="Inf Knives">
<Cheatline>
<Absolute>True</Absolute>
<Section>0</Section>
<Offset>40F430</Offset>
<ValueOn>8B-87-18-02-00-00</ValueOn>
<ValueOff>8B-87-14-02-00-00</ValueOff>
</Cheatline>
</Cheat>
</Trainer>









Binary file not shown.

0 comments on commit 768c5c9

Please sign in to comment.