Allow immediate values to reference string indexes

This commit is contained in:
Pierre Pronchery 2011-04-28 07:51:45 +00:00
parent 17f9579803
commit 25dce8d5bf
15 changed files with 211 additions and 91 deletions

View File

@ -46,7 +46,7 @@ typedef enum _ArchOperandType
{ {
AOT_NONE = 0x0, AOT_NONE = 0x0,
AOT_CONSTANT = 0x1, /* flags | 0 | size | value */ 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_REGISTER = 0x3, /* flags | 0 | size | id */
AOT_DREGISTER = 0x4, /* flags | dsize | rsize | id */ AOT_DREGISTER = 0x4, /* flags | dsize | rsize | id */
AOT_DREGISTER2 = 0x5 /* flags | did | rsize | id */ AOT_DREGISTER2 = 0x5 /* flags | did | rsize | id */
@ -74,6 +74,9 @@ typedef enum _ArchOperandType
/* for registers */ /* for registers */
# define AOF_IMPLICIT 0x1 # define AOF_IMPLICIT 0x1
/* immediate refers */
# define AOI_REFERS_STRING 0x1
/* macros */ /* macros */
# define AO_GET_FLAGS(operand) ((operand & AOM_FLAGS) >> AOD_FLAGS) # define AO_GET_FLAGS(operand) ((operand & AOM_FLAGS) >> AOD_FLAGS)
# define AO_GET_OFFSET(operand) ((operand & AOM_OFFSET) >> AOD_OFFSET) # define AO_GET_OFFSET(operand) ((operand & AOM_OFFSET) >> AOD_OFFSET)
@ -88,11 +91,11 @@ typedef enum _ArchOperandType
| ((flags) << AOD_FLAGS) \ | ((flags) << AOD_FLAGS) \
| ((size) << AOD_SIZE) \ | ((size) << AOD_SIZE) \
| ((value) << AOD_VALUE)) | ((value) << AOD_VALUE))
# define AO_IMMEDIATE(flags, offset, size) \ # define AO_IMMEDIATE(flags, size, type) \
((AOT_IMMEDIATE << AOD_TYPE) \ ((AOT_IMMEDIATE << AOD_TYPE) \
| ((flags) << AOD_FLAGS) \ | ((flags) << AOD_FLAGS) \
| ((offset) << AOD_OFFSET) \ | ((size) << AOD_SIZE) \
| ((size) << AOD_SIZE)) | ((type) << AOD_VALUE))
# define AO_REGISTER(flags, size, id) \ # define AO_REGISTER(flags, size, id) \
((AOT_REGISTER << AOD_TYPE) \ ((AOT_REGISTER << AOD_TYPE) \
| ((flags) << AOD_FLAGS) \ | ((flags) << AOD_FLAGS) \

View File

@ -66,23 +66,21 @@ int asm_set_format(Asm * a, char const * format);
/* functions */ /* functions */
AsmFunction * asm_get_function_by_name(Asm * a, char const * name); 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, int asm_set_function(Asm * a, char const * name, off_t offset, ssize_t size);
ssize_t size);
/* labels */ /* labels */
AsmLabel * asm_get_label_by_name(Asm * a, char const * label); AsmLabel * asm_get_label_by_name(Asm * a, char const * label);
AsmLabel * asm_get_label_by_offset(Asm * a, off_t offset); 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 */ /* sections */
int asm_set_section(Asm * a, char const * name, off_t offset, int whence, int asm_set_section(Asm * a, char const * name, off_t offset, ssize_t size);
ssize_t size);
/* strings */ /* strings */
AsmString * asm_get_string_by_id(Asm * a, AsmId id); AsmString * asm_get_string_by_id(Asm * a, AsmId id);
AsmString * asm_get_string_by_name(Asm * a, char const * name); 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 asm_set_string(Asm * a, int id, char const * name, off_t offset,
int whence, ssize_t size); ssize_t size);
/* useful */ /* useful */

View File

@ -44,6 +44,8 @@ typedef struct _FormatPluginHelper
/* disassembly */ /* disassembly */
/* FIXME let a different architecture be specified in the callback */ /* 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, int (*decode)(Format * format, char const * section,
off_t offset, size_t size, off_t base); off_t offset, size_t size, off_t base);
} FormatPluginHelper; } FormatPluginHelper;

View File

@ -432,6 +432,7 @@ ArchRegister * arch_get_register_by_name_size(Arch * arch, char const * name,
/* useful */ /* useful */
/* arch_decode */ /* arch_decode */
static int _decode_print(Arch * arch, ArchInstructionCall * call); static int _decode_print(Arch * arch, ArchInstructionCall * call);
static void _decode_print_immediate(Arch * arch, ArchOperand * ao);
int arch_decode(Arch * arch) 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++) for(i = 0; i < call->operands_cnt; i++)
{ {
ao = &call->operands[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: case AOT_DREGISTER:
name = ao->value.dregister.name; name = ao->value.dregister.name;
if(ao->value.dregister.offset == 0) if(ao->value.dregister.offset == 0)
{ {
printf("%s[%%%s]", sep, name); printf("[%%%s]", name);
break; break;
} }
printf("%s[%%%s + $0x%lx]", sep, name, printf("[%%%s + $0x%lx]", name,
ao->value.dregister.offset); ao->value.dregister.offset);
break; break;
case AOT_DREGISTER2: case AOT_DREGISTER2:
name = ao->value.dregister2.name; name = ao->value.dregister2.name;
printf("%s[%%%s + %%%s]", sep, name, printf("[%%%s + %%%s]", name,
ao->value.dregister2.name2); ao->value.dregister2.name2);
break; break;
case AOT_IMMEDIATE: case AOT_IMMEDIATE:
printf("%s%s$0x%lx", sep, _decode_print_immediate(arch, ao);
ao->value.immediate.negative
? "-" : "",
ao->value.immediate.value);
break; break;
case AOT_REGISTER: case AOT_REGISTER:
name = call->operands[i].value._register.name; name = call->operands[i].value._register.name;
printf("%s%%%s", sep, name); printf("%%%s", name);
break; break;
} }
sep = ", "; sep = ", ";
@ -526,6 +525,15 @@ static int _decode_print(Arch * arch, ArchInstructionCall * call)
return 0; 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 */ /* arch_decode_at */
int arch_decode_at(Arch * arch, off_t offset, size_t size, off_t base) int arch_decode_at(Arch * arch, off_t offset, size_t size, off_t base)

View File

@ -163,7 +163,7 @@ static int _dalvik_decode(ArchPlugin * plugin, ArchInstructionCall * call)
if(helper->read(helper->arch, &u8, sizeof(u8)) != sizeof(u8)) if(helper->read(helper->arch, &u8, sizeof(u8)) != sizeof(u8))
{ {
call->name = "db"; 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.value = u16;
call->operands[0].value.immediate.negative = 0; call->operands[0].value.immediate.negative = 0;
return 0; return 0;
@ -173,7 +173,7 @@ static int _dalvik_decode(ArchPlugin * plugin, ArchInstructionCall * call)
u16)) == NULL) u16)) == NULL)
{ {
call->name = "dw"; 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.value = u16;
call->operands[0].value.immediate.negative = 0; call->operands[0].value.immediate.negative = 0;
return 0; return 0;

View File

@ -29,11 +29,12 @@
#define OP_REG16 AO_REGISTER(AOF_DALVIK_REGSIZE, 32, 16) #define OP_REG16 AO_REGISTER(AOF_DALVIK_REGSIZE, 32, 16)
/* immediate values */ /* immediate values */
#define OP_U4 AO_IMMEDIATE(0, 0, 4) #define OP_U4 AO_IMMEDIATE(0, 4, 0)
#define OP_U8 AO_IMMEDIATE(0, 0, 8) #define OP_U8 AO_IMMEDIATE(0, 8, 0)
#define OP_U16 AO_IMMEDIATE(0, 0, 16) #define OP_U16 AO_IMMEDIATE(0, 16, 0)
#define OP_U32 AO_IMMEDIATE(0, 0, 32) #define OP_U16_STR AO_IMMEDIATE(0, 16, AOI_REFERS_STRING)
#define OP_U64 AO_IMMEDIATE(0, 0, 64) #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 }, { "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/16", 0x13, OP1F, OP_REG8, OP_U16, AOT_NONE },
{ "const/high16", 0x15, 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-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", 0x18, OP1F, OP_REG8, OP_U64, AOT_NONE },
{ "const-wide/16", 0x16, OP1F, OP_REG8, OP_U16, AOT_NONE }, { "const-wide/16", 0x16, OP1F, OP_REG8, OP_U16, AOT_NONE },
{ "const-wide/32", 0x17, OP1F, OP_REG8, OP_U32, AOT_NONE }, { "const-wide/32", 0x17, OP1F, OP_REG8, OP_U32, AOT_NONE },

View File

@ -66,7 +66,7 @@ static int _i386_decode(ArchPlugin * plugin, ArchInstructionCall * call)
if(helper->read(helper->arch, &u8, sizeof(u8)) != sizeof(u8)) if(helper->read(helper->arch, &u8, sizeof(u8)) != sizeof(u8))
{ {
call->name = "db"; 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.value = u8;
call->operands[0].value.immediate.negative = 0; call->operands[0].value.immediate.negative = 0;
call->operands_cnt = 1; call->operands_cnt = 1;
@ -77,7 +77,7 @@ static int _i386_decode(ArchPlugin * plugin, ArchInstructionCall * call)
u16)) == NULL) u16)) == NULL)
{ {
call->name = "dw"; 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.value = u16;
call->operands[0].value.immediate.negative = 0; call->operands[0].value.immediate.negative = 0;
call->operands_cnt = 1; call->operands_cnt = 1;
@ -106,7 +106,7 @@ static int _decode_constant(ArchPlugin * plugin, ArchInstructionCall * call,
#endif #endif
if(AO_GET_FLAGS(aod) & AOF_IMPLICIT) 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); ao->value.immediate.value = AO_GET_VALUE(aod);
return 0; return 0;
} }
@ -280,7 +280,7 @@ static int _decode_modrm_do(ArchPlugin * plugin, ArchInstructionCall * call,
!= sizeof(uW)) != sizeof(uW))
return -1; return -1;
/* FIXME endian */ /* FIXME endian */
ao->type = AO_IMMEDIATE(0, 0, W); ao->type = AO_IMMEDIATE(0, W, 0);
ao->value.immediate.value = uW; ao->value.immediate.value = uW;
} }
else if((ar = helper->get_register_by_id_size(helper->arch, reg, 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) == NULL)
return -1; return -1;
/* write register */ /* write register */
idefinition = AO_IMMEDIATE(0, 0, 8); idefinition = AO_IMMEDIATE(0, 8, 0);
memset(&ioperand, 0, sizeof(ioperand)); memset(&ioperand, 0, sizeof(ioperand));
ioperand.type = AOT_IMMEDIATE; ioperand.type = AOT_IMMEDIATE;
/* FIXME some combinations of register values are illegal */ /* 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) if(_write_immediate(plugin, idefinition, &ioperand) != 0)
return -1; return -1;
/* write offset */ /* 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; ioperand.value.immediate.value = operand->value.dregister.offset;
return _write_immediate(plugin, idefinition, &ioperand); return _write_immediate(plugin, idefinition, &ioperand);
} }
@ -590,7 +590,7 @@ static int _write_register(ArchPlugin * plugin, uint32_t * i,
== NULL) == NULL)
return -1; return -1;
/* write register */ /* write register */
idefinition = AO_IMMEDIATE(0, 0, 8); idefinition = AO_IMMEDIATE(0, 8, 0);
memset(&ioperand, 0, sizeof(ioperand)); memset(&ioperand, 0, sizeof(ioperand));
ioperand.type = AOT_IMMEDIATE; ioperand.type = AOT_IMMEDIATE;
ioperand.value.immediate.value = ar->id; ioperand.value.immediate.value = ar->id;

View File

@ -127,11 +127,11 @@
#define OP_C3 AO_CONSTANT(AOF_IMPLICIT, 8, 0x03) #define OP_C3 AO_CONSTANT(AOF_IMPLICIT, 8, 0x03)
/* immediate values */ /* immediate values */
#define OP_S8 AO_IMMEDIATE(AOF_SIGNED, 0, 8) #define OP_S8 AO_IMMEDIATE(AOF_SIGNED, 8, 0)
#define OP_SW AO_IMMEDIATE(AOF_SIGNED, 0, W) #define OP_SW AO_IMMEDIATE(AOF_SIGNED, W, 0)
#define OP_U8 AO_IMMEDIATE(0, 0, 8) #define OP_U8 AO_IMMEDIATE(0, 8, 0)
#define OP_U16 AO_IMMEDIATE(0, 0, 16) #define OP_U16 AO_IMMEDIATE(0, 16, 0)
#define OP_UW AO_IMMEDIATE(0, 0, W) #define OP_UW AO_IMMEDIATE(0, W, 0)
/* instructions */ /* instructions */

View File

@ -33,9 +33,9 @@ static ArchRegister _java_registers[] =
}; };
#define OP1F (8 << AOD_SIZE) #define OP1F (8 << AOD_SIZE)
#define OP_U8 AO_IMMEDIATE(0, 0, 8) #define OP_U8 AO_IMMEDIATE(0, 8, 0)
#define OP_U16 AO_IMMEDIATE(0, 0, 16) #define OP_U16 AO_IMMEDIATE(0, 16, 0)
#define OP_U32 AO_IMMEDIATE(0, 0, 32) #define OP_U32 AO_IMMEDIATE(0, 32, 0)
static ArchInstruction _java_instructions[] = static ArchInstruction _java_instructions[] =
{ {
{ "aaload", 0x32, OP1F, AOT_NONE, AOT_NONE, AOT_NONE }, { "aaload", 0x32, OP1F, AOT_NONE, AOT_NONE, AOT_NONE },

View File

@ -41,7 +41,7 @@
#define OPCBF (4 << AOD_SIZE) #define OPCBF (4 << AOD_SIZE)
/* helpers */ /* helpers */
#define OPCB(opcode) (opcode << 25 | 0x2 << 22) #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 */ /* integer arithmetic */
/* opcodes */ /* opcodes */
@ -78,8 +78,8 @@
/* helpers */ /* helpers */
#define OPIA1(opcode) (0x80000000 | opcode << 19) #define OPIA1(opcode) (0x80000000 | opcode << 19)
#define OPIA2(opcode) (0x80000000 | opcode << 19 | 0x1 << 13) #define OPIA2(opcode) (0x80000000 | opcode << 19 | 0x1 << 13)
#define OPIA_S12 AO_IMMEDIATE(AOF_SIGNED, 0, 12) #define OPIA_S12 AO_IMMEDIATE(AOF_SIGNED, 12, 0)
#define OPIA_U12 AO_IMMEDIATE(AOF_SIGNED, 0, 12) #define OPIA_U12 AO_IMMEDIATE(AOF_SIGNED, 12, 0)
/* load store */ /* load store */
/* opcodes */ /* opcodes */
@ -111,7 +111,7 @@
#define OPSHF (4 << AOD_SIZE) #define OPSHF (4 << AOD_SIZE)
/* helpers */ /* helpers */
#define OPSH(opcode) (opcode << 22) #define OPSH(opcode) (opcode << 22)
#define OPSH_U21 AO_IMMEDIATE(0, 0, 32) #define OPSH_U21 AO_IMMEDIATE(0, 32, 0)
/* instructions */ /* instructions */

View File

@ -140,8 +140,7 @@ int asm_set_format(Asm * a, char const * format)
/* asm_set_section */ /* asm_set_section */
int asm_set_section(Asm * a, char const * name, off_t offset, int whence, int asm_set_section(Asm * a, char const * name, off_t offset, ssize_t size)
ssize_t size)
{ {
/* FIXME fully implement */ /* FIXME fully implement */
return code_section(a->code, name); return code_section(a->code, name);

View File

@ -32,6 +32,14 @@
/* Code */ /* Code */
/* private */ /* private */
/* types */ /* types */
typedef struct _CodeString
{
int id;
char * name;
off_t offset;
ssize_t size;
} CodeString;
struct _Code struct _Code
{ {
Arch * arch; Arch * arch;
@ -39,9 +47,24 @@ struct _Code
Format * format; Format * format;
char * filename; char * filename;
FILE * fp; 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 */ /* functions */
/* code_new */ /* code_new */
Code * code_new(char const * arch, char const * format) 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, ret |= -error_set_code(1, "%s: %s", code->filename,
strerror(errno)); strerror(errno));
code->fp = NULL; code->fp = NULL;
_code_string_delete_all(code);
return ret; return ret;
} }
@ -136,6 +160,8 @@ int code_decode(Code * code, char const * buffer, size_t size)
/* code_decode_file */ /* code_decode_file */
static int _decode_file_callback(void * priv, char const * section, static int _decode_file_callback(void * priv, char const * section,
off_t offset, size_t size, off_t base); 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) 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)); return -error_set_code(1, "%s: %s", filename, strerror(errno));
arch_init(code->arch, filename, fp); arch_init(code->arch, filename, fp);
format_init(code->format, 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); format_exit(code->format);
arch_exit(code->arch); arch_exit(code->arch);
if(fclose(fp) != 0 && ret == 0) 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); 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 */ /* code_function */
int code_function(Code * code, char const * function) int code_function(Code * code, char const * function)
@ -219,3 +261,69 @@ int code_section(Code * code, char const * section)
#endif #endif
return format_section(code->format, section); 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;
}

View File

@ -41,9 +41,10 @@ struct _Format
FILE * fp; FILE * fp;
/* diassembly */ /* diassembly */
int (*decode_callback)(void * priv, char const * section, off_t offset, /* callbacks */
size_t size, off_t base); FormatSetStringCallback callback_set_string;
void * decode_priv; FormatDecodeCallback callback_decode;
void * callback_priv;
}; };
@ -113,23 +114,28 @@ char const * format_get_name(Format * format)
/* format_decode */ /* format_decode */
static int _decode_callback(Format * format, char const * section, static int _decode_callback(Format * format, char const * section,
off_t offset, size_t size, off_t base); 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, int format_decode(Format * format, FormatSetStringCallback set_string,
char const * section, off_t offset, size_t size, FormatDecodeCallback decode, void * priv)
off_t base), void * priv)
{ {
int ret; int ret;
if(format->plugin->decode == NULL) if(format->plugin->decode == NULL)
return error_set_code(1, "%s: %s", format_get_name(format), return error_set_code(1, "%s: %s", format_get_name(format),
"Disassembly is not supported"); "Disassembly is not supported");
format->helper.set_string = _set_string_callback;
format->callback_set_string = set_string;
format->helper.decode = _decode_callback; format->helper.decode = _decode_callback;
format->decode_callback = callback; format->callback_decode = decode;
format->decode_priv = priv; format->callback_priv = priv;
ret = format->plugin->decode(format->plugin); ret = format->plugin->decode(format->plugin);
format->decode_callback = NULL; format->helper.set_string = NULL;
format->decode_priv = NULL; format->callback_set_string = NULL;
format->helper.decode = NULL; format->helper.decode = NULL;
format->callback_decode = NULL;
format->callback_priv = NULL;
return ret; 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__, fprintf(stderr, "DEBUG: %s(\"%s\", 0x%lx, 0x%lx, 0x%lx)\n", __func__,
section, offset, size, base); section, offset, size, base);
#endif #endif
return format->decode_callback(format->decode_priv, section, offset, return format->callback_decode(format->callback_priv, section, offset,
size, base); 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 */ /* format_exit */
int format_exit(Format * format) int format_exit(Format * format)

View File

@ -23,6 +23,12 @@
/* Format */ /* Format */
/* public */ /* 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 */ /* functions */
Format * format_new(char const * format, char const * arch); Format * format_new(char const * format, char const * arch);
void format_delete(Format * format); 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); int format_section(Format * format, char const * section);
/* disassembly */ /* disassembly */
int format_decode(Format * format, int (*callback)(void * priv, int format_decode(Format * format, FormatSetStringCallback set_string,
char const * section, off_t offset, size_t size, FormatDecodeCallback decode, void * priv);
off_t base), void * priv);
#endif /* !ASM_FORMAT_H */ #endif /* !ASM_FORMAT_H */

View File

@ -103,8 +103,6 @@ typedef struct _DexString
typedef struct _Dex typedef struct _Dex
{ {
DexString * strings;
size_t strings_cnt;
} Dex; } Dex;
@ -157,8 +155,6 @@ static int _dex_init(FormatPlugin * format, char const * arch)
if((dex = object_new(sizeof(*dex))) == NULL) if((dex = object_new(sizeof(*dex))) == NULL)
return -1; return -1;
format->priv = dex; format->priv = dex;
dex->strings = NULL;
dex->strings_cnt = 0;
return 0; return 0;
} }
@ -169,9 +165,6 @@ static int _dex_destroy(FormatPlugin * format)
Dex * dex = format->priv; Dex * dex = format->priv;
size_t i; size_t i;
for(i = 0; i < dex->strings_cnt; i++)
string_delete(dex->strings[i].string);
free(dex->strings);
object_delete(dex); object_delete(dex);
return 0; return 0;
} }
@ -322,36 +315,26 @@ static int _decode_map_string_id(FormatPlugin * format, off_t offset,
FormatPluginHelper * helper = format->helper; FormatPluginHelper * helper = format->helper;
Dex * dex = format->priv; Dex * dex = format->priv;
size_t i; size_t i;
DexStringIdItem dsii; DexStringIdItem * dsii;
ssize_t s; 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) if(helper->seek(helper->format, offset, SEEK_SET) != offset)
return -1; return -1;
if((dex->strings = malloc(sizeof(*dex->strings) * size)) == NULL) s = sizeof(*dsii) * size;
return -_dex_error(format); 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++) for(i = 0; i < size; i++)
{ {
s = sizeof(dsii); dsii[i].string_data_off = _htol32(dsii[i].string_data_off);
if(helper->read(helper->format, &dsii, s) != s) #if 1 /* def DEBUG */
break;
dsii.string_data_off = _htol32(dsii.string_data_off);
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s() string %lu offset 0x%x\n", fprintf(stderr, "DEBUG: %s() string %lu offset 0x%x\n",
__func__, i, dsii.string_data_off); __func__, i, dsii[i].string_data_off);
#endif #endif
dex->strings[i].offset = dsii.string_data_off; helper->set_string(helper->format, i, NULL,
dex->strings[i].string = NULL; dsii[i].string_data_off, -1);
} }
if(i != size)
{
free(dex->strings);
dex->strings = NULL;
return -1;
}
dex->strings_cnt = size;
return 0; return 0;
} }