Skip to content

Commit

Permalink
Add sanity check that prevents OOM errors.
Browse files Browse the repository at this point in the history
The `pe_parse_delayed_imports` function didn't take into account that `pe_rva_to_offset` could return -1 when the RVA can't be translated into a file offset.
  • Loading branch information
plusvic committed Apr 30, 2024
1 parent adf3dde commit 4b9b4c0
Showing 1 changed file with 22 additions and 17 deletions.
39 changes: 22 additions & 17 deletions libyara/modules/pe/pe.c
Original file line number Diff line number Diff line change
Expand Up @@ -1279,6 +1279,10 @@ uint64_t pe_parse_delay_import_pointer(
uint64_t rva)
{
const int64_t offset = pe_rva_to_offset(pe, rva);

if (offset < 0)
return YR_UNDEFINED;

const uint8_t* data = pe->data + offset;

if (!fits_in_pe(pe, data, pointerSize))
Expand Down Expand Up @@ -1419,17 +1423,8 @@ static void* pe_parse_delayed_imports(PE* pe)
if (nameAddress == 0 || funcAddress == 0)
break;

IMPORT_FUNCTION* imported_func = (IMPORT_FUNCTION*) yr_malloc(
sizeof(IMPORT_FUNCTION));

if (imported_func == NULL)
continue;

imported_func->name = NULL;
imported_func->has_ordinal = 0;
imported_func->ordinal = 0;
imported_func->rva = 0;
imported_func->next = NULL;
char* func_name;
uint8_t has_ordinal = 0;

// Check name address. It could be ordinal, VA or RVA
if (!(nameAddress & ordinal_mask))
Expand All @@ -1441,21 +1436,31 @@ static void* pe_parse_delayed_imports(PE* pe)

offset = pe_rva_to_offset(pe, nameAddress + sizeof(uint16_t));

imported_func->name = (char*) yr_strndup(
if (offset < 0)
continue;

func_name = (char*) yr_strndup(
(char*) (pe->data + offset),
yr_min(available_space(pe, (char*) (pe->data + offset)), 512));
}
else
{
// If imported by ordinal. Lookup the ordinal.
imported_func->name = ord_lookup(dll_name, nameAddress & 0xFFFF);

// Also store the ordinal.
imported_func->ordinal = nameAddress & 0xFFFF;
imported_func->has_ordinal = 1;
func_name = ord_lookup(dll_name, nameAddress & 0xFFFF);
has_ordinal = 1;
}

IMPORT_FUNCTION* imported_func = (IMPORT_FUNCTION*) yr_malloc(
sizeof(IMPORT_FUNCTION));

if (imported_func == NULL)
continue;

imported_func->name = func_name;
imported_func->rva = func_rva;
imported_func->has_ordinal = has_ordinal;
imported_func->ordinal = (has_ordinal) ? nameAddress & 0xFFFF : 0;
imported_func->next = NULL;

num_function_imports++;
name_rva += pointer_size;
Expand Down

0 comments on commit 4b9b4c0

Please sign in to comment.