mirror of
https://github.com/radareorg/radare2.git
synced 2025-01-09 06:50:49 +00:00
RBin: fix PE and ELF versioninfo
PE parser is now able to get the StringTable value even if the wValueLength of the structure is incorrect. Fix a regression with ELF versioninfo.
This commit is contained in:
parent
76fa5bddcf
commit
10de21de7e
@ -449,13 +449,16 @@ static Sdb *store_versioninfo_gnu_versym(struct Elf_(r_bin_elf_obj_t) *bin, Elf_
|
||||
ut64 offset = Elf_(r_bin_elf_v2p) (bin, bin->version_info[DT_VERSIONTAGIDX (DT_VERNEED)]);
|
||||
do {
|
||||
Elf_(Vernaux) vna;
|
||||
ut64 a_off = offset + vn.vn_aux;
|
||||
ut64 a_off;
|
||||
|
||||
if (offset > bin->size || offset + sizeof (vn) > bin->size)
|
||||
goto beach;
|
||||
if (r_buf_read_at (bin->b, offset, (ut8*)&vn, sizeof (vn)) < 0) {
|
||||
eprintf ("Warning: Cannot read Verneed for Versym\n");
|
||||
goto beach;
|
||||
}
|
||||
|
||||
a_off = offset + vn.vn_aux;
|
||||
do {
|
||||
if (a_off > bin->size || a_off + sizeof (vna) > bin->size)
|
||||
goto beach;
|
||||
@ -469,6 +472,7 @@ static Sdb *store_versioninfo_gnu_versym(struct Elf_(r_bin_elf_obj_t) *bin, Elf_
|
||||
if (vna.vna_other == data[i + j]) {
|
||||
if (vna.vna_name > bin->strtab_size)
|
||||
goto beach;
|
||||
|
||||
sdb_set (sdb_entry, key, sdb_fmt (0, "%s(%s)", tmp_val, bin->strtab + vna.vna_name), 0);
|
||||
check_def = false;
|
||||
break;
|
||||
@ -482,8 +486,10 @@ static Sdb *store_versioninfo_gnu_versym(struct Elf_(r_bin_elf_obj_t) *bin, Elf_
|
||||
if (check_def && data[i + j] != 0x8001 && vinfoaddr) {
|
||||
Elf_(Verdef) vd;
|
||||
ut64 offset = Elf_(r_bin_elf_v2p) (bin, vinfoaddr);
|
||||
|
||||
if (offset > bin->size || offset + sizeof (vd) > bin->size)
|
||||
goto beach;
|
||||
|
||||
do {
|
||||
if (r_buf_read_at (bin->b, offset, (ut8*)&vd, sizeof (vd)) < 0) {
|
||||
eprintf ("Warning: Cannot read Verdef for Versym\n");
|
||||
@ -504,6 +510,7 @@ static Sdb *store_versioninfo_gnu_versym(struct Elf_(r_bin_elf_obj_t) *bin, Elf_
|
||||
}
|
||||
if (vda.vda_name > bin->strtab_size)
|
||||
goto beach;
|
||||
|
||||
const char *name = bin->strtab + vda.vda_name;
|
||||
sdb_set (sdb_entry, key, sdb_fmt (0,"%s(%s%-*s)", tmp_val, name, (int)(12 - strlen (name)),")") , 0);
|
||||
}
|
||||
@ -652,9 +659,7 @@ static Sdb *store_versioninfo_gnu_verneed(struct Elf_(r_bin_elf_obj_t) *bin, Elf
|
||||
aux = (Elf_(Vernaux)*)(vstart);
|
||||
if (aux->vna_name > bin->dynstr_size)
|
||||
goto beach;
|
||||
if (!aux->vna_next)
|
||||
//it'll loop forever
|
||||
goto beach;
|
||||
|
||||
sdb_num_set (sdb_vernaux, "idx", isum, 0);
|
||||
sdb_set (sdb_vernaux, "name", &bin->dynstr[aux->vna_name], 0);
|
||||
sdb_set (sdb_vernaux, "flags", get_ver_flags (aux->vna_flags), 0);
|
||||
@ -679,16 +684,16 @@ beach:
|
||||
}
|
||||
|
||||
static Sdb *store_versioninfo(struct Elf_(r_bin_elf_obj_t) *bin) {
|
||||
Sdb *sdb_versioninfo;
|
||||
Sdb *sdb_versioninfo = NULL;
|
||||
int num_verdef = 0;
|
||||
int num_verneed = 0;
|
||||
int num_versym = 0;
|
||||
int i;
|
||||
|
||||
if (!bin || !bin->shdr || !sdb_versioninfo) {
|
||||
if (!bin || !bin->shdr)
|
||||
return NULL;
|
||||
if (!(sdb_versioninfo = sdb_new0 ()))
|
||||
return NULL;
|
||||
}
|
||||
sdb_versioninfo = sdb_new0 ();
|
||||
|
||||
for (i = 0; i < bin->ehdr.e_shnum; ++i) {
|
||||
Sdb *sdb = NULL;
|
||||
|
@ -1178,6 +1178,10 @@ static VarFileInfo *Pe_r_bin_pe_parse_var_file_info(struct PE_(r_bin_pe_obj_t)*
|
||||
|
||||
static String *Pe_r_bin_pe_parse_string(struct PE_(r_bin_pe_obj_t)* bin, PE_DWord *curAddr) {
|
||||
String *string = calloc (1, sizeof(*string));
|
||||
PE_DWord begAddr = *curAddr;
|
||||
int len_value = 0;
|
||||
int i = 0;
|
||||
|
||||
if (string == NULL) {
|
||||
eprintf ("Warning: calloc (String)\n");
|
||||
return NULL;
|
||||
@ -1210,36 +1214,43 @@ static String *Pe_r_bin_pe_parse_string(struct PE_(r_bin_pe_obj_t)* bin, PE_DWor
|
||||
return NULL;
|
||||
}
|
||||
|
||||
string->wKeyLen = string->wLength - string->wValueLength * 2 - sizeof(string->wLength) * 3;
|
||||
string->szKey = (ut16 *) malloc (string->wKeyLen); //If there was padding, we would read it in string
|
||||
if (string->szKey == NULL) {
|
||||
eprintf ("Warning: malloc (String szKey)\n");
|
||||
free_String(string);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; *curAddr < begAddr + string->wLength; ++i, *curAddr += sizeof (ut16)) {
|
||||
ut16 utf16_char;
|
||||
if (r_buf_read_at(bin->b, *curAddr, (ut8*)&utf16_char, sizeof (ut16)) != sizeof (ut16)) {
|
||||
eprintf ("Warning: check (String szKey)\n");
|
||||
free_String(string);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (r_buf_read_at(bin->b, *curAddr, (ut8*)string->szKey, string->wKeyLen) != string->wKeyLen) {
|
||||
eprintf ("Warning: read (String szKey)\n");
|
||||
free_String(string);
|
||||
return NULL;
|
||||
string->szKey = (ut16*)realloc (string->szKey, (i + 1) * sizeof (ut16));
|
||||
string->szKey[i] = utf16_char;
|
||||
string->wKeyLen += sizeof (ut16);
|
||||
|
||||
if (!utf16_char) {
|
||||
*curAddr += sizeof (ut16);
|
||||
break;
|
||||
}
|
||||
}
|
||||
*curAddr += string->wKeyLen;
|
||||
|
||||
align32(*curAddr);
|
||||
|
||||
string->Value = (ut16 *) calloc (string->wValueLength, 2);
|
||||
len_value = R_MIN (string->wValueLength * 2, string->wLength - (*curAddr - begAddr));
|
||||
if (len_value < 0)
|
||||
len_value = 0;
|
||||
|
||||
string->Value = (ut16 *) calloc (len_value, 1);
|
||||
if (string->Value == NULL) {
|
||||
eprintf ("Warning: malloc (String Value)\n");
|
||||
free_String(string);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (r_buf_read_at(bin->b, *curAddr, (ut8*)string->Value, string->wValueLength * 2) != string->wValueLength * 2) {
|
||||
if (r_buf_read_at(bin->b, *curAddr, (ut8*)string->Value, len_value) != len_value) {
|
||||
eprintf ("Warning: read (String Value)\n");
|
||||
free_String(string);
|
||||
return NULL;
|
||||
}
|
||||
*curAddr += string->wValueLength * 2;
|
||||
*curAddr += len_value;
|
||||
|
||||
return string;
|
||||
}
|
||||
|
@ -1894,19 +1894,30 @@ static void bin_pe_versioninfo(RCore *r) {
|
||||
if (!(sdb = sdb_ns_path (r->sdb, path_fixedfileinfo, 0)))
|
||||
break;
|
||||
|
||||
r_cons_printf ("Signature: %s\n", sdb_const_get (sdb, "Signature", 0));
|
||||
r_cons_printf ("StrucVersion: %s\n", sdb_const_get (sdb, "FileVersionMS", 0));
|
||||
r_cons_printf ("FileVersionMS: %s\n", sdb_const_get (sdb, "FileVersionMS", 0));
|
||||
r_cons_printf ("FileVersionLS: %s\n", sdb_const_get (sdb, "FileVersionLS", 0));
|
||||
r_cons_printf ("ProductVersionMS: %s\n", sdb_const_get (sdb, "ProductVersionMS", 0));
|
||||
r_cons_printf ("ProductVersionLS: %s\n", sdb_const_get (sdb, "ProductVersionLS", 0));
|
||||
r_cons_printf ("FileFlagsMask: %s\n", sdb_const_get (sdb, "FileFlagsMask", 0));
|
||||
r_cons_printf ("FileFlags: %s\n", sdb_const_get (sdb, "FileFlags", 0));
|
||||
r_cons_printf ("FileOS: %s\n", sdb_const_get (sdb, "FileOS", 0));
|
||||
r_cons_printf ("FileType: %s\n", sdb_const_get (sdb, "FileType", 0));
|
||||
r_cons_printf ("FileSubType: %s\n", sdb_const_get (sdb, "FileSubType", 0));
|
||||
r_cons_printf ("FileDateMS: %s\n", sdb_const_get (sdb, "FileDateMS", 0));
|
||||
r_cons_printf ("FileDateLS: %s\n", sdb_const_get (sdb, "FileDateLS", 0));
|
||||
r_cons_printf (" Signature: 0x%"PFMT64x"\n", sdb_num_get (sdb, "Signature", 0));
|
||||
r_cons_printf (" StrucVersion: 0x%"PFMT64x"\n", sdb_num_get (sdb, "StrucVersion", 0));
|
||||
r_cons_printf (" FileVersion: %"PFMT64d".%"PFMT64d".%"PFMT64d".%"PFMT64d"\n",
|
||||
sdb_num_get (sdb, "FileVersionMS", 0) >> 16,
|
||||
sdb_num_get (sdb, "FileVersionMS", 0) & 0xFFFF,
|
||||
sdb_num_get (sdb, "FileVersionLS", 0) >> 16,
|
||||
sdb_num_get (sdb, "FileVersionLS", 0) & 0xFFFF);
|
||||
r_cons_printf (" ProductVersion: %"PFMT64d".%"PFMT64d".%"PFMT64d".%"PFMT64d"\n",
|
||||
sdb_num_get (sdb, "ProductVersionMS", 0) >> 16,
|
||||
sdb_num_get (sdb, "ProductVersionMS", 0) & 0xFFFF,
|
||||
sdb_num_get (sdb, "ProductVersionLS", 0) >> 16,
|
||||
sdb_num_get (sdb, "ProductVersionLS", 0) & 0xFFFF);
|
||||
r_cons_printf (" FileFlagsMask: 0x%"PFMT64x"\n", sdb_num_get (sdb, "FileFlagsMask", 0));
|
||||
r_cons_printf (" FileFlags: 0x%"PFMT64x"\n", sdb_num_get (sdb, "FileFlags", 0));
|
||||
r_cons_printf (" FileOS: 0x%"PFMT64x"\n", sdb_num_get (sdb, "FileOS", 0));
|
||||
r_cons_printf (" FileType: 0x%"PFMT64x"\n", sdb_num_get (sdb, "FileType", 0));
|
||||
r_cons_printf (" FileSubType: 0x%"PFMT64x"\n", sdb_num_get (sdb, "FileSubType", 0));
|
||||
#if 0
|
||||
r_cons_printf (" FileDate: %d.%d.%d.%d\n",
|
||||
sdb_num_get (sdb, "FileDateMS", 0) >> 16,
|
||||
sdb_num_get (sdb, "FileDateMS", 0) & 0xFFFF,
|
||||
sdb_num_get (sdb, "FileDateLS", 0) >> 16,
|
||||
sdb_num_get (sdb, "FileDateLS", 0) & 0xFFFF);
|
||||
#endif
|
||||
r_cons_printf ("\n");
|
||||
|
||||
r_cons_printf ("# StringTable\n\n");
|
||||
@ -1930,7 +1941,7 @@ static void bin_pe_versioninfo(RCore *r) {
|
||||
|| r_str_utf16_to_utf8 (val_utf8, lenval * 2, val_utf16, lenval, true) < 0) {
|
||||
eprintf ("Warning: Cannot decode utf16 to utf8\n");
|
||||
} else {
|
||||
r_cons_printf ("%s: %s\n", (char*)key_utf8, (char*)val_utf8);
|
||||
r_cons_printf (" %s: %s\n", (char*)key_utf8, (char*)val_utf8);
|
||||
}
|
||||
|
||||
free (key_utf8);
|
||||
|
Loading…
Reference in New Issue
Block a user