-
-
Save anonymous/909e6af6a5d98985779887cbd1d1cbca to your computer and use it in GitHub Desktop.
hacked up reversed code
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 "stdbool.h" | |
#include "stdint.h" | |
#include "stdio.h" | |
#include "stdlib.h" | |
#include "string.h" | |
#include "ctype.h" | |
struct key { | |
union { | |
uint32_t key_part[4]; | |
uint8_t bytes[0x10]; | |
}; | |
}; | |
struct key* gen_key(uint32_t in1, uint32_t in2, uint32_t in3) | |
{ | |
struct key* res = malloc(sizeof(struct key)); | |
for (uint32_t i = 0; i++ <= 0xff;) | |
{ | |
uint32_t temp1 = in1 ^ (~in1 >> 0x10); | |
in1 = ((temp1 + i) * 0x1234567) ^ 0x89abcdef; | |
in2 ^= in1; | |
in3 += in1; | |
in1 = ((temp1 + i) * 0x89abcdef) ^ 0x1234567; | |
uint32_t old_in1 = in1; | |
in1 = in2; | |
in2 = in3; | |
in3 = old_in1; | |
} | |
res->key_part[0] = in1; | |
res->key_part[1] = in2; | |
res->key_part[2] = in3; | |
res->key_part[3] = in1 ^ in2 ^ in3; | |
return res; | |
} | |
void crypt_in_place(uint8_t* input, struct key* k, size_t input_len, uint8_t keystate_rotation) | |
{ | |
uint8_t keystate[0x100]; | |
// this has no effect, but is in the executable blob (obfuscated slightly). | |
// dunno. | |
memcpy(keystate, "strings4flag", 0xc); | |
for (uint32_t i = 0, next_keystate_val = keystate_rotation; i < sizeof(keystate); i++) | |
{ | |
// yes, this seems to replace the possible flag string thing it seeds the keystate | |
// with... not sure why | |
keystate[i] = next_keystate_val++; | |
} | |
for (uint32_t i = 0, swap_temp = 0; i < sizeof(keystate); i++) | |
{ | |
uint8_t keystate_byte = keystate[i]; | |
uint8_t input_key_byte = k->bytes[i & 0xf]; | |
swap_temp += keystate_byte + input_key_byte; | |
swap_temp &= 0xff; | |
keystate[i] = keystate[swap_temp]; | |
keystate[swap_temp] = keystate_byte; | |
} | |
// early counter increment intentional -- just mimicry | |
for (uint32_t i = 0, swap_temp = 0; i++ < input_len;) | |
{ | |
uint32_t keystate_index = i & 0xff; | |
uint8_t keystate_byte = keystate[keystate_index]; | |
swap_temp += keystate_byte; | |
swap_temp &= 0xff; | |
uint8_t next_keystate_byte = keystate[swap_temp]; | |
keystate[swap_temp] = keystate[keystate_index]; | |
keystate[keystate_index] = next_keystate_byte; | |
input[i - 1] ^= keystate[0xff & (keystate[swap_temp] + next_keystate_byte)]; | |
} | |
} | |
void attempt(struct key* k, uint8_t keystate_rotation, const uint8_t* in_data, size_t len) | |
{ | |
bool printable = true; | |
uint8_t* working_data = malloc(len); | |
memcpy(working_data, in_data, len); | |
crypt_in_place(working_data, k, len, keystate_rotation); | |
printf("Keystate rotation %3d (%02x) ", keystate_rotation, keystate_rotation); | |
for (uint32_t i = 0; i < len; i++) | |
{ | |
if (i && !(i&3)) printf(" "); | |
printf("%02x", working_data[i]); | |
printable = printable && isprint(working_data[i]); | |
} | |
if (printable) | |
printf("\n PRINTABLE: %.*s\n", (uint32_t) len, working_data); | |
else | |
printf("\n"); | |
free(working_data); | |
} | |
int main(int argc, char* argv[]) | |
{ | |
struct key* k = gen_key(1095923727, 3459613537, 2312051101); | |
printf("key: %x %x %x %x\nrawkey: ", k->key_part[0], k->key_part[1], k->key_part[2], k->key_part[3]); | |
for (uint32_t i = 0; i < sizeof(k->bytes); i++) | |
printf("%02x", k->bytes[i]); | |
printf("\n\n"); | |
// data to try decrypting goes here. | |
unsigned char data[] = "l\xd0\"\xc2\xdam\xc5Z\x92t\xca\xb9!w\x17u\'\xd6\x83\xfa\xd2\x05\xfbq\xd7\x93\x1fg\x17\n\x90\x08\x0f\x92"; | |
// fuck it, brute force everything | |
for (uint32_t i = 0; i < 0x100; i++) | |
attempt(k, i, data, sizeof(data) - 1); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment