You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
2.7 KiB
128 lines
2.7 KiB
#include <lz4.h> |
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
|
|
#include "xxtea.h" |
|
|
|
const unsigned char key[16] = |
|
"\xd2\"\x82\x7f\xe9\xd3r\xa5$\x90\x8cm\n\x96\xcb\xa3"; |
|
const unsigned char password[16] = "MODDEDBYPL0NK!!!"; |
|
const int key_len = 16; |
|
|
|
void tj_decrypt(const char *path, const char *out) { |
|
unsigned char tmp = 0, fix_key[16] = {0}; |
|
unsigned char *dec = 0, *dst = 0; |
|
xxtea_long ret = 0; |
|
|
|
FILE *f = fopen(path, "rb"); |
|
fseek(f, 0, SEEK_END); |
|
long size = ftell(f); |
|
fseek(f, 0, SEEK_SET); |
|
|
|
char *buffer = malloc(size + 1); |
|
fread(buffer, 1, size, f); |
|
fclose(f); |
|
|
|
if (buffer[0] != 't' || buffer[1] != 'j' || buffer[2] != '!') { |
|
fprintf(stderr, "can't decrypt this type of file\n"); |
|
goto BAIL_OUT; |
|
} |
|
|
|
for (int i = 0; i < 16; i++) { |
|
tmp = key[i % key_len]; |
|
fix_key[i] ^= tmp ^ buffer[i + 3]; |
|
} |
|
|
|
dec = xxtea_decrypt(buffer + 23, size - 23, fix_key, 16, &ret); |
|
if (!ret) goto BAIL_OUT; |
|
|
|
unsigned int dstSz = *(unsigned int *)dec; |
|
if (dstSz != *(unsigned int *)(buffer + 19)) goto BAIL_OUT; |
|
|
|
dst = malloc(dstSz + 1); |
|
if (!dst) goto BAIL_OUT; |
|
|
|
LZ4_decompress_safe(dec + 4, dst, ret - 4, dstSz); |
|
|
|
f = fopen(out, "wb"); |
|
fwrite(dst, dstSz, 1, f); |
|
fclose(f); |
|
|
|
BAIL_OUT: |
|
free(dst); |
|
free(buffer); |
|
|
|
return; |
|
} |
|
|
|
void tj_encrypt(const char *path, const char *out) { |
|
unsigned char tmp = 0, fix_key[16] = {0}; |
|
unsigned char *enc = 0, *dst = 0; |
|
xxtea_long ret = 0; |
|
|
|
FILE *f = fopen(path, "rb"); |
|
fseek(f, 0, SEEK_END); |
|
long size = ftell(f); |
|
fseek(f, 0, SEEK_SET); |
|
|
|
char *buffer = malloc(size + 1); |
|
fread(buffer, 1, size, f); |
|
fclose(f); |
|
|
|
dst = malloc(size*2+1); |
|
ret = LZ4_compress_default(buffer, dst + 4, size, size*2); |
|
if (!ret) { |
|
fprintf(stderr, "failed compressing\n"); |
|
goto BAIL_OUT; |
|
} |
|
fprintf(stderr, "[ret] %ld %d\n", size*2, ret); |
|
|
|
for (int i = 0; i < 16; i++) { |
|
tmp = key[i % key_len]; |
|
fix_key[i] ^= tmp ^ password[i]; |
|
} |
|
|
|
f = fopen(out, "wb"); |
|
fwrite("tj!", 3, 1, f); |
|
fwrite(password, 16, 1, f); |
|
fwrite(&size, 4, 1, f); |
|
|
|
*(unsigned int*) dst = size; |
|
size = ret; |
|
ret = 0; |
|
|
|
enc = xxtea_encrypt(dst, size + 4, fix_key, 16, &ret); |
|
if (!ret) { |
|
fprintf(stderr, "failed encrypting\n"); |
|
goto BAIL_OUT; |
|
} |
|
fprintf(stderr, "[ret] %ld %d\n", size, ret); |
|
|
|
fwrite(enc, ret, 1, f); |
|
fclose(f); |
|
|
|
BAIL_OUT: |
|
free(dst); |
|
free(buffer); |
|
|
|
return; |
|
} |
|
|
|
int main(int argc, char const *argv[]) { |
|
if (argc < 4) goto HELP; |
|
switch (argv[1][0]) { |
|
case 'e': |
|
/* encrypt */ |
|
tj_encrypt(argv[2], argv[3]); |
|
break; |
|
case 'd': |
|
/* decrypt */ |
|
tj_decrypt(argv[2], argv[3]); |
|
break; |
|
default: |
|
HELP: |
|
fprintf(stderr, "usage: %s [d|e] in out\n", argv[0]); |
|
break; |
|
} |
|
return 0; |
|
}
|
|
|