void generate_random_data(void *buf, size_t sz) { FILE *rand_fd = fopen("/dev/urandom", "rb"); if(rand_fd == NULL) bugp("failed to open /dev/urandom"); if(fread(buf, 1, sz, rand_fd) != sz) bugp("failed to read /dev/urandom"); fclose(rand_fd); }
static void extract_sb_section(struct sb_section_t *sec) { if(sec->is_data) { char sec_name[5]; char *filename = xmalloc(strlen(g_out_prefix) + 32); sb_fill_section_name(sec_name, sec->identifier); sprintf(filename, "%s%s.bin", g_out_prefix, sec_name); FILE *fd = fopen(filename, "wb"); if(fd == NULL) bugp("Cannot open %s for writing\n", filename); if(g_debug) printf("Write data section %s to %s\n", sec_name, filename); free(filename); for(int j = 0; j < sec->nr_insts; j++) { assert(sec->insts[j].inst == SB_INST_DATA); fwrite(sec->insts[j].data, sec->insts[j].size, 1, fd); } fclose(fd); } int elf_count = 0; struct elf_params_t elf; elf_init(&elf); for(int i = 0; i < sec->nr_insts; i++) { struct sb_inst_t *inst = &sec->insts[i]; switch(inst->inst) { case SB_INST_LOAD: elf_add_load_section(&elf, inst->addr, inst->size, inst->data); break; case SB_INST_FILL: elf_add_fill_section(&elf, inst->addr, inst->size, inst->pattern); break; case SB_INST_CALL: case SB_INST_JUMP: elf_set_start_addr(&elf, inst->addr); extract_elf_section(&elf, elf_count++, sec->identifier); elf_release(&elf); elf_init(&elf); break; default: /* ignore mode and nop */ break; } } if(!elf_is_empty(&elf)) extract_elf_section(&elf, elf_count, sec->identifier); elf_release(&elf); }
static key_array_t read_keys(int num_keys) { int size; struct stat st; int fd = open(key_file,O_RDONLY); if(fd == -1) bugp("opening key file failed"); if(fstat(fd,&st) == -1) bugp("key file stat() failed"); size = st.st_size; char *buf = xmalloc(size); if(read(fd, buf, size) != (ssize_t)size) bugp("reading key file"); close(fd); key_array_t keys = xmalloc(sizeof(byte[16]) * num_keys); int pos = 0; for(int i = 0; i < num_keys; i++) { /* skip ws */ while(pos < size && isspace(buf[pos])) pos++; /* enough space ? */ if((pos + 32) > size) bugp("invalid key file (not enough keys)"); for(int j = 0; j < 16; j++) { byte a, b; if(convxdigit(buf[pos + 2 * j], &a) || convxdigit(buf[pos + 2 * j + 1], &b)) bugp(" invalid key, it should be a 128-bit key written in hexadecimal\n"); keys[i][j] = (a << 4) | b; } pos += 32; } free(buf); return keys; }
void *xmalloc(size_t s) /* malloc helper, used in elf.c */ { void * r = malloc(s); if(!r) bugp("malloc"); return r; }
void *xmalloc(size_t s) { void * r = malloc(s); if(!r) bugp("malloc"); return r; }
static void extract_sb_section(struct sb_section_t *sec, struct cmd_file_t *cmd_file) { struct cmd_section_t *db_sec = db_add_section(cmd_file, sec->identifier, sec->is_data); db_add_int_opt(&db_sec->opt_list, "alignment", sec->alignment); db_add_int_opt(&db_sec->opt_list, "cleartext", sec->is_cleartext); db_add_int_opt(&db_sec->opt_list, "sectionFlags", sec->other_flags); if(sec->is_data) { char sec_name[5]; char *filename = xmalloc(strlen(g_out_prefix) + 32); sb_fill_section_name(sec_name, sec->identifier); sprintf(filename, "%s%s.bin", g_out_prefix, sec_name); db_add_source(cmd_file, sec_name, filename + strlen(g_out_prefix)); db_sec->source_id = strdup(sec_name); FILE *fd = fopen(filename, "wb"); if(fd == NULL) bugp("Cannot open %s for writing\n", filename); if(g_debug) printf("Write data section %s to %s\n", sec_name, filename); free(filename); for(int j = 0; j < sec->nr_insts; j++) { assert(sec->insts[j].inst == SB_INST_DATA); fwrite(sec->insts[j].data, sec->insts[j].size, 1, fd); } fclose(fd); } int elf_count = 0; struct elf_params_t elf; elf_init(&elf); int bss_idx = 0, text_idx = 0; char secname[32]; for(int i = 0; i < sec->nr_insts; i++) { struct sb_inst_t *inst = &sec->insts[i]; switch(inst->inst) { case SB_INST_LOAD: sprintf(secname, ".text%d", text_idx++); elf_add_load_section(&elf, inst->addr, inst->size, inst->data, secname); break; case SB_INST_FILL: sprintf(secname, ".bss%d", bss_idx++); elf_add_fill_section(&elf, inst->addr, inst->size, inst->pattern, secname); break; case SB_INST_CALL: case SB_INST_JUMP: elf_set_start_addr(&elf, inst->addr); extract_elf_section(&elf, elf_count++, sec->identifier, cmd_file, db_sec, inst->inst == SB_INST_CALL, inst->argument); elf_release(&elf); elf_init(&elf); bss_idx = text_idx = 0; break; default: /* ignore mode and nop */ break; } } if(!elf_is_empty(&elf)) extract_elf_section(&elf, elf_count, sec->identifier, cmd_file, db_sec, false, 0); elf_release(&elf); }