From a8407ddd19de590843d145269c2d36b6c3940a8b Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Sat, 23 Apr 2011 03:01:55 +0000 Subject: [PATCH] Using helper callbacks to write assembly instructions --- include/Asm/arch.h | 9 +++++---- src/arch.c | 44 +++++++++++++++++++++++++++++++++++++++++--- src/arch/dalvik.c | 7 ++++--- src/arch/i386.h | 28 ++++++++++++++++------------ src/arch/java.c | 5 ++--- src/arch/sparc.h | 4 +++- 6 files changed, 71 insertions(+), 26 deletions(-) diff --git a/include/Asm/arch.h b/include/Asm/arch.h index 8c45e1c..88402ce 100644 --- a/include/Asm/arch.h +++ b/include/Asm/arch.h @@ -176,13 +176,14 @@ typedef struct _ArchPluginHelper { Arch * arch; - /* variables */ - char const * filename; - FILE * fp; - /* callbacks */ + /* accessors */ + char const * (*get_filename)(Arch * arch); ArchRegister * (*get_register_by_name_size)(Arch * arch, char const * name, uint32_t size); + + /* assembly */ + ssize_t (*write)(Arch * arch, void const * buf, size_t size); } ArchPluginHelper; typedef struct _ArchPlugin ArchPlugin; diff --git a/src/arch.c b/src/arch.c index 9dc46d0..fb43426 100644 --- a/src/arch.c +++ b/src/arch.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include "Asm/arch.h" #include "Asm/asm.h" #include "arch.h" @@ -41,6 +41,10 @@ struct _Arch ArchPlugin * plugin; size_t instructions_cnt; size_t registers_cnt; + + /* internal */ + char const * filename; + FILE * fp; }; @@ -50,6 +54,12 @@ struct _Arch ((ai->op3 & AOM_TYPE) ? 1 : 0)) +/* prototypes */ +/* callbacks */ +static char const * _arch_get_filename(Arch * arch); +static ssize_t _arch_write(Arch * arch, void const * buf, size_t size); + + /* public */ /* functions */ /* arch_new */ @@ -413,6 +423,8 @@ ArchRegister * arch_get_register_by_name_size(Arch * arch, char const * name, /* arch_exit */ int arch_exit(Arch * arch) { + arch->filename = NULL; + arch->fp = NULL; memset(&arch->helper, 0, sizeof(arch->helper)); return 0; } @@ -425,10 +437,12 @@ int arch_init(Arch * arch, char const * filename, FILE * fp) fprintf(stderr, "DEBUG: %s(\"%s\", %p)\n", __func__, filename, (void *)fp); #endif + arch->filename = filename; + arch->fp = fp; arch->helper.arch = arch; - arch->helper.filename = filename; - arch->helper.fp = fp; + arch->helper.get_filename = _arch_get_filename; arch->helper.get_register_by_name_size = arch_get_register_by_name_size; + arch->helper.write = _arch_write; arch->plugin->helper = &arch->helper; return 0; } @@ -443,3 +457,27 @@ int arch_write(Arch * arch, ArchInstruction * instruction, #endif return arch->plugin->write(arch->plugin, instruction, call); } + + +/* private */ +/* callbacks */ +/* arch_get_filename */ +static char const * _arch_get_filename(Arch * arch) +{ + return arch->filename; +} + + +/* arch_write */ +static ssize_t _arch_write(Arch * arch, void const * buf, size_t size) +{ + if(fwrite(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, "Write error"); +} diff --git a/src/arch/dalvik.c b/src/arch/dalvik.c index 813803e..a2baf29 100644 --- a/src/arch/dalvik.c +++ b/src/arch/dalvik.c @@ -111,10 +111,11 @@ static int _dalvik_write(ArchPlugin * plugin, ArchInstruction * instruction, break; default: /* FIXME should not happen */ - return -error_set_code(1, "%s: %s", helper->filename, + return -error_set_code(1, "%s: %s", + helper->get_filename(helper->arch), "Invalid size for opcode"); } - if(fwrite(buf, size, 1, helper->fp) != 1) - return -1; /* XXX report error */ + if(helper->write(helper->arch, buf, size) != size) + return -1; return 0; } diff --git a/src/arch/i386.h b/src/arch/i386.h index 5b218de..ba137a5 100644 --- a/src/arch/i386.h +++ b/src/arch/i386.h @@ -158,36 +158,40 @@ static int _write_immediate(ArchPlugin * plugin, static int _write_immediate8(ArchPlugin * plugin, uint8_t value) { - if(fwrite(&value, sizeof(value), 1, plugin->helper->fp) != 1) - return -error_set_code(1, "%s: %s", plugin->helper->filename, - strerror(errno)); + ArchPluginHelper * helper = plugin->helper; + + if(helper->write(helper->arch, &value, sizeof(value)) != sizeof(value)) + return -1; return 0; } static int _write_immediate16(ArchPlugin * plugin, uint16_t value) { + ArchPluginHelper * helper = plugin->helper; + value = _htol16(value); - if(fwrite(&value, sizeof(value), 1, plugin->helper->fp) != 1) - return -error_set_code(1, "%s: %s", plugin->helper->filename, - strerror(errno)); + if(helper->write(helper->arch, &value, sizeof(value)) != sizeof(value)) + return -1; return 0; } static int _write_immediate24(ArchPlugin * plugin, uint32_t value) { + ArchPluginHelper * helper = plugin->helper; + value = _htol32(value) >> 8; - if(fwrite(&value, 3, 1, plugin->helper->fp) != 1) - return -error_set_code(1, "%s: %s", plugin->helper->filename, - strerror(errno)); + if(helper->write(helper->arch, &value, 3) != 3) + return -1; return 0; } static int _write_immediate32(ArchPlugin * plugin, uint32_t value) { + ArchPluginHelper * helper = plugin->helper; + value = _htol32(value); - if(fwrite(&value, sizeof(value), 1, plugin->helper->fp) != 1) - return -error_set_code(1, "%s: %s", plugin->helper->filename, - strerror(errno)); + if(helper->write(helper->arch, &value, sizeof(value)) != sizeof(value)) + return -1; return 0; } diff --git a/src/arch/java.c b/src/arch/java.c index 2e4fc79..eadd6cc 100644 --- a/src/arch/java.c +++ b/src/arch/java.c @@ -275,7 +275,6 @@ static int _java_write(ArchPlugin * plugin, ArchInstruction * instruction, ArchPluginHelper * helper = plugin->helper; /* FIXME really implement */ - return (fwrite(&instruction->opcode, sizeof(char), 1, helper->fp) == 1) - ? 0 : -error_set_code(1, "%s: %s", helper->filename, - strerror(errno)); + return (helper->write(helper->arch, &instruction->opcode, 1) == 1) + ? 0 : -1; } diff --git a/src/arch/sparc.h b/src/arch/sparc.h index 612283a..e0d4910 100644 --- a/src/arch/sparc.h +++ b/src/arch/sparc.h @@ -41,6 +41,7 @@ static int _write_sethi(ArchPlugin * plugin, ArchInstruction * instruction, static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction, ArchInstructionCall * call) { + ArchPluginHelper * helper = plugin->helper; uint32_t opcode = instruction->opcode; if((opcode & 0xc0000000) == 0xc0000000) @@ -66,7 +67,8 @@ static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction, else return -1; opcode = _htob32(opcode); - if(fwrite(&opcode, sizeof(opcode), 1, plugin->helper->fp) != 1) + if(helper->write(helper->arch, &opcode, sizeof(opcode)) + != sizeof(opcode)) return -1; return 0; }