Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XOR Values. #1745

Merged
merged 2 commits into from
Jul 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion cli/yara.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ static bool show_tags = false;
static bool show_stats = false;
static bool show_strings = false;
static bool show_string_length = false;
static bool show_xor_key = false;
static bool show_meta = false;
static bool show_namespace = false;
static bool show_version = false;
Expand Down Expand Up @@ -296,6 +297,12 @@ args_option_t options[] = {
&show_string_length,
_T("print length of matched strings")),

OPT_BOOLEAN(
'X',
_T("print-xor-key"),
&show_xor_key,
_T("print xor key of matched strings")),

OPT_BOOLEAN('g', _T("print-tags"), &show_tags, _T("print tags")),

OPT_BOOLEAN(
Expand Down Expand Up @@ -1081,7 +1088,7 @@ static int handle_message(

// Show matched strings.

if (show_strings || show_string_length)
if (show_strings || show_string_length || show_xor_key)
{
YR_STRING* string;

Expand All @@ -1103,6 +1110,9 @@ static int handle_message(
match->base + match->offset,
string->identifier);

if (show_xor_key)
_tprintf(_T(":xor(0x%02x)"), match->xor_key);

if (show_strings)
{
_tprintf(_T(": "));
Expand Down
3 changes: 3 additions & 0 deletions libyara/include/yara/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,9 @@ struct YR_MATCH

// True if this is match for a private string.
bool is_private;

// Set to the xor key if this is an xor string.
uint8_t xor_key;
};

struct YR_AC_STATE
Expand Down
42 changes: 35 additions & 7 deletions libyara/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,16 @@ typedef struct _CALLBACK_ARGS

int forward_matches;
int full_word;
int xor_key;

} CALLBACK_ARGS;

static int _yr_scan_xor_compare(
const uint8_t* data,
size_t data_size,
uint8_t* string,
size_t string_length)
size_t string_length,
uint8_t* xor_key)
{
int result = 0;
const uint8_t* s1 = data;
Expand Down Expand Up @@ -94,15 +96,20 @@ _exit:;
string_length,
result);

if (result > 0)
*xor_key = k;

return result;
}

static int _yr_scan_xor_wcompare(
const uint8_t* data,
size_t data_size,
uint8_t* string,
size_t string_length)
size_t string_length,
uint8_t* xor_key)
{
int result = 0;
const uint8_t* s1 = data;
const uint8_t* s2 = string;
uint8_t k = 0;
Expand All @@ -124,7 +131,12 @@ static int _yr_scan_xor_wcompare(
i++;
}

return (int) ((i == string_length) ? i * 2 : 0);
result = (int) ((i == string_length) ? i * 2 : 0);

if (result > 0)
*xor_key = k;

return result;
}

static int _yr_scan_compare(
Expand Down Expand Up @@ -397,7 +409,8 @@ static int _yr_scan_verify_chained_string_match(
const uint8_t* match_data,
uint64_t match_base,
uint64_t match_offset,
int32_t match_length)
int32_t match_length,
uint8_t xor_key)
{
YR_DEBUG_FPRINTF(
2,
Expand Down Expand Up @@ -584,6 +597,7 @@ static int _yr_scan_verify_chained_string_match(
new_match->prev = NULL;
new_match->next = NULL;
new_match->is_private = STRING_IS_PRIVATE(matching_string);
new_match->xor_key = xor_key;

// A copy of the matching data is written to the matches_arena, the
// amount of data copies is limited by YR_CONFIG_MAX_MATCH_DATA.
Expand Down Expand Up @@ -687,7 +701,8 @@ static int _yr_scan_match_callback(
match_data,
callback_args->data_base,
match_offset,
match_length);
match_length,
callback_args->xor_key);
}
else
{
Expand Down Expand Up @@ -733,6 +748,7 @@ static int _yr_scan_match_callback(
new_match->prev = NULL;
new_match->next = NULL;
new_match->is_private = STRING_IS_PRIVATE(string);
new_match->xor_key = callback_args->xor_key;

FAIL_ON_ERROR(_yr_scan_add_match_to_list(
new_match,
Expand Down Expand Up @@ -843,6 +859,8 @@ static int _yr_scan_verify_re_match(
callback_args.data_base = data_base;
callback_args.forward_matches = forward_matches;
callback_args.full_word = STRING_IS_FULL_WORD(ac_match->string);
// xor modifier is not valid for RE but set it so we don't leak stack values.
callback_args.xor_key = 0;

if (ac_match->backward_code != NULL)
{
Expand Down Expand Up @@ -886,6 +904,7 @@ static int _yr_scan_verify_literal_match(

int flags = 0;
int forward_matches = 0;
uint8_t xor_key = 0;

CALLBACK_ARGS callback_args;
YR_STRING* string = ac_match->string;
Expand Down Expand Up @@ -927,13 +946,21 @@ static int _yr_scan_verify_literal_match(
if (STRING_IS_WIDE(string))
{
forward_matches = _yr_scan_xor_wcompare(
data + offset, data_size - offset, string->string, string->length);
data + offset,
data_size - offset,
string->string,
string->length,
&xor_key);
}

if (forward_matches == 0)
{
forward_matches = _yr_scan_xor_compare(
data + offset, data_size - offset, string->string, string->length);
data + offset,
data_size - offset,
string->string,
string->length,
&xor_key);
}
}
}
Expand All @@ -954,6 +981,7 @@ static int _yr_scan_verify_literal_match(
callback_args.data_base = data_base;
callback_args.forward_matches = forward_matches;
callback_args.full_word = STRING_IS_FULL_WORD(string);
callback_args.xor_key = xor_key;

FAIL_ON_ERROR(
_yr_scan_match_callback(data + offset, 0, flags, &callback_args));
Expand Down