Using callbacks for file operations
This commit is contained in:
parent
0f1d52fbb9
commit
2bb09ddb7d
@ -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;
|
||||
};
|
||||
|
92
src/format.c
92
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");
|
||||
}
|
||||
|
@ -18,15 +18,11 @@
|
||||
#ifndef ASM_FORMAT_H
|
||||
# define ASM_FORMAT_H
|
||||
|
||||
# include <stdio.h>
|
||||
# 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);
|
||||
|
121
src/format/dex.c
121
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));
|
||||
}
|
||||
|
271
src/format/elf.c
271
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;
|
||||
|
@ -16,9 +16,7 @@
|
||||
|
||||
|
||||
#include <System.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#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);
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user