int main(int argc, char **argv) { bool raw_mode = false; const char *loopback = NULL; while(1) { static struct option long_options[] = { {"help", no_argument, 0, '?'}, {"debug", no_argument, 0, 'd'}, {"add-key", required_argument, 0, 'a'}, {"no-color", no_argument, 0, 'n'}, {"loopback", required_argument, 0, 'l'}, {0, 0, 0, 0} }; int c = getopt_long(argc, argv, "?do:k:zra:nl:", long_options, NULL); if(c == -1) break; switch(c) { case -1: break; case 'l': if(loopback) bug("Only one loopback file can be specified !\n"); loopback = optarg; break; case 'n': enable_color(false); break; case 'd': g_debug = true; break; case '?': usage(); break; case 'o': g_out_prefix = optarg; break; case 'k': { add_keys_from_file(optarg); break; } case 'z': { add_keys(&g_zero_key, 1); break; } case 'r': raw_mode = true; break; case 'a': { struct crypto_key_t key; char *s = optarg; if(!parse_key(&s, &key)) bug("Invalid key specified as argument"); if(*s != 0) bug("Trailing characters after key specified as argument"); add_keys(&key, 1); break; } default: abort(); } } if(argc - optind != 1) { usage(); return 1; } const char *sb_filename = argv[optind]; enum sb_error_t err; struct sb_file_t *file = sb_read_file(sb_filename, raw_mode, NULL, sb_printf, &err); if(file == NULL) { color(OFF); printf("SB read failed: %d\n", err); return 1; } color(OFF); if(g_out_prefix) extract_sb_file(file); if(g_debug) { color(GREY); printf("[Debug output]\n"); sb_dump(file, NULL, sb_printf); } if(loopback) { /* sb_read_file will fill real key and IV but we don't want to override * them when looping back otherwise the output will be inconsistent and * garbage */ file->override_real_key = false; file->override_crypto_iv = false; sb_write_file(file, loopback); } sb_free(file); clear_keys(); return 0; }
int main(int argc, char **argv) { bool raw_mode = false; const char *loopback = NULL; bool force_sb1 = false; bool force_sb2 = false; bool brute_force = false; while(1) { static struct option long_options[] = { {"help", no_argument, 0, '?'}, {"debug", no_argument, 0, 'd'}, {"add-key", required_argument, 0, 'a'}, {"no-color", no_argument, 0, 'n'}, {"loopback", required_argument, 0, 'l'}, {"force", no_argument, 0, 'f'}, {"v1", no_argument, 0, '1'}, {"v2", no_argument, 0, '2'}, {"no-simpl", no_argument, 0, 's'}, {0, 0, 0, 0} }; int c = getopt_long(argc, argv, "?do:k:zra:nl:f12xsb", long_options, NULL); if(c == -1) break; switch(c) { case -1: break; case 'l': if(loopback) bug("Only one loopback file can be specified !\n"); loopback = optarg; break; case 'n': enable_color(false); break; case 'd': g_debug = true; break; case '?': usage(); break; case 'o': g_out_prefix = optarg; break; case 'f': g_force = true; break; case 'k': { if(!add_keys_from_file(optarg)) bug("Cannot add keys from %s\n", optarg); break; } case 'z': { struct crypto_key_t g_zero_key; sb_get_zero_key(&g_zero_key); add_keys(&g_zero_key, 1); break; } case 'x': { struct crypto_key_t key; sb1_get_default_key(&key); add_keys(&key, 1); break; } case 'r': raw_mode = true; break; case 'a': { struct crypto_key_t key; char *s = optarg; if(!parse_key(&s, &key)) bug("Invalid key specified as argument\n"); if(*s != 0) bug("Trailing characters after key specified as argument\n"); add_keys(&key, 1); break; } case '1': force_sb1 = true; break; case '2': force_sb2 = true; break; case 's': g_elf_simplify = false; break; case 'b': brute_force = true; break; default: bug("Internal error: unknown option '%c'\n", c); } } if(force_sb1 && force_sb2) bug("You cannot force both version 1 and 2\n"); if(argc - optind != 1) { usage(); return 1; } const char *sb_filename = argv[optind]; enum sb_version_guess_t ver = guess_sb_version(sb_filename); if(ver == SB_VERSION_ERR) { printf("Cannot open/read SB file: %m\n"); return 1; } if(force_sb2 || ver == SB_VERSION_2) { enum sb_error_t err; struct sb_file_t *file = sb_read_file(sb_filename, raw_mode, NULL, generic_std_printf, &err); if(file == NULL) { color(OFF); printf("SB read failed: %d\n", err); return 1; } color(OFF); if(g_out_prefix) extract_sb_file(file); if(g_debug) { color(GREY); printf("[Debug output]\n"); sb_dump(file, NULL, generic_std_printf); } if(loopback) { /* sb_read_file will fill real key and IV but we don't want to override * them when looping back otherwise the output will be inconsistent and * garbage */ file->override_real_key = false; file->override_crypto_iv = false; sb_write_file(file, loopback, 0, generic_std_printf); } sb_free(file); } else if(force_sb1 || ver == SB_VERSION_1) { if(brute_force) { struct crypto_key_t key; enum sb1_error_t err; if(!sb1_brute_force(sb_filename, NULL, generic_std_printf, &err, &key)) { color(OFF); printf("Brute force failed: %d\n", err); return 1; } color(RED); printf("Key found:"); color(YELLOW); for(int i = 0; i < 32; i++) printf(" %08x", key.u.xor_key[i / 16].k[i % 16]); color(OFF); printf("\n"); color(RED); printf("Key: "); color(YELLOW); for(int i = 0; i < 128; i++) printf("%02x", key.u.xor_key[i / 64].key[i % 64]); color(OFF); printf("\n"); add_keys(&key, 1); } enum sb1_error_t err; struct sb1_file_t *file = sb1_read_file(sb_filename, NULL, generic_std_printf, &err); if(file == NULL) { color(OFF); printf("SB read failed: %d\n", err); return 1; } color(OFF); if(g_out_prefix) extract_sb1_file(file); if(g_debug) { color(GREY); printf("[Debug output]\n"); sb1_dump(file, NULL, generic_std_printf); } if(loopback) sb1_write_file(file, loopback); sb1_free(file); } else { color(OFF); printf("Cannot guess file type, are you sure it's a valid image ?\n"); return 1; } clear_keys(); return 0; }