diff --git a/include/Asm/format.h b/include/Asm/format.h index da6dc06..2683a60 100644 --- a/include/Asm/format.h +++ b/include/Asm/format.h @@ -23,15 +23,31 @@ /* AsmFormat */ /* types */ -typedef struct _FormatPluginHelper -{ - char const * filename; - FILE * fp; - void * priv; -} FormatPluginHelper; +typedef struct _Format Format; typedef struct _FormatPlugin FormatPlugin; +typedef struct _FormatPluginHelper +{ + Format * format; + + /* callbacks */ + /* accessors */ + char const * (*get_filename)(Format * format); + + /* useful */ + ssize_t (*read)(Format * format, void * buf, size_t size); + off_t (*seek)(Format * format, off_t offset, int whence); + + /* assembly */ + ssize_t (*write)(Format * format, void const * buf, size_t size); + + /* disassembly */ + /* FIXME let a different architecture be specified in the callback */ + int (*disas)(Format * format, char const * section, + off_t offset, size_t size, off_t base); +} FormatPluginHelper; + struct _FormatPlugin { FormatPluginHelper * helper; @@ -47,12 +63,7 @@ struct _FormatPlugin int (*section)(FormatPlugin * format, char const * section); char const * (*detect)(FormatPlugin * format); - /* FIXME: - * - put the callback in the helper structure - * - let a different architecture be specified in the callback */ - int (*disas)(FormatPlugin * format, int (*callback)( - FormatPlugin * format, char const * section, - off_t offset, size_t size, off_t base)); + int (*disas)(FormatPlugin * format); void * priv; }; diff --git a/src/format.c b/src/format.c index e90f5a6..6f9485b 100644 --- a/src/format.c +++ b/src/format.c @@ -34,9 +34,24 @@ struct _Format FormatPluginHelper helper; Plugin * handle; FormatPlugin * plugin; + + /* internal */ + /* file */ + char const * filename; + FILE * fp; }; +/* prototypes */ +/* callbacks */ +static char const * _format_get_filename(Format * format); + +static ssize_t _format_read(Format * format, void * buf, size_t size); +static off_t _format_seek(Format * format, off_t offset, int whence); + +static ssize_t _format_write(Format * format, void const * buf, size_t size); + + /* public */ /* functions */ /* format_new */ @@ -100,10 +115,12 @@ int format_exit(Format * format) #endif if(format->plugin->exit != NULL) ret = format->plugin->exit(format->plugin); + format->helper.format = NULL; + format->helper.read = NULL; + format->helper.seek = NULL; format->plugin->helper = NULL; - format->helper.fp = NULL; - format->helper.filename = NULL; - format->helper.priv = NULL; + format->fp = NULL; + format->filename = NULL; return ret; } @@ -124,9 +141,13 @@ int format_init(Format * format, char const * filename, FILE * fp) fprintf(stderr, "DEBUG: %s(\"%s\", %p)\n", __func__, filename, (void *)fp); #endif - format->helper.filename = filename; - format->helper.fp = fp; - format->helper.priv = NULL; + format->filename = filename; + format->fp = fp; + format->helper.format = format; + format->helper.get_filename = _format_get_filename; + format->helper.read = _format_read; + format->helper.seek = _format_seek; + format->helper.write = _format_write; format->plugin->helper = &format->helper; if(format->plugin->init != NULL) return format->plugin->init(format->plugin, format->arch); @@ -141,3 +162,62 @@ int format_section(Format * format, char const * section) return 0; return format->plugin->section(format->plugin, section); } + + +/* private */ +/* functions */ +/* format_get_filename */ +static char const * _format_get_filename(Format * format) +{ + return format->filename; +} + + +/* format_read */ +static ssize_t _format_read(Format * format, void * buf, size_t size) +{ + if(fread(buf, size, 1, format->fp) == 1) + return size; + if(ferror(format->fp)) + return -error_set_code(1, "%s: %s", format->filename, + strerror(errno)); + if(feof(format->fp)) + return -error_set_code(1, "%s: %s", format->filename, + "End of file reached"); + return -error_set_code(1, "%s: %s", format->filename, "Read error"); +} + + +/* format_seek */ +static off_t _format_seek(Format * format, off_t offset, int whence) +{ + if(whence == SEEK_SET) + { + if(fseek(format->fp, offset, whence) == 0) + return offset; + } + else if(whence == SEEK_CUR || whence == SEEK_END) + { + if(fseek(format->fp, offset, whence) == 0) + return ftello(format->fp); + } + else + return -error_set_code(1, "%s: %s", format->filename, + "Invalid argument for seeking"); + return -error_set_code(1, "%s: %s", format->filename, strerror(errno)); +} + + +/* format_write */ +static ssize_t _format_write(Format * format, void const * buf, size_t size) +{ + if(fwrite(buf, size, 1, format->fp) == 1) + return size; + if(ferror(format->fp)) + return -error_set_code(1, "%s: %s", format->filename, + strerror(errno)); + if(feof(format->fp)) + return -error_set_code(1, "%s: %s", format->filename, + "End of file reached"); + return -error_set_code(1, "%s: %s", format->filename, "Write error"); +} diff --git a/src/format.h b/src/format.h index a9232e8..71fb350 100644 --- a/src/format.h +++ b/src/format.h @@ -18,15 +18,11 @@ #ifndef ASM_FORMAT_H # define ASM_FORMAT_H -# include +# include "Asm/format.h" /* Format */ /* public */ -/* types */ -typedef struct _Format Format; - - /* functions */ Format * format_new(char const * format, char const * arch); void format_delete(Format * format); diff --git a/src/format/dex.c b/src/format/dex.c index 814445c..d61972d 100644 --- a/src/format/dex.c +++ b/src/format/dex.c @@ -117,12 +117,9 @@ static char _dex_signature[4] = "dex\n"; static int _dex_init(FormatPlugin * format, char const * arch); static int _dex_destroy(FormatPlugin * format); static char const * _dex_detect(FormatPlugin * format); -static int _dex_disas(FormatPlugin * format, int (*callback)( - FormatPlugin * format, char const * section, - off_t offset, size_t size, off_t base)); +static int _dex_disas(FormatPlugin * format); static int _dex_error(FormatPlugin * format); -static int _dex_error_fread(FormatPlugin * format); /* public */ @@ -189,59 +186,52 @@ static char const * _dex_detect(FormatPlugin * format) /* dex_disas */ -static int _disas_map(FormatPlugin * format, DexHeader * dh, int (*callback)( - FormatPlugin * format, char const * section, - off_t offset, size_t size, off_t base)); -static int _disas_map_code(FormatPlugin * format, off_t offset, size_t size, - int (*callback)(FormatPlugin * format, char const * section, - off_t offset, size_t size, off_t base)); +static int _disas_map(FormatPlugin * format, DexHeader * dh); +static int _disas_map_code(FormatPlugin * format, off_t offset, size_t size); static int _disas_map_string_id(FormatPlugin * format, off_t offset, size_t size); -static int _dex_disas(FormatPlugin * format, int (*callback)( - FormatPlugin * format, char const * section, - off_t offset, size_t size, off_t base)) +static int _dex_disas(FormatPlugin * format) { - FILE * fp = format->helper->fp; + FormatPluginHelper * helper = format->helper; DexHeader dh; - if(fseek(fp, 0, SEEK_SET) != 0) - return -_dex_error(format); - if(fread(&dh, sizeof(dh), 1, fp) != 1) - return _dex_error_fread(format); + if(helper->seek(helper->format, 0, SEEK_SET) != 0) + return -1; + if(helper->read(helper->format, &dh, sizeof(dh)) != sizeof(dh)) + return -1; dh.map_off = _htol32(dh.map_off); - if(_disas_map(format, &dh, callback) != 0) + if(_disas_map(format, &dh) != 0) return -1; return 0; } -static int _disas_map(FormatPlugin * format, DexHeader * dh, int (*callback)( - FormatPlugin * format, char const * section, - off_t offset, size_t size, off_t base)) +static int _disas_map(FormatPlugin * format, DexHeader * dh) { int ret = 0; - FILE * fp = format->helper->fp; + FormatPluginHelper * helper = format->helper; uint32_t size; uint32_t i; - fpos_t pos; + off_t offset; DexMapItem dmi; #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); #endif - if(fseek(fp, dh->map_off, SEEK_SET) != 0) - return -_dex_error(format); - if(fread(&size, sizeof(size), 1, fp) != 1) - return -_dex_error_fread(format); + if(helper->seek(helper->format, dh->map_off, SEEK_SET) != dh->map_off) + return -1; + if(helper->read(helper->format, &size, sizeof(size)) != sizeof(size)) + return -1; size = _htol32(size); #ifdef DEBUG fprintf(stderr, "DEBUG: %s() %u items\n", __func__, size); #endif for(i = 0; i < size; i++) { - if(fread(&dmi, sizeof(dmi), 1, fp) != 1) - return -_dex_error_fread(format); - fgetpos(fp, &pos); + if(helper->read(helper->format, &dmi, sizeof(dmi)) + != sizeof(dmi)) + return -1; + offset = helper->seek(helper->format, 0, SEEK_CUR); dmi.type = _htol16(dmi.type); dmi.size = _htol32(dmi.size); dmi.offset = _htol32(dmi.offset); @@ -253,44 +243,48 @@ static int _disas_map(FormatPlugin * format, DexHeader * dh, int (*callback)( { case TYPE_CODE_ITEM: ret |= _disas_map_code(format, dmi.offset, - dmi.size, callback); + dmi.size); break; case TYPE_STRING_ID_ITEM: ret |= _disas_map_string_id(format, dmi.offset, dmi.size); } - fsetpos(fp, &pos); + if(helper->seek(helper->format, offset, SEEK_SET) != offset) + return -1; if(ret != 0) break; } return ret; } -static int _disas_map_code(FormatPlugin * format, off_t offset, size_t size, - int (*callback)(FormatPlugin * format, char const * section, - off_t offset, size_t size, off_t base)) +static int _disas_map_code(FormatPlugin * format, off_t offset, size_t size) { - FILE * fp = format->helper->fp; + FormatPluginHelper * helper = format->helper; DexMapCodeItem dmci; size_t i; off_t seek; size_t j; DexMapTryItem dmti; + ssize_t s; - if(fseek(fp, offset, SEEK_SET) != 0) - return -_dex_error(format); - callback(format, ".text", ftello(fp), 0, 0); + if(helper->disas(helper->format, ".text", offset, 0, 0) != 0) + return -1; for(i = 0; i < size; i++) { - if(fread(&dmci, sizeof(dmci), 1, fp) != 1) - return -_dex_error_fread(format); + s = sizeof(dmci); + if(helper->read(helper->format, &dmci, s) != s) + return -1; dmci.registers_size = _htol16(dmci.registers_size); dmci.ins_size = _htol16(dmci.ins_size); dmci.outs_size = _htol16(dmci.outs_size); dmci.tries_size = _htol16(dmci.tries_size); dmci.debug_info_off = _htol32(dmci.debug_info_off); dmci.insns_size = _htol32(dmci.insns_size); - seek = (dmci.insns_size & 0x1) == 0x1 ? 2 : 0; /* padding */ + seek = helper->seek(helper->format, 0, SEEK_CUR); + helper->disas(helper->format, NULL, seek, dmci.insns_size * 2, + 0); + /* skip padding and try_items */ + seek = (dmci.insns_size & 0x1) == 0x1 ? 2 : 0; #ifdef DEBUG fprintf(stderr, "DEBUG: code item %lu, registers 0x%x" ", size 0x%x, debug @0x%x, tries 0x%x" @@ -298,21 +292,22 @@ static int _disas_map_code(FormatPlugin * format, off_t offset, size_t size, dmci.insns_size * 2, dmci.debug_info_off, dmci.tries_size, seek); #endif - callback(format, NULL, ftello(fp), dmci.insns_size * 2, 0); - /* skip padding and try_items */ - if(seek != 0 && fseek(fp, seek, SEEK_CUR) != 0) - return -_dex_error(format); + if(seek != 0 && helper->seek(helper->format, seek, SEEK_CUR) + < 0) + return -1; if(dmci.tries_size > 0) { for(j = 0; j < dmci.tries_size; j++) { - if(fread(&dmti, sizeof(dmti), 1, fp) != 1) - return -_dex_error_fread(format); + s = sizeof(dmti); + if(helper->read(helper->format, &dmti, s) != s) + return -1; dmti.start_addr = _htol32(dmti.start_addr); dmti.insn_count = _htol16(dmti.insn_count); dmti.handler_off = _htol16(dmti.handler_off); } - callback(format, NULL, ftello(fp), 8, 0); + seek = helper->seek(helper->format, 0, SEEK_CUR); + helper->disas(helper->format, NULL, seek, 8, 0); } } return 0; @@ -321,21 +316,23 @@ static int _disas_map_code(FormatPlugin * format, off_t offset, size_t size, static int _disas_map_string_id(FormatPlugin * format, off_t offset, size_t size) { - FILE * fp = format->helper->fp; + FormatPluginHelper * helper = format->helper; Dex * dex = format->priv; size_t i; DexStringIdItem dsii; + ssize_t s; if(dex->strings_cnt != 0) return -error_set_code(1, "%s: %s", "dex", "String section already parsed"); - if(fseek(fp, offset, SEEK_SET) != 0) - return -_dex_error(format); + if(helper->seek(helper->format, offset, SEEK_SET) != offset) + return -1; if((dex->strings = malloc(sizeof(*dex->strings) * size)) == NULL) return -_dex_error(format); for(i = 0; i < size; i++) { - if(fread(&dsii, sizeof(dsii), 1, fp) != 1) + s = sizeof(dsii); + if(helper->read(helper->format, &dsii, s) != s) break; dsii.string_data_off = _htol32(dsii.string_data_off); #ifdef DEBUG @@ -349,7 +346,7 @@ static int _disas_map_string_id(FormatPlugin * format, off_t offset, { free(dex->strings); dex->strings = NULL; - return -_dex_error_fread(format); + return -1; } dex->strings_cnt = size; return 0; @@ -359,16 +356,8 @@ static int _disas_map_string_id(FormatPlugin * format, off_t offset, /* dex_error */ static int _dex_error(FormatPlugin * format) { - return -error_set_code(1, "%s: %s", format->helper->filename, - strerror(errno)); -} + FormatPluginHelper * helper = format->helper; - -/* dex_error_fread */ -static int _dex_error_fread(FormatPlugin * format) -{ - if(ferror(format->helper->fp)) - return _dex_error(format); - return -error_set_code(1, "%s: %s", format->helper->filename, - "End of file reached"); + return -error_set_code(1, "%s: %s", + helper->get_filename(helper->format), strerror(errno)); } diff --git a/src/format/elf.c b/src/format/elf.c index c459717..133be52 100644 --- a/src/format/elf.c +++ b/src/format/elf.c @@ -56,18 +56,14 @@ typedef struct _ElfStrtab /* prototypes */ +static int _elf_error(FormatPlugin * format); + /* plug-in */ static int _elf_init(FormatPlugin * format, char const * arch); static char const * _elf_detect(FormatPlugin * format); -static int _elf_disas(FormatPlugin * format, int (*callback)( - FormatPlugin * format, char const * section, - off_t offset, size_t size, off_t base)); -static int _elf_disas32(FormatPlugin * format, int (*callback)( - FormatPlugin * format, char const * section, - off_t offset, size_t size, off_t base)); -static int _elf_disas64(FormatPlugin * format, int (*callback)( - FormatPlugin * format, char const * section, - off_t offset, size_t size, off_t base)); +static int _elf_disas(FormatPlugin * format); +static int _elf_disas32(FormatPlugin * format); +static int _elf_disas64(FormatPlugin * format); /* ELF32 */ static int _init_32(FormatPlugin * format); @@ -152,8 +148,8 @@ FormatPlugin format_plugin = /* elf_error */ static int _elf_error(FormatPlugin * format) { - return -error_set_code(1, "%s: %s", format->helper->filename, - strerror(errno)); + return -error_set_code(1, "%s: %s", format->helper->get_filename( + format->helper->format), strerror(errno)); } @@ -196,22 +192,22 @@ static ElfArch * _init_arch(char const * arch) /* elf_detect */ -static char const * _detect_error(FormatPlugin * format); static char const * _detect_32(FormatPlugin * format, Elf32_Ehdr * ehdr); static char const * _detect_64(FormatPlugin * format, Elf64_Ehdr * ehdr); static char const * _elf_detect(FormatPlugin * format) { + FormatPluginHelper * helper = format->helper; union { Elf32_Ehdr ehdr32; Elf64_Ehdr ehdr64; } ehdr; - if(fseek(format->helper->fp, 0, SEEK_SET) != 0) - return _detect_error(format); - if(fread(&ehdr, sizeof(ehdr), 1, format->helper->fp) != 1) - return _detect_error(format); + if(helper->seek(helper->format, 0, SEEK_SET) != 0) + return NULL; + if(helper->read(helper->format, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) + return NULL; switch(ehdr.ehdr32.e_ident[EI_CLASS]) { case ELFCLASS32: @@ -219,17 +215,11 @@ static char const * _elf_detect(FormatPlugin * format) case ELFCLASS64: return _detect_64(format, &ehdr.ehdr64); } - error_set_code(1, "%s: %s 0x%x\n", format->helper->filename, + error_set_code(1, "%s: %s 0x%x\n", helper->get_filename(helper->format), "Unsupported ELF class", ehdr.ehdr32.e_ident[EI_CLASS]); return NULL; } -static char const * _detect_error(FormatPlugin * format) -{ - error_set_code(1, "%s: %s", format->helper->filename, strerror(errno)); - return NULL; -} - static char const * _detect_32(FormatPlugin * format, Elf32_Ehdr * ehdr) { format->disas = _elf_disas32; @@ -272,13 +262,11 @@ static char const * _detect_64(FormatPlugin * format, Elf64_Ehdr * ehdr) /* elf_disas */ -static int _elf_disas(FormatPlugin * format, int (*callback)( - FormatPlugin * format, char const * section, - off_t offset, size_t size, off_t base)) +static int _elf_disas(FormatPlugin * format) { if(_elf_detect(format) == NULL) return -1; - return format->disas(format, callback); + return format->disas(format); } @@ -291,10 +279,9 @@ static int _disas32_strtab(FormatPlugin * format, Elf32_Shdr * shdr, size_t shdr_cnt, uint16_t ndx, char ** strtab, size_t * strtab_cnt); -static int _elf_disas32(FormatPlugin * format, int (*callback)( - FormatPlugin * format, char const * section, - off_t offset, size_t size, off_t base)) +static int _elf_disas32(FormatPlugin * format) { + FormatPluginHelper * helper = format->helper; Elf32_Ehdr ehdr; Elf32_Shdr * shdr = NULL; Elf32_Addr base = 0x0; @@ -306,10 +293,10 @@ static int _elf_disas32(FormatPlugin * format, int (*callback)( fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__, format->helper->filename); #endif - if(fseek(format->helper->fp, 0, SEEK_SET) != 0 - || fread(&ehdr, sizeof(ehdr), 1, format->helper->fp) - != 1) - return -_elf_error(format); + if(helper->seek(helper->format, 0, SEEK_SET) != 0 + || helper->read(helper->format, &ehdr, sizeof(ehdr)) + != sizeof(ehdr)) + return -1; if(_disas32_shdr(format, &ehdr, &shdr) != 0) return -1; if(_disas32_addr(format, &ehdr, &base) != 0 @@ -326,7 +313,8 @@ static int _elf_disas32(FormatPlugin * format, int (*callback)( continue; if(shdr[i].sh_type == SHT_PROGBITS && shdr[i].sh_flags & SHF_EXECINSTR) - callback(format, &shstrtab[shdr[i].sh_name], + helper->disas(helper->format, + &shstrtab[shdr[i].sh_name], shdr[i].sh_offset, shdr[i].sh_size, base); } @@ -338,24 +326,27 @@ static int _elf_disas32(FormatPlugin * format, int (*callback)( static int _disas32_shdr(FormatPlugin * format, Elf32_Ehdr * ehdr, Elf32_Shdr ** shdr) { + FormatPluginHelper * helper = format->helper; + ssize_t size; + if(ehdr->e_shentsize == 0) { *shdr = NULL; return 0; } if(ehdr->e_shentsize != sizeof(**shdr)) - return -error_set_code(1, "%s: %s", format->helper->filename, + return -error_set_code(1, "%s: %s", + helper->get_filename(helper->format), "Invalid section header size"); - if(fseek(format->helper->fp, ehdr->e_shoff, SEEK_SET) != 0 - || (*shdr = malloc(ehdr->e_shentsize * ehdr->e_shnum)) - == NULL) + if(helper->seek(helper->format, ehdr->e_shoff, SEEK_SET) < 0) + return -1; + size = sizeof(**shdr) * ehdr->e_shnum; + if((*shdr = malloc(size)) == NULL) return -_elf_error(format); - if(fread(*shdr, sizeof(**shdr), ehdr->e_shnum, format->helper->fp) - != ehdr->e_shnum) + if(helper->read(helper->format, *shdr, size) != size) { free(*shdr); - return -error_set_code(1, "%s: %s", format->helper->filename, - "Short read"); + return -1; } return 0; } @@ -363,14 +354,16 @@ static int _disas32_shdr(FormatPlugin * format, Elf32_Ehdr * ehdr, static int _disas32_addr(FormatPlugin * format, Elf32_Ehdr * ehdr, Elf32_Addr * addr) { + FormatPluginHelper * helper = format->helper; Elf32_Half i; Elf32_Phdr phdr; - if(fseek(format->helper->fp, ehdr->e_phoff, SEEK_SET) != 0) - return -_elf_error(format); + if(helper->seek(helper->format, ehdr->e_phoff, SEEK_SET) < 0) + return -1; for(i = 0; i < ehdr->e_phnum; i++) - if(fread(&phdr, sizeof(phdr), 1, format->helper->fp) != 1) - return -_elf_error(format); + if(helper->read(helper->format, &phdr, sizeof(phdr)) + != sizeof(phdr)) + return -1; else if(phdr.p_type == PT_LOAD && phdr.p_flags & (PF_R | PF_X)) { *addr = phdr.p_vaddr; @@ -384,19 +377,22 @@ static int _disas32_strtab(FormatPlugin * format, Elf32_Shdr * shdr, size_t shdr_cnt, uint16_t ndx, char ** strtab, size_t * strtab_cnt) { + FormatPluginHelper * helper = format->helper; + if(ndx >= shdr_cnt) - return -error_set_code(1, "%s: %s", format->helper->filename, + return -error_set_code(1, "%s: %s", + helper->get_filename(helper->format), "Unable to read the string table"); shdr = &shdr[ndx]; - if(fseek(format->helper->fp, shdr->sh_offset, SEEK_SET) != 0 - || (*strtab = malloc(shdr->sh_size)) == NULL) + if(helper->seek(helper->format, shdr->sh_offset, SEEK_SET) < 0) + return -1; + if((*strtab = malloc(shdr->sh_size)) == NULL) return -_elf_error(format); - if(fread(*strtab, sizeof(**strtab), shdr->sh_size, format->helper->fp) + if(helper->read(helper->format, *strtab, shdr->sh_size) != shdr->sh_size) { free(*strtab); - return -error_set_code(1, "%s: %s", format->helper->filename, - "Short read"); + return -1; } *strtab_cnt = shdr->sh_size; return 0; @@ -412,10 +408,9 @@ static int _disas64_strtab(FormatPlugin * format, Elf64_Shdr * shdr, size_t shdr_cnt, uint16_t ndx, char ** strtab, size_t * strtab_cnt); -static int _elf_disas64(FormatPlugin * format, int (*callback)( - FormatPlugin * format, char const * section, - off_t offset, size_t size, off_t base)) +static int _elf_disas64(FormatPlugin * format) { + FormatPluginHelper * helper = format->helper; Elf64_Ehdr ehdr; Elf64_Shdr * shdr = NULL; Elf64_Addr base = 0x0; @@ -425,12 +420,12 @@ static int _elf_disas64(FormatPlugin * format, int (*callback)( #ifdef DEBUG fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__, - format->helper->filename); + helper->get_filename(helper->format)); #endif - if(fseek(format->helper->fp, 0, SEEK_SET) != 0 - || fread(&ehdr, sizeof(ehdr), 1, format->helper->fp) - != 1) - return -_elf_error(format); + if(helper->seek(helper->format, 0, SEEK_SET) != 0 + || helper->read(helper->format, &ehdr, sizeof(ehdr)) + != sizeof(ehdr)) + return -1; if(_disas64_shdr(format, &ehdr, &shdr) != 0) return -1; if(_disas64_addr(format, &ehdr, &base) != 0 @@ -447,7 +442,8 @@ static int _elf_disas64(FormatPlugin * format, int (*callback)( continue; if(shdr[i].sh_type == SHT_PROGBITS && shdr[i].sh_flags & SHF_EXECINSTR) - callback(format, &shstrtab[shdr[i].sh_name], + helper->disas(helper->format, + &shstrtab[shdr[i].sh_name], shdr[i].sh_offset, shdr[i].sh_size, base); } @@ -459,24 +455,27 @@ static int _elf_disas64(FormatPlugin * format, int (*callback)( static int _disas64_shdr(FormatPlugin * format, Elf64_Ehdr * ehdr, Elf64_Shdr ** shdr) { + FormatPluginHelper * helper = format->helper; + ssize_t size; + if(ehdr->e_shentsize == 0) { *shdr = NULL; return 0; } if(ehdr->e_shentsize != sizeof(**shdr)) - return -error_set_code(1, "%s: %s", format->helper->filename, + return -error_set_code(1, "%s: %s", + helper->get_filename(helper->format), "Invalid section header size"); - if(fseek(format->helper->fp, ehdr->e_shoff, SEEK_SET) != 0 - || (*shdr = malloc(ehdr->e_shentsize * ehdr->e_shnum)) - == NULL) + if(helper->seek(helper->format, ehdr->e_shoff, SEEK_SET) < 0) + return -1; + size = sizeof(**shdr) * ehdr->e_shnum; + if((*shdr = malloc(size)) == NULL) return -_elf_error(format); - if(fread(*shdr, sizeof(**shdr), ehdr->e_shnum, format->helper->fp) - != ehdr->e_shnum) + if(helper->read(helper->format, *shdr, size) != size) { free(*shdr); - return -error_set_code(1, "%s: %s", format->helper->filename, - "Short read"); + return -1; } return 0; } @@ -484,14 +483,16 @@ static int _disas64_shdr(FormatPlugin * format, Elf64_Ehdr * ehdr, static int _disas64_addr(FormatPlugin * format, Elf64_Ehdr * ehdr, Elf64_Addr * addr) { + FormatPluginHelper * helper = format->helper; Elf64_Quarter i; Elf64_Phdr phdr; - if(fseek(format->helper->fp, ehdr->e_phoff, SEEK_SET) != 0) - return -_elf_error(format); + if(helper->seek(helper->format, ehdr->e_phoff, SEEK_SET) < 0) + return -1; for(i = 0; i < ehdr->e_phnum; i++) - if(fread(&phdr, sizeof(phdr), 1, format->helper->fp) != 1) - return -_elf_error(format); + if(helper->read(helper->format, &phdr, sizeof(phdr)) + != sizeof(phdr)) + return -1; else if(phdr.p_type == PT_LOAD && phdr.p_flags & (PF_R | PF_X)) { *addr = phdr.p_vaddr; @@ -505,19 +506,23 @@ static int _disas64_strtab(FormatPlugin * format, Elf64_Shdr * shdr, size_t shdr_cnt, uint16_t ndx, char ** strtab, size_t * strtab_cnt) { + FormatPluginHelper * helper = format->helper; + ssize_t size; + if(ndx >= shdr_cnt) - return -error_set_code(1, "%s: %s", format->helper->filename, + return -error_set_code(1, "%s: %s", + helper->get_filename(helper->format), "Unable to read the string table"); shdr = &shdr[ndx]; - if(fseek(format->helper->fp, shdr->sh_offset, SEEK_SET) != 0 - || (*strtab = malloc(shdr->sh_size)) == NULL) + if(helper->seek(helper->format, shdr->sh_offset, SEEK_SET) < 0) + return -1; + size = sizeof(**strtab) * shdr->sh_size; + if((*strtab = malloc(size)) == NULL) return -_elf_error(format); - if(fread(*strtab, sizeof(**strtab), shdr->sh_size, format->helper->fp) - != shdr->sh_size) + if(helper->read(helper->format, *strtab, size) != size) { free(*strtab); - return -error_set_code(1, "%s: %s", format->helper->filename, - "Short read"); + return -1; } *strtab_cnt = shdr->sh_size; return 0; @@ -549,6 +554,7 @@ static int es32_cnt = 0; /* init_32 */ static int _init_32(FormatPlugin * format) { + FormatPluginHelper * helper = format->helper; Elf32_Ehdr hdr; memset(&hdr, 0, sizeof(hdr)); @@ -574,7 +580,7 @@ static int _init_32(FormatPlugin * format) hdr.e_shentsize = _htol16(sizeof(Elf32_Shdr)); hdr.e_shstrndx = _htol16(SHN_UNDEF); } - if(fwrite(&hdr, sizeof(hdr), 1, format->helper->fp) != 1) + if(helper->write(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr)) return _elf_error(format); return 0; } @@ -587,18 +593,19 @@ static int _exit_32_shdr(FormatPlugin * format, Elf32_Off offset); static int _exit_32(FormatPlugin * format) { int ret = 0; + FormatPluginHelper * helper = format->helper; long offset; if(_section_32(format, ".shstrtab") != 0) - ret = 1; - else if(fwrite(shstrtab.buf, sizeof(char), shstrtab.cnt, - format->helper->fp) != shstrtab.cnt) - ret = _elf_error(format); - else if((offset = ftell(format->helper->fp)) == -1) - ret = _elf_error(format); + ret = -1; + else if(helper->write(helper->format, shstrtab.buf, shstrtab.cnt) + != (ssize_t)shstrtab.cnt) + ret = -1; + else if((offset = helper->seek(helper->format, 0, SEEK_CUR)) < 0) + ret = -1; else if(_exit_32_phdr(format, offset) != 0 || _exit_32_shdr(format, offset) != 0) - ret = 1; + ret = -1; free(es32); es32 = NULL; es32_cnt = 0; @@ -610,13 +617,14 @@ static int _exit_32(FormatPlugin * format) static int _exit_32_phdr(FormatPlugin * format, Elf32_Off offset) { + FormatPluginHelper * helper = format->helper; Elf32_Ehdr hdr; if(es32_cnt == 0) return 0; - if(fseek(format->helper->fp, 0, SEEK_SET) != 0) - return _elf_error(format); - if(fread(&hdr, sizeof(hdr), 1, format->helper->fp) != 1) + 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) { @@ -630,19 +638,20 @@ static int _exit_32_phdr(FormatPlugin * format, Elf32_Off offset) hdr.e_shnum = _htol16(es32_cnt + 1); hdr.e_shstrndx = _htol16(es32_cnt); } - if(fseek(format->helper->fp, 0, SEEK_SET) != 0) - return _elf_error(format); - if(fwrite(&hdr, sizeof(hdr), 1, format->helper->fp) != 1) - return _elf_error(format); + 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(FormatPlugin * format, Elf32_Off offset) { + FormatPluginHelper * helper = format->helper; Elf32_Shdr hdr; int i; - if(fseek(format->helper->fp, 0, SEEK_END) != 0) + if(helper->seek(helper->format, 0, SEEK_END) < 0) return _elf_error(format); memset(&hdr, 0, sizeof(hdr)); if(ea->endian == ELFDATA2MSB) @@ -655,20 +664,20 @@ static int _exit_32_shdr(FormatPlugin * format, Elf32_Off offset) hdr.sh_type = _htol32(SHT_NULL); hdr.sh_link = _htol32(SHN_UNDEF); } - if(fwrite(&hdr, sizeof(hdr), 1, format->helper->fp) != 1) - return _elf_error(format); + if(helper->write(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr)) + return -1; for(i = 0; i < es32_cnt; i++) { - if(i+1 == es32_cnt) + if(i + 1 == 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_size = ea->endian == ELFDATA2MSB ? _htob32(es32[i].sh_size) : _htol32(es32[i].sh_size); - if(fwrite(&es32[i], sizeof(Elf32_Shdr), 1, format->helper->fp) - != 1) - return _elf_error(format); + if(helper->write(helper->format, &es32[i], sizeof(Elf32_Shdr)) + != sizeof(Elf32_Shdr)) + return -1; } return 0; } @@ -677,13 +686,14 @@ static int _exit_32_shdr(FormatPlugin * format, Elf32_Off offset) /* section_32 */ static int _section_32(FormatPlugin * format, char const * name) { + FormatPluginHelper * helper = format->helper; int ss; Elf32_Shdr * p; ElfSectionValues * esv; long offset; if((ss = _elfstrtab_set(format, &shstrtab, name)) < 0) - return 1; + return -1; if((p = realloc(es32, sizeof(*es32) * (es32_cnt + 1))) == NULL) return _elf_error(format); es32 = p; @@ -693,8 +703,8 @@ static int _section_32(FormatPlugin * format, char const * name) p->sh_name = ss; p->sh_type = esv->type; p->sh_flags = esv->flags; - if((offset = ftell(format->helper->fp)) == -1) - return _elf_error(format); + if((offset = helper->seek(helper->format, 0, SEEK_CUR)) < 0) + return -1; p->sh_offset = offset; p->sh_link = SHN_UNDEF; /* FIXME */ return 0; @@ -710,6 +720,7 @@ static int es64_cnt = 0; /* init_64 */ static int _init_64(FormatPlugin * format) { + FormatPluginHelper * helper = format->helper; Elf64_Ehdr hdr; memset(&hdr, 0, sizeof(hdr)); @@ -734,8 +745,8 @@ static int _init_64(FormatPlugin * format) hdr.e_shentsize = _htol16(sizeof(Elf64_Shdr)); } hdr.e_shstrndx = SHN_UNDEF; - if(fwrite(&hdr, sizeof(hdr), 1, format->helper->fp) != 1) - return _elf_error(format); + if(helper->write(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr)) + return -1; return 0; } @@ -747,15 +758,16 @@ static int _exit_64_shdr(FormatPlugin * format, Elf64_Off offset); static int _exit_64(FormatPlugin * format) { int ret = 0; + FormatPluginHelper * helper = format->helper; long offset; if(_section_64(format, ".shstrtab") != 0) ret = 1; - else if(fwrite(shstrtab.buf, sizeof(char), shstrtab.cnt, - format->helper->fp) != shstrtab.cnt) - ret = _elf_error(format); - else if((offset = ftell(format->helper->fp)) == -1) - ret = _elf_error(format); + else if(helper->write(helper->format, shstrtab.buf, shstrtab.cnt) + != (ssize_t)shstrtab.cnt) + ret = -1; + else if((offset = helper->seek(helper->format, 0, SEEK_CUR)) < 0) + ret = -1; else if(_exit_64_phdr(format, offset) != 0 || _exit_64_shdr(format, offset) != 0) ret = 1; @@ -770,14 +782,15 @@ static int _exit_64(FormatPlugin * format) static int _exit_64_phdr(FormatPlugin * format, Elf64_Off offset) { + FormatPluginHelper * helper = format->helper; Elf64_Ehdr hdr; if(es64_cnt == 0) return 0; - if(fseek(format->helper->fp, 0, SEEK_SET) != 0) - return _elf_error(format); - if(fread(&hdr, sizeof(hdr), 1, format->helper->fp) != 1) - return _elf_error(format); + if(helper->seek(helper->format, 0, SEEK_SET) != 0) + return -1; + if(helper->read(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr)) + return -1; if(ea->endian == ELFDATA2MSB) { hdr.e_shoff = _htob64(offset); @@ -790,19 +803,20 @@ static int _exit_64_phdr(FormatPlugin * format, Elf64_Off offset) hdr.e_shnum = _htol16(es64_cnt); hdr.e_shstrndx = _htol16(es64_cnt - 1); } - if(fseek(format->helper->fp, 0, SEEK_SET) != 0) - return _elf_error(format); - if(fwrite(&hdr, sizeof(hdr), 1, format->helper->fp) != 1) - return _elf_error(format); + 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_64_shdr(FormatPlugin * format, Elf64_Off offset) { + FormatPluginHelper * helper = format->helper; int i; - if(fseek(format->helper->fp, 0, SEEK_END) != 0) - return _elf_error(format); + if(helper->seek(helper->format, 0, SEEK_END) < 0) + return -1; for(i = 0; i < es64_cnt; i++) { if(i + 1 == es64_cnt) @@ -812,9 +826,9 @@ static int _exit_64_shdr(FormatPlugin * format, Elf64_Off offset) - es64[i].sh_offset; es64[i].sh_size = ea->endian == ELFDATA2MSB ? _htob64(es64[i].sh_size) : _htol64(es64[i].sh_size); - if(fwrite(&es64[i], sizeof(Elf64_Shdr), 1, format->helper->fp) - != 1) - return _elf_error(format); + if(helper->write(helper->format, &es64[i], sizeof(Elf64_Shdr)) + != sizeof(Elf64_Shdr)) + return -1; } return 0; } @@ -823,6 +837,7 @@ static int _exit_64_shdr(FormatPlugin * format, Elf64_Off offset) /* section_64 */ static int _section_64(FormatPlugin * format, char const * name) { + FormatPluginHelper * helper = format->helper; int ss; Elf64_Shdr * p; ElfSectionValues * esv; @@ -839,8 +854,8 @@ static int _section_64(FormatPlugin * format, char const * name) p->sh_name = ss; p->sh_type = esv->type; p->sh_flags = esv->flags; - if((offset = ftell(format->helper->fp)) == -1) - return _elf_error(format); + if((offset = helper->seek(helper->format, 0, SEEK_CUR)) < 0) + return -1; p->sh_offset = offset; p->sh_link = SHN_UNDEF; /* FIXME */ return 0; diff --git a/src/format/flat.c b/src/format/flat.c index 57402bf..235846f 100644 --- a/src/format/flat.c +++ b/src/format/flat.c @@ -16,9 +16,7 @@ #include -#include #include -#include #include "Asm.h" @@ -26,9 +24,7 @@ /* private */ /* prototypes */ /* plug-in */ -static int _flat_disas(FormatPlugin * format, int (*callback)( - FormatPlugin * format, char const * section, - off_t offset, size_t size, off_t base)); +static int _flat_disas(FormatPlugin * format); /* public */ @@ -53,14 +49,12 @@ FormatPlugin format_plugin = /* functions */ /* plug-in */ /* flat_disas */ -static int _flat_disas(FormatPlugin * format, int (*callback)( - FormatPlugin * format, char const * section, - off_t offset, size_t size, off_t base)) +static int _flat_disas(FormatPlugin * format) { - struct stat st; + FormatPluginHelper * helper = format->helper; + off_t offset; - if(fstat(fileno(format->helper->fp), &st) != 0) - return -error_set_code(1, "%s: %s", format->helper->filename, - strerror(errno)); - return callback(format, ".data", 0, st.st_size, 0); + if((offset = helper->seek(helper->format, 0, SEEK_END)) < 0) + return -1; + return helper->disas(helper->format, ".data", 0, offset, 0); } diff --git a/src/format/java.c b/src/format/java.c index cc11635..ea50dcc 100644 --- a/src/format/java.c +++ b/src/format/java.c @@ -105,12 +105,9 @@ static char _java_signature[4] = "\xca\xfe\xba\xbe"; static int _java_init(FormatPlugin * format, char const * arch); static int _java_exit(FormatPlugin * format); static char const * _java_detect(FormatPlugin * format); -static int _java_disas(FormatPlugin * format, int (*callback)( - FormatPlugin * format, char const * section, - off_t offset, size_t size, off_t base)); +static int _java_disas(FormatPlugin * format); static int _java_error(FormatPlugin * format); -static int _java_error_fread(FormatPlugin * format); /* public */ @@ -137,6 +134,7 @@ FormatPlugin format_plugin = /* java_init */ static int _java_init(FormatPlugin * format, char const * arch) { + FormatPluginHelper * helper = format->helper; JavaHeader jh; JavaPlugin * java; @@ -147,8 +145,8 @@ static int _java_init(FormatPlugin * format, char const * arch) jh.minor = _htob16(0); jh.major = _htob16(0x32); /* XXX choose a more appropriate version */ jh.cp_cnt = _htob16(0); - if(fwrite(&jh, sizeof(jh), 1, format->helper->fp) != 1) - return -_java_error(format); + if(helper->write(helper->format, &jh, sizeof(jh)) != sizeof(jh)) + return -1; if((java = malloc(sizeof(*java))) == NULL) return -_java_error(format); memset(java, 0, sizeof(*java)); @@ -186,85 +184,96 @@ static int _java_exit(FormatPlugin * format) static int _exit_constant_pool(FormatPlugin * format) { + FormatPluginHelper * helper = format->helper; JavaPlugin * java = format->priv; uint16_t cnt = _htob16(java->constants_cnt + 1); - if(fwrite(&cnt, sizeof(cnt), 1, format->helper->fp) != 1) - return -_java_error(format); + if(helper->write(helper->format, &cnt, sizeof(cnt)) != sizeof(cnt)) + return -1; /* XXX output the constants */ return 0; } static int _exit_access_flags(FormatPlugin * format) { + FormatPluginHelper * helper = format->helper; JavaPlugin * java = format->priv; uint16_t flags = _htob16(java->access_flags); - if(fwrite(&flags, sizeof(flags), 1, format->helper->fp) != 1) - return -_java_error(format); + if(helper->write(helper->format, &flags, sizeof(flags)) + != sizeof(flags)) + return -1; return 0; } static int _exit_class_name(FormatPlugin * format) { + FormatPluginHelper * helper = format->helper; uint16_t index = _htob16(0); /* FIXME really implement */ - if(fwrite(&index, sizeof(index), 1, format->helper->fp) != 1) - return -_java_error(format); + if(helper->write(helper->format, &index, sizeof(index)) + != sizeof(index)) + return -1; return 0; } static int _exit_super_name(FormatPlugin * format) { + FormatPluginHelper * helper = format->helper; uint16_t index = _htob16(0); /* FIXME really implement */ - if(fwrite(&index, sizeof(index), 1, format->helper->fp) != 1) - return -_java_error(format); + if(helper->write(helper->format, &index, sizeof(index)) + != sizeof(index)) + return -1; return 0; } static int _exit_interface_table(FormatPlugin * format) { + FormatPluginHelper * helper = format->helper; JavaPlugin * java = format->priv; uint16_t cnt = _htob16(java->interfaces_cnt); - if(fwrite(&cnt, sizeof(cnt), 1, format->helper->fp) != 1) - return -_java_error(format); + if(helper->write(helper->format, &cnt, sizeof(cnt)) != sizeof(cnt)) + return -1; /* XXX output the interfaces */ return 0; } static int _exit_field_table(FormatPlugin * format) { + FormatPluginHelper * helper = format->helper; JavaPlugin * java = format->priv; uint16_t cnt = _htob16(java->fields_cnt); - if(fwrite(&cnt, sizeof(cnt), 1, format->helper->fp) != 1) - return -_java_error(format); + if(helper->write(helper->format, &cnt, sizeof(cnt)) != sizeof(cnt)) + return -1; /* XXX output the fields */ return 0; } static int _exit_method_table(FormatPlugin * format) { + FormatPluginHelper * helper = format->helper; JavaPlugin * java = format->priv; uint16_t cnt = _htob16(java->methods_cnt); - if(fwrite(&cnt, sizeof(cnt), 1, format->helper->fp) != 1) - return -_java_error(format); + if(helper->write(helper->format, &cnt, sizeof(cnt)) != sizeof(cnt)) + return -1; /* XXX output the methods */ return 0; } static int _exit_attribute_table(FormatPlugin * format) { + FormatPluginHelper * helper = format->helper; JavaPlugin * java = format->priv; uint16_t cnt = _htob16(java->attributes_cnt); - if(fwrite(&cnt, sizeof(cnt), 1, format->helper->fp) != 1) - return -_java_error(format); + if(helper->write(helper->format, &cnt, sizeof(cnt)) != sizeof(cnt)) + return -1; /* XXX output the attributes */ return 0; } @@ -283,48 +292,47 @@ static int _disas_skip_constants(FormatPlugin * format, uint16_t cnt); static int _disas_skip_fields(FormatPlugin * format, uint16_t cnt); static int _disas_skip_interfaces(FormatPlugin * format, uint16_t cnt); -static int _java_disas(FormatPlugin * format, int (*callback)( - FormatPlugin * format, char const * section, - off_t offset, size_t size, off_t base)) +static int _java_disas(FormatPlugin * format) { - FILE * fp = format->helper->fp; + FormatPluginHelper * helper = format->helper; JavaHeader jh; JavaHeader2 jh2; uint16_t u16; off_t offset; off_t end; - if(fseek(fp, sizeof(JavaHeader), SEEK_SET) != 0) - return -_java_error(format); - if(fread(&jh, sizeof(jh), 1, fp) != 1) - return -_java_error_fread(format); + /* FIXME can this be correct? */ + if(helper->seek(helper->format, sizeof(jh), SEEK_SET) != sizeof(jh)) + return -1; + if(helper->read(helper->format, &jh, sizeof(jh)) != sizeof(jh)) + return -1; /* skip constants */ jh.cp_cnt = _htob16(jh.cp_cnt); if(jh.cp_cnt > 1 && _disas_skip_constants(format, jh.cp_cnt) != 0) return -1; /* skip interfaces */ - if(fread(&jh2, sizeof(jh2), 1, fp) != 1) - return -_java_error_fread(format); + if(helper->read(helper->format, &jh2, sizeof(jh2)) != sizeof(jh2)) + return -1; jh2.interfaces_cnt = _htob16(jh2.interfaces_cnt); if(_disas_skip_interfaces(format, jh2.interfaces_cnt) != 0) return -1; /* skip fields */ - if(fread(&u16, sizeof(u16), 1, fp) != 1) - return -_java_error_fread(format); + if(helper->read(helper->format, &u16, sizeof(u16)) != sizeof(u16)) + return -1; u16 = _htob16(u16); if(_disas_skip_fields(format, u16) != 0) return -1; /* disassemble the rest */ - if((offset = ftello(fp)) == -1 - || fseek(fp, 0, SEEK_END) != 0 - || (end = ftello(fp)) == -1) - return -_java_error(format); - return callback(format, NULL, offset, end - offset, 0); + if((offset = helper->seek(helper->format, 0, SEEK_CUR)) < 0 + || (end = helper->seek(helper->format, 0, SEEK_END)) + < 0) + return -1; + return helper->disas(helper->format, NULL, offset, end - offset, 0); } static int _disas_skip_attributes(FormatPlugin * format, uint16_t cnt) { - FILE * fp = format->helper->fp; + FormatPluginHelper * helper = format->helper; size_t i; JavaAttributeInfo jai; @@ -333,22 +341,23 @@ static int _disas_skip_attributes(FormatPlugin * format, uint16_t cnt) #endif for(i = 0; i < cnt; i++) { - if(fread(&jai, sizeof(jai), 1, fp) != 1) - return -_java_error_fread(format); + if(helper->read(helper->format, &jai, sizeof(jai)) + != sizeof(jai)) + return -1; jai.length = _htob32(jai.length); #ifdef DEBUG fprintf(stderr, "DEBUG: %s() length=%u\n", __func__, jai.length); #endif - if(fseek(fp, jai.length, SEEK_CUR) != 0) - return -_java_error(format); + if(helper->seek(helper->format, jai.length, SEEK_CUR) < 0) + return -1; } return 0; } static int _disas_skip_constants(FormatPlugin * format, uint16_t cnt) { - FILE * fp = format->helper->fp; + FormatPluginHelper * helper = format->helper; size_t i; JavaCpInfo jci; size_t size; @@ -360,8 +369,9 @@ static int _disas_skip_constants(FormatPlugin * format, uint16_t cnt) #endif for(i = 0; i < cnt; i++) { - if(fread(&jci, sizeof(jci), 1, fp) != 1) - return -_java_error_fread(format); + if(helper->read(helper->format, &jci, sizeof(jci)) + != sizeof(jci)) + return -1; switch(jci.tag) { case CONSTANT_Double: @@ -381,28 +391,33 @@ static int _disas_skip_constants(FormatPlugin * format, uint16_t cnt) size = 2; break; case CONSTANT_Utf8: - if(fread(&u16, sizeof(u16), 1, fp) != 1) - return -_java_error_fread(format); + size = sizeof(u16); + if(helper->read(helper->format, &u16, size) + != (ssize_t)size) + return -1; u16 = _htob16(u16); - if(fseek(fp, u16, SEEK_CUR) != 0) - return -_java_error(format); + if(helper->seek(helper->format, u16, SEEK_CUR) + < 0) + return -1; size = 0; break; default: return -error_set_code(1, "%s: %s 0x%x", - format->helper->filename, + helper->get_filename( + helper->format), "Unknown constant tag", jci.tag); } - if(size != 0 && fread(buf, sizeof(*buf), size, fp) != size) - return -_java_error_fread(format); + if(size != 0 && helper->read(helper->format, buf, size) + != (ssize_t)size) + return -1; } return 0; } static int _disas_skip_fields(FormatPlugin * format, uint16_t cnt) { - FILE * fp = format->helper->fp; + FormatPluginHelper * helper = format->helper; size_t i; JavaFieldInfo jfi; @@ -411,8 +426,9 @@ static int _disas_skip_fields(FormatPlugin * format, uint16_t cnt) #endif for(i = 0; i < cnt; i++) { - if(fread(&jfi, sizeof(jfi), 1, fp) != 1) - return -_java_error_fread(format); + if(helper->read(helper->format, &jfi, sizeof(jfi)) + != sizeof(jfi)) + return -1; jfi.attributes_cnt = _htob16(jfi.attributes_cnt); _disas_skip_attributes(format, jfi.attributes_cnt); } @@ -421,7 +437,7 @@ static int _disas_skip_fields(FormatPlugin * format, uint16_t cnt) static int _disas_skip_interfaces(FormatPlugin * format, uint16_t cnt) { - FILE * fp = format->helper->fp; + FormatPluginHelper * helper = format->helper; size_t i; uint16_t u16; @@ -429,8 +445,9 @@ static int _disas_skip_interfaces(FormatPlugin * format, uint16_t cnt) fprintf(stderr, "DEBUG: %s(%u)\n", __func__, cnt); #endif for(i = 0; i < cnt; i++) - if(fread(&u16, sizeof(u16), 1, fp) != 1) - return -_java_error_fread(format); + if(helper->read(helper->format, &u16, sizeof(u16)) + != sizeof(u16)) + return -1; return 0; } @@ -438,16 +455,6 @@ static int _disas_skip_interfaces(FormatPlugin * format, uint16_t cnt) /* java_error */ static int _java_error(FormatPlugin * format) { - return -error_set_code(1, "%s: %s", format->helper->filename, - strerror(errno)); -} - - -/* java_error_fread */ -static int _java_error_fread(FormatPlugin * format) -{ - if(ferror(format->helper->fp)) - return _java_error(format); - return -error_set_code(1, "%s: %s", format->helper->filename, - "End of file reached"); + return -error_set_code(1, "%s: %s", format->helper->get_filename( + format->helper->format), strerror(errno)); } diff --git a/src/format/pe.c b/src/format/pe.c index e2b6286..73eb320 100644 --- a/src/format/pe.c +++ b/src/format/pe.c @@ -89,9 +89,7 @@ static char const _pe_header_signature[4] = "PE\0\0"; /* plug-in */ static int _pe_init(FormatPlugin * format, char const * arch); static char const * _pe_detect(FormatPlugin * format); -static int _pe_disas(FormatPlugin * format, int (*callback)( - FormatPlugin * format, char const * section, - off_t offset, size_t size, off_t base)); +static int _pe_disas(FormatPlugin * format); /* useful */ static char const * _pe_get_arch(uint16_t machine); @@ -121,6 +119,7 @@ FormatPlugin format_plugin = /* pe_init */ static int _pe_init(FormatPlugin * format, char const * arch) { + FormatPluginHelper * helper = format->helper; int machine; struct pe_msdos pm; struct pe_header ph; @@ -135,12 +134,10 @@ static int _pe_init(FormatPlugin * format, char const * arch) ph.machine = _htol16(machine); ph.timestamp = _htol32(time(NULL)); /* FIXME update the section and symbol lists */ - if(fwrite(&pm, sizeof(pm), 1, format->helper->fp) != 1) - return -error_set_code(1, "%s: %s", format->helper->filename, - strerror(errno)); - if(fwrite(&ph, sizeof(ph), 1, format->helper->fp) != 1) - return -error_set_code(1, "%s: %s", format->helper->filename, - strerror(errno)); + if(helper->write(helper->format, &pm, sizeof(pm)) != sizeof(pm)) + return -1; + if(helper->write(helper->format, &ph, sizeof(ph)) != sizeof(ph)) + return -1; return 0; } @@ -150,25 +147,28 @@ static char const * _detect_error(FormatPlugin * format); static char const * _pe_detect(FormatPlugin * format) { + FormatPluginHelper * helper = format->helper; struct pe_msdos pm; struct pe_header ph; - if(fseek(format->helper->fp, 0, SEEK_SET) != 0) - return _detect_error(format); - if(fread(&pm, sizeof(pm), 1, format->helper->fp) != 1) - return _detect_error(format); - if((pm.offset = _htol16(pm.offset)) != sizeof(pm) - && fseek(format->helper->fp, pm.offset, SEEK_SET) != 0) - return _detect_error(format); - if(fread(&ph, sizeof(ph), 1, format->helper->fp) != 1) + if(helper->seek(helper->format, 0, SEEK_SET) != 0) + return NULL; + if(helper->read(helper->format, &pm, sizeof(pm)) != sizeof(pm)) + return NULL; + if((pm.offset = _htol16(pm.offset)) != sizeof(pm)) return _detect_error(format); + if(helper->seek(helper->format, pm.offset, SEEK_SET) != pm.offset) + return NULL; + if(helper->read(helper->format, &ph, sizeof(ph)) != sizeof(ph)) + return NULL; ph.machine = _htol16(ph.machine); return _pe_get_arch(ph.machine); } static char const * _detect_error(FormatPlugin * format) { - error_set_code(1, "%s: %s", format->helper->filename, strerror(errno)); + error_set_code(1, "%s: %s", format->helper->get_filename( + format->helper->format), strerror(errno)); return NULL; } @@ -176,47 +176,49 @@ static char const * _detect_error(FormatPlugin * format) /* pe_disas */ static int _disas_error(FormatPlugin * format); -static int _pe_disas(FormatPlugin * format, int (*callback)( - FormatPlugin * format, char const * section, - off_t offset, size_t size, off_t base)) +static int _pe_disas(FormatPlugin * format) { + FormatPluginHelper * helper = format->helper; struct pe_msdos pm; struct pe_header ph; size_t i; struct pe_section_header psh; - if(fseek(format->helper->fp, 0, SEEK_SET) != 0) - return _disas_error(format); - if(fread(&pm, sizeof(pm), 1, format->helper->fp) != 1) - return _disas_error(format); + if(helper->seek(helper->format, 0, SEEK_SET) != 0) + return -1; + if(helper->read(helper->format, &pm, sizeof(pm)) != sizeof(pm)) + return -1; if((pm.offset = _htol16(pm.offset)) != sizeof(pm) - && fseek(format->helper->fp, pm.offset, SEEK_SET) != 0) - return _disas_error(format); - if(fread(&ph, sizeof(ph), 1, format->helper->fp) != 1) + && helper->seek(helper->format, pm.offset, SEEK_SET) + != pm.offset) + return -1; + if(helper->read(helper->format, &ph, sizeof(ph)) != sizeof(ph)) return _disas_error(format); ph.section_cnt = _htol16(ph.section_cnt); ph.opthdr_size = _htol16(ph.opthdr_size); if(ph.section_cnt > 0 && ph.opthdr_size != 0 - && fseek(format->helper->fp, ph.opthdr_size, SEEK_CUR)) + && helper->seek(helper->format, ph.opthdr_size, + SEEK_CUR) < 0) return _disas_error(format); for(i = 0; i < ph.section_cnt; i++) { - if(fread(&psh, sizeof(psh), 1, format->helper->fp) != 1) - return _disas_error(format); + if(helper->read(helper->format, &psh, sizeof(psh)) + != sizeof(psh)) + return -1; psh.name[sizeof(psh.name) - 1] = '\0'; psh.vaddr = _htol32(psh.vaddr); psh.raw_size = _htol32(psh.raw_size); psh.raw_offset = _htol32(psh.raw_offset); - callback(format, psh.name, psh.raw_offset, psh.raw_size, - psh.vaddr); + helper->disas(helper->format, psh.name, psh.raw_offset, + psh.raw_size, psh.vaddr); } return 0; } static int _disas_error(FormatPlugin * format) { - return -error_set_code(1, "%s: %s", format->helper->filename, - strerror(errno)); + return -error_set_code(1, "%s: %s", format->helper->get_filename( + format->helper->format), strerror(errno)); }