aindump: add decrypt mode

Add -d,--decrypt option to dump decrypted ain file (for reverse
engineering).
This commit is contained in:
Nunuhara Cabbage
2020-01-10 12:28:44 -08:00
parent d764757894
commit 302598ace2
3 changed files with 47 additions and 9 deletions
+1
View File
@@ -237,6 +237,7 @@ struct ain {
const char *ain_strerror(int error);
const char *ain_strtype(struct ain *ain, enum ain_data_type type, int struct_type);
uint8_t *ain_read(const char *path, long *len, int *error);
struct ain *ain_open(const char *path, int *error);
void ain_free(struct ain *ain);
+18 -8
View File
@@ -594,12 +594,10 @@ static bool ain_is_encrypted(uint8_t *buf)
return !strncmp((char*)magic, "VERS", 4) && !magic[5] && !magic[6] && !magic[7];
}
struct ain *ain_open(const char *path, int *error)
uint8_t *ain_read(const char *path, long *len, int *error)
{
FILE *fp;
long len;
uint8_t *buf = NULL;
struct ain *ain = NULL;
if (!(fp = fopen(path, "rb"))) {
*error = AIN_FILE_ERROR;
@@ -608,17 +606,17 @@ struct ain *ain_open(const char *path, int *error)
// get size of AIN file
fseek(fp, 0, SEEK_END);
len = ftell(fp);
*len = ftell(fp);
fseek(fp, 0, SEEK_SET);
// read AIN file into memory
buf = xmalloc(len + 4); // why +4?
fread(buf, 1, len, fp);
buf = xmalloc(*len + 4); // why +4?
fread(buf, 1, *len, fp);
fclose(fp);
// check magic
if (!strncmp((char*)buf, "AI2\0\0\0\0", 8)) {
uint8_t *uc = decompress_ain(buf, &len);
uint8_t *uc = decompress_ain(buf, len);
if (!uc) {
*error = AIN_INVALID;
goto err;
@@ -626,13 +624,25 @@ struct ain *ain_open(const char *path, int *error)
free(buf);
buf = uc;
} else if (ain_is_encrypted(buf)) {
decrypt_ain(buf, len);
decrypt_ain(buf, *len);
} else {
printf("%.4s\n", buf);
*error = AIN_UNRECOGNIZED_FORMAT;
goto err;
}
return buf;
err:
free(buf);
return NULL;
}
struct ain *ain_open(const char *path, int *error)
{
long len;
struct ain *ain = NULL;
uint8_t *buf = ain_read(path, &len, error);
// read data into ain struct
struct ain_reader r = {
.buf = buf,
+28 -1
View File
@@ -92,6 +92,7 @@ static void print_function(FILE *out, struct ain *ain, struct ain_function *f)
static void ain_dump_functions(FILE *f, struct ain *ain)
{
for (int i = 0; i < ain->nr_functions; i++) {
fprintf(f, "0x%x:\t", i);
print_function(f, ain, &ain->functions[i]);
}
}
@@ -244,6 +245,21 @@ static void ain_audit(FILE *f, struct ain *ain)
fflush(f);
}
static void ain_decrypt(FILE *f, const char *path)
{
int err;
long len;
uint8_t *ain;
if (!(ain = ain_read(path, &len, &err))) {
ERROR("Failed to open ain file: %s\n", ain_strerror(err));
}
fwrite(ain, len, 1, f);
fflush(f);
free(ain);
}
int main(int argc, char *argv[])
{
bool dump_version = false;
@@ -260,6 +276,7 @@ int main(int argc, char *argv[])
bool dump_global_group_names = false;
bool dump_enums = false;
bool audit = false;
bool decrypt = false;
char *output_file = NULL;
FILE *output = stdout;
int err = AIN_SUCCESS;
@@ -282,12 +299,13 @@ int main(int argc, char *argv[])
{ "global-group-names", no_argument, 0, 'r' },
{ "enums", no_argument, 0, 'e' },
{ "audit", no_argument, 0, 'A' },
{ "decrypt", no_argument, 0, 'd' },
{ "output", required_argument, 0, 'o' },
};
int option_index = 0;
int c;
c = getopt_long(argc, argv, "hVcCfgSmlsFeAo:", long_options, &option_index);
c = getopt_long(argc, argv, "hVcCfgSmlsFeAdo:", long_options, &option_index);
if (c == -1)
break;
@@ -337,6 +355,9 @@ int main(int argc, char *argv[])
case 'A':
audit = true;
break;
case 'd':
decrypt = true;
break;
case 'o':
output_file = xstrdup(optarg);
break;
@@ -360,6 +381,11 @@ int main(int argc, char *argv[])
free(output_file);
}
if (decrypt) {
ain_decrypt(output, argv[0]);
return 0;
}
if (!(ain = ain_open(argv[0], &err))) {
ERROR("Failed to open ain file: %s\n", ain_strerror(err));
return 1;
@@ -395,4 +421,5 @@ int main(int argc, char *argv[])
ain_audit(output, ain);
ain_free(ain);
return 0;
}