#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdint.h> | |
#include <string.h> | |
#include <unistd.h> | |
struct __attribute__((__packed__)) header_struct { | |
uint32_t MAGIC_NUMBER; | |
uint32_t file_length; | |
char original_filename[256]; | |
char encrypted_password[32]; | |
}; | |
int decrypt_queue[4] = {0x81922669, 0x68920CF6, 0x9A596725, 0x592C3156}; | |
uint32_t param_hard_1 = 0x2137; | |
uint32_t param_hard_2 = 0x7a69; | |
uint32_t param_hard_3 = 0x1234567; | |
void push_data_to_buffer(uint32_t param_1){ | |
uint32_t tmpval = param_1 ^ decrypt_queue[0]; | |
decrypt_queue[0] = decrypt_queue[1]; | |
decrypt_queue[1] = decrypt_queue[2]; | |
decrypt_queue[2] = decrypt_queue[3]; | |
decrypt_queue[3] = tmpval >> 6 | tmpval << 0x1a; | |
return; | |
} | |
uint32_t decrypt_easy(uint32_t arg) { | |
uint32_t retval = arg ^ decrypt_queue[0]; | |
uint32_t tmp = decrypt_queue[2] * 0x2137 + retval; | |
decrypt_queue[0] = decrypt_queue[1]; | |
decrypt_queue[1] = decrypt_queue[2]; | |
decrypt_queue[2] = decrypt_queue[3]; | |
decrypt_queue[3] = tmp >> 6 | tmp << 0x1a; | |
return retval; | |
} | |
uint32_t decrypt_hard(uint32_t arg) { | |
uint32_t retval = arg ^ decrypt_queue[0]; | |
uint32_t tmp = decrypt_queue[2] * param_hard_1 + retval; | |
decrypt_queue[0] = decrypt_queue[2] * param_hard_2 + decrypt_queue[1]; | |
decrypt_queue[1] = decrypt_queue[2]; | |
decrypt_queue[2] = decrypt_queue[2] * param_hard_3 + decrypt_queue[3]; | |
decrypt_queue[3] = tmp >> 6 | tmp << 0x1a; | |
return retval; | |
} | |
void strange_function(struct header_struct* header) { | |
char status_key [256]; | |
char status_value [1032]; | |
char* orig_filename = header->original_filename; | |
char* enc_password = header->encrypted_password; | |
do { | |
push_data_to_buffer(*(uint32_t *)orig_filename); | |
orig_filename += 4; | |
} while (orig_filename != enc_password); | |
FILE *status_file = fopen("/proc/self/status","r"); | |
if(status_file == NULL) { | |
perror("status"); | |
exit(1); | |
} | |
int scanf_result; | |
while(1) { | |
scanf_result = fscanf(status_file,"%[^:]: %s ", status_key, status_value); | |
if (scanf_result == -1) { | |
scanf_result = fclose(status_file); | |
return; | |
} | |
if (scanf_result != 2) break; | |
size_t key_length = strlen(status_key); | |
if (((status_key[key_length + -3] == 'P') && (status_key[key_length + -2] == 'i')) && (status_key[key_length + -1] == 'd')) { | |
uint our_pid; | |
sscanf(status_value, "%u", &our_pid); | |
push_data_to_buffer(our_pid); | |
} | |
} | |
fprintf(stderr,"%d? umm what?\n",(ulong)scanf_result); | |
exit(1); | |
} | |
int main(int argc,char **argv){ | |
int retval = 0; | |
if (argc < 2) { | |
printf("usage: %s <input filename> [<key>]\n",*argv); | |
return 0; | |
} | |
FILE *encrypted_file = fopen(argv[1], "rb"); | |
if (encrypted_file == NULL) { | |
perror("fopen"); | |
retval = 1; | |
goto cleanup_1; | |
} | |
struct header_struct file_header; | |
memset(&file_header, 0, sizeof(file_header)); | |
size_t read_chars = fread(&file_header,0x128,1,encrypted_file); | |
if(read_chars != 1) { | |
perror("fread"); | |
retval = 1; | |
goto cleanup_1; | |
} | |
if ((file_header.MAGIC_NUMBER != 0xb542020) && (file_header.MAGIC_NUMBER != 0x20200b54)) { | |
fwrite("unrecognized file\n",1,0x12,stderr); | |
retval = 1; | |
goto cleanup_1; | |
} | |
if (argc == 2) { | |
const char *mode_name = "easy"; | |
if (file_header.MAGIC_NUMBER != 0xb542020) { | |
mode_name = "hard"; | |
} | |
printf("%s mode file, original name %s\n", mode_name, file_header.original_filename); | |
retval = 0; | |
goto cleanup_1; | |
} | |
size_t key_len = strlen(argv[2]); | |
if(key_len != 0x40) { | |
fwrite("wrong key length\n",1,0x11,stderr); | |
retval = 1; | |
goto cleanup_1; | |
} | |
decrypt_queue[0] = getpid(); | |
decrypt_queue[1] = getppid(); | |
strange_function(&file_header); | |
const char *pass = argv[2]; | |
char password_fragment [9] = {0}; | |
int unhexlified_pass_buffer[8] = {0}; | |
for(int i = 0; i < 8; i++) { | |
memcpy(password_fragment, &pass[8 * i], 8); | |
sscanf(password_fragment,"%x", &unhexlified_pass_buffer[i]); | |
} | |
param_hard_1 = unhexlified_pass_buffer[2]; | |
param_hard_2 = unhexlified_pass_buffer[3]; | |
param_hard_3 = unhexlified_pass_buffer[5]; | |
int password_processed[8] = {0}; | |
for(int i = 0; i < 8; i++) { | |
password_processed[i] = decrypt_easy(unhexlified_pass_buffer[i]); | |
} | |
int identical = memcmp(file_header.encrypted_password,password_processed,0x20); | |
if(identical != 0) { | |
fwrite("wrong key\n",1,10,stderr); | |
retval = 1; | |
goto cleanup_1; | |
} | |
fwrite("OK, decrypting...\n",1,0x12,stderr); | |
FILE *decrypted_file = fopen(file_header.original_filename,"wb"); | |
if (decrypted_file == NULL) { | |
perror("open"); | |
retval = 1; | |
goto cleanup_2; | |
} | |
if (file_header.file_length == 0) { | |
retval = 0; | |
goto cleanup_2; | |
} | |
uint32_t current_data; | |
for(int i = 0; i < file_header.file_length; i += 4) { | |
read_chars = fread(¤t_data,4,1,encrypted_file); | |
if (read_chars != 1) { | |
perror("fread"); | |
retval = 1; | |
goto cleanup_2; | |
} | |
if (file_header.MAGIC_NUMBER == 0xb542020) { | |
current_data = decrypt_easy(current_data); | |
} | |
else { | |
current_data = decrypt_hard(current_data); | |
} | |
int32_t remaining = file_header.file_length - i; | |
if (4 < remaining) { | |
remaining = 4; | |
} | |
read_chars = fwrite(¤t_data,(long)remaining,1,decrypted_file); | |
if (read_chars != 1) { | |
retval = 1; | |
goto cleanup_2; | |
} | |
} | |
cleanup_2: | |
fclose(decrypted_file); | |
cleanup_1: | |
fclose(encrypted_file); | |
return retval; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment