mirror of
https://github.com/VirusTotal/yara.git
synced 2026-10-11 22:49:58 +00:00
read dotnet and pe file fields through unaligned helpers (#2210)
This commit is contained in:
@@ -1707,9 +1707,9 @@ void dotnet_parse_guid(
|
||||
sprintf(
|
||||
guid,
|
||||
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
yr_le32toh(*(uint32_t*) guid_offset),
|
||||
yr_le16toh(*(uint16_t*) (guid_offset + 4)),
|
||||
yr_le16toh(*(uint16_t*) (guid_offset + 6)),
|
||||
yr_le32toh(yr_unaligned_u32(guid_offset)),
|
||||
yr_le16toh(yr_unaligned_u16(guid_offset + 4)),
|
||||
yr_le16toh(yr_unaligned_u16(guid_offset + 6)),
|
||||
*(guid_offset + 8),
|
||||
*(guid_offset + 9),
|
||||
*(guid_offset + 10),
|
||||
@@ -2192,10 +2192,10 @@ void dotnet_parse_tilde_2(
|
||||
blob_offset = ((uint8_t*) constant_table) + 2 + index_size;
|
||||
|
||||
if (index_sizes.blob == 4)
|
||||
blob_index = *(DWORD*) blob_offset;
|
||||
blob_index = yr_unaligned_u32(blob_offset);
|
||||
else
|
||||
// Cast the value (index into blob table) to a 32bit value.
|
||||
blob_index = (DWORD) (*(WORD*) blob_offset);
|
||||
blob_index = (DWORD) (yr_unaligned_u16(blob_offset));
|
||||
|
||||
// Everything checks out. Make sure the index into the blob field
|
||||
// is valid (non-null and within range).
|
||||
@@ -2294,7 +2294,7 @@ void dotnet_parse_tilde_2(
|
||||
// Low 5 bits tell us what this is an index into. Remaining bits
|
||||
// tell us the index value.
|
||||
// Parent must be an index into the Assembly (0x0E) table.
|
||||
if ((*(DWORD*) customattribute_table & 0x1F) != 0x0E)
|
||||
if ((yr_unaligned_u32(customattribute_table) & 0x1F) != 0x0E)
|
||||
{
|
||||
row_ptr += row_size;
|
||||
continue;
|
||||
@@ -2305,7 +2305,7 @@ void dotnet_parse_tilde_2(
|
||||
// Low 5 bits tell us what this is an index into. Remaining bits
|
||||
// tell us the index value.
|
||||
// Parent must be an index into the Assembly (0x0E) table.
|
||||
if ((*(WORD*) customattribute_table & 0x1F) != 0x0E)
|
||||
if ((yr_unaligned_u16(customattribute_table) & 0x1F) != 0x0E)
|
||||
{
|
||||
row_ptr += row_size;
|
||||
continue;
|
||||
@@ -2321,27 +2321,27 @@ void dotnet_parse_tilde_2(
|
||||
// Low 3 bits tell us what this is an index into. Remaining bits
|
||||
// tell us the index value. Only values 2 and 3 are defined.
|
||||
// Type must be an index into the MemberRef table.
|
||||
if ((*(DWORD*) customattribute_table & 0x07) != 0x03)
|
||||
if ((yr_unaligned_u32(customattribute_table) & 0x07) != 0x03)
|
||||
{
|
||||
row_ptr += row_size;
|
||||
continue;
|
||||
}
|
||||
|
||||
type_index = *(DWORD*) customattribute_table >> 3;
|
||||
type_index = yr_unaligned_u32(customattribute_table) >> 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Low 3 bits tell us what this is an index into. Remaining bits
|
||||
// tell us the index value. Only values 2 and 3 are defined.
|
||||
// Type must be an index into the MemberRef table.
|
||||
if ((*(WORD*) customattribute_table & 0x07) != 0x03)
|
||||
if ((yr_unaligned_u16(customattribute_table) & 0x07) != 0x03)
|
||||
{
|
||||
row_ptr += row_size;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Cast the index to a 32bit value.
|
||||
type_index = (DWORD) ((*(WORD*) customattribute_table >> 3));
|
||||
type_index = (DWORD) (yr_unaligned_u16(customattribute_table) >> 3);
|
||||
}
|
||||
|
||||
if (type_index > 0)
|
||||
@@ -2358,27 +2358,27 @@ void dotnet_parse_tilde_2(
|
||||
// Low 3 bits tell us what this is an index into. Remaining bits
|
||||
// tell us the index value. Class must be an index into the
|
||||
// TypeRef table.
|
||||
if ((*(DWORD*) memberref_row & 0x07) != 0x01)
|
||||
if ((yr_unaligned_u32(memberref_row) & 0x07) != 0x01)
|
||||
{
|
||||
row_ptr += row_size;
|
||||
continue;
|
||||
}
|
||||
|
||||
class_index = *(DWORD*) memberref_row >> 3;
|
||||
class_index = yr_unaligned_u32(memberref_row) >> 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Low 3 bits tell us what this is an index into. Remaining bits
|
||||
// tell us the index value. Class must be an index into the
|
||||
// TypeRef table.
|
||||
if ((*(WORD*) memberref_row & 0x07) != 0x01)
|
||||
if ((yr_unaligned_u16(memberref_row) & 0x07) != 0x01)
|
||||
{
|
||||
row_ptr += row_size;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Cast the index to a 32bit value.
|
||||
class_index = (DWORD) (*(WORD*) memberref_row >> 3);
|
||||
class_index = (DWORD) (yr_unaligned_u16(memberref_row) >> 3);
|
||||
}
|
||||
|
||||
if (class_index > 0)
|
||||
@@ -2407,12 +2407,18 @@ void dotnet_parse_tilde_2(
|
||||
if (index_sizes.string == 4)
|
||||
{
|
||||
name = pe_get_dotnet_string(
|
||||
pe, string_offset, str_heap_size, *(DWORD*) typeref_row);
|
||||
pe,
|
||||
string_offset,
|
||||
str_heap_size,
|
||||
yr_unaligned_u32(typeref_row));
|
||||
}
|
||||
else
|
||||
{
|
||||
name = pe_get_dotnet_string(
|
||||
pe, string_offset, str_heap_size, *(WORD*) typeref_row);
|
||||
pe,
|
||||
string_offset,
|
||||
str_heap_size,
|
||||
yr_unaligned_u16(typeref_row));
|
||||
}
|
||||
|
||||
if (name != NULL && strncmp(name, "GuidAttribute", 13) != 0)
|
||||
@@ -2427,10 +2433,10 @@ void dotnet_parse_tilde_2(
|
||||
index_size2);
|
||||
|
||||
if (index_sizes.blob == 4)
|
||||
blob_index = *(DWORD*) customattribute_table;
|
||||
blob_index = yr_unaligned_u32(customattribute_table);
|
||||
else
|
||||
// Cast the value (index into blob table) to a 32bit value.
|
||||
blob_index = (DWORD) (*(WORD*) customattribute_table);
|
||||
blob_index = (DWORD) (yr_unaligned_u16(customattribute_table));
|
||||
|
||||
// Everything checks out. Make sure the index into the blob field
|
||||
// is valid (non-null and within range).
|
||||
@@ -2468,7 +2474,7 @@ void dotnet_parse_tilde_2(
|
||||
}
|
||||
|
||||
// Custom attributes MUST have a 16 bit prolog of 0x0001
|
||||
if (*(WORD*) blob_offset != 0x0001)
|
||||
if (yr_unaligned_u16(blob_offset) != 0x0001)
|
||||
{
|
||||
row_ptr += row_size;
|
||||
continue;
|
||||
@@ -2745,15 +2751,16 @@ void dotnet_parse_tilde_2(
|
||||
pe,
|
||||
string_offset,
|
||||
str_heap_size,
|
||||
yr_le32toh(*(DWORD*) (row_ptr + 4 + 2 + 2 + 2 + 2 + 4 +
|
||||
index_sizes.blob)));
|
||||
yr_le32toh(yr_unaligned_u32(
|
||||
row_ptr + 4 + 2 + 2 + 2 + 2 + 4 + index_sizes.blob)));
|
||||
else
|
||||
name = pe_get_dotnet_string(
|
||||
pe,
|
||||
string_offset,
|
||||
str_heap_size,
|
||||
yr_le16toh(
|
||||
*(WORD*) (row_ptr + 4 + 2 + 2 + 2 + 2 + 4 + index_sizes.blob)));
|
||||
yr_unaligned_u16(
|
||||
row_ptr + 4 + 2 + 2 + 2 + 2 + 4 + index_sizes.blob)));
|
||||
|
||||
if (name != NULL)
|
||||
yr_set_string(name, pe->object, "assembly.name");
|
||||
@@ -2765,8 +2772,9 @@ void dotnet_parse_tilde_2(
|
||||
pe,
|
||||
string_offset,
|
||||
str_heap_size,
|
||||
yr_le32toh(*(DWORD*) (row_ptr + 4 + 2 + 2 + 2 + 2 + 4 +
|
||||
index_sizes.blob + index_sizes.string)));
|
||||
yr_le32toh(yr_unaligned_u32(
|
||||
row_ptr + 4 + 2 + 2 + 2 + 2 + 4 + index_sizes.blob +
|
||||
index_sizes.string)));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2774,8 +2782,9 @@ void dotnet_parse_tilde_2(
|
||||
pe,
|
||||
string_offset,
|
||||
str_heap_size,
|
||||
yr_le16toh(*(WORD*) (row_ptr + 4 + 2 + 2 + 2 + 2 + 4 +
|
||||
index_sizes.blob + index_sizes.string)));
|
||||
yr_le16toh(yr_unaligned_u16(
|
||||
row_ptr + 4 + 2 + 2 + 2 + 2 + 4 + index_sizes.blob +
|
||||
index_sizes.string)));
|
||||
}
|
||||
|
||||
// Sometimes it will be a zero length string. This is technically
|
||||
@@ -2868,15 +2877,15 @@ void dotnet_parse_tilde_2(
|
||||
pe,
|
||||
string_offset,
|
||||
str_heap_size,
|
||||
yr_le32toh(
|
||||
*(DWORD*) (row_ptr + 2 + 2 + 2 + 2 + 4 + index_sizes.blob)));
|
||||
yr_le32toh(yr_unaligned_u32(
|
||||
row_ptr + 2 + 2 + 2 + 2 + 4 + index_sizes.blob)));
|
||||
else
|
||||
name = pe_get_dotnet_string(
|
||||
pe,
|
||||
string_offset,
|
||||
str_heap_size,
|
||||
yr_le16toh(
|
||||
*(WORD*) (row_ptr + 2 + 2 + 2 + 2 + 4 + index_sizes.blob)));
|
||||
yr_le16toh(yr_unaligned_u16(
|
||||
row_ptr + 2 + 2 + 2 + 2 + 4 + index_sizes.blob)));
|
||||
|
||||
if (name != NULL)
|
||||
yr_set_string(name, pe->object, "assembly_refs[%i].name", i);
|
||||
@@ -2943,10 +2952,10 @@ void dotnet_parse_tilde_2(
|
||||
|
||||
if (index_size == 4)
|
||||
implementation = yr_le32toh(
|
||||
*(DWORD*) (row_ptr + 4 + 4 + index_sizes.string));
|
||||
yr_unaligned_u32(row_ptr + 4 + 4 + index_sizes.string));
|
||||
else
|
||||
implementation = yr_le16toh(
|
||||
*(WORD*) (row_ptr + 4 + 4 + index_sizes.string));
|
||||
yr_unaligned_u16(row_ptr + 4 + 4 + index_sizes.string));
|
||||
|
||||
row_ptr += row_size;
|
||||
|
||||
@@ -2971,7 +2980,7 @@ void dotnet_parse_tilde_2(
|
||||
continue;
|
||||
|
||||
resource_size = yr_le32toh(
|
||||
*(DWORD*) (pe->data + resource_base + resource_offset));
|
||||
yr_unaligned_u32(pe->data + resource_base + resource_offset));
|
||||
|
||||
// Add 4 to skip the size.
|
||||
yr_set_integer(
|
||||
|
||||
@@ -45,6 +45,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <yara/pe.h>
|
||||
#include <yara/pe_utils.h>
|
||||
#include <yara/strutils.h>
|
||||
#include <yara/unaligned.h>
|
||||
#include <yara/utils.h>
|
||||
|
||||
#define MODULE_NAME pe
|
||||
@@ -1311,9 +1312,9 @@ uint64_t pe_parse_delay_import_pointer(
|
||||
return YR_UNDEFINED;
|
||||
|
||||
if (IS_64BITS_PE(pe))
|
||||
return yr_le64toh(*(uint64_t*) data);
|
||||
return yr_le64toh(yr_unaligned_u64(data));
|
||||
else
|
||||
return yr_le32toh(*(uint32_t*) data);
|
||||
return yr_le32toh(yr_unaligned_u32(data));
|
||||
}
|
||||
|
||||
static void* pe_parse_delayed_imports(PE* pe)
|
||||
|
||||
Binary file not shown.
@@ -141,6 +141,17 @@ int main(int argc, char** argv)
|
||||
"tests/data/"
|
||||
"bad_dotnet_pe");
|
||||
|
||||
// #GUID stream offset is not 4-byte aligned, the guid is read through the
|
||||
// unaligned helpers so this must parse cleanly (traps under -fsanitize=
|
||||
// alignment otherwise).
|
||||
assert_true_rule_file(
|
||||
"import \"dotnet\" \
|
||||
rule test { \
|
||||
condition: \
|
||||
dotnet.is_dotnet \
|
||||
}",
|
||||
"tests/data/dotnet_misaligned_guid");
|
||||
|
||||
yr_finalize();
|
||||
|
||||
YR_DEBUG_FPRINTF(
|
||||
|
||||
Reference in New Issue
Block a user