This commit is contained in:
parent
ec6a52e8a9
commit
89e1618e3c
|
@ -1083,7 +1083,7 @@ static VariableLocation *parse_dwarf_location (Context *ctx, const RBinDwarfAttr
|
|||
/* I need to find binaries that uses this so I can test it out*/
|
||||
const ut8 *buffer = &block.data[++i];
|
||||
const ut8 *buf_end = &block.data[block.length];
|
||||
buffer = r_uleb128 (buffer, buf_end - buffer, ®_num);
|
||||
buffer = r_uleb128 (buffer, buf_end - buffer, ®_num, NULL);
|
||||
if (buffer == buf_end) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -480,17 +480,17 @@ static const ut8 *parse_line_header_source(RBinFile *bf, const ut8 *buf, const u
|
|||
buf = NULL;
|
||||
goto beach;
|
||||
}
|
||||
buf = r_uleb128 (buf, buf_end - buf, &id_idx);
|
||||
buf = r_uleb128 (buf, buf_end - buf, &id_idx, NULL);
|
||||
if (buf >= buf_end) {
|
||||
buf = NULL;
|
||||
goto beach;
|
||||
}
|
||||
buf = r_uleb128 (buf, buf_end - buf, &mod_time);
|
||||
buf = r_uleb128 (buf, buf_end - buf, &mod_time, NULL);
|
||||
if (buf >= buf_end) {
|
||||
buf = NULL;
|
||||
goto beach;
|
||||
}
|
||||
buf = r_uleb128 (buf, buf_end - buf, &file_len);
|
||||
buf = r_uleb128 (buf, buf_end - buf, &file_len, NULL);
|
||||
if (buf >= buf_end) {
|
||||
buf = NULL;
|
||||
goto beach;
|
||||
|
@ -779,17 +779,17 @@ static const ut8 *parse_ext_opcode(const RBin *bin, const ut8 *obuf,
|
|||
ut64 dir_idx;
|
||||
ut64 ignore;
|
||||
if (buf + 1 < buf_end) {
|
||||
buf = r_uleb128 (buf, buf_end - buf, &dir_idx);
|
||||
buf = r_uleb128 (buf, buf_end - buf, &dir_idx, NULL);
|
||||
}
|
||||
if (buf + 1 < buf_end) {
|
||||
buf = r_uleb128 (buf, buf_end - buf, &ignore);
|
||||
buf = r_uleb128 (buf, buf_end - buf, &ignore, NULL);
|
||||
}
|
||||
if (buf + 1 < buf_end) {
|
||||
buf = r_uleb128 (buf, buf_end - buf, &ignore);
|
||||
buf = r_uleb128 (buf, buf_end - buf, &ignore, NULL);
|
||||
}
|
||||
break;
|
||||
case DW_LNE_set_discriminator:
|
||||
buf = r_uleb128 (buf, buf_end - buf, &addr);
|
||||
buf = r_uleb128 (buf, buf_end - buf, &addr, NULL);
|
||||
if (mode == R_MODE_PRINT) {
|
||||
print ("set Discriminator to %"PFMT64d"\n", addr);
|
||||
}
|
||||
|
@ -887,7 +887,7 @@ static const ut8 *parse_std_opcode(
|
|||
regs->basic_block = DWARF_FALSE;
|
||||
break;
|
||||
case DW_LNS_advance_pc:
|
||||
buf = r_uleb128 (buf, buf_end - buf, &addr);
|
||||
buf = r_uleb128 (buf, buf_end - buf, &addr, NULL);
|
||||
regs->address += addr * hdr->min_inst_len;
|
||||
if (mode == R_MODE_PRINT) {
|
||||
print ("Advance PC by %"PFMT64d" to 0x%"PFMT64x"\n",
|
||||
|
@ -902,14 +902,14 @@ static const ut8 *parse_std_opcode(
|
|||
}
|
||||
break;
|
||||
case DW_LNS_set_file:
|
||||
buf = r_uleb128 (buf, buf_end - buf, &addr);
|
||||
buf = r_uleb128 (buf, buf_end - buf, &addr, NULL);
|
||||
if (mode == R_MODE_PRINT) {
|
||||
print ("Set file to %"PFMT64d"\n", addr);
|
||||
}
|
||||
regs->file = addr;
|
||||
break;
|
||||
case DW_LNS_set_column:
|
||||
buf = r_uleb128 (buf, buf_end - buf, &addr);
|
||||
buf = r_uleb128 (buf, buf_end - buf, &addr, NULL);
|
||||
if (mode == R_MODE_PRINT) {
|
||||
print ("Set column to %"PFMT64d"\n", addr);
|
||||
}
|
||||
|
@ -960,7 +960,7 @@ static const ut8 *parse_std_opcode(
|
|||
}
|
||||
break;
|
||||
case DW_LNS_set_isa:
|
||||
buf = r_uleb128 (buf, buf_end - buf, &addr);
|
||||
buf = r_uleb128 (buf, buf_end - buf, &addr, NULL);
|
||||
regs->isa = addr;
|
||||
if (mode == R_MODE_PRINT) {
|
||||
print ("set_isa\n");
|
||||
|
@ -1654,7 +1654,7 @@ static const ut8 *parse_attr_value(const ut8 *obuf, int obuf_len,
|
|||
break;
|
||||
case DW_FORM_udata:
|
||||
value->kind = DW_AT_KIND_CONSTANT;
|
||||
buf = r_uleb128 (buf, buf_end - buf, &value->uconstant);
|
||||
buf = r_uleb128 (buf, buf_end - buf, &value->uconstant, NULL);
|
||||
break;
|
||||
case DW_FORM_string:
|
||||
value->kind = DW_AT_KIND_STRING;
|
||||
|
@ -1686,7 +1686,7 @@ static const ut8 *parse_attr_value(const ut8 *obuf, int obuf_len,
|
|||
break;
|
||||
case DW_FORM_block: // variable length ULEB128
|
||||
value->kind = DW_AT_KIND_BLOCK;
|
||||
buf = r_uleb128 (buf, buf_end - buf, &value->block.length);
|
||||
buf = r_uleb128 (buf, buf_end - buf, &value->block.length, NULL);
|
||||
if (!buf || buf >= buf_end) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1733,7 +1733,7 @@ static const ut8 *parse_attr_value(const ut8 *obuf, int obuf_len,
|
|||
case DW_FORM_ref_udata:
|
||||
value->kind = DW_AT_KIND_REFERENCE;
|
||||
// uleb128 is enough to fit into ut64?
|
||||
buf = r_uleb128 (buf, buf_end - buf, &value->reference);
|
||||
buf = r_uleb128 (buf, buf_end - buf, &value->reference, NULL);
|
||||
value->reference += hdr->unit_offset;
|
||||
break;
|
||||
// offset in a section other than .debug_info or .debug_str
|
||||
|
@ -1743,7 +1743,7 @@ static const ut8 *parse_attr_value(const ut8 *obuf, int obuf_len,
|
|||
break;
|
||||
case DW_FORM_exprloc:
|
||||
value->kind = DW_AT_KIND_BLOCK;
|
||||
buf = r_uleb128 (buf, buf_end - buf, &value->block.length);
|
||||
buf = r_uleb128 (buf, buf_end - buf, &value->block.length, NULL);
|
||||
if (!buf || buf >= buf_end) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1794,7 +1794,7 @@ static const ut8 *parse_attr_value(const ut8 *obuf, int obuf_len,
|
|||
index into an array of addresses in the .debug_addr section.*/
|
||||
case DW_FORM_addrx:
|
||||
value->kind = DW_AT_KIND_ADDRESS;
|
||||
buf = r_uleb128 (buf, buf_end - buf, &value->address);
|
||||
buf = r_uleb128 (buf, buf_end - buf, &value->address, NULL);
|
||||
break;
|
||||
case DW_FORM_addrx1:
|
||||
value->kind = DW_AT_KIND_ADDRESS;
|
||||
|
@ -1838,7 +1838,7 @@ static const ut8 *parse_attr_value(const ut8 *obuf, int obuf_len,
|
|||
// An index into the .debug_rnglists
|
||||
case DW_FORM_rnglistx:
|
||||
value->kind = DW_AT_KIND_ADDRESS;
|
||||
buf = r_uleb128 (buf, buf_end - buf, &value->address);
|
||||
buf = r_uleb128 (buf, buf_end - buf, &value->address, NULL);
|
||||
break;
|
||||
default:
|
||||
eprintf ("Unknown DW_FORM 0x%02" PFMT64x "\n", def->attr_form);
|
||||
|
@ -1919,7 +1919,7 @@ static const ut8 *parse_comp_unit(RBinDwarfDebugInfo *info, Sdb *sdb, const ut8
|
|||
|
||||
// DIE starts with ULEB128 with the abbreviation code
|
||||
ut64 abbr_code;
|
||||
buf = r_uleb128 (buf, buf_end - buf, &abbr_code);
|
||||
buf = r_uleb128 (buf, buf_end - buf, &abbr_code, NULL);
|
||||
|
||||
if (abbr_code > abbrevs->count || !buf) { // something invalid
|
||||
return NULL;
|
||||
|
@ -2114,7 +2114,7 @@ static RBinDwarfDebugAbbrev *parse_abbrev_raw(const ut8 *obuf, size_t len) {
|
|||
|
||||
while (buf && buf+1 < buf_end) {
|
||||
offset = buf - obuf;
|
||||
buf = r_uleb128 (buf, (size_t)(buf_end-buf), &tmp);
|
||||
buf = r_uleb128 (buf, (size_t)(buf_end-buf), &tmp, NULL);
|
||||
if (!buf || !tmp || buf >= buf_end) {
|
||||
continue;
|
||||
}
|
||||
|
@ -2125,7 +2125,7 @@ static RBinDwarfDebugAbbrev *parse_abbrev_raw(const ut8 *obuf, size_t len) {
|
|||
init_abbrev_decl (tmpdecl);
|
||||
|
||||
tmpdecl->code = tmp;
|
||||
buf = r_uleb128 (buf, (size_t)(buf_end-buf), &tmp);
|
||||
buf = r_uleb128 (buf, (size_t)(buf_end-buf), &tmp, NULL);
|
||||
tmpdecl->tag = tmp;
|
||||
|
||||
tmpdecl->offset = offset;
|
||||
|
@ -2138,11 +2138,11 @@ static RBinDwarfDebugAbbrev *parse_abbrev_raw(const ut8 *obuf, size_t len) {
|
|||
if (tmpdecl->count == tmpdecl->capacity) {
|
||||
expand_abbrev_decl (tmpdecl);
|
||||
}
|
||||
buf = r_uleb128 (buf, (size_t)(buf_end - buf), &attr_code);
|
||||
buf = r_uleb128 (buf, (size_t)(buf_end - buf), &attr_code, NULL);
|
||||
if (buf >= buf_end) {
|
||||
break;
|
||||
}
|
||||
buf = r_uleb128 (buf, (size_t)(buf_end - buf), &attr_form);
|
||||
buf = r_uleb128 (buf, (size_t)(buf_end - buf), &attr_form, NULL);
|
||||
// http://www.dwarfstd.org/doc/DWARF5.pdf#page=225
|
||||
if (attr_form == DW_FORM_implicit_const) {
|
||||
buf = r_leb128 (buf, (size_t)(buf_end - buf), &special);
|
||||
|
|
|
@ -10,10 +10,6 @@
|
|||
#define bprintf if (bin->verbose) eprintf
|
||||
#define Eprintf if (mo->verbose) eprintf
|
||||
|
||||
typedef struct _ulebr {
|
||||
ut8 *p;
|
||||
} ulebr;
|
||||
|
||||
typedef struct {
|
||||
struct symbol_t *symbols;
|
||||
int j;
|
||||
|
@ -34,54 +30,16 @@ typedef struct {
|
|||
// USE THIS: int ws = bf->o->info->big_endian;
|
||||
#define mach0_endian 1
|
||||
|
||||
// TODO: Use the implementation from RUtil
|
||||
static ut64 read_uleb128(ulebr *r, ut8 *end) {
|
||||
ut64 result = 0;
|
||||
int bit = 0;
|
||||
ut64 slice = 0;
|
||||
ut8 *p = r->p;
|
||||
do {
|
||||
if (p == end) {
|
||||
eprintf ("malformed uleb128\n");
|
||||
return UT64_MAX;
|
||||
}
|
||||
slice = *p & 0x7f;
|
||||
if (bit > 63) {
|
||||
eprintf ("uleb128 too big for uint64, bit=%d, result=0x%"PFMT64x"\n", bit, result);
|
||||
return UT64_MAX;
|
||||
} else {
|
||||
result |= (slice << bit);
|
||||
bit += 7;
|
||||
}
|
||||
} while (*p++ & 0x80);
|
||||
r->p = p;
|
||||
return result;
|
||||
}
|
||||
|
||||
static st64 read_sleb128(ulebr *r, ut8 *end) {
|
||||
st64 result = 0;
|
||||
int bit = 0;
|
||||
ut8 byte = 0;
|
||||
ut8 *p = r->p;
|
||||
do {
|
||||
if (p == end) {
|
||||
eprintf ("malformed sleb128\n");
|
||||
break;
|
||||
}
|
||||
byte = *p++;
|
||||
result |= (((st64)(byte & 0x7f)) << bit);
|
||||
bit += 7;
|
||||
if (bit > 63) {
|
||||
eprintf ("too large sleb128 shift\n");
|
||||
return result;
|
||||
}
|
||||
} while (byte & 0x80);
|
||||
// sign extend negative numbers
|
||||
if ((byte & 0x40)) {
|
||||
result |= (-1LL) << bit;
|
||||
static ut64 read_uleb128(ut8 **p, ut8 *end) {
|
||||
const char *error = NULL;
|
||||
ut64 v;
|
||||
*p = (ut8 *)r_uleb128 (*p, end - *p, &v, &error);
|
||||
if (error) {
|
||||
eprintf (error);
|
||||
R_FREE (error);
|
||||
return UT64_MAX;
|
||||
}
|
||||
r->p = p;
|
||||
return result;
|
||||
return v;
|
||||
}
|
||||
|
||||
static ut64 entry_to_vaddr(struct MACH0_(obj_t) *bin) {
|
||||
|
@ -1588,7 +1546,7 @@ static bool reconstruct_chained_fixup(struct MACH0_(obj_t) *bin) {
|
|||
return false;
|
||||
}
|
||||
size_t wordsize = get_word_size (bin);
|
||||
ulebr ur = {NULL};
|
||||
ut8 *p = NULL;
|
||||
size_t j, count, skip, bind_size;
|
||||
int seg_idx = 0;
|
||||
ut64 seg_off = 0;
|
||||
|
@ -1615,9 +1573,9 @@ static bool reconstruct_chained_fixup(struct MACH0_(obj_t) *bin) {
|
|||
size_t cur_seg_idx = 0;
|
||||
ut8 *end;
|
||||
bool done = false;
|
||||
for (ur.p = opcodes, end = opcodes + bind_size; !done && ur.p < end;) {
|
||||
ut8 imm = *ur.p & BIND_IMMEDIATE_MASK, op = *ur.p & BIND_OPCODE_MASK;
|
||||
ur.p++;
|
||||
for (p = opcodes, end = opcodes + bind_size; !done && p < end;) {
|
||||
ut8 imm = *p & BIND_IMMEDIATE_MASK, op = *p & BIND_OPCODE_MASK;
|
||||
p++;
|
||||
switch (op) {
|
||||
case BIND_OPCODE_DONE:
|
||||
done = true;
|
||||
|
@ -1625,7 +1583,7 @@ static bool reconstruct_chained_fixup(struct MACH0_(obj_t) *bin) {
|
|||
case BIND_OPCODE_THREADED: {
|
||||
switch (imm) {
|
||||
case BIND_SUBOPCODE_THREADED_SET_BIND_ORDINAL_TABLE_SIZE_ULEB: {
|
||||
read_uleb128 (&ur, end);
|
||||
read_uleb128 (&p, end);
|
||||
break;
|
||||
}
|
||||
case BIND_SUBOPCODE_THREADED_APPLY: {
|
||||
|
@ -1670,15 +1628,15 @@ static bool reconstruct_chained_fixup(struct MACH0_(obj_t) *bin) {
|
|||
case BIND_OPCODE_SET_TYPE_IMM:
|
||||
break;
|
||||
case BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
|
||||
read_uleb128 (&ur, end);
|
||||
read_uleb128 (&p, end);
|
||||
break;
|
||||
case BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
|
||||
while (*ur.p++ && ur.p < end) {
|
||||
while (*p++ && p < end) {
|
||||
/* empty loop */
|
||||
}
|
||||
break;
|
||||
case BIND_OPCODE_SET_ADDEND_SLEB:
|
||||
read_sleb128 (&ur, end);
|
||||
r_sleb128 ((const ut8 **)&p, end);
|
||||
break;
|
||||
case BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
|
||||
seg_idx = imm;
|
||||
|
@ -1688,29 +1646,29 @@ static bool reconstruct_chained_fixup(struct MACH0_(obj_t) *bin) {
|
|||
R_FREE (opcodes);
|
||||
return false;
|
||||
} else {
|
||||
seg_off = read_uleb128 (&ur, end);
|
||||
seg_off = read_uleb128 (&p, end);
|
||||
}
|
||||
break;
|
||||
case BIND_OPCODE_ADD_ADDR_ULEB:
|
||||
seg_off += read_uleb128 (&ur, end);
|
||||
seg_off += read_uleb128 (&p, end);
|
||||
break;
|
||||
case BIND_OPCODE_DO_BIND:
|
||||
break;
|
||||
case BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
|
||||
seg_off += read_uleb128 (&ur, end) + wordsize;
|
||||
seg_off += read_uleb128 (&p, end) + wordsize;
|
||||
break;
|
||||
case BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
|
||||
seg_off += (ut64)imm * (ut64)wordsize + wordsize;
|
||||
break;
|
||||
case BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
|
||||
count = read_uleb128 (&ur, end);
|
||||
skip = read_uleb128 (&ur, end);
|
||||
count = read_uleb128 (&p, end);
|
||||
skip = read_uleb128 (&p, end);
|
||||
for (j = 0; j < count; j++) {
|
||||
seg_off += skip + wordsize;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
bprintf ("Error: unknown bind opcode 0x%02x in dyld_info\n", *ur.p);
|
||||
bprintf ("Error: unknown bind opcode 0x%02x in dyld_info\n", *p);
|
||||
R_FREE (opcodes);
|
||||
return false;
|
||||
}
|
||||
|
@ -2507,14 +2465,14 @@ static char *get_name(struct MACH0_(obj_t) *mo, ut32 stridx, bool filter) {
|
|||
}
|
||||
|
||||
static int walk_exports(struct MACH0_(obj_t) *bin, RExportsIterator iterator, void * ctx) {
|
||||
#define ULEB(at) read_uleb128 (&ur, end)
|
||||
#define ULEB(at) read_uleb128 (&p, end)
|
||||
r_return_val_if_fail (bin, 0);
|
||||
if (!bin->dyld_info) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t count = 0;
|
||||
ulebr ur = {NULL};
|
||||
ut8 *p = NULL;
|
||||
ut8 * trie = NULL;
|
||||
RList * states = NULL;
|
||||
ut64 size = bin->dyld_info->export_size;
|
||||
|
@ -2547,7 +2505,7 @@ static int walk_exports(struct MACH0_(obj_t) *bin, RExportsIterator iterator, vo
|
|||
|
||||
do {
|
||||
RTrieState * state = r_list_get_top (states);
|
||||
ur.p = state->node;
|
||||
p = state->node;
|
||||
ut64 len = ULEB ();
|
||||
if (len == UT64_MAX) {
|
||||
break;
|
||||
|
@ -2571,7 +2529,7 @@ static int walk_exports(struct MACH0_(obj_t) *bin, RExportsIterator iterator, vo
|
|||
}
|
||||
resolver = res + bin->header_at;
|
||||
} else if (isReexport) {
|
||||
ur.p += strlen ((char*) ur.p) + 1;
|
||||
p += strlen ((char*) p) + 1;
|
||||
// TODO: handle this
|
||||
}
|
||||
if (!isReexport) {
|
||||
|
@ -2617,17 +2575,17 @@ static int walk_exports(struct MACH0_(obj_t) *bin, RExportsIterator iterator, vo
|
|||
continue;
|
||||
}
|
||||
if (!state->next_child) {
|
||||
state->next_child = ur.p;
|
||||
state->next_child = p;
|
||||
} else {
|
||||
ur.p = state->next_child;
|
||||
p = state->next_child;
|
||||
}
|
||||
RTrieState * next = R_NEW0 (RTrieState);
|
||||
if (!next) {
|
||||
goto beach;
|
||||
}
|
||||
next->label = (char *) ur.p;
|
||||
ur.p += strlen (next->label) + 1;
|
||||
if (ur.p >= end) {
|
||||
next->label = (char *) p;
|
||||
p += strlen (next->label) + 1;
|
||||
if (p >= end) {
|
||||
eprintf ("malformed export trie\n");
|
||||
R_FREE (next);
|
||||
goto beach;
|
||||
|
@ -2656,7 +2614,7 @@ static int walk_exports(struct MACH0_(obj_t) *bin, RExportsIterator iterator, vo
|
|||
}
|
||||
next->i = 0;
|
||||
state->i++;
|
||||
state->next_child = ur.p;
|
||||
state->next_child = p;
|
||||
r_list_push (states, next);
|
||||
} while (r_list_length (states));
|
||||
#undef ULEB
|
||||
|
@ -3298,16 +3256,16 @@ RSkipList *MACH0_(get_relocs)(struct MACH0_(obj_t) *bin) {
|
|||
ut64 addr = bin->segs[0].vmaddr;
|
||||
ut64 segment_end_addr = addr + bin->segs[0].vmsize;
|
||||
|
||||
ulebr ur = {opcodes + opcodes_offset};
|
||||
ut8 *end = ur.p + partition_size;
|
||||
ut8 *p = opcodes + opcodes_offset;
|
||||
ut8 *end = p + partition_size;
|
||||
bool done = false;
|
||||
while (!done && ur.p < end) {
|
||||
ut8 imm = *ur.p & BIND_IMMEDIATE_MASK;
|
||||
ut8 op = *ur.p & BIND_OPCODE_MASK;
|
||||
ur.p++;
|
||||
while (!done && p < end) {
|
||||
ut8 imm = *p & BIND_IMMEDIATE_MASK;
|
||||
ut8 op = *p & BIND_OPCODE_MASK;
|
||||
p++;
|
||||
switch (op) {
|
||||
#define ULEB() read_uleb128 (&ur, end)
|
||||
#define SLEB() read_sleb128 (&ur, end)
|
||||
#define ULEB() read_uleb128 (&p, end)
|
||||
#define SLEB() r_sleb128 ((const ut8 **)&p, end)
|
||||
case BIND_OPCODE_DONE: {
|
||||
bool in_lazy_binds = pidx == 1;
|
||||
if (!in_lazy_binds) {
|
||||
|
@ -3414,8 +3372,8 @@ RSkipList *MACH0_(get_relocs)(struct MACH0_(obj_t) *bin) {
|
|||
lib_ord = imm? (st8)(BIND_OPCODE_MASK | imm) : 0;
|
||||
break;
|
||||
case BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: {
|
||||
sym_name = (char*)ur.p;
|
||||
while (*ur.p++ && ur.p < end) {
|
||||
sym_name = (char*)p;
|
||||
while (*p++ && p < end) {
|
||||
/* empty loop */
|
||||
}
|
||||
if (threaded_binds) {
|
||||
|
@ -3541,7 +3499,7 @@ RSkipList *MACH0_(get_relocs)(struct MACH0_(obj_t) *bin) {
|
|||
#undef ULEB
|
||||
#undef SLEB
|
||||
default:
|
||||
bprintf ("Error: unknown bind opcode 0x%02x in dyld_info\n", *ur.p);
|
||||
bprintf ("Error: unknown bind opcode 0x%02x in dyld_info\n", *p);
|
||||
R_FREE (opcodes);
|
||||
r_pvector_free (threaded_binds);
|
||||
return relocs;
|
||||
|
|
|
@ -97,7 +97,7 @@ static const char *getstr(RBinDexObj *dex, int idx) {
|
|||
return NULL;
|
||||
}
|
||||
ut64 len;
|
||||
int uleblen = r_uleb128 (buf, sizeof (buf), &len) - buf;
|
||||
int uleblen = r_uleb128 (buf, sizeof (buf), &len, NULL) - buf;
|
||||
if (!uleblen || uleblen >= dex->size || uleblen >= dex->header.strings_size) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -854,7 +854,7 @@ static RList *strings(RBinFile *bf) {
|
|||
goto out_error;
|
||||
}
|
||||
r_buf_read_at (bin->b, bin->strings[i], buf, sizeof (buf));
|
||||
r_uleb128 (buf, sizeof (buf), &len);
|
||||
r_uleb128 (buf, sizeof (buf), &len, NULL);
|
||||
|
||||
if (len > 5 && len < R_BIN_SIZEOF_STRINGS) {
|
||||
ptr->string = malloc (len + 1);
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
// compression used to store an arbitrarily large integer in a small number of
|
||||
// bytes. LEB128 is used in the DWARF debug file format.
|
||||
|
||||
R_API const ut8 *r_uleb128(const ut8 *data, int datalen, ut64 *v);
|
||||
R_API const ut8 *r_uleb128(const ut8 *data, int datalen, ut64 *v, const char **error);
|
||||
R_API const ut8 *r_uleb128_decode(const ut8 *data, int *datalen, ut64 *v);
|
||||
R_API int r_uleb128_len (const ut8 *data, int size);
|
||||
R_API int r_uleb128_len(const ut8 *data, int size);
|
||||
R_API ut8 *r_uleb128_encode(const ut64 s, int *len);
|
||||
R_API const ut8 *r_leb128(const ut8 *data, int datalen, st64 *v);
|
||||
R_API st64 r_sleb128(const ut8 **data, const ut8 *end);
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
/* radare - LGPL - Copyright 2014-2015 - pancake */
|
||||
|
||||
#include "r_util/r_str.h"
|
||||
#include <r_util.h>
|
||||
|
||||
/* dex/dwarf uleb128 implementation */
|
||||
|
||||
R_API const ut8 *r_uleb128(const ut8 *data, int datalen, ut64 *v) {
|
||||
R_API const ut8 *r_uleb128(const ut8 *data, int datalen, ut64 *v, const char **error) {
|
||||
ut8 c;
|
||||
ut64 s, sum = 0;
|
||||
const ut8 *data_end;
|
||||
bool malformed_uleb = true;
|
||||
if (v) {
|
||||
*v = 0LL;
|
||||
}
|
||||
|
@ -24,14 +26,23 @@ R_API const ut8 *r_uleb128(const ut8 *data, int datalen, ut64 *v) {
|
|||
for (s = 0; data < data_end; s += 7) {
|
||||
c = *(data++) & 0xff;
|
||||
if (s > 63) {
|
||||
eprintf ("r_uleb128: undefined behaviour in %d shift on ut32\n", (int)s);
|
||||
if (error) {
|
||||
*error = r_str_newf ("r_uleb128: undefined behaviour in %d shift on ut32\n", (int)s);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
sum |= ((ut64) (c & 0x7f) << s);
|
||||
}
|
||||
if (!(c & 0x80)) {
|
||||
malformed_uleb = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (malformed_uleb) {
|
||||
if (error) {
|
||||
*error = r_str_newf ("malformed uleb128\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
data++;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
NAME=macho trie malformed uleb128
|
||||
FILE=bins/mach0/macho-trie-bad-export-info-malformed-uleb128
|
||||
CMDS=<<EOF
|
||||
EOF
|
||||
EXPECT_ERR=<<EOF
|
||||
malformed uleb128
|
||||
malformed uleb128
|
||||
EOF
|
||||
RUN
|
|
@ -10,7 +10,7 @@ bool test_uleb128_small(void) {
|
|||
mu_assert_memeq (data, (ut8 *)"\xef\xfd\x02", 3, "right bytes");
|
||||
|
||||
ut64 val;
|
||||
r_uleb128 (data, len, &val);
|
||||
r_uleb128 (data, len, &val, NULL);
|
||||
mu_assert_eq (val, 0xbeef, "uleb128 decoded");
|
||||
|
||||
r_uleb128_decode (data, &len, &val);
|
||||
|
@ -47,7 +47,7 @@ bool test_uleb128_big(void) {
|
|||
mu_assert_memeq (data, (ut8 *)"\xa3\xe0\xd4\xb9\xbf\x86\x02", 7, "right bytes");
|
||||
|
||||
ut64 val;
|
||||
r_uleb128 (data, len, &val);
|
||||
r_uleb128 (data, len, &val, NULL);
|
||||
mu_assert_eq (val, 9019283812387, "uleb128 decoded");
|
||||
|
||||
r_uleb128_decode (data, &len, &val);
|
||||
|
|
Loading…
Reference in New Issue