forked from len0rd/rockbox
sbtools: refactor and cleanup
Factor common elf/sb read/write/printf routines. Factor sb zero key, move sb version guess. Change-Id: I5ae1885587456736e782e623610281bbee545039
This commit is contained in:
parent
3c5ee9ac57
commit
1c8c24183e
12 changed files with 131 additions and 123 deletions
|
|
@ -20,6 +20,7 @@
|
|||
****************************************************************************/
|
||||
#include "elf.h"
|
||||
#include "misc.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
/**
|
||||
* Definitions
|
||||
|
|
@ -723,3 +724,28 @@ void elf_release(struct elf_params_t *params)
|
|||
seg = next_seg;
|
||||
}
|
||||
}
|
||||
|
||||
void elf_std_printf(void *user, bool error, const char *fmt, ...)
|
||||
{
|
||||
if(!g_debug && !error)
|
||||
return;
|
||||
(void) user;
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vprintf(fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void elf_std_write(void *user, uint32_t addr, const void *buf, size_t count)
|
||||
{
|
||||
FILE *f = user;
|
||||
fseek(f, addr, SEEK_SET);
|
||||
fwrite(buf, count, 1, f);
|
||||
}
|
||||
|
||||
bool elf_std_read(void *user, uint32_t addr, void *buf, size_t count)
|
||||
{
|
||||
if(fseek((FILE *)user, addr, SEEK_SET) == -1)
|
||||
return false;
|
||||
return fread(buf, 1, count, (FILE *)user) == count;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,4 +93,10 @@ bool elf_get_start_addr(struct elf_params_t *params, uint32_t *addr);
|
|||
int elf_get_nr_sections(struct elf_params_t *params);
|
||||
void elf_release(struct elf_params_t *params);
|
||||
|
||||
/* standard implementation of read/write/printf functions
|
||||
* with user being a FILE* pointer */
|
||||
void elf_std_printf(void *user, bool error, const char *fmt, ...);
|
||||
void elf_std_write(void *user, uint32_t addr, const void *buf, size_t count);
|
||||
bool elf_std_read(void *user, uint32_t addr, void *buf, size_t count);
|
||||
|
||||
#endif /* __ELF_H__ */
|
||||
|
|
|
|||
|
|
@ -52,24 +52,6 @@ int g_extern_count;
|
|||
* command file to sb conversion
|
||||
*/
|
||||
|
||||
static bool elf_read(void *user, uint32_t addr, void *buf, size_t count)
|
||||
{
|
||||
if(fseek((FILE *)user, addr, SEEK_SET) == -1)
|
||||
return false;
|
||||
return fread(buf, 1, count, (FILE *)user) == count;
|
||||
}
|
||||
|
||||
static void elf_printf(void *user, bool error, const char *fmt, ...)
|
||||
{
|
||||
if(!g_debug && !error)
|
||||
return;
|
||||
(void) user;
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vprintf(fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static void resolve_extern(struct cmd_source_t *src)
|
||||
{
|
||||
if(!src->is_extern)
|
||||
|
|
@ -102,7 +84,7 @@ static void load_elf_by_id(struct cmd_file_t *cmd_file, const char *id)
|
|||
if(g_debug)
|
||||
printf("Loading ELF file '%s'...\n", src->filename);
|
||||
elf_init(&src->elf);
|
||||
src->loaded = elf_read_file(&src->elf, elf_read, elf_printf, fd);
|
||||
src->loaded = elf_read_file(&src->elf, elf_std_read, elf_std_printf, fd);
|
||||
fclose(fd);
|
||||
if(!src->loaded)
|
||||
bug("error loading elf file '%s' (id '%s')\n", src->filename, id);
|
||||
|
|
@ -333,12 +315,6 @@ static void usage(void)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
static struct crypto_key_t g_zero_key =
|
||||
{
|
||||
.method = CRYPTO_KEY,
|
||||
.u.key = {0}
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *cmd_filename = NULL;
|
||||
|
|
@ -385,6 +361,8 @@ int main(int argc, char **argv)
|
|||
}
|
||||
case 'z':
|
||||
{
|
||||
struct crypto_key_t g_zero_key;
|
||||
sb_get_zero_key(&g_zero_key);
|
||||
add_keys(&g_zero_key, 1);
|
||||
break;
|
||||
}
|
||||
|
|
@ -407,7 +385,7 @@ int main(int argc, char **argv)
|
|||
break;
|
||||
}
|
||||
default:
|
||||
abort();
|
||||
bug("Internal error: unknown option '%c'\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -305,3 +305,44 @@ void color(color_t c)
|
|||
if(g_color_enable)
|
||||
printf("%s", (char *)c);
|
||||
}
|
||||
|
||||
enum sb_version_guess_t guess_sb_version(const char *filename)
|
||||
{
|
||||
#define ret(x) do { fclose(f); return x; } while(0)
|
||||
FILE *f = fopen(filename, "rb");
|
||||
if(f == NULL)
|
||||
ret(SB_VERSION_ERR);
|
||||
// check signature
|
||||
uint8_t sig[4];
|
||||
if(fseek(f, 20, SEEK_SET))
|
||||
ret(SB_VERSION_UNK);
|
||||
if(fread(sig, 4, 1, f) != 1)
|
||||
ret(SB_VERSION_UNK);
|
||||
if(memcmp(sig, "STMP", 4) != 0)
|
||||
ret(SB_VERSION_UNK);
|
||||
// check header size (v1)
|
||||
uint32_t hdr_size;
|
||||
if(fseek(f, 8, SEEK_SET))
|
||||
ret(SB_VERSION_UNK);
|
||||
if(fread(&hdr_size, 4, 1, f) != 1)
|
||||
ret(SB_VERSION_UNK);
|
||||
if(hdr_size == 0x34)
|
||||
ret(SB_VERSION_1);
|
||||
// check header params relationship
|
||||
struct
|
||||
{
|
||||
uint16_t nr_keys; /* Number of encryption keys */
|
||||
uint16_t key_dict_off; /* Offset to key dictionary (in blocks) */
|
||||
uint16_t header_size; /* In blocks */
|
||||
uint16_t nr_sections; /* Number of sections */
|
||||
uint16_t sec_hdr_size; /* Section header size (in blocks) */
|
||||
} __attribute__((packed)) u;
|
||||
if(fseek(f, 0x28, SEEK_SET))
|
||||
ret(SB_VERSION_UNK);
|
||||
if(fread(&u, sizeof(u), 1, f) != 1)
|
||||
ret(SB_VERSION_UNK);
|
||||
if(u.sec_hdr_size == 1 && u.header_size == 6 && u.key_dict_off == u.header_size + u.nr_sections)
|
||||
ret(SB_VERSION_2);
|
||||
ret(SB_VERSION_UNK);
|
||||
#undef ret
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,4 +63,14 @@ extern color_t OFF, GREY, RED, GREEN, YELLOW, BLUE;
|
|||
void color(color_t c);
|
||||
void enable_color(bool enable);
|
||||
|
||||
enum sb_version_guess_t
|
||||
{
|
||||
SB_VERSION_1,
|
||||
SB_VERSION_2,
|
||||
SB_VERSION_UNK,
|
||||
SB_VERSION_ERR,
|
||||
};
|
||||
|
||||
enum sb_version_guess_t guess_sb_version(const char *filename);
|
||||
|
||||
#endif /* __MISC_H__ */
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ int main(int argc, char **argv)
|
|||
break;
|
||||
}
|
||||
default:
|
||||
abort();
|
||||
bug("Internal error: unknown option '%c'\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include "misc.h"
|
||||
#include "crypto.h"
|
||||
#include "sb.h"
|
||||
|
|
@ -1245,3 +1246,20 @@ void sb_dump(struct sb_file_t *file, void *u, sb_color_printf cprintf)
|
|||
#undef printf
|
||||
#undef print_hex
|
||||
}
|
||||
|
||||
void sb_get_zero_key(struct crypto_key_t *key)
|
||||
{
|
||||
key->method = CRYPTO_KEY;
|
||||
memset(key->u.key, 0, sizeof(key->u.key));
|
||||
}
|
||||
|
||||
void sb_std_printf(void *user, bool error, color_t c, const char *fmt, ...)
|
||||
{
|
||||
(void) user;
|
||||
(void) error;
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
color(c);
|
||||
vprintf(fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -239,5 +239,9 @@ void sb_dump(struct sb_file_t *file, void *u, sb_color_printf printf);
|
|||
void sb_free_instruction(struct sb_inst_t inst);
|
||||
void sb_free_section(struct sb_section_t file);
|
||||
void sb_free(struct sb_file_t *file);
|
||||
void sb_get_zero_key(struct crypto_key_t *key);
|
||||
|
||||
/* standard implementation: user is unused*/
|
||||
void sb_std_printf(void *user, bool error, color_t c, const char *fmt, ...);
|
||||
|
||||
#endif /* __SB_H__ */
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ enum sb1_error_t sb1_write_file(struct sb1_file_t *sb, const char *filename)
|
|||
image_size += 8;
|
||||
break;
|
||||
default:
|
||||
bugp("Unknown SB instruction: %#x\n", sb->insts[i].cmd);
|
||||
bugp("Internal error: unknown SB instruction: %#x\n", sb->insts[i].cmd);
|
||||
}
|
||||
}
|
||||
// now take crypto marks and sector size into account:
|
||||
|
|
@ -140,7 +140,7 @@ enum sb1_error_t sb1_write_file(struct sb1_file_t *sb, const char *filename)
|
|||
sb->insts[i].sdram.size_index);
|
||||
break;
|
||||
default:
|
||||
bugp("Unknown SB instruction: %#x\n", sb->insts[i].cmd);
|
||||
bugp("Internal error: unknown SB instruction: %#x\n", sb->insts[i].cmd);
|
||||
}
|
||||
|
||||
/* handle most common cases */
|
||||
|
|
|
|||
|
|
@ -445,6 +445,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
break;
|
||||
default:
|
||||
printf("Internal error: unknown option '%c'\n", c);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,24 +60,6 @@
|
|||
static char *g_out_prefix;
|
||||
static bool g_elf_simplify = true;
|
||||
|
||||
static void elf_printf(void *user, bool error, const char *fmt, ...)
|
||||
{
|
||||
if(!g_debug && !error)
|
||||
return;
|
||||
(void) user;
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vprintf(fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static void elf_write(void *user, uint32_t addr, const void *buf, size_t count)
|
||||
{
|
||||
FILE *f = user;
|
||||
fseek(f, addr, SEEK_SET);
|
||||
fwrite(buf, count, 1, f);
|
||||
}
|
||||
|
||||
static void extract_elf_section(struct elf_params_t *elf, int count, uint32_t id)
|
||||
{
|
||||
char name[5];
|
||||
|
|
@ -94,7 +76,7 @@ static void extract_elf_section(struct elf_params_t *elf, int count, uint32_t id
|
|||
return;
|
||||
if(g_elf_simplify)
|
||||
elf_simplify(elf);
|
||||
elf_write_file(elf, elf_write, elf_printf, fd);
|
||||
elf_write_file(elf, elf_std_write, elf_std_printf, fd);
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
|
|
@ -174,7 +156,7 @@ static void extract_elf(struct elf_params_t *elf, int count)
|
|||
return;
|
||||
if(g_elf_simplify)
|
||||
elf_simplify(elf);
|
||||
elf_write_file(elf, elf_write, elf_printf, fd);
|
||||
elf_write_file(elf, elf_std_write, elf_std_printf, fd);
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
|
|
@ -236,73 +218,6 @@ static void usage(void)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
static void sb_printf(void *user, bool error, color_t c, const char *fmt, ...)
|
||||
{
|
||||
(void) user;
|
||||
(void) error;
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
color(c);
|
||||
vprintf(fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static struct crypto_key_t g_zero_key =
|
||||
{
|
||||
.method = CRYPTO_KEY,
|
||||
.u.key = {0}
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum sb_version_guess_t
|
||||
{
|
||||
SB_VERSION_1,
|
||||
SB_VERSION_2,
|
||||
SB_VERSION_UNK,
|
||||
};
|
||||
|
||||
enum sb_version_guess_t guess_sb_version(const char *filename)
|
||||
{
|
||||
#define ret(x) do { fclose(f); return x; } while(0)
|
||||
FILE *f = fopen(filename, "rb");
|
||||
if(f == NULL)
|
||||
bugp("Cannot open file for reading\n");
|
||||
// check signature
|
||||
uint8_t sig[4];
|
||||
if(fseek(f, 20, SEEK_SET))
|
||||
ret(SB_VERSION_UNK);
|
||||
if(fread(sig, 4, 1, f) != 1)
|
||||
ret(SB_VERSION_UNK);
|
||||
if(memcmp(sig, "STMP", 4) != 0)
|
||||
ret(SB_VERSION_UNK);
|
||||
// check header size (v1)
|
||||
uint32_t hdr_size;
|
||||
if(fseek(f, 8, SEEK_SET))
|
||||
ret(SB_VERSION_UNK);
|
||||
if(fread(&hdr_size, 4, 1, f) != 1)
|
||||
ret(SB_VERSION_UNK);
|
||||
if(hdr_size == 0x34)
|
||||
ret(SB_VERSION_1);
|
||||
// check header params relationship
|
||||
struct
|
||||
{
|
||||
uint16_t nr_keys; /* Number of encryption keys */
|
||||
uint16_t key_dict_off; /* Offset to key dictionary (in blocks) */
|
||||
uint16_t header_size; /* In blocks */
|
||||
uint16_t nr_sections; /* Number of sections */
|
||||
uint16_t sec_hdr_size; /* Section header size (in blocks) */
|
||||
} __attribute__((packed)) u;
|
||||
if(fseek(f, 0x28, SEEK_SET))
|
||||
ret(SB_VERSION_UNK);
|
||||
if(fread(&u, sizeof(u), 1, f) != 1)
|
||||
ret(SB_VERSION_UNK);
|
||||
if(u.sec_hdr_size == 1 && u.header_size == 6 && u.key_dict_off == u.header_size + u.nr_sections)
|
||||
ret(SB_VERSION_2);
|
||||
ret(SB_VERSION_UNK);
|
||||
#undef ret
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
bool raw_mode = false;
|
||||
|
|
@ -361,8 +276,12 @@ int main(int argc, char **argv)
|
|||
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;
|
||||
|
|
@ -397,7 +316,7 @@ int main(int argc, char **argv)
|
|||
brute_force = true;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
bug("Internal error: unknown option '%c'\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -413,11 +332,16 @@ int main(int argc, char **argv)
|
|||
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, sb_printf, &err);
|
||||
struct sb_file_t *file = sb_read_file(sb_filename, raw_mode, NULL, sb_std_printf, &err);
|
||||
if(file == NULL)
|
||||
{
|
||||
color(OFF);
|
||||
|
|
@ -432,7 +356,7 @@ int main(int argc, char **argv)
|
|||
{
|
||||
color(GREY);
|
||||
printf("[Debug output]\n");
|
||||
sb_dump(file, NULL, sb_printf);
|
||||
sb_dump(file, NULL, sb_std_printf);
|
||||
}
|
||||
if(loopback)
|
||||
{
|
||||
|
|
@ -451,7 +375,7 @@ int main(int argc, char **argv)
|
|||
{
|
||||
struct crypto_key_t key;
|
||||
enum sb1_error_t err;
|
||||
if(!sb1_brute_force(sb_filename, NULL, sb_printf, &err, &key))
|
||||
if(!sb1_brute_force(sb_filename, NULL, sb_std_printf, &err, &key))
|
||||
{
|
||||
color(OFF);
|
||||
printf("Brute force failed: %d\n", err);
|
||||
|
|
@ -475,7 +399,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
enum sb1_error_t err;
|
||||
struct sb1_file_t *file = sb1_read_file(sb_filename, NULL, sb_printf, &err);
|
||||
struct sb1_file_t *file = sb1_read_file(sb_filename, NULL, sb_std_printf, &err);
|
||||
if(file == NULL)
|
||||
{
|
||||
color(OFF);
|
||||
|
|
@ -490,7 +414,7 @@ int main(int argc, char **argv)
|
|||
{
|
||||
color(GREY);
|
||||
printf("[Debug output]\n");
|
||||
sb1_dump(file, NULL, sb_printf);
|
||||
sb1_dump(file, NULL, sb_std_printf);
|
||||
}
|
||||
if(loopback)
|
||||
sb1_write_file(file, loopback);
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ static uint32_t do_unround(union xorcrypt_key_t *key)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void test_round(union xorcrypt_key_t keys[2])
|
||||
static void __attribute__((unused)) test_round(union xorcrypt_key_t keys[2])
|
||||
{
|
||||
union xorcrypt_key_t save[2];
|
||||
memcpy(save, keys, sizeof(save));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue