Project

General

Profile

Bug #202 » 0001-implement-pcre-relative-matching-in-detect-engine-pa.patch

Anoop Saldanha, 07/05/2010 12:49 PM

View differences:

src/detect-engine-payload.c
#include "util-spm-bm.h"
#include "util-debug.h"
#include "util-print.h"
#include "pkt-var.h"
#include "flow-var.h"
#include "util-unittest.h"
#include "util-unittest-helper.h"
......
{
SCEnter();
if (sm == NULL) {
int punt_matching = 0;
if (sm == NULL || payload_len == 0) {
SCReturnInt(0);
}
......
SCReturnInt(1);
}
if (punt_matching == 1) {
SCReturnInt(0);
}
/* set the previous match offset to the start of this match + 1 */
prev_offset = (match_offset - (cd->content_len - 1));
SCLogDebug("trying to see if there is another match after prev_offset %"PRIu32, prev_offset);
......
} while(1);
}
case DETECT_ISDATAAT:
{
SCLogDebug("inspecting isdataat");
......
}
}
}
case DETECT_PCRE:
{
SCLogDebug("inspecting pcre");
int r = DetectPcrePayloadMatch(det_ctx, s, sm, p, f, payload, payload_len);
if (r == 1) {
goto match;
}
DetectPcreData *pd = (DetectPcreData *)sm->ctx;
/* search for our pattern, checking the matches recursively.
* if we match we look for the next SigMatch as well */
uint32_t offset = 0;
uint32_t prev_offset = 0; /**< used in recursive searching */
uint32_t prev_payload_offset = det_ctx->payload_offset;
#define MAX_SUBSTRINGS 30
int ov[MAX_SUBSTRINGS];
uint8_t *ptr = NULL;
uint16_t len = 0;
int ret = 0;
do {
if (s->flags & SIG_FLAG_RECURSIVE ||
pd->flags & DETECT_PCRE_RELATIVE) {
offset = prev_payload_offset;
} else {
offset = 0;
}
if (prev_offset != 0) {
offset = prev_offset;
}
ptr = payload + offset;
len = payload_len - offset;
/* run the actual pcre detection */
ret = pcre_exec(pd->re, pd->sd, (char *)ptr, len, 0, 0, ov,
MAX_SUBSTRINGS);
SCLogDebug("ret %d (negating %s)",
ret, pd->negate ? "set" : "not set");
if (ret == PCRE_ERROR_NOMATCH) {
if (pd->negate == 1) {
/* regex didn't match with negate option means we
* consider it a match */
SCReturnInt(1);
} else {
/* we have no matches here. if we don't get a pcre match
* here, it's pointless carrying our further matches */
punt_matching = 1;
SCReturnInt(0);
}
} else if (ret >= 0) {
if (pd->negate == 1) {
punt_matching = 1;
/* regex matched but we're negated, so not
* considering it a match */
SCReturnInt(0);
} else {
/* regex matched and we're not negated,
* considering it a match */
/* see if we need to do substring capturing. */
if (ret > 1 && pd->capidx != 0) {
const char *str_ptr;
ret = pcre_get_substring((char *)ptr, ov,
MAX_SUBSTRINGS, 1, &str_ptr);
if (ret) {
if (pd->flags & DETECT_PCRE_CAPTURE_PKT) {
/* any more indentation, and we'll
* reach the moon */
if (p != NULL) {
PktVarAdd(p, pd->capname,
(uint8_t *)str_ptr, ret);
}
} else if (pd->flags & DETECT_PCRE_CAPTURE_FLOW) {
if (f != NULL) {
/* flow will be locked be FlowVarAddStr */
FlowVarAddStr(f, pd->capidx,
(uint8_t *)str_ptr, ret);
}
}
} /* if (ret) */
} /* if (ret > 1 && pd->capidx != 0) */
/* update offset for pcre RELATIVE */
det_ctx->payload_offset = (ptr + ov[1]) - payload;
if ( !(pd->flags & DETECT_PCRE_RELATIVE_NEXT)) {
SCLogDebug("no relative match coming up, so this "
"is a match");
goto match;
}
SCReturnInt(0);
/* see if the next payload keywords match. If not, we will
* search for another occurence of this pcre and see
* if the others match, until we run out of matches */
int r = DoInspectPacketPayload(de_ctx, det_ctx, s,
sm->next, p, f,
payload, payload_len);
if (r == 1) {
SCReturnInt(1);
}
if (punt_matching == 1) {
SCReturnInt(0);
}
/* set the previous match offset to the start of this match + 1 */
prev_offset = (ptr + ov[0] + 1) - payload;
}
} else {
SCLogDebug("pcre had matching error");
punt_matching = 1;
SCReturnInt(0);
}
} while (1);
}
case DETECT_BYTETEST:
{
if (DetectBytetestDoMatch(det_ctx,s,sm,payload,payload_len) != 1) {
......
goto match;
}
case DETECT_BYTEJUMP:
{
if (DetectBytejumpDoMatch(det_ctx,s,sm,payload,payload_len) != 1) {
......
goto match;
}
/* we should never get here, but bail out just in case */
default:
{
......
return result;
}
/**
* \test Test pcre recursive matching.
*/
static int PayloadTestSig08(void)
{
uint8_t *buf = (uint8_t *)"this is a super duper nova in super nova now";
uint16_t buflen = strlen((char *)buf);
Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP);
int result = 0;
char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; "
"pcre:/super/; content:nova; within:7; sid:1;)";
if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 0) {
result = 0;
goto end;
}
result = 1;
end:
if (p != NULL)
UTHFreePacket(p);
return result;
}
#endif /* UNITTESTS */
void PayloadRegisterTests(void) {
......
UtRegisterTest("PayloadTestSig05", PayloadTestSig05, 1);
UtRegisterTest("PayloadTestSig06", PayloadTestSig06, 1);
UtRegisterTest("PayloadTestSig07", PayloadTestSig07, 1);
UtRegisterTest("PayloadTestSig08", PayloadTestSig08, 1);
#endif /* UNITTESTS */
}
(2-2/3)