Beginning to disassemble files again

This commit is contained in:
Pierre Pronchery 2011-04-23 17:40:05 +00:00
parent c0a0820fe4
commit 383ca51178
9 changed files with 130 additions and 9 deletions

View File

@ -41,6 +41,7 @@ char const * as_get_format_name(As * as);
/* useful */ /* useful */
int as_decode(As * as, char const * buffer, size_t size); int as_decode(As * as, char const * buffer, size_t size);
int as_decode_file(As * as, char const * filename, FILE * fp);
int as_parse(As * as, char const * infile, char const * outfile); int as_parse(As * as, char const * infile, char const * outfile);
int as_open(As * as, char const * outfile); int as_open(As * as, char const * outfile);

View File

@ -63,6 +63,7 @@ struct _Arch
/* prototypes */ /* prototypes */
/* callbacks */ /* callbacks */
static char const * _arch_get_filename(Arch * arch); static char const * _arch_get_filename(Arch * arch);
static ssize_t _arch_read(Arch * arch, void * buf, size_t size);
static ssize_t _arch_read_buffer(Arch * arch, void * buf, size_t size); static ssize_t _arch_read_buffer(Arch * arch, void * buf, size_t size);
static ssize_t _arch_write(Arch * arch, void const * buf, size_t size); static ssize_t _arch_write(Arch * arch, void const * buf, size_t size);
@ -489,6 +490,23 @@ static void _decode_print(ArchInstructionCall * call)
} }
/* arch_decode_at */
int arch_decode_at(Arch * arch, off_t offset, size_t size, off_t base)
{
int ret;
if(arch->fp == NULL)
return -error_set_code(1, "%s", strerror(ENOSYS));
if(fseek(arch->fp, offset, SEEK_SET) != 0)
return -error_set_code(1, "%s", strerror(errno));
/* FIXME implement size, consider offset and base */
if((ret = arch_decode(arch)) == 0
&& fseek(arch->fp, offset + size, SEEK_SET) != 0)
ret = -error_set_code(1, "%s", strerror(errno));
return ret;
}
/* arch_exit */ /* arch_exit */
int arch_exit(Arch * arch) int arch_exit(Arch * arch)
{ {
@ -519,7 +537,7 @@ int arch_init(Arch * arch, char const * filename, FILE * fp)
arch->helper.get_instruction_by_opcode = arch_get_instruction_by_opcode; arch->helper.get_instruction_by_opcode = arch_get_instruction_by_opcode;
arch->helper.get_register_by_id_size = arch_get_register_by_id_size; arch->helper.get_register_by_id_size = arch_get_register_by_id_size;
arch->helper.get_register_by_name_size = arch_get_register_by_name_size; arch->helper.get_register_by_name_size = arch_get_register_by_name_size;
arch->helper.read = NULL; arch->helper.read = _arch_read;
arch->helper.write = _arch_write; arch->helper.write = _arch_write;
arch->plugin->helper = &arch->helper; arch->plugin->helper = &arch->helper;
return 0; return 0;
@ -568,6 +586,21 @@ static char const * _arch_get_filename(Arch * arch)
} }
/* arch_read */
static ssize_t _arch_read(Arch * arch, void * buf, size_t size)
{
if(fread(buf, size, 1, arch->fp) == 1)
return size;
if(ferror(arch->fp))
return -error_set_code(1, "%s: %s", arch->filename,
strerror(errno));
if(feof(arch->fp))
return -error_set_code(1, "%s: %s", arch->filename,
"End of file reached");
return -error_set_code(1, "%s: %s", arch->filename, "Read error");
}
/* arch_read_buffer */ /* arch_read_buffer */
static ssize_t _arch_read_buffer(Arch * arch, void * buf, size_t size) static ssize_t _arch_read_buffer(Arch * arch, void * buf, size_t size)
{ {

View File

@ -60,5 +60,6 @@ int arch_write(Arch * arch, ArchInstruction * instruction,
/* disassembly */ /* disassembly */
int arch_decode(Arch * arch); int arch_decode(Arch * arch);
int arch_decode_at(Arch * arch, off_t offset, size_t size, off_t base);
#endif /* !ASM_ARCH_H */ #endif /* !ASM_ARCH_H */

View File

@ -154,6 +154,21 @@ int as_decode(As * as, char const * buffer, size_t size)
} }
/* as_decode_file */
int as_decode_file(As * as, char const * filename, FILE * fp)
{
int ret;
if(fp != NULL)
return code_decode_file(as->code, filename, fp);
if((fp = fopen(filename, "r")) == NULL)
return -error_set_code(1, "%s: %s", filename, strerror(errno));
ret = code_decode_file(as->code, filename, fp);
fclose(fp);
return ret;
}
/* as_parse */ /* as_parse */
int as_parse(As * as, char const * infile, char const * outfile) int as_parse(As * as, char const * infile, char const * outfile)
{ {

View File

@ -137,6 +137,35 @@ int code_decode(Code * code, char const * buffer, size_t size)
arch_exit(code->arch); arch_exit(code->arch);
return ret; return ret;
} }
/* code_decode_file */
static int _decode_file_callback(void * priv, char const * section,
off_t offset, size_t size, off_t base);
int code_decode_file(Code * code, char const * filename, FILE * fp)
{
int ret;
arch_init(code->arch, filename, fp);
format_init(code->format, filename, fp);
ret = format_decode(code->format, _decode_file_callback, code);
format_exit(code->format);
arch_exit(code->arch);
return ret;
}
static int _decode_file_callback(void * priv, char const * section,
off_t offset, size_t size, off_t base)
{
Code * code = priv;
if(section != NULL)
printf("%s%s:\n", "\nDisassembly of section ", section);
return arch_decode_at(code->arch, offset, size, base);
}
#if 0 #if 0
static ArchInstruction * _decode_size(Code * code, size_t * size, static ArchInstruction * _decode_size(Code * code, size_t * size,
ArchInstruction * ai); ArchInstruction * ai);

View File

@ -50,5 +50,6 @@ int code_section(Code * code, char const * section);
/* disassembly */ /* disassembly */
int code_decode(Code * code, char const * buffer, size_t size); int code_decode(Code * code, char const * buffer, size_t size);
int code_decode_file(Code * code, char const * filename, FILE * fp);
#endif /* !ASM_CODE_H */ #endif /* !ASM_CODE_H */

View File

@ -53,7 +53,6 @@ typedef struct _DeasmFormat
typedef struct _Deasm typedef struct _Deasm
{ {
char const * arch; char const * arch;
As * as;
FormatPluginHelper helper; FormatPluginHelper helper;
DeasmFormat * format; DeasmFormat * format;
@ -108,7 +107,6 @@ static int _deasm(char const * arch, char const * format,
Deasm deasm; Deasm deasm;
deasm.arch = arch; deasm.arch = arch;
deasm.as = NULL;
deasm.helper.format = &deasm; deasm.helper.format = &deasm;
deasm.helper.read = _deasm_helper_read; deasm.helper.read = _deasm_helper_read;
deasm.helper.seek = _deasm_helper_seek; deasm.helper.seek = _deasm_helper_seek;
@ -123,8 +121,6 @@ static int _deasm(char const * arch, char const * format,
ret = _deasm_do_format(&deasm, format); ret = _deasm_do_format(&deasm, format);
else else
ret = _deasm_do(&deasm); ret = _deasm_do(&deasm);
if(deasm.as != NULL)
as_delete(deasm.as);
fclose(deasm.fp); fclose(deasm.fp);
_deasm_format_close_all(&deasm); _deasm_format_close_all(&deasm);
if(ret != 0) if(ret != 0)
@ -205,6 +201,7 @@ static int _deasm_do(Deasm * deasm)
static int _deasm_do_callback(Deasm * deasm, FormatPlugin * format) static int _deasm_do_callback(Deasm * deasm, FormatPlugin * format)
{ {
int ret; int ret;
As * as;
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, format->name); fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, format->name);
@ -217,11 +214,12 @@ static int _deasm_do_callback(Deasm * deasm, FormatPlugin * format)
if((deasm->arch = format->detect(format)) == NULL) if((deasm->arch = format->detect(format)) == NULL)
return -1; return -1;
} }
if((deasm->as = as_new(deasm->arch, format->name)) == NULL) if((as = as_new(deasm->arch, format->name)) == NULL)
return -error_print("deasm"); return -error_print("deasm");
printf("\n%s: %s-%s\n", deasm->filename, format->name, printf("\n%s: %s-%s\n", deasm->filename, format->name, as_get_arch_name(
as_get_arch_name(deasm->as)); as));
ret = format->decode(format); ret = as_decode_file(as, deasm->filename, deasm->fp);
as_delete(as);
return ret; return ret;
} }

View File

@ -39,6 +39,11 @@ struct _Format
/* file */ /* file */
char const * filename; char const * filename;
FILE * fp; FILE * fp;
/* diassembly */
int (*decode_callback)(void * priv, char const * section, off_t offset,
size_t size, off_t base);
void * decode_priv;
}; };
@ -105,6 +110,37 @@ char const * format_get_name(Format * format)
/* useful */ /* useful */
/* format_decode */
static int _decode_callback(Format * format, char const * section,
off_t offset, size_t size, off_t base);
int format_decode(Format * format, int (*callback)(void * priv,
char const * section, off_t offset, size_t size,
off_t base), void * priv)
{
int ret;
if(format->plugin->decode == NULL)
return error_set_code(1, "%s: %s", format_get_name(format),
"Disassembly is not supported");
format->helper.decode = _decode_callback;
format->decode_callback = callback;
format->decode_priv = priv;
ret = format->plugin->decode(format->plugin);
format->decode_callback = NULL;
format->decode_priv = NULL;
format->helper.decode = NULL;
return ret;
}
static int _decode_callback(Format * format, char const * section,
off_t offset, size_t size, off_t base)
{
return format->decode_callback(format->decode_priv, section, offset,
size, base);
}
/* format_exit */ /* format_exit */
int format_exit(Format * format) int format_exit(Format * format)
{ {
@ -116,6 +152,7 @@ int format_exit(Format * format)
if(format->plugin->exit != NULL) if(format->plugin->exit != NULL)
ret = format->plugin->exit(format->plugin); ret = format->plugin->exit(format->plugin);
format->helper.format = NULL; format->helper.format = NULL;
format->helper.decode = NULL;
format->helper.read = NULL; format->helper.read = NULL;
format->helper.seek = NULL; format->helper.seek = NULL;
format->plugin->helper = NULL; format->plugin->helper = NULL;
@ -144,6 +181,7 @@ int format_init(Format * format, char const * filename, FILE * fp)
format->filename = filename; format->filename = filename;
format->fp = fp; format->fp = fp;
format->helper.format = format; format->helper.format = format;
format->helper.decode = NULL;
format->helper.get_filename = _format_get_filename; format->helper.get_filename = _format_get_filename;
format->helper.read = _format_read; format->helper.read = _format_read;
format->helper.seek = _format_seek; format->helper.seek = _format_seek;

View File

@ -38,4 +38,9 @@ int format_exit(Format * format);
int format_function(Format * format, char const * function); int format_function(Format * format, char const * function);
int format_section(Format * format, char const * section); int format_section(Format * format, char const * section);
/* disassembly */
int format_decode(Format * format, int (*callback)(void * priv,
char const * section, off_t offset, size_t size,
off_t base), void * priv);
#endif /* !ASM_FORMAT_H */ #endif /* !ASM_FORMAT_H */