Skip to content

Commit 953df53

Browse files
committed
fix several bugs in array type handling in dotnet module
Several bugs were present in the parsing and generation of a string to represent an array type, notably when the "lo_bound" value is set. - The "read_blob_signed" was buggy for values outside the [-2**6, 2**6-1], the sign edition did not use the right bitmask, and the type used was unsigned. - The display when lo_bound != 0 was buggy: - size=5, lobound=0 => should be `5`, this was ok - size=5, lobound=1 => should be `1...5`, this was buggy and displayed `1...6`. The "range format" is inclusive. - 0 should still be displayed if size is 0. Only when size is unset should it be left out. So an array declared as `[5,0,3]` should be displayed the same way, and not as `[5,,3]`.
1 parent 1be9811 commit 953df53

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

libyara/modules/dotnet/dotnet.c

+12-10
Original file line numberDiff line numberDiff line change
@@ -581,10 +581,10 @@ static int32_t read_blob_signed(const uint8_t** data, uint32_t* len)
581581
{
582582
uint16_t tmp1 = yr_be16toh(yr_unaligned_u16(*data));
583583
// shift and leave top 2 bits clear
584-
uint16_t tmp2 = (tmp1 >> 1) & 0x3FFF;
584+
int16_t tmp2 = (tmp1 >> 1) & 0x3FFF;
585585
// sign extension in case of negative number
586586
if (tmp1 & 0x1)
587-
tmp2 |= 0xC000;
587+
tmp2 |= 0xE000;
588588

589589
*data += sizeof(uint16_t);
590590
*len -= sizeof(uint16_t);
@@ -602,10 +602,10 @@ static int32_t read_blob_signed(const uint8_t** data, uint32_t* len)
602602
{
603603
uint32_t tmp1 = yr_be32toh(yr_unaligned_u32(*data));
604604
// shift and leave top 3 bits clear
605-
uint32_t tmp2 = (tmp1 >> 1) & 0x1FFFFFFF;
605+
int32_t tmp2 = (tmp1 >> 1) & 0x1FFFFFFF;
606606
// sign extension in case of negative number
607607
if (tmp1 & 0x1)
608-
tmp2 |= 0xE0000000;
608+
tmp2 |= 0xF0000000;
609609

610610
*data += sizeof(uint32_t);
611611
*len -= sizeof(uint32_t);
@@ -892,13 +892,15 @@ static char* parse_signature_type(
892892

893893
// Read number of specified sizes
894894
uint32_t num_sizes = read_blob_unsigned(data, len);
895-
sizes = yr_malloc(sizeof(uint32_t) * num_sizes);
896-
if (!sizes || num_sizes > rank)
895+
if (num_sizes > rank)
896+
goto cleanup;
897+
sizes = yr_malloc(sizeof(int64_t) * num_sizes);
898+
if (!sizes)
897899
goto cleanup;
898900

899901
for (uint32_t i = 0; i < num_sizes; ++i)
900902
{
901-
sizes[i] = read_blob_unsigned(data, len);
903+
sizes[i] = (int64_t) read_blob_unsigned(data, len);
902904
}
903905

904906
// Read number of specified lower bounds
@@ -912,8 +914,8 @@ static char* parse_signature_type(
912914
lo_bounds[i] = read_blob_signed(data, len);
913915

914916
// Adjust higher bound according to lower bound
915-
if (num_sizes > i)
916-
sizes[i] += lo_bounds[i];
917+
if (num_sizes > i && lo_bounds[i] != 0)
918+
sizes[i] += lo_bounds[i] - 1;
917919
}
918920

919921
// Build the resulting array type
@@ -929,7 +931,7 @@ static char* parse_signature_type(
929931
{
930932
if (num_lowbounds > i && lo_bounds[i] != 0)
931933
sstr_appendf(ss, "%d...", lo_bounds[i]);
932-
if (num_sizes > i && sizes[i] != 0)
934+
if (num_sizes > i)
933935
sstr_appendf(ss, "%d", sizes[i]);
934936
}
935937
if (i + 1 != rank)

0 commit comments

Comments
 (0)