Allow immediate values to reference string indexes
This commit is contained in:
parent
17f9579803
commit
25dce8d5bf
@ -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) \
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
26
src/arch.c
26
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)
|
||||
|
@ -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;
|
||||
|
@ -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 },
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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 },
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
110
src/code.c
110
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;
|
||||
}
|
||||
|
35
src/format.c
35
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)
|
||||
|
11
src/format.h
11
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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user