📄 dce2_roptions.c
字号:
/**************************************************************************** * Copyright (C) 2008-2008 Sourcefire,Inc * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as * published by the Free Software Foundation. You may not use, modify or * distribute this program under any other version of the GNU General * Public License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * **************************************************************************** * ****************************************************************************/#include "dce2_roptions.h"#include "dce2_memory.h"#include "dcerpc.h"#include "dce2_utils.h"#include "dce2_session.h"#include "sf_types.h"#include "sf_dynamic_preprocessor.h"#include "stream_api.h"#include "sf_dynamic_engine.h"#include "sfhashfcn.h"#include "profiler.h"#include <errno.h>#include <string.h>/******************************************************************** * Extern variables ********************************************************************/extern DynamicPreprocessorData _dpd;#ifdef PERF_PROFILINGextern PreprocStats dce2_pstat_roptions;#endif/******************************************************************** * Macros ********************************************************************/#define DCE2_RTOKEN__OPT_SEP "," /* Rule option option separator */#define DCE2_RTOKEN__ARG_SEP " \t" /* Rule option argument separator */#define DCE2_RTOKEN__IFACE_SEP "-" /* Rule option interface separator */#define DCE2_ROPT__IFACE "dce_iface"#define DCE2_ROPT__OPNUM "dce_opnum"#define DCE2_ROPT__STUB_DATA "dce_stub_data"#define DCE2_ROPT__BYTE_TEST "byte_test" /* Override keyword */#define DCE2_ROPT__BYTE_JUMP "byte_jump" /* Override keyword */#define DCE2_RARG__LT '<'#define DCE2_RARG__EQ '='#define DCE2_RARG__GT '>'#define DCE2_RARG__NE '!'#define DCE2_RARG__AND '&'#define DCE2_RARG__XOR '^'#define DCE2_RARG__ANY_FRAG "any_frag"#define DCE2_RARG__RELATIVE "relative"#define DCE2_RARG__MULTIPLIER "multiplier"#define DCE2_RARG__ALIGN "align"#define DCE2_RARG__DCE_OVERRIDE "dce"#define DCE2_IFACE__MIN_ARGS 1#define DCE2_IFACE__MAX_ARGS 3#define DCE2_IFACE__LEN 36 /* counting the dashes */#define DCE2_IFACE__TIME_LOW_LEN 8#define DCE2_IFACE__TIME_MID_LEN 4#define DCE2_IFACE__TIME_HIGH_LEN 4#define DCE2_IFACE__CLOCK_SEQ_LEN 4#define DCE2_IFACE__NODE_LEN 12#define DCE2_BTEST__MIN_ARGS 4#define DCE2_BTEST__MAX_ARGS 6#define DCE2_BJUMP__MIN_ARGS 2#define DCE2_BJUMP__MAX_ARGS 6#define DCE2_OPNUM__MAX (UINT16_MAX + 1)#define DCE2_OPNUM__MAX_INDEX (DCE2_OPNUM__MAX / 8)/******************************************************************** * Enumerations ********************************************************************/typedef enum _DCE2_IfOp{ DCE2_IF_OP__LT = 1, DCE2_IF_OP__EQ, DCE2_IF_OP__GT, DCE2_IF_OP__NE} DCE2_IfOp;typedef enum _DCE2_BtOp{ DCE2_BT_OP__LT = 1, DCE2_BT_OP__EQ, DCE2_BT_OP__GT, DCE2_BT_OP__AND, DCE2_BT_OP__XOR} DCE2_BtOp;typedef enum _DCE2_OpnumType{ DCE2_OPNUM_TYPE__SINGLE, DCE2_OPNUM_TYPE__MULTIPLE} DCE2_OpnumType;typedef enum _DCE2_OpnumListState{ DCE2_OPNUM_LIST_STATE__START, DCE2_OPNUM_LIST_STATE__OPNUM_START, DCE2_OPNUM_LIST_STATE__OPNUM_LO, DCE2_OPNUM_LIST_STATE__OPNUM_RANGE, DCE2_OPNUM_LIST_STATE__OPNUM_HI, DCE2_OPNUM_LIST_STATE__OPNUM_END, DCE2_OPNUM_LIST_STATE__END} DCE2_OpnumListState;/******************************************************************** * Structures ********************************************************************/typedef struct _DCE2_IfaceData{ Uuid iface; uint32_t iface_vers; int iface_vers_maj; int iface_vers_min; DCE2_IfOp operator; int any_frag; } DCE2_IfaceData;typedef struct _DCE_OpnumData{ DCE2_OpnumType type;} DCE2_OpnumData;typedef struct _DCE_OpnumSingle{ DCE2_OpnumData odata; uint16_t opnum;} DCE2_OpnumSingle;typedef struct _DCE2_OpnumMultiple{ DCE2_OpnumData odata; uint8_t *mask; uint16_t mask_size; uint16_t opnum_lo; uint16_t opnum_hi;} DCE2_OpnumMultiple;typedef struct _DCE2_ByteTestData{ int num_bytes; uint32_t value; int invert; DCE2_BtOp operator; int32_t offset; /* can be negative */ int relative;} DCE2_ByteTestData;typedef struct _DCE2_ByteJumpData{ int num_bytes; int32_t offset; /* can be negative */ int relative; int multiplier; int align;} DCE2_ByteJumpData;/******************************************************************** * Private function prototypes ********************************************************************/static int DCE2_IfaceInit(char *, char *, void **);static int DCE2_OpnumInit(char *, char *, void **);static DCE2_Ret DCE2_ParseOpnumList(char **, char *, uint8_t *);static INLINE void DCE2_OpnumSet(uint8_t *, const uint16_t);static INLINE void DCE2_OpnumSetRange(uint8_t *, uint16_t, uint16_t);static INLINE int DCE2_OpnumIsSet(const uint8_t *, const uint16_t, const uint16_t, const uint16_t);static int DCE2_StubDataInit(char *, char *, void **);static int DCE2_ByteTestInit(char *, char *, void **);static int DCE2_ByteJumpInit(char *, char *, void **);static void DCE2_ParseIface(char *, DCE2_IfaceData *);static int DCE2_IfaceEval(void *, const uint8_t **, void *);static int DCE2_OpnumEval(void *, const uint8_t **, void *);static int DCE2_StubDataEval(void *, const uint8_t **, void *);static int DCE2_ByteTestEval(void *, const uint8_t **, void *);static int DCE2_ByteJumpEval(void *, const uint8_t **, void *);static void DCE2_IfaceCleanup(void *);static void DCE2_OpnumCleanup(void *);static void DCE2_ByteTestCleanup(void *);static void DCE2_ByteJumpCleanup(void *);static uint32_t DCE2_IfaceHash(void *);static uint32_t DCE2_OpnumHash(void *);static uint32_t DCE2_ByteTestHash(void *);static uint32_t DCE2_ByteJumpHash(void *);static int DCE2_IfaceKeyCompare(void *, void *);static int DCE2_OpnumKeyCompare(void *, void *);static int DCE2_ByteTestKeyCompare(void *, void *);static int DCE2_ByteJumpKeyCompare(void *, void *);static INLINE int DCE2_RoptDoEval(SFSnortPacket *);/******************************************************************** * Function: * * Purpose: * * Arguments: * * Returns: * ********************************************************************/void DCE2_RegRuleOptions(void){ _dpd.preprocOptRegister(DCE2_ROPT__IFACE, DCE2_IfaceInit, DCE2_IfaceEval, DCE2_IfaceCleanup, DCE2_IfaceHash, DCE2_IfaceKeyCompare); _dpd.preprocOptRegister(DCE2_ROPT__OPNUM, DCE2_OpnumInit, DCE2_OpnumEval, DCE2_OpnumCleanup, DCE2_OpnumHash, DCE2_OpnumKeyCompare); _dpd.preprocOptRegister(DCE2_ROPT__STUB_DATA, DCE2_StubDataInit, DCE2_StubDataEval, NULL, NULL, NULL); _dpd.preprocOptOverrideKeyword(DCE2_ROPT__BYTE_TEST, DCE2_RARG__DCE_OVERRIDE, DCE2_ByteTestInit, DCE2_ByteTestEval, DCE2_ByteTestCleanup, DCE2_ByteTestHash, DCE2_ByteTestKeyCompare); _dpd.preprocOptOverrideKeyword(DCE2_ROPT__BYTE_JUMP, DCE2_RARG__DCE_OVERRIDE, DCE2_ByteJumpInit, DCE2_ByteJumpEval, DCE2_ByteJumpCleanup, DCE2_ByteJumpHash, DCE2_ByteJumpKeyCompare);}/******************************************************************** * Function: * * Purpose: * * Arguments: * * Returns: * ********************************************************************/static int DCE2_IfaceInit(char *name, char *args, void **data){ char *token, *saveptr; int iface_vers = 0, any_frag = 0; int tok_num = 0; DCE2_IfaceData *iface_data; if (strcmp(name, DCE2_ROPT__IFACE) != 0) return 0; iface_data = (DCE2_IfaceData *)DCE2_Alloc(sizeof(DCE2_IfaceData), DCE2_MEM_TYPE__ROPTION); if (iface_data == NULL) { DCE2_Die("%s(%d) => %s rule option: Failed to allocate memory for " "iface data structure.\n", *_dpd.config_file, *_dpd.config_line, DCE2_ROPT__IFACE); } iface_data->operator = DCE2_SENTINEL; /* Must have arguments */ if (DCE2_IsEmptyStr(args)) { DCE2_Die("%s(%d) => %s rule option: No arguments. Example => %s: " "4b324fc8-1670-01d3-1278-5a47bf6ee188;\n", *_dpd.config_file, *_dpd.config_line, DCE2_ROPT__IFACE, DCE2_ROPT__IFACE); } /* Get argument */ token = strtok_r(args, DCE2_RTOKEN__OPT_SEP, &saveptr); if (token == NULL) { DCE2_Die("%s(%d) => %s rule option: strtok_r() returned NULL when " "str argument was not NULL.\n", *_dpd.config_file, *_dpd.config_line, DCE2_ROPT__IFACE); } do { tok_num++; token = DCE2_PruneWhiteSpace(token); if (tok_num == 1) /* Iface uuid */ { DCE2_ParseIface(token, iface_data); } else if ((tok_num > DCE2_IFACE__MIN_ARGS) && (tok_num <= DCE2_IFACE__MAX_ARGS)) { int try_any_frag = 0; /* Need at least two bytes */ if (strlen(token) < 2) { DCE2_Die("%s(%d) => %s rule option: Invalid argument: %s\n", *_dpd.config_file, *_dpd.config_line, DCE2_ROPT__IFACE, token); } switch (*token) { case DCE2_RARG__LT: iface_data->operator = DCE2_IF_OP__LT; break; case DCE2_RARG__EQ: iface_data->operator = DCE2_IF_OP__EQ; break; case DCE2_RARG__GT: iface_data->operator = DCE2_IF_OP__GT; break; case DCE2_RARG__NE: iface_data->operator = DCE2_IF_OP__NE; break; default: try_any_frag = 1; } if (!try_any_frag) { char *endptr; if (iface_vers) { DCE2_Die("%s(%d) => %s rule option: Cannot configure interface " "version more than once.\n", *_dpd.config_file, *_dpd.config_line, DCE2_ROPT__IFACE); } token++; iface_data->iface_vers = strtoul(token, &endptr, 16); if ((errno == ERANGE) || (*endptr != '\0')) { DCE2_Die("%s(%d) => %s rule option: Invalid argument: %s\n", *_dpd.config_file, *_dpd.config_line, DCE2_ROPT__IFACE, token); } if (iface_data->iface_vers <= UINT16_MAX) iface_data->iface_vers_maj = (int)iface_data->iface_vers; else iface_data->iface_vers_maj = DCE2_SENTINEL; iface_vers = 1; } else { if (any_frag) { DCE2_Die("%s(%d) => %s rule option: Cannot configure " "\"%s\" more than once.\n", *_dpd.config_file, *_dpd.config_line, DCE2_ROPT__IFACE, DCE2_RARG__ANY_FRAG); } if (strcmp(token, DCE2_RARG__ANY_FRAG) == 0) { iface_data->any_frag = 1; } else { DCE2_Die("%s(%d) => %s rule option: Invalid argument: %s.\n", *_dpd.config_file, *_dpd.config_line, DCE2_ROPT__IFACE, token); } any_frag = 1; } } else { DCE2_Die("%s(%d) => %s rule option: Too many arguments\n", *_dpd.config_file, *_dpd.config_line, DCE2_ROPT__IFACE); } } while ((token = strtok_r(NULL, DCE2_RTOKEN__OPT_SEP, &saveptr)) != NULL); *data = (void *)iface_data; return 1;}/******************************************************************** * Function: * * Purpose: * * Arguments: * * Returns: * ********************************************************************/static void DCE2_ParseIface(char *token, DCE2_IfaceData *iface_data){ char *iface, *ifaceptr; char *if_hex, *if_hexptr; int num_pieces = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -