static int _exit_64_shdr(AsmFormatPlugin * format, Elf64_Off offset) { AsmFormatPluginHelper * helper = format->helper; Elf * elf = format->priv; ElfArch * ea = elf->arch; Elf64_Xword addralign = ea->addralign; Elf64_Shdr * es64 = elf->es64; Elf64_Shdr hdr; int i; if(helper->seek(helper->format, 0, SEEK_END) < 0) return _elf_error(format); memset(&hdr, 0, sizeof(hdr)); if(ea->endian == ELFDATA2MSB) { hdr.sh_type = _htob32(SHT_NULL); hdr.sh_link = _htob32(SHN_UNDEF); } else { hdr.sh_type = _htol32(SHT_NULL); hdr.sh_link = _htol32(SHN_UNDEF); } if(helper->write(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr)) return -1; for(i = 0; i < elf->es64_cnt; i++) { if(i + 1 == elf->es64_cnt) es64[i].sh_size = offset - es64[i].sh_offset; else es64[i].sh_size = es64[i + 1].sh_offset - es64[i].sh_offset; es64[i].sh_offset = (ea->endian == ELFDATA2MSB) ? _htob64(es64[i].sh_offset) : _htol64(es64[i].sh_offset); es64[i].sh_size = (ea->endian == ELFDATA2MSB) ? _htob64(es64[i].sh_size) : _htol64(es64[i].sh_size); if(es64[i].sh_type == SHT_PROGBITS) es64[i].sh_addralign = (ea->endian == ELFDATA2MSB) ? _htob64(addralign) : _htol64(addralign); es64[i].sh_type = (ea->endian == ELFDATA2MSB) ? _htob32(es64[i].sh_type) : _htol32(es64[i].sh_type); if(helper->write(helper->format, &es64[i], sizeof(Elf64_Shdr)) != sizeof(Elf64_Shdr)) return -1; } return 0; }
static int _exit_32_phdr(AsmFormatPlugin * format, Elf32_Off offset) { AsmFormatPluginHelper * helper = format->helper; Elf * elf = format->priv; ElfArch * ea = elf->arch; Elf32_Ehdr hdr; #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); #endif if(elf->es32_cnt == 0) return 0; if(helper->seek(helper->format, 0, SEEK_SET) != 0) return -1; if(helper->read(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr)) return _elf_error(format); if(ea->endian == ELFDATA2MSB) { hdr.e_shoff = _htob32(offset); hdr.e_shnum = _htob16(elf->es32_cnt + 1); hdr.e_shstrndx = _htob16(elf->es32_cnt); } else { hdr.e_shoff = _htol32(offset); hdr.e_shnum = _htol16(elf->es32_cnt + 1); hdr.e_shstrndx = _htol16(elf->es32_cnt); } if(helper->seek(helper->format, 0, SEEK_SET) != 0) return -1; if(helper->write(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr)) return -1; return 0; }
static int _exit_32_shdr(AsmFormatPlugin * format, Elf32_Off offset) { AsmFormatPluginHelper * helper = format->helper; Elf * elf = format->priv; ElfArch * ea = elf->arch; Elf32_Word addralign = ea->addralign; Elf32_Shdr * es32 = elf->es32; Elf32_Shdr hdr; int i; #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); #endif if(helper->seek(helper->format, 0, SEEK_END) < 0) return _elf_error(format); memset(&hdr, 0, sizeof(hdr)); if(ea->endian == ELFDATA2MSB) { hdr.sh_type = _htob32(SHT_NULL); hdr.sh_link = _htob32(SHN_UNDEF); } else { hdr.sh_type = _htol32(SHT_NULL); hdr.sh_link = _htol32(SHN_UNDEF); } if(helper->write(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr)) return -1; for(i = 0; i < elf->es32_cnt; i++) { #ifdef DEBUG fprintf(stderr, "DEBUG: %s() %d\n", __func__, i); #endif if(i + 1 == elf->es32_cnt) es32[i].sh_size = offset - es32[i].sh_offset; else es32[i].sh_size = es32[i + 1].sh_offset - es32[i].sh_offset; es32[i].sh_offset = (ea->endian == ELFDATA2MSB) ? _htob32(es32[i].sh_offset) : _htol32(es32[i].sh_offset); es32[i].sh_size = (ea->endian == ELFDATA2MSB) ? _htob32(es32[i].sh_size) : _htol32(es32[i].sh_size); if(es32[i].sh_type == SHT_PROGBITS) es32[i].sh_addralign = (ea->endian == ELFDATA2MSB) ? _htob32(addralign) : _htol32(addralign); es32[i].sh_type = (ea->endian == ELFDATA2MSB) ? _htob32(es32[i].sh_type) : _htol32(es32[i].sh_type); if(helper->write(helper->format, &es32[i], sizeof(Elf32_Shdr)) != sizeof(Elf32_Shdr)) return -1; } return 0; }
/* java_encode */ static int _java_encode(AsmArchPlugin * plugin, AsmArchInstruction const * instruction, AsmArchInstructionCall * call) { AsmArchPluginHelper * helper = plugin->helper; size_t i; AsmArchOperandDefinition definitions[3]; AsmArchOperand * ao; uint8_t u8; uint16_t u16; uint32_t u32; if((helper->write(helper->arch, &instruction->opcode, 1)) != 1) return -1; /* FIXME tableswitch may need some padding */ definitions[0] = instruction->op1; definitions[1] = instruction->op2; definitions[2] = instruction->op3; for(i = 0; i < call->operands_cnt; i++) { ao = &call->operands[i]; if(AO_GET_TYPE(ao->definition) != AOT_IMMEDIATE) return -error_set_code(1, "%s", "Not implemented"); if(AO_GET_SIZE(definitions[i]) == 8) { u8 = ao->value.immediate.value; if(helper->write(helper->arch, &u8, 1) != 1) return -1; } else if(AO_GET_SIZE(definitions[i]) == 16) { u16 = _htob16(ao->value.immediate.value); if(helper->write(helper->arch, &u16, 2) != 2) return -1; } else if(AO_GET_SIZE(definitions[i]) == 32) { u32 = _htob32(ao->value.immediate.value); if(helper->write(helper->arch, &u32, 4) != 4) return -1; } else return -error_set_code(1, "%s", "Size not implemented"); } return 0; }
/* init_32 */ static int _init_32(AsmFormatPlugin * format) { AsmFormatPluginHelper * helper = format->helper; Elf * elf = format->priv; ElfArch * ea = elf->arch; Elf32_Ehdr hdr; #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); #endif memset(&hdr, 0, sizeof(hdr)); memcpy(&hdr.e_ident, ELFMAG, SELFMAG); hdr.e_ident[EI_CLASS] = ELFCLASS32; hdr.e_ident[EI_DATA] = ea->endian; hdr.e_ident[EI_VERSION] = EV_CURRENT; if(ea->endian == ELFDATA2MSB) { hdr.e_type = _htob16(ET_REL); hdr.e_machine = _htob16(ea->machine); hdr.e_version = _htob32(EV_CURRENT); hdr.e_ehsize = _htob16(sizeof(hdr)); hdr.e_shentsize = _htob16(sizeof(Elf32_Shdr)); hdr.e_shstrndx = _htob16(SHN_UNDEF); } else { hdr.e_type = _htol16(ET_REL); hdr.e_machine = _htol16(ea->machine); hdr.e_version = _htol32(EV_CURRENT); hdr.e_ehsize = _htol16(sizeof(hdr)); hdr.e_shentsize = _htol16(sizeof(Elf32_Shdr)); hdr.e_shstrndx = _htol16(SHN_UNDEF); } if(helper->write(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr)) return _elf_error(format); return 0; }
/* java_decode */ static int _java_decode(AsmArchPlugin * plugin, AsmArchInstructionCall * call) { AsmArchPluginHelper * helper = plugin->helper; uint8_t u8; AsmArchInstruction const * ai; size_t i; AsmArchOperand * ao; uint16_t u16; uint32_t u32; AsmString * as; uint32_t begin; uint32_t end; if(helper->read(helper->arch, &u8, sizeof(u8)) != sizeof(u8)) return -1; if((ai = helper->get_instruction_by_opcode(helper->arch, 8, u8)) == NULL) { call->name = "db"; call->operands[0].definition = AO_IMMEDIATE(0, 8, 0); call->operands[0].value.immediate.name = NULL; call->operands[0].value.immediate.value = u8; call->operands[0].value.immediate.negative = 0; call->operands_cnt = 1; return 0; } call->name = ai->name; /* tableswitch may be followed by padding */ if(ai->opcode == 0xaa && (i = call->offset % 4) > 0 && helper->read(helper->arch, &u32, i) != i) return -1; call->operands[0].definition = ai->op1; call->operands[1].definition = ai->op2; call->operands[2].definition = ai->op3; for(i = 0; i < 3 && AO_GET_TYPE(call->operands[i].definition) != AOT_NONE; i++) { ao = &call->operands[i]; if(AO_GET_TYPE(ao->definition) != AOT_IMMEDIATE) /* XXX should there be more types? */ return -error_set_code(1, "%s", "Not implemented"); if(AO_GET_SIZE(ao->definition) == 8) { if(helper->read(helper->arch, &u8, 1) != 1) return -1; ao->value.immediate.value = u8; } else if(AO_GET_SIZE(ao->definition) == 16) { if(helper->read(helper->arch, &u16, 2) != 2) return -1; u16 = _htob16(u16); ao->value.immediate.value = u16; } else if(AO_GET_SIZE(ao->definition) == 32) { if(helper->read(helper->arch, &u32, 4) != 4) return -1; u32 = _htob32(u32); ao->value.immediate.value = u32; } else return -error_set_code(1, "%s", "Size not implemented"); ao->value.immediate.name = NULL; ao->value.immediate.negative = 0; switch(AO_GET_VALUE(ao->definition)) { case AOI_REFERS_FUNCTION: case AOI_REFERS_STRING: as = helper->get_string_by_id(helper->arch, ao->value.immediate.value); if(as != NULL) ao->value.immediate.name = as->name; ao->value.immediate.negative = 0; break; } } call->operands_cnt = i; /* tableswitch may be followed by offsets */ if(ai->opcode == 0xaa) { for(begin = call->operands[1].value.immediate.value, end = call->operands[2].value.immediate.value; begin <= end; begin++) if(helper->read(helper->arch, &u32, sizeof(u32)) != (ssize_t)sizeof(u32)) return -1; } return 0; }