int action_parse_key(char *key, char *value) { if (strcmp(key, "FIRMWARE_VER") == 0) { unsigned int a, b, c; sscanf(value, "%d.%d.%d", &a, &b, &c); package_image.version = (a << 24) + (b << 16) + c; } else if (strcmp(key, "MACHINE_MODEL") == 0) { package_image.machine_model[sizeof(package_image.machine_model) - 1] = 0; strncpy(package_image.machine_model, value, sizeof(package_image.machine_model)); if (package_image.machine_model[sizeof(package_image.machine_model) - 1]) return -1; } else if (strcmp(key, "MACHINE_ID") == 0) { package_image.machine_id[sizeof(package_image.machine_id) - 1] = 0; strncpy(package_image.machine_id, value, sizeof(package_image.machine_id)); if (package_image.machine_id[sizeof(package_image.machine_id) - 1]) return -1; } else if (strcmp(key, "MANUFACTURER") == 0) { package_image.manufacturer[sizeof(package_image.manufacturer) - 1] = 0; strncpy(package_image.manufacturer, value, sizeof(package_image.manufacturer)); if (package_image.manufacturer[sizeof(package_image.manufacturer) - 1]) return -1; } else if (strcmp(key, "CMDLINE") == 0) { char *param, *token1; char *param_key, *param_value; param = strtok_r(value, " ", &token1); while (param) { param_key = param; param_value = strchr(param, '='); if (param_value) { *param_value = '\0'; param_value++; } else { continue; } if (strcmp(param_key, "mtdparts") == 0) { parse_partitions(param_value); } param = strtok_r(NULL, " ", &token1); } } return 0; }
int main(int argc, char** argv){ FILE* fp; uint8_t* buf = NULL; size_t size; uint8_t xorpad[XORPAD_SIZE]; uint8_t* wearlevel_buf = NULL; if(argc < 5){ fprintf(stderr, "Syntax: %s <operation> <savegame> <xorpad> <outfile>\n", argv[0]); goto exit; } if(!strcmp("decrypt", argv[1])){ do_decrypt = 1; } else if(!strcmp("wearlevel", argv[1])){ do_decrypt = 1; do_wearlevel = 1; } else if(!strcmp("filesystem", argv[1])){ do_decrypt = 1; do_wearlevel = 1; do_filesys = 1; } // Read in the savefile fp = fopen(argv[2], "rb"); if(fp == NULL){ fprintf(stderr, "Failed to open %s\n", argv[2]); goto exit; } size = file_size(fp); buf = malloc(size); fread(buf, 1, size, fp); fclose(fp); fp = fopen(argv[3], "rb"); if(fp == NULL){ fprintf(stderr, "Failed to open %s\n", argv[3]); goto exit; } if(fread(xorpad, 1, XORPAD_SIZE, fp) != XORPAD_SIZE){ fprintf(stderr, "Failed to read in the xor pad\n"); goto exit; } fclose(fp); void* decrypt_ptr = buf + SECTOR_SIZE; void* write_ptr = buf; if(do_wearlevel){ wearlevel_buf = calloc(1, size - SECTOR_SIZE); if(wearlevel(buf, size, wearlevel_buf) < 0) goto exit; size -= SECTOR_SIZE; decrypt_ptr = wearlevel_buf; write_ptr = wearlevel_buf; } if(do_decrypt){ decrypt(decrypt_ptr, size, xorpad); if(do_wearlevel && do_filesys){ parse_partitions(wearlevel_buf, argv[4]); } else { fp = fopen(argv[4], "wb"); if(fp == NULL){ fprintf(stderr, "Couldn't open %s for writing.\n", argv[4]); goto exit; } fwrite(write_ptr, 1, size, fp); fclose(fp); } } exit: free(buf); free(wearlevel_buf); return 0; }