Skip to content

Commit

Permalink
Add maximum match length limit to regex matcher
Browse files Browse the repository at this point in the history
  • Loading branch information
sjanusz-r7 committed Dec 11, 2023
1 parent 190325a commit e3dc185
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -601,8 +601,8 @@ DWORD request_sys_process_memory_search(Remote* remote, Packet* packet)
{
const unsigned char* current_buffer_ptr = memory_buffer + current_buffer_offset;
const size_t bytes_to_regex = bytes_read - current_buffer_offset;

result = re_matchp((re_t)&regex_needles[current_needle_index].compiled_regex, current_buffer_ptr, bytes_to_regex, &match_length);
result = re_matchp((re_t)&regex_needles[current_needle_index].compiled_regex, current_buffer_ptr, bytes_to_regex, current_max_match_length, &match_length);

if (result != -1)
{
Expand All @@ -617,15 +617,13 @@ DWORD request_sys_process_memory_search(Remote* remote, Packet* packet)
continue;
}

// TODO: Add a workaround for match length to the regex itself, allowing the regex engine to stop matching once an upper limit has been reached.
const size_t current_match_length = min(max_match_length, match_length);
const unsigned char* memory_buffer_ptr = memory_buffer + current_buffer_offset + result;
if (add_needle_results_to_packet(response, memory_buffer_ptr, current_match_length, match_address, (size_t)mem.BaseAddress, mem.RegionSize) != ERROR_SUCCESS)
if (add_needle_results_to_packet(response, memory_buffer_ptr, match_length, match_address, (size_t)mem.BaseAddress, mem.RegionSize) != ERROR_SUCCESS)
{
dprintf("[MEM SEARCH] Adding search results to packet was not successful");
}

current_buffer_offset += (result + current_match_length);
current_buffer_offset += (result + match_length);
}

} while (result != -1);
Expand Down
43 changes: 22 additions & 21 deletions c/meterpreter/source/tiny-regex-c/re.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@
enum { UNUSED, DOT, BEGIN, END, QUESTIONMARK, STAR, PLUS, CHAR_RE, CHAR_CLASS, INV_CHAR_CLASS, DIGIT, NOT_DIGIT, ALPHA, NOT_ALPHA, WHITESPACE, NOT_WHITESPACE, /* BRANCH */ };

/* Private function declarations: */
static int matchpattern(regex_t* pattern, const char* text, size_t text_length, size_t text_offset, size_t* matchlength);
static int matchpattern(regex_t* pattern, const char* text, size_t text_length, size_t text_offset, size_t max_match_size, size_t* matchlength);
static int matchcharclass(char c, const char* str);
static int matchstar(regex_t p, regex_t* pattern, const char* text, size_t text_length, size_t text_offset, size_t* matchlength);
static int matchplus(regex_t p, regex_t* pattern, const char* text, size_t text_length, size_t text_offset, size_t* matchlength);
static int matchstar(regex_t p, regex_t* pattern, const char* text, size_t text_length, size_t text_offset, size_t max_match_size, size_t* matchlength);
static int matchplus(regex_t p, regex_t* pattern, const char* text, size_t text_length, size_t text_offset, size_t max_match_size, size_t* matchlength);
static int matchone(regex_t p, char c);
static int matchdigit(char c);
static int matchalpha(char c);
Expand All @@ -51,15 +51,16 @@ static int matchdot(char c);
static int ismetachar(char c);

/* Public functions: */
int re_matchp(re_t pattern, const char* text, size_t text_length, size_t* matchlength)
int re_matchp(re_t pattern, const char* text, size_t text_length, size_t max_match_length, size_t* matchlength)
{
if (max_match_length == 0) { return -1; }
*matchlength = 0;

if (pattern == 0 || text_length == 0) { return -1; }

if (pattern[0].type == BEGIN)
{
return ((matchpattern(&pattern[1], text, text_length, 0, matchlength)) ? 0 : -1);
return ((matchpattern(&pattern[1], text, text_length, 0, max_match_length, matchlength)) ? 0 : -1);
}

int idx = -1;
Expand All @@ -68,7 +69,7 @@ int re_matchp(re_t pattern, const char* text, size_t text_length, size_t* matchl
{
idx += 1;

if (matchpattern(pattern, text, text_length, idx, matchlength))
if (matchpattern(pattern, text, text_length, idx, max_match_length, matchlength))
{
return idx;
}
Expand Down Expand Up @@ -356,18 +357,18 @@ static int matchone(regex_t p, char c)
}
}

static int matchstar(regex_t p, regex_t* pattern, const char* text, size_t text_length, size_t text_offset, size_t* matchlength)
static int matchstar(regex_t p, regex_t* pattern, const char* text, size_t text_length, size_t text_offset, size_t max_match_length, size_t* matchlength)
{
size_t prelen = *matchlength;
const char* prepoint = text;
while ((text_offset < text_length) && matchone(p, text[text_offset]))
while ((text_offset < text_length) && (max_match_length > *matchlength) && matchone(p, text[text_offset]))
{
text_offset++;
(*matchlength)++;
}
while (&text[text_offset] >= prepoint)
{
if (matchpattern(pattern, text, text_length, text_offset--, matchlength))
if (matchpattern(pattern, text, text_length, text_offset--, max_match_length, matchlength))
return 1;
(*matchlength)--;
}
Expand All @@ -376,33 +377,33 @@ static int matchstar(regex_t p, regex_t* pattern, const char* text, size_t text_
return 0;
}

static int matchplus(regex_t p, regex_t* pattern, const char* text, size_t text_length, size_t text_offset, size_t* matchlength)
static int matchplus(regex_t p, regex_t* pattern, const char* text, size_t text_length, size_t text_offset, size_t max_match_length, size_t* matchlength)
{
const char* prepoint = text;
while ((text_offset < text_length) && matchone(p, text[text_offset]))
while ((text_offset < text_length) && (max_match_length > *matchlength) && matchone(p, text[text_offset]))
{
text_offset++;
(*matchlength)++;
}
while (text > prepoint)
{
if (matchpattern(pattern, text, text_length, text_offset--, matchlength))
if (matchpattern(pattern, text, text_length, text_offset--, max_match_length, matchlength))
return 1;
(*matchlength)--;
}

return 0;
}

static int matchquestion(regex_t p, regex_t* pattern, const char* text, size_t text_length, size_t text_offset, size_t* matchlength)
static int matchquestion(regex_t p, regex_t* pattern, const char* text, size_t text_length, size_t text_offset, size_t max_match_length, size_t* matchlength)
{
if (p.type == UNUSED)
return 1;
if (matchpattern(pattern, text, text_length, text_offset, matchlength))
if (matchpattern(pattern, text, text_length, text_offset, max_match_length, matchlength))
return 1;
if ((text_offset < text_length) && matchone(p, text[text_offset++]))
if ((text_offset < text_length) && (max_match_length > *matchlength) && matchone(p, text[text_offset++]))
{
if (matchpattern(pattern, text, text_length, text_offset, matchlength))
if (matchpattern(pattern, text, text_length, text_offset, max_match_length, matchlength))
{
(*matchlength)++;
return 1;
Expand Down Expand Up @@ -449,22 +450,22 @@ static int matchpattern(regex_t* pattern, const char* text, int *matchlength)
#else

/* Iterative matching */
static int matchpattern(regex_t* pattern, const char* text, size_t text_length, size_t text_offset, size_t* matchlength)
static int matchpattern(regex_t* pattern, const char* text, size_t text_length, size_t text_offset, size_t max_match_length, size_t* matchlength)
{
size_t pre = *matchlength;
do
{
if ((pattern[0].type == UNUSED) || (pattern[1].type == QUESTIONMARK))
{
return matchquestion(pattern[0], &pattern[2], text, text_length, text_offset, matchlength);
return matchquestion(pattern[0], &pattern[2], text, text_length, text_offset, max_match_length, matchlength);
}
else if (pattern[1].type == STAR)
{
return matchstar(pattern[0], &pattern[2], text, text_length, text_offset, matchlength);
return matchstar(pattern[0], &pattern[2], text, text_length, text_offset, max_match_length, matchlength);
}
else if (pattern[1].type == PLUS)
{
return matchplus(pattern[0], &pattern[2], text, text_length, text_offset, matchlength);
return matchplus(pattern[0], &pattern[2], text, text_length, text_offset, max_match_length, matchlength);
}
else if ((pattern[0].type == END) && pattern[1].type == UNUSED)
{
Expand All @@ -478,7 +479,7 @@ static int matchpattern(regex_t* pattern, const char* text, size_t text_length,
*/
(*matchlength)++;
}
while ((text_offset < text_length) && matchone(*pattern++, text[text_offset++]));
while ((text_offset < text_length) && (max_match_length > *matchlength) && matchone(*pattern++, text[text_offset++]));

*matchlength = pre;
return 0;
Expand Down
2 changes: 1 addition & 1 deletion c/meterpreter/source/tiny-regex-c/re.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ typedef struct regex_t* re_t;
#define MAX_CHAR_CLASS_LEN 255 /* Max length of character-class buffer in. */

/* Find matches of the compiled pattern inside text. */
int re_matchp(re_t pattern, const char* text, size_t text_length, size_t* matchlength);
int re_matchp(re_t pattern, const char* text, size_t text_length, size_t max_match_length, size_t* matchlength);

/* Compile a regular expression in-place, allowing for multiple needles to be compiled without the usage of a static buffer. Returns ERROR_SUCCESS (0) on success, else 1. */
int re_compile(const char* pattern, size_t pattern_length, re_t compiled_regex, unsigned char* regex_char_buffer);
Expand Down

0 comments on commit e3dc185

Please sign in to comment.