Moved deassembly printout into the Code class (allows printing strings)
This commit is contained in:
parent
25dce8d5bf
commit
24200d4689
@ -80,7 +80,7 @@ int asm_set_section(Asm * a, char const * name, off_t offset, ssize_t size);
|
|||||||
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,
|
||||||
ssize_t size);
|
ssize_t length);
|
||||||
|
|
||||||
|
|
||||||
/* useful */
|
/* useful */
|
||||||
|
118
src/arch.c
118
src/arch.c
@ -431,112 +431,41 @@ 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);
|
int arch_decode(Arch * arch, ArchInstructionCall ** calls, size_t * calls_cnt)
|
||||||
static void _decode_print_immediate(Arch * arch, ArchOperand * ao);
|
|
||||||
|
|
||||||
int arch_decode(Arch * arch)
|
|
||||||
{
|
{
|
||||||
ArchInstructionCall * calls = NULL;
|
ArchInstructionCall * c = NULL;
|
||||||
size_t calls_cnt = 0;
|
size_t c_cnt = 0;
|
||||||
ArchInstructionCall * p;
|
ArchInstructionCall * p;
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if(arch->plugin->decode == NULL)
|
if(arch->plugin->decode == NULL)
|
||||||
return -error_set_code(1, "%s: %s", arch->plugin->name,
|
return -error_set_code(1, "%s: %s", arch->plugin->name,
|
||||||
"Disassembly not supported");
|
"Disassembly not supported");
|
||||||
printf("\n%08lx:\n", arch->buffer_pos + (long)arch->base);
|
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
if((p = realloc(calls, sizeof(*calls) * (calls_cnt + 1)))
|
if((p = realloc(c, sizeof(*c) * (c_cnt + 1))) == NULL)
|
||||||
== NULL)
|
|
||||||
{
|
{
|
||||||
free(calls);
|
free(c);
|
||||||
return -error_set_code(1, "%s", strerror(errno));
|
return -error_set_code(1, "%s", strerror(errno));
|
||||||
}
|
}
|
||||||
calls = p;
|
c = p;
|
||||||
p = &calls[calls_cnt];
|
p = &c[c_cnt];
|
||||||
memset(p, 0, sizeof(*p));
|
memset(p, 0, sizeof(*p));
|
||||||
p->base = arch->base;
|
p->base = arch->base;
|
||||||
p->offset = arch->buffer_pos;
|
p->offset = arch->buffer_pos;
|
||||||
if(arch->plugin->decode(arch->plugin, p) != 0)
|
if(arch->plugin->decode(arch->plugin, p) != 0)
|
||||||
break;
|
break;
|
||||||
p->size = arch->buffer_pos - p->offset;
|
p->size = arch->buffer_pos - p->offset;
|
||||||
calls_cnt++;
|
c_cnt++;
|
||||||
}
|
}
|
||||||
for(i = 0; i < calls_cnt; i++)
|
*calls = c;
|
||||||
if(_decode_print(arch, &calls[i]) != 0)
|
*calls_cnt = c_cnt;
|
||||||
return -1;
|
|
||||||
free(calls);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _decode_print(Arch * arch, ArchInstructionCall * call)
|
|
||||||
{
|
|
||||||
char const * sep = " ";
|
|
||||||
size_t i;
|
|
||||||
uint8_t u8;
|
|
||||||
ArchOperand * ao;
|
|
||||||
char const * name;
|
|
||||||
|
|
||||||
if(arch->helper.seek(arch, call->offset, SEEK_SET) < 0)
|
|
||||||
return -1;
|
|
||||||
printf("%8lx:", (long)call->base + (long)call->offset);
|
|
||||||
for(i = 0; i < call->size; i++)
|
|
||||||
{
|
|
||||||
if(arch->helper.read(arch, &u8, sizeof(u8)) != sizeof(u8))
|
|
||||||
return -1;
|
|
||||||
printf(" %02x", u8);
|
|
||||||
}
|
|
||||||
for(; i < 8; i++)
|
|
||||||
printf(" ");
|
|
||||||
printf(" %-12s", call->name);
|
|
||||||
for(i = 0; i < call->operands_cnt; i++)
|
|
||||||
{
|
|
||||||
ao = &call->operands[i];
|
|
||||||
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]", name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
printf("[%%%s + $0x%lx]", name,
|
|
||||||
ao->value.dregister.offset);
|
|
||||||
break;
|
|
||||||
case AOT_DREGISTER2:
|
|
||||||
name = ao->value.dregister2.name;
|
|
||||||
printf("[%%%s + %%%s]", name,
|
|
||||||
ao->value.dregister2.name2);
|
|
||||||
break;
|
|
||||||
case AOT_IMMEDIATE:
|
|
||||||
_decode_print_immediate(arch, ao);
|
|
||||||
break;
|
|
||||||
case AOT_REGISTER:
|
|
||||||
name = call->operands[i].value._register.name;
|
|
||||||
printf("%%%s", name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sep = ", ";
|
|
||||||
}
|
|
||||||
putchar('\n');
|
|
||||||
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, ArchInstructionCall ** calls,
|
||||||
|
size_t * calls_cnt, off_t offset, size_t size, off_t base)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -550,9 +479,12 @@ int arch_decode_at(Arch * arch, off_t offset, size_t size, off_t base)
|
|||||||
arch->base = base;
|
arch->base = base;
|
||||||
arch->buffer_pos = offset;
|
arch->buffer_pos = offset;
|
||||||
arch->buffer_cnt = offset + size;
|
arch->buffer_cnt = offset + size;
|
||||||
if((ret = arch_decode(arch)) == 0
|
if((ret = arch_decode(arch, calls, calls_cnt)) == 0
|
||||||
&& fseek(arch->fp, offset + size, SEEK_SET) != 0)
|
&& fseek(arch->fp, offset + size, SEEK_SET) != 0)
|
||||||
|
{
|
||||||
|
free(*calls); /* XXX the pointer was updated anyway... */
|
||||||
ret = -error_set_code(1, "%s", strerror(errno));
|
ret = -error_set_code(1, "%s", strerror(errno));
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -624,6 +556,24 @@ int arch_init_buffer(Arch * arch, char const * buffer, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* arch_read */
|
||||||
|
ssize_t arch_read(Arch * arch, void * buf, size_t size)
|
||||||
|
{
|
||||||
|
if(arch->helper.read == NULL)
|
||||||
|
return -error_set_code(1, "%s", "read: No helper defined");
|
||||||
|
return arch->helper.read(arch, buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* arch_seek */
|
||||||
|
off_t arch_seek(Arch * arch, off_t offset, int whence)
|
||||||
|
{
|
||||||
|
if(arch->helper.seek == NULL)
|
||||||
|
return -error_set_code(1, "%s", "seek: No helper defined");
|
||||||
|
return arch->helper.seek(arch, offset, whence);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* arch_write */
|
/* arch_write */
|
||||||
int arch_write(Arch * arch, ArchInstruction * instruction,
|
int arch_write(Arch * arch, ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call)
|
ArchInstructionCall * call)
|
||||||
|
@ -59,7 +59,10 @@ int arch_write(Arch * arch, ArchInstruction * instruction,
|
|||||||
ArchInstructionCall * call);
|
ArchInstructionCall * call);
|
||||||
|
|
||||||
/* disassembly */
|
/* disassembly */
|
||||||
int arch_decode(Arch * arch);
|
int arch_decode(Arch * arch, ArchInstructionCall ** calls, size_t * calls_cnt);
|
||||||
int arch_decode_at(Arch * arch, off_t offset, size_t size, off_t base);
|
int arch_decode_at(Arch * arch, ArchInstructionCall ** calls,
|
||||||
|
size_t * calls_cnt, off_t offset, size_t size, off_t base);
|
||||||
|
ssize_t arch_read(Arch * arch, void * buf, size_t cnt);
|
||||||
|
off_t arch_seek(Arch * arch, off_t offset, int whence);
|
||||||
|
|
||||||
#endif /* !ASM_ARCH_H */
|
#endif /* !ASM_ARCH_H */
|
||||||
|
138
src/code.c
138
src/code.c
@ -37,7 +37,7 @@ typedef struct _CodeString
|
|||||||
int id;
|
int id;
|
||||||
char * name;
|
char * name;
|
||||||
off_t offset;
|
off_t offset;
|
||||||
ssize_t size;
|
ssize_t length;
|
||||||
} CodeString;
|
} CodeString;
|
||||||
|
|
||||||
struct _Code
|
struct _Code
|
||||||
@ -60,9 +60,10 @@ static void _code_string_delete_all(Code * code);
|
|||||||
|
|
||||||
static CodeString * _code_string_get_by_id(Code * code, AsmId id);
|
static CodeString * _code_string_get_by_id(Code * code, AsmId id);
|
||||||
static int _code_string_set(CodeString * codestring, int id, char const * name,
|
static int _code_string_set(CodeString * codestring, int id, char const * name,
|
||||||
off_t offset, ssize_t size);
|
off_t offset, ssize_t length);
|
||||||
|
|
||||||
static CodeString * _code_string_append(Code * code);
|
static CodeString * _code_string_append(Code * code);
|
||||||
|
static int _code_string_read(Code * code, CodeString * codestring);
|
||||||
|
|
||||||
|
|
||||||
/* functions */
|
/* functions */
|
||||||
@ -146,16 +147,101 @@ int code_close(Code * code)
|
|||||||
|
|
||||||
|
|
||||||
/* code_decode */
|
/* code_decode */
|
||||||
|
static int _decode_print(Code * code, ArchInstructionCall * call);
|
||||||
|
static void _decode_print_immediate(Code * code, ArchOperand * ao);
|
||||||
|
|
||||||
int code_decode(Code * code, char const * buffer, size_t size)
|
int code_decode(Code * code, char const * buffer, size_t size)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
ArchInstructionCall * calls = NULL;
|
||||||
|
size_t calls_cnt = 0;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
arch_init_buffer(code->arch, buffer, size);
|
arch_init_buffer(code->arch, buffer, size);
|
||||||
ret = arch_decode(code->arch);
|
if((ret = arch_decode(code->arch, &calls, &calls_cnt)) == 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "DEBUG: %lu\n", calls_cnt);
|
||||||
|
for(i = 0; i < calls_cnt; i++)
|
||||||
|
_decode_print(code, &calls[i]);
|
||||||
|
free(calls);
|
||||||
|
}
|
||||||
arch_exit(code->arch);
|
arch_exit(code->arch);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _decode_print(Code * code, ArchInstructionCall * call)
|
||||||
|
{
|
||||||
|
char const * sep = " ";
|
||||||
|
size_t i;
|
||||||
|
uint8_t u8;
|
||||||
|
ArchOperand * ao;
|
||||||
|
char const * name;
|
||||||
|
|
||||||
|
if(arch_seek(code->arch, call->offset, SEEK_SET) < 0)
|
||||||
|
return -1;
|
||||||
|
printf("%8lx:", (long)call->base + (long)call->offset);
|
||||||
|
for(i = 0; i < call->size; i++)
|
||||||
|
{
|
||||||
|
if(arch_read(code->arch, &u8, sizeof(u8)) != sizeof(u8))
|
||||||
|
return -1;
|
||||||
|
printf(" %02x", u8);
|
||||||
|
}
|
||||||
|
for(; i < 8; i++)
|
||||||
|
printf(" ");
|
||||||
|
printf(" %-12s", call->name);
|
||||||
|
for(i = 0; i < call->operands_cnt; i++)
|
||||||
|
{
|
||||||
|
ao = &call->operands[i];
|
||||||
|
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]", name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf("[%%%s + $0x%lx]", name,
|
||||||
|
ao->value.dregister.offset);
|
||||||
|
break;
|
||||||
|
case AOT_DREGISTER2:
|
||||||
|
name = ao->value.dregister2.name;
|
||||||
|
printf("[%%%s + %%%s]", name,
|
||||||
|
ao->value.dregister2.name2);
|
||||||
|
break;
|
||||||
|
case AOT_IMMEDIATE:
|
||||||
|
_decode_print_immediate(code, ao);
|
||||||
|
break;
|
||||||
|
case AOT_REGISTER:
|
||||||
|
name = call->operands[i].value._register.name;
|
||||||
|
printf("%%%s", name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sep = ", ";
|
||||||
|
}
|
||||||
|
putchar('\n');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _decode_print_immediate(Code * code, ArchOperand * ao)
|
||||||
|
{
|
||||||
|
CodeString * cs;
|
||||||
|
|
||||||
|
printf("%s$0x%lx", ao->value.immediate.negative ? "-" : "",
|
||||||
|
ao->value.immediate.value);
|
||||||
|
if(AO_GET_VALUE(ao->type) == AOI_REFERS_STRING)
|
||||||
|
{
|
||||||
|
cs = _code_string_get_by_id(code, ao->value.immediate.value);
|
||||||
|
if(cs != NULL && cs->name == NULL)
|
||||||
|
_code_string_read(code, cs);
|
||||||
|
if(cs != NULL && cs->name != NULL)
|
||||||
|
printf(" \"%s\"", cs->name);
|
||||||
|
else
|
||||||
|
printf("%s", " (string)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* 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,
|
||||||
@ -185,14 +271,23 @@ 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)
|
||||||
{
|
{
|
||||||
Code * code = priv;
|
Code * code = priv;
|
||||||
|
ArchInstructionCall * calls = NULL;
|
||||||
|
size_t calls_cnt = 0;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
if(section != NULL)
|
if(section != NULL)
|
||||||
printf("%s%s:\n", "\nDisassembly of section ", section);
|
printf("%s%s:\n", "\nDisassembly of section ", section);
|
||||||
return arch_decode_at(code->arch, offset, size, base);
|
if(arch_decode_at(code->arch, &calls, &calls_cnt, offset, size, base)
|
||||||
|
!= 0)
|
||||||
|
return -1;
|
||||||
|
for(i = 0; i < calls_cnt; i++)
|
||||||
|
_decode_print(code, &calls[i]);
|
||||||
|
free(calls);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _set_string_callback(void * priv, int id, char const * name,
|
static int _set_string_callback(void * priv, int id, char const * name,
|
||||||
off_t offset, ssize_t size)
|
off_t offset, ssize_t length)
|
||||||
{
|
{
|
||||||
Code * code = priv;
|
Code * code = priv;
|
||||||
CodeString * cs = NULL;
|
CodeString * cs = NULL;
|
||||||
@ -201,7 +296,7 @@ static int _set_string_callback(void * priv, int id, char const * name,
|
|||||||
cs = _code_string_get_by_id(code, id);
|
cs = _code_string_get_by_id(code, id);
|
||||||
if(cs == NULL)
|
if(cs == NULL)
|
||||||
cs = _code_string_append(code);
|
cs = _code_string_append(code);
|
||||||
if(cs == NULL || _code_string_set(cs, id, name, offset, size) != 0)
|
if(cs == NULL || _code_string_set(cs, id, name, offset, length) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
return cs->id;
|
return cs->id;
|
||||||
}
|
}
|
||||||
@ -293,7 +388,7 @@ static CodeString * _code_string_get_by_id(Code * code, AsmId id)
|
|||||||
|
|
||||||
/* code_string_set */
|
/* code_string_set */
|
||||||
static int _code_string_set(CodeString * codestring, int id, char const * name,
|
static int _code_string_set(CodeString * codestring, int id, char const * name,
|
||||||
off_t offset, ssize_t size)
|
off_t offset, ssize_t length)
|
||||||
{
|
{
|
||||||
char * p = NULL;
|
char * p = NULL;
|
||||||
|
|
||||||
@ -303,7 +398,7 @@ static int _code_string_set(CodeString * codestring, int id, char const * name,
|
|||||||
free(codestring->name);
|
free(codestring->name);
|
||||||
codestring->name = p;
|
codestring->name = p;
|
||||||
codestring->offset = offset;
|
codestring->offset = offset;
|
||||||
codestring->size = size;
|
codestring->length = length;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,6 +419,31 @@ static CodeString * _code_string_append(Code * code)
|
|||||||
p->id = -1;
|
p->id = -1;
|
||||||
p->name = NULL;
|
p->name = NULL;
|
||||||
p->offset = -1;
|
p->offset = -1;
|
||||||
p->size = -1;
|
p->length = -1;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* code_string_read */
|
||||||
|
static int _code_string_read(Code * code, CodeString * codestring)
|
||||||
|
{
|
||||||
|
char * buf;
|
||||||
|
|
||||||
|
if(codestring->offset < 0 || codestring->length < 0)
|
||||||
|
return -error_set_code(1, "%s", "Insufficient information to"
|
||||||
|
" read string");
|
||||||
|
if(arch_seek(code->arch, codestring->offset, SEEK_SET)
|
||||||
|
!= codestring->offset)
|
||||||
|
return -1;
|
||||||
|
if((buf = malloc(codestring->length + 1)) == NULL)
|
||||||
|
return -error_set_code(1, "%s", strerror(errno));
|
||||||
|
if(arch_read(code->arch, buf, codestring->length) != codestring->length)
|
||||||
|
{
|
||||||
|
free(buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
buf[codestring->length] = '\0';
|
||||||
|
free(codestring->name);
|
||||||
|
codestring->name = buf;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
typedef int (*FormatDecodeCallback)(void * priv, char const * section,
|
typedef int (*FormatDecodeCallback)(void * priv, char const * section,
|
||||||
off_t offset, size_t size, off_t base);
|
off_t offset, size_t size, off_t base);
|
||||||
typedef int (*FormatSetStringCallback)(void * priv, int id, char const * name,
|
typedef int (*FormatSetStringCallback)(void * priv, int id, char const * name,
|
||||||
off_t offset, ssize_t size);
|
off_t offset, ssize_t length);
|
||||||
|
|
||||||
/* functions */
|
/* functions */
|
||||||
Format * format_new(char const * format, char const * arch);
|
Format * format_new(char const * format, char const * arch);
|
||||||
|
@ -101,10 +101,6 @@ typedef struct _DexString
|
|||||||
char * string;
|
char * string;
|
||||||
} DexString;
|
} DexString;
|
||||||
|
|
||||||
typedef struct _Dex
|
|
||||||
{
|
|
||||||
} Dex;
|
|
||||||
|
|
||||||
|
|
||||||
/* variables */
|
/* variables */
|
||||||
static char _dex_signature[4] = "dex\n";
|
static char _dex_signature[4] = "dex\n";
|
||||||
@ -113,12 +109,9 @@ static char _dex_signature[4] = "dex\n";
|
|||||||
/* prototypes */
|
/* prototypes */
|
||||||
/* plug-in */
|
/* plug-in */
|
||||||
static int _dex_init(FormatPlugin * format, char const * arch);
|
static int _dex_init(FormatPlugin * format, char const * arch);
|
||||||
static int _dex_destroy(FormatPlugin * format);
|
|
||||||
static char const * _dex_detect(FormatPlugin * format);
|
static char const * _dex_detect(FormatPlugin * format);
|
||||||
static int _dex_decode(FormatPlugin * format);
|
static int _dex_decode(FormatPlugin * format);
|
||||||
|
|
||||||
static int _dex_error(FormatPlugin * format);
|
|
||||||
|
|
||||||
|
|
||||||
/* public */
|
/* public */
|
||||||
/* variables */
|
/* variables */
|
||||||
@ -129,7 +122,7 @@ FormatPlugin format_plugin =
|
|||||||
_dex_signature,
|
_dex_signature,
|
||||||
sizeof(_dex_signature),
|
sizeof(_dex_signature),
|
||||||
_dex_init,
|
_dex_init,
|
||||||
_dex_destroy,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
_dex_detect,
|
_dex_detect,
|
||||||
@ -144,28 +137,12 @@ FormatPlugin format_plugin =
|
|||||||
/* dex_init */
|
/* dex_init */
|
||||||
static int _dex_init(FormatPlugin * format, char const * arch)
|
static int _dex_init(FormatPlugin * format, char const * arch)
|
||||||
{
|
{
|
||||||
Dex * dex;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, arch);
|
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, arch);
|
||||||
#endif
|
#endif
|
||||||
if(arch != NULL && strcmp(arch, "dalvik") != 0)
|
if(arch != NULL && strcmp(arch, "dalvik") != 0)
|
||||||
return -error_set_code(1, "%s: %s", arch,
|
return -error_set_code(1, "%s: %s", arch,
|
||||||
"Unsupported Dex architecture");
|
"Unsupported Dex architecture");
|
||||||
if((dex = object_new(sizeof(*dex))) == NULL)
|
|
||||||
return -1;
|
|
||||||
format->priv = dex;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* dex_destroy */
|
|
||||||
static int _dex_destroy(FormatPlugin * format)
|
|
||||||
{
|
|
||||||
Dex * dex = format->priv;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
object_delete(dex);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,10 +290,10 @@ static int _decode_map_string_id(FormatPlugin * format, off_t offset,
|
|||||||
size_t size)
|
size_t size)
|
||||||
{
|
{
|
||||||
FormatPluginHelper * helper = format->helper;
|
FormatPluginHelper * helper = format->helper;
|
||||||
Dex * dex = format->priv;
|
|
||||||
size_t i;
|
size_t i;
|
||||||
DexStringIdItem * dsii;
|
DexStringIdItem * dsii;
|
||||||
ssize_t s;
|
ssize_t s;
|
||||||
|
uint8_t u8;
|
||||||
|
|
||||||
if(helper->seek(helper->format, offset, SEEK_SET) != offset)
|
if(helper->seek(helper->format, offset, SEEK_SET) != offset)
|
||||||
return -1;
|
return -1;
|
||||||
@ -328,22 +305,16 @@ static int _decode_map_string_id(FormatPlugin * format, off_t offset,
|
|||||||
for(i = 0; i < size; i++)
|
for(i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
dsii[i].string_data_off = _htol32(dsii[i].string_data_off);
|
dsii[i].string_data_off = _htol32(dsii[i].string_data_off);
|
||||||
#if 1 /* def DEBUG */
|
offset = dsii[i].string_data_off;
|
||||||
fprintf(stderr, "DEBUG: %s() string %lu offset 0x%x\n",
|
if(helper->seek(helper->format, offset, SEEK_SET) != offset)
|
||||||
__func__, i, dsii[i].string_data_off);
|
return -1;
|
||||||
|
if(helper->read(helper->format, &u8, sizeof(u8)) != sizeof(u8))
|
||||||
|
return -1;
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "DEBUG: %s() string %lu offset 0x%x len %u\n",
|
||||||
|
__func__, i, offset, u8);
|
||||||
#endif
|
#endif
|
||||||
helper->set_string(helper->format, i, NULL,
|
helper->set_string(helper->format, i, NULL, offset + 1, u8);
|
||||||
dsii[i].string_data_off, -1);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* dex_error */
|
|
||||||
static int _dex_error(FormatPlugin * format)
|
|
||||||
{
|
|
||||||
FormatPluginHelper * helper = format->helper;
|
|
||||||
|
|
||||||
return -error_set_code(1, "%s: %s",
|
|
||||||
helper->get_filename(helper->format), strerror(errno));
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user