From 25dce8d5bf647bd51eec2563c6b707865bb2cb49 Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Thu, 28 Apr 2011 07:51:45 +0000 Subject: [PATCH] Allow immediate values to reference string indexes --- include/Asm/arch.h | 11 +++-- include/Asm/asm.h | 10 ++-- include/Asm/format.h | 2 + src/arch.c | 26 ++++++---- src/arch/dalvik.c | 4 +- src/arch/dalvik.ins | 13 ++--- src/arch/i386.h | 14 +++--- src/arch/i386.ins | 10 ++-- src/arch/java.c | 6 +-- src/arch/sparc.ins | 8 ++-- src/asm.c | 3 +- src/code.c | 110 ++++++++++++++++++++++++++++++++++++++++++- src/format.c | 35 +++++++++----- src/format.h | 11 +++-- src/format/dex.c | 39 +++++---------- 15 files changed, 211 insertions(+), 91 deletions(-) diff --git a/include/Asm/arch.h b/include/Asm/arch.h index b1832d5..7aa1da7 100644 --- a/include/Asm/arch.h +++ b/include/Asm/arch.h @@ -46,7 +46,7 @@ typedef enum _ArchOperandType { AOT_NONE = 0x0, AOT_CONSTANT = 0x1, /* flags | 0 | size | value */ - AOT_IMMEDIATE = 0x2, /* flags | offset | 0 | size */ + AOT_IMMEDIATE = 0x2, /* flags | 0 | size | refers */ AOT_REGISTER = 0x3, /* flags | 0 | size | id */ AOT_DREGISTER = 0x4, /* flags | dsize | rsize | id */ AOT_DREGISTER2 = 0x5 /* flags | did | rsize | id */ @@ -74,6 +74,9 @@ typedef enum _ArchOperandType /* for registers */ # define AOF_IMPLICIT 0x1 +/* immediate refers */ +# define AOI_REFERS_STRING 0x1 + /* macros */ # define AO_GET_FLAGS(operand) ((operand & AOM_FLAGS) >> AOD_FLAGS) # define AO_GET_OFFSET(operand) ((operand & AOM_OFFSET) >> AOD_OFFSET) @@ -88,11 +91,11 @@ typedef enum _ArchOperandType | ((flags) << AOD_FLAGS) \ | ((size) << AOD_SIZE) \ | ((value) << AOD_VALUE)) -# define AO_IMMEDIATE(flags, offset, size) \ +# define AO_IMMEDIATE(flags, size, type) \ ((AOT_IMMEDIATE << AOD_TYPE) \ | ((flags) << AOD_FLAGS) \ - | ((offset) << AOD_OFFSET) \ - | ((size) << AOD_SIZE)) + | ((size) << AOD_SIZE) \ + | ((type) << AOD_VALUE)) # define AO_REGISTER(flags, size, id) \ ((AOT_REGISTER << AOD_TYPE) \ | ((flags) << AOD_FLAGS) \ diff --git a/include/Asm/asm.h b/include/Asm/asm.h index d6d79cc..c4c79b7 100644 --- a/include/Asm/asm.h +++ b/include/Asm/asm.h @@ -66,23 +66,21 @@ int asm_set_format(Asm * a, char const * format); /* functions */ AsmFunction * asm_get_function_by_name(Asm * a, char const * name); -int asm_set_function(Asm * a, char const * name, off_t offset, int whence, - ssize_t size); +int asm_set_function(Asm * a, char const * name, off_t offset, ssize_t size); /* labels */ AsmLabel * asm_get_label_by_name(Asm * a, char const * label); AsmLabel * asm_get_label_by_offset(Asm * a, off_t offset); -int asm_set_label(Asm * a, char const * label, off_t offset, int whence); +int asm_set_label(Asm * a, char const * label, off_t offset); /* sections */ -int asm_set_section(Asm * a, char const * name, off_t offset, int whence, - ssize_t size); +int asm_set_section(Asm * a, char const * name, off_t offset, ssize_t size); /* strings */ AsmString * asm_get_string_by_id(Asm * a, AsmId id); AsmString * asm_get_string_by_name(Asm * a, char const * name); int asm_set_string(Asm * a, int id, char const * name, off_t offset, - int whence, ssize_t size); + ssize_t size); /* useful */ diff --git a/include/Asm/format.h b/include/Asm/format.h index ecf8e71..d8a4d75 100644 --- a/include/Asm/format.h +++ b/include/Asm/format.h @@ -44,6 +44,8 @@ typedef struct _FormatPluginHelper /* disassembly */ /* FIXME let a different architecture be specified in the callback */ + int (*set_string)(Format * format, int id, char const * name, + off_t offset, ssize_t size); int (*decode)(Format * format, char const * section, off_t offset, size_t size, off_t base); } FormatPluginHelper; diff --git a/src/arch.c b/src/arch.c index 924f3a5..7bc169d 100644 --- a/src/arch.c +++ b/src/arch.c @@ -432,6 +432,7 @@ ArchRegister * arch_get_register_by_name_size(Arch * arch, char const * name, /* useful */ /* arch_decode */ static int _decode_print(Arch * arch, ArchInstructionCall * call); +static void _decode_print_immediate(Arch * arch, ArchOperand * ao); int arch_decode(Arch * arch) { @@ -492,32 +493,30 @@ static int _decode_print(Arch * arch, ArchInstructionCall * call) for(i = 0; i < call->operands_cnt; i++) { ao = &call->operands[i]; - switch(AO_GET_TYPE(call->operands[i].type)) + fputs(sep, stdout); + switch(AO_GET_TYPE(ao->type)) { case AOT_DREGISTER: name = ao->value.dregister.name; if(ao->value.dregister.offset == 0) { - printf("%s[%%%s]", sep, name); + printf("[%%%s]", name); break; } - printf("%s[%%%s + $0x%lx]", sep, name, + printf("[%%%s + $0x%lx]", name, ao->value.dregister.offset); break; case AOT_DREGISTER2: name = ao->value.dregister2.name; - printf("%s[%%%s + %%%s]", sep, name, + printf("[%%%s + %%%s]", name, ao->value.dregister2.name2); break; case AOT_IMMEDIATE: - printf("%s%s$0x%lx", sep, - ao->value.immediate.negative - ? "-" : "", - ao->value.immediate.value); + _decode_print_immediate(arch, ao); break; case AOT_REGISTER: name = call->operands[i].value._register.name; - printf("%s%%%s", sep, name); + printf("%%%s", name); break; } sep = ", "; @@ -526,6 +525,15 @@ static int _decode_print(Arch * arch, ArchInstructionCall * call) return 0; } +static void _decode_print_immediate(Arch * arch, ArchOperand * ao) +{ + printf("%s$0x%lx", ao->value.immediate.negative ? "-" : "", + ao->value.immediate.value); + if(AO_GET_VALUE(ao->type) == AOI_REFERS_STRING) + /* FIXME really print */ + printf("%s", " (string)"); +} + /* arch_decode_at */ int arch_decode_at(Arch * arch, off_t offset, size_t size, off_t base) diff --git a/src/arch/dalvik.c b/src/arch/dalvik.c index d3c4bbc..9789037 100644 --- a/src/arch/dalvik.c +++ b/src/arch/dalvik.c @@ -163,7 +163,7 @@ static int _dalvik_decode(ArchPlugin * plugin, ArchInstructionCall * call) if(helper->read(helper->arch, &u8, sizeof(u8)) != sizeof(u8)) { call->name = "db"; - call->operands[0].type = AO_IMMEDIATE(0, 0, 8); + call->operands[0].type = AO_IMMEDIATE(0, 8, 0); call->operands[0].value.immediate.value = u16; call->operands[0].value.immediate.negative = 0; return 0; @@ -173,7 +173,7 @@ static int _dalvik_decode(ArchPlugin * plugin, ArchInstructionCall * call) u16)) == NULL) { call->name = "dw"; - call->operands[0].type = AO_IMMEDIATE(0, 0, 16); + call->operands[0].type = AO_IMMEDIATE(0, 16, 0); call->operands[0].value.immediate.value = u16; call->operands[0].value.immediate.negative = 0; return 0; diff --git a/src/arch/dalvik.ins b/src/arch/dalvik.ins index 058c715..1cda41e 100644 --- a/src/arch/dalvik.ins +++ b/src/arch/dalvik.ins @@ -29,11 +29,12 @@ #define OP_REG16 AO_REGISTER(AOF_DALVIK_REGSIZE, 32, 16) /* immediate values */ -#define OP_U4 AO_IMMEDIATE(0, 0, 4) -#define OP_U8 AO_IMMEDIATE(0, 0, 8) -#define OP_U16 AO_IMMEDIATE(0, 0, 16) -#define OP_U32 AO_IMMEDIATE(0, 0, 32) -#define OP_U64 AO_IMMEDIATE(0, 0, 64) +#define OP_U4 AO_IMMEDIATE(0, 4, 0) +#define OP_U8 AO_IMMEDIATE(0, 8, 0) +#define OP_U16 AO_IMMEDIATE(0, 16, 0) +#define OP_U16_STR AO_IMMEDIATE(0, 16, AOI_REFERS_STRING) +#define OP_U32 AO_IMMEDIATE(0, 32, 0) +#define OP_U64 AO_IMMEDIATE(0, 64, 0) { "add-double", 0xab, OP1F, OP_REG8, OP_REG8, OP_REG8 }, @@ -78,7 +79,7 @@ { "const/16", 0x13, OP1F, OP_REG8, OP_U16, AOT_NONE }, { "const/high16", 0x15, OP1F, OP_REG8, OP_U16, AOT_NONE }, { "const-class", 0x1c, OP1F, OP_REG8, OP_U16, AOT_NONE }, -{ "const-string", 0x1a, OP1F, OP_REG8, OP_U16, AOT_NONE }, +{ "const-string", 0x1a, OP1F, OP_REG8, OP_U16_STR, AOT_NONE }, { "const-wide", 0x18, OP1F, OP_REG8, OP_U64, AOT_NONE }, { "const-wide/16", 0x16, OP1F, OP_REG8, OP_U16, AOT_NONE }, { "const-wide/32", 0x17, OP1F, OP_REG8, OP_U32, AOT_NONE }, diff --git a/src/arch/i386.h b/src/arch/i386.h index ab963d2..885042d 100644 --- a/src/arch/i386.h +++ b/src/arch/i386.h @@ -66,7 +66,7 @@ static int _i386_decode(ArchPlugin * plugin, ArchInstructionCall * call) if(helper->read(helper->arch, &u8, sizeof(u8)) != sizeof(u8)) { call->name = "db"; - call->operands[0].type = AO_IMMEDIATE(0, 0, 8); + call->operands[0].type = AO_IMMEDIATE(0, 8, 0); call->operands[0].value.immediate.value = u8; call->operands[0].value.immediate.negative = 0; call->operands_cnt = 1; @@ -77,7 +77,7 @@ static int _i386_decode(ArchPlugin * plugin, ArchInstructionCall * call) u16)) == NULL) { call->name = "dw"; - call->operands[0].type = AO_IMMEDIATE(0, 0, 16); + call->operands[0].type = AO_IMMEDIATE(0, 16, 0); call->operands[0].value.immediate.value = u16; call->operands[0].value.immediate.negative = 0; call->operands_cnt = 1; @@ -106,7 +106,7 @@ static int _decode_constant(ArchPlugin * plugin, ArchInstructionCall * call, #endif if(AO_GET_FLAGS(aod) & AOF_IMPLICIT) { - ao->type = AO_IMMEDIATE(0, 0, AO_GET_SIZE(aod)); + ao->type = AO_IMMEDIATE(0, AO_GET_SIZE(aod), 0); ao->value.immediate.value = AO_GET_VALUE(aod); return 0; } @@ -280,7 +280,7 @@ static int _decode_modrm_do(ArchPlugin * plugin, ArchInstructionCall * call, != sizeof(uW)) return -1; /* FIXME endian */ - ao->type = AO_IMMEDIATE(0, 0, W); + ao->type = AO_IMMEDIATE(0, W, 0); ao->value.immediate.value = uW; } else if((ar = helper->get_register_by_id_size(helper->arch, reg, @@ -411,7 +411,7 @@ static int _write_dregister(ArchPlugin * plugin, uint32_t * i, == NULL) return -1; /* write register */ - idefinition = AO_IMMEDIATE(0, 0, 8); + idefinition = AO_IMMEDIATE(0, 8, 0); memset(&ioperand, 0, sizeof(ioperand)); ioperand.type = AOT_IMMEDIATE; /* FIXME some combinations of register values are illegal */ @@ -449,7 +449,7 @@ static int _write_dregister(ArchPlugin * plugin, uint32_t * i, if(_write_immediate(plugin, idefinition, &ioperand) != 0) return -1; /* write offset */ - idefinition = AO_IMMEDIATE(0, 0, AO_GET_OFFSET(definition)); + idefinition = AO_IMMEDIATE(0, AO_GET_OFFSET(definition), 0); ioperand.value.immediate.value = operand->value.dregister.offset; return _write_immediate(plugin, idefinition, &ioperand); } @@ -590,7 +590,7 @@ static int _write_register(ArchPlugin * plugin, uint32_t * i, == NULL) return -1; /* write register */ - idefinition = AO_IMMEDIATE(0, 0, 8); + idefinition = AO_IMMEDIATE(0, 8, 0); memset(&ioperand, 0, sizeof(ioperand)); ioperand.type = AOT_IMMEDIATE; ioperand.value.immediate.value = ar->id; diff --git a/src/arch/i386.ins b/src/arch/i386.ins index 94f39d1..6f0a161 100644 --- a/src/arch/i386.ins +++ b/src/arch/i386.ins @@ -127,11 +127,11 @@ #define OP_C3 AO_CONSTANT(AOF_IMPLICIT, 8, 0x03) /* immediate values */ -#define OP_S8 AO_IMMEDIATE(AOF_SIGNED, 0, 8) -#define OP_SW AO_IMMEDIATE(AOF_SIGNED, 0, W) -#define OP_U8 AO_IMMEDIATE(0, 0, 8) -#define OP_U16 AO_IMMEDIATE(0, 0, 16) -#define OP_UW AO_IMMEDIATE(0, 0, W) +#define OP_S8 AO_IMMEDIATE(AOF_SIGNED, 8, 0) +#define OP_SW AO_IMMEDIATE(AOF_SIGNED, W, 0) +#define OP_U8 AO_IMMEDIATE(0, 8, 0) +#define OP_U16 AO_IMMEDIATE(0, 16, 0) +#define OP_UW AO_IMMEDIATE(0, W, 0) /* instructions */ diff --git a/src/arch/java.c b/src/arch/java.c index eadd6cc..be8f83e 100644 --- a/src/arch/java.c +++ b/src/arch/java.c @@ -33,9 +33,9 @@ static ArchRegister _java_registers[] = }; #define OP1F (8 << AOD_SIZE) -#define OP_U8 AO_IMMEDIATE(0, 0, 8) -#define OP_U16 AO_IMMEDIATE(0, 0, 16) -#define OP_U32 AO_IMMEDIATE(0, 0, 32) +#define OP_U8 AO_IMMEDIATE(0, 8, 0) +#define OP_U16 AO_IMMEDIATE(0, 16, 0) +#define OP_U32 AO_IMMEDIATE(0, 32, 0) static ArchInstruction _java_instructions[] = { { "aaload", 0x32, OP1F, AOT_NONE, AOT_NONE, AOT_NONE }, diff --git a/src/arch/sparc.ins b/src/arch/sparc.ins index 9a93fd9..8c570aa 100644 --- a/src/arch/sparc.ins +++ b/src/arch/sparc.ins @@ -41,7 +41,7 @@ #define OPCBF (4 << AOD_SIZE) /* helpers */ #define OPCB(opcode) (opcode << 25 | 0x2 << 22) -#define OPCB_U22 AO_IMMEDIATE(0, 0, 21) +#define OPCB_U22 AO_IMMEDIATE(0, 21, 0) /* integer arithmetic */ /* opcodes */ @@ -78,8 +78,8 @@ /* helpers */ #define OPIA1(opcode) (0x80000000 | opcode << 19) #define OPIA2(opcode) (0x80000000 | opcode << 19 | 0x1 << 13) -#define OPIA_S12 AO_IMMEDIATE(AOF_SIGNED, 0, 12) -#define OPIA_U12 AO_IMMEDIATE(AOF_SIGNED, 0, 12) +#define OPIA_S12 AO_IMMEDIATE(AOF_SIGNED, 12, 0) +#define OPIA_U12 AO_IMMEDIATE(AOF_SIGNED, 12, 0) /* load store */ /* opcodes */ @@ -111,7 +111,7 @@ #define OPSHF (4 << AOD_SIZE) /* helpers */ #define OPSH(opcode) (opcode << 22) -#define OPSH_U21 AO_IMMEDIATE(0, 0, 32) +#define OPSH_U21 AO_IMMEDIATE(0, 32, 0) /* instructions */ diff --git a/src/asm.c b/src/asm.c index 21d394e..1b4c1a9 100644 --- a/src/asm.c +++ b/src/asm.c @@ -140,8 +140,7 @@ int asm_set_format(Asm * a, char const * format) /* asm_set_section */ -int asm_set_section(Asm * a, char const * name, off_t offset, int whence, - ssize_t size) +int asm_set_section(Asm * a, char const * name, off_t offset, ssize_t size) { /* FIXME fully implement */ return code_section(a->code, name); diff --git a/src/code.c b/src/code.c index 208d93c..5eaff50 100644 --- a/src/code.c +++ b/src/code.c @@ -32,6 +32,14 @@ /* Code */ /* private */ /* types */ +typedef struct _CodeString +{ + int id; + char * name; + off_t offset; + ssize_t size; +} CodeString; + struct _Code { Arch * arch; @@ -39,9 +47,24 @@ struct _Code Format * format; char * filename; FILE * fp; + + /* strings */ + CodeString * strings; + size_t strings_cnt; }; +/* prototypes */ +/* strings */ +static void _code_string_delete_all(Code * code); + +static CodeString * _code_string_get_by_id(Code * code, AsmId id); +static int _code_string_set(CodeString * codestring, int id, char const * name, + off_t offset, ssize_t size); + +static CodeString * _code_string_append(Code * code); + + /* functions */ /* code_new */ Code * code_new(char const * arch, char const * format) @@ -117,6 +140,7 @@ int code_close(Code * code) ret |= -error_set_code(1, "%s: %s", code->filename, strerror(errno)); code->fp = NULL; + _code_string_delete_all(code); return ret; } @@ -136,6 +160,8 @@ int code_decode(Code * code, char const * buffer, size_t size) /* code_decode_file */ static int _decode_file_callback(void * priv, char const * section, off_t offset, size_t size, off_t base); +static int _set_string_callback(void * priv, int id, char const * name, + off_t offset, ssize_t size); int code_decode_file(Code * code, char const * filename) { @@ -146,7 +172,8 @@ int code_decode_file(Code * code, char const * filename) return -error_set_code(1, "%s: %s", filename, strerror(errno)); arch_init(code->arch, filename, fp); format_init(code->format, filename, fp); - ret = format_decode(code->format, _decode_file_callback, code); + ret = format_decode(code->format, _set_string_callback, + _decode_file_callback, code); format_exit(code->format); arch_exit(code->arch); if(fclose(fp) != 0 && ret == 0) @@ -164,6 +191,21 @@ static int _decode_file_callback(void * priv, char const * section, return arch_decode_at(code->arch, offset, size, base); } +static int _set_string_callback(void * priv, int id, char const * name, + off_t offset, ssize_t size) +{ + Code * code = priv; + CodeString * cs = NULL; + + if(id >= 0) + cs = _code_string_get_by_id(code, id); + if(cs == NULL) + cs = _code_string_append(code); + if(cs == NULL || _code_string_set(cs, id, name, offset, size) != 0) + return -1; + return cs->id; +} + /* code_function */ int code_function(Code * code, char const * function) @@ -219,3 +261,69 @@ int code_section(Code * code, char const * section) #endif return format_section(code->format, section); } + + +/* private */ +/* functions */ +/* strings */ +/* code_string_delete_all */ +static void _code_string_delete_all(Code * code) +{ + size_t i; + + for(i = 0; i < code->strings_cnt; i++) + free(code->strings[i].name); + code->strings_cnt = 0; + free(code->strings); + code->strings = NULL; +} + + +/* code_string_get_by_id */ +static CodeString * _code_string_get_by_id(Code * code, AsmId id) +{ + size_t i; + + for(i = 0; i < code->strings_cnt; i++) + if(code->strings[i].id >= 0 && code->strings[i].id == id) + return &code->strings[i]; + return NULL; +} + + +/* code_string_set */ +static int _code_string_set(CodeString * codestring, int id, char const * name, + off_t offset, ssize_t size) +{ + char * p = NULL; + + if(name != NULL && (p = strdup(name)) == NULL) + return -error_set_code(1, "%s", strerror(errno)); + codestring->id = id; + free(codestring->name); + codestring->name = p; + codestring->offset = offset; + codestring->size = size; + return 0; +} + + +/* code_string_append */ +static CodeString * _code_string_append(Code * code) +{ + CodeString * p; + + if((p = realloc(code->strings, sizeof(*p) * (code->strings_cnt + 1))) + == NULL) + { + error_set_code(1, "%s", strerror(errno)); + return NULL; + } + code->strings = p; + p = &code->strings[code->strings_cnt++]; + p->id = -1; + p->name = NULL; + p->offset = -1; + p->size = -1; + return p; +} diff --git a/src/format.c b/src/format.c index 5b49bfc..a7f3521 100644 --- a/src/format.c +++ b/src/format.c @@ -41,9 +41,10 @@ struct _Format FILE * fp; /* diassembly */ - int (*decode_callback)(void * priv, char const * section, off_t offset, - size_t size, off_t base); - void * decode_priv; + /* callbacks */ + FormatSetStringCallback callback_set_string; + FormatDecodeCallback callback_decode; + void * callback_priv; }; @@ -113,23 +114,28 @@ char const * format_get_name(Format * format) /* format_decode */ static int _decode_callback(Format * format, char const * section, off_t offset, size_t size, off_t base); +static int _set_string_callback(Format * format, int id, char const * name, + off_t offset, ssize_t size); -int format_decode(Format * format, int (*callback)(void * priv, - char const * section, off_t offset, size_t size, - off_t base), void * priv) +int format_decode(Format * format, FormatSetStringCallback set_string, + FormatDecodeCallback decode, 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.set_string = _set_string_callback; + format->callback_set_string = set_string; format->helper.decode = _decode_callback; - format->decode_callback = callback; - format->decode_priv = priv; + format->callback_decode = decode; + format->callback_priv = priv; ret = format->plugin->decode(format->plugin); - format->decode_callback = NULL; - format->decode_priv = NULL; + format->helper.set_string = NULL; + format->callback_set_string = NULL; format->helper.decode = NULL; + format->callback_decode = NULL; + format->callback_priv = NULL; return ret; } @@ -140,10 +146,17 @@ static int _decode_callback(Format * format, char const * section, fprintf(stderr, "DEBUG: %s(\"%s\", 0x%lx, 0x%lx, 0x%lx)\n", __func__, section, offset, size, base); #endif - return format->decode_callback(format->decode_priv, section, offset, + return format->callback_decode(format->callback_priv, section, offset, size, base); } +static int _set_string_callback(Format * format, int id, char const * name, + off_t offset, ssize_t size) +{ + return format->callback_set_string(format->callback_priv, id, name, + offset, size); +} + /* format_exit */ int format_exit(Format * format) diff --git a/src/format.h b/src/format.h index 528df34..6fb4918 100644 --- a/src/format.h +++ b/src/format.h @@ -23,6 +23,12 @@ /* Format */ /* public */ +/* types */ +typedef int (*FormatDecodeCallback)(void * priv, char const * section, + off_t offset, size_t size, off_t base); +typedef int (*FormatSetStringCallback)(void * priv, int id, char const * name, + off_t offset, ssize_t size); + /* functions */ Format * format_new(char const * format, char const * arch); void format_delete(Format * format); @@ -39,8 +45,7 @@ int format_function(Format * format, char const * function); 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); +int format_decode(Format * format, FormatSetStringCallback set_string, + FormatDecodeCallback decode, void * priv); #endif /* !ASM_FORMAT_H */ diff --git a/src/format/dex.c b/src/format/dex.c index a72b922..1d209d6 100644 --- a/src/format/dex.c +++ b/src/format/dex.c @@ -103,8 +103,6 @@ typedef struct _DexString typedef struct _Dex { - DexString * strings; - size_t strings_cnt; } Dex; @@ -157,8 +155,6 @@ static int _dex_init(FormatPlugin * format, char const * arch) if((dex = object_new(sizeof(*dex))) == NULL) return -1; format->priv = dex; - dex->strings = NULL; - dex->strings_cnt = 0; return 0; } @@ -169,9 +165,6 @@ static int _dex_destroy(FormatPlugin * format) Dex * dex = format->priv; size_t i; - for(i = 0; i < dex->strings_cnt; i++) - string_delete(dex->strings[i].string); - free(dex->strings); object_delete(dex); return 0; } @@ -322,36 +315,26 @@ static int _decode_map_string_id(FormatPlugin * format, off_t offset, FormatPluginHelper * helper = format->helper; Dex * dex = format->priv; size_t i; - DexStringIdItem dsii; + DexStringIdItem * dsii; ssize_t s; - if(dex->strings_cnt != 0) - return -error_set_code(1, "%s: %s", "dex", - "String section already parsed"); if(helper->seek(helper->format, offset, SEEK_SET) != offset) return -1; - if((dex->strings = malloc(sizeof(*dex->strings) * size)) == NULL) - return -_dex_error(format); + s = sizeof(*dsii) * size; + if((dsii = malloc(s)) == NULL) + return -error_set_code(1, "%s", strerror(errno)); + if(helper->read(helper->format, dsii, s) != s) + return -1; for(i = 0; i < size; i++) { - s = sizeof(dsii); - if(helper->read(helper->format, &dsii, s) != s) - break; - dsii.string_data_off = _htol32(dsii.string_data_off); -#ifdef DEBUG + dsii[i].string_data_off = _htol32(dsii[i].string_data_off); +#if 1 /* def DEBUG */ fprintf(stderr, "DEBUG: %s() string %lu offset 0x%x\n", - __func__, i, dsii.string_data_off); + __func__, i, dsii[i].string_data_off); #endif - dex->strings[i].offset = dsii.string_data_off; - dex->strings[i].string = NULL; + helper->set_string(helper->format, i, NULL, + dsii[i].string_data_off, -1); } - if(i != size) - { - free(dex->strings); - dex->strings = NULL; - return -1; - } - dex->strings_cnt = size; return 0; }