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 void extract_sb1_file(struct sb1_file_t *file) { 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 < file->nr_insts; i++) { struct sb1_inst_t *inst = &file->insts[i]; switch(inst->cmd) { case SB1_INST_LOAD: sprintf(secname, ".text%d", text_idx++); elf_add_load_section(&elf, inst->addr, inst->size, inst->data, secname); break; case SB1_INST_FILL: sprintf(secname, ".bss%d", bss_idx++); elf_add_fill_section(&elf, inst->addr, inst->size, inst->pattern, secname); break; case SB1_INST_CALL: case SB1_INST_JUMP: elf_set_start_addr(&elf, inst->addr); extract_elf(&elf, elf_count++); elf_release(&elf); elf_init(&elf); break; default: /* ignore mode and nop */ break; } } if(!elf_is_empty(&elf)) extract_elf(&elf, elf_count); elf_release(&elf); }
static void extract_section(int data_sec, char name[5], byte *buf, int size, const char *indent) { char filename[PREFIX_SIZE + 32]; snprintf(filename, sizeof filename, "%s%s.bin", out_prefix, name); FILE *fd = fopen(filename, "wb"); if (fd != NULL) { fwrite(buf, size, 1, fd); fclose(fd); } if(data_sec) return; snprintf(filename, sizeof filename, "%s%s", out_prefix, name); /* elf construction */ struct elf_params_t elf; elf_init(&elf); int elf_count = 0; /* Pretty print the content */ int pos = 0; while(pos < size) { struct sb_instruction_header_t *hdr = (struct sb_instruction_header_t *)&buf[pos]; printf("%s", indent); uint8_t checksum = instruction_checksum(hdr); if(checksum != hdr->checksum) { color(GREY); printf("[Bad checksum]"); } if(hdr->opcode == SB_INST_LOAD) { struct sb_instruction_load_t *load = (struct sb_instruction_load_t *)&buf[pos]; color(RED); printf("LOAD"); color(OFF);printf(" | "); color(BLUE); printf("addr=0x%08x", load->addr); color(OFF);printf(" | "); color(GREEN); printf("len=0x%08x", load->len); color(OFF);printf(" | "); color(YELLOW); printf("crc=0x%08x", load->crc); /* data is padded to 16-byte boundary with random data and crc'ed with it */ uint32_t computed_crc = crc(&buf[pos + sizeof(struct sb_instruction_load_t)], ROUND_UP(load->len, 16)); color(RED); if(load->crc == computed_crc) printf(" Ok\n"); else printf(" Failed (crc=0x%08x)\n", computed_crc); /* elf construction */ elf_add_load_section(&elf, load->addr, load->len, &buf[pos + sizeof(struct sb_instruction_load_t)]); pos += load->len + sizeof(struct sb_instruction_load_t); // unsure about rounding pos = ROUND_UP(pos, 16); } else if(hdr->opcode == SB_INST_FILL) { struct sb_instruction_fill_t *fill = (struct sb_instruction_fill_t *)&buf[pos]; color(RED); printf("FILL"); color(OFF);printf(" | "); color(BLUE); printf("addr=0x%08x", fill->addr); color(OFF);printf(" | "); color(GREEN); printf("len=0x%08x", fill->len); color(OFF);printf(" | "); color(YELLOW); printf("pattern=0x%08x\n", fill->pattern); color(OFF); /* elf construction */ elf_add_fill_section(&elf, fill->addr, fill->len, fill->pattern); pos += sizeof(struct sb_instruction_fill_t); // fixme: useless as pos is a multiple of 16 and fill struct is 4-bytes wide ? pos = ROUND_UP(pos, 16); } else if(hdr->opcode == SB_INST_CALL || hdr->opcode == SB_INST_JUMP) { int is_call = (hdr->opcode == SB_INST_CALL); struct sb_instruction_call_t *call = (struct sb_instruction_call_t *)&buf[pos]; color(RED); if(is_call) printf("CALL"); else printf("JUMP"); color(OFF);printf(" | "); color(BLUE); printf("addr=0x%08x", call->addr); color(OFF);printf(" | "); color(GREEN); printf("arg=0x%08x\n", call->arg); color(OFF); /* elf construction */ elf_set_start_addr(&elf, call->addr); extract_elf_section(&elf, elf_count++, filename, indent); elf_release(&elf); elf_init(&elf); pos += sizeof(struct sb_instruction_call_t); // fixme: useless as pos is a multiple of 16 and call struct is 4-bytes wide ? pos = ROUND_UP(pos, 16); } else { color(RED); printf("Unknown instruction %d at address 0x%08lx\n", hdr->opcode, (unsigned long)pos); break; } } if(!elf_is_empty(&elf)) extract_elf_section(&elf, elf_count++, filename, indent); elf_release(&elf); }
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); }