aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Tang <10972498-jtang613@users.noreply.gitlab.com>2023-11-01 22:01:15 +0000
committerGilbert Ramirez <gilbertr@gmail.com>2023-11-01 22:01:15 +0000
commitec001766f6990cc2b3e92d23b12f937e967fa7ad (patch)
tree583a947f8de129ae8b97eaa201c44c1ff4178134
parent14a934fb220827c6d68d086c85265b6664091b2b (diff)
WSLua DissectorTable GUID Support
-rw-r--r--epan/dissectors/packet-dcerpc.c58
-rw-r--r--epan/dissectors/packet-dcerpc.h2
-rw-r--r--epan/guid-utils.c41
-rw-r--r--epan/guid-utils.h3
-rw-r--r--epan/packet.c30
-rw-r--r--epan/packet.h4
-rw-r--r--epan/wslua/wslua_dissector.c73
7 files changed, 196 insertions, 15 deletions
diff --git a/epan/dissectors/packet-dcerpc.c b/epan/dissectors/packet-dcerpc.c
index 8d31002d09..19818c83b5 100644
--- a/epan/dissectors/packet-dcerpc.c
+++ b/epan/dissectors/packet-dcerpc.c
@@ -26,6 +26,7 @@
#include "config.h"
+#include <guid-utils.h>
#include <stdio.h> /* for sscanf() */
#include <epan/packet.h>
#include <epan/exceptions.h>
@@ -1658,6 +1659,28 @@ dissect_dcerpc_guid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *d
return tvb_captured_length(tvb);
}
+static void
+dcerpc_init_finalize(dissector_handle_t guid_handle, guid_key *key, dcerpc_uuid_value *value)
+{
+ module_t *samr_module;
+ const char *filter_name = proto_get_protocol_filter_name(value->proto_id);
+
+ g_hash_table_insert(dcerpc_uuids, key, value);
+
+ /* Register the GUID with the dissector table */
+ dissector_add_guid( "dcerpc.uuid", key, guid_handle );
+
+ /* add this GUID to the global name resolving */
+ guids_add_uuid(&key->guid, proto_get_protocol_short_name(value->proto));
+
+ /* Register the samr.nt_password preference as obsolete */
+ /* This should be in packet-dcerpc-samr.c */
+ if (strcmp(filter_name, "samr") == 0) {
+ samr_module = prefs_register_protocol_obsolete(value->proto_id);
+ prefs_register_obsolete_preference(samr_module, "nt_password");
+ }
+}
+
void
dcerpc_init_uuid(int proto, int ett, e_guid_t *uuid, guint16 ver,
dcerpc_sub_dissector *procs, int opnum_hf)
@@ -1665,8 +1688,6 @@ dcerpc_init_uuid(int proto, int ett, e_guid_t *uuid, guint16 ver,
guid_key *key = (guid_key *)g_malloc(sizeof (*key));
dcerpc_uuid_value *value = (dcerpc_uuid_value *)g_malloc(sizeof (*value));
header_field_info *hf_info;
- module_t *samr_module;
- const char *filter_name = proto_get_protocol_filter_name(proto);
dissector_handle_t guid_handle;
key->guid = *uuid;
@@ -1679,24 +1700,37 @@ dcerpc_init_uuid(int proto, int ett, e_guid_t *uuid, guint16 ver,
value->procs = procs;
value->opnum_hf = opnum_hf;
- g_hash_table_insert(dcerpc_uuids, key, value);
-
hf_info = proto_registrar_get_nth(opnum_hf);
hf_info->strings = value_string_from_subdissectors(procs);
/* Register the GUID with the dissector table */
guid_handle = create_dissector_handle( dissect_dcerpc_guid, proto);
- dissector_add_guid( "dcerpc.uuid", key, guid_handle );
- /* add this GUID to the global name resolving */
- guids_add_uuid(uuid, proto_get_protocol_short_name(value->proto));
+ dcerpc_init_finalize(guid_handle, key, value);
+}
- /* Register the samr.nt_password preference as obsolete */
- /* This should be in packet-dcerpc-samr.c */
- if (strcmp(filter_name, "samr") == 0) {
- samr_module = prefs_register_protocol_obsolete(proto);
- prefs_register_obsolete_preference(samr_module, "nt_password");
+void
+dcerpc_init_from_handle(int proto, e_guid_t *uuid, guint16 ver,
+ dissector_handle_t guid_handle)
+{
+ guid_key *key = (guid_key *)g_malloc(sizeof (*key));
+ dcerpc_uuid_value *value = (dcerpc_uuid_value *)g_malloc(sizeof (*value));
+
+ key->guid = *uuid;
+ key->ver = ver;
+
+ value->proto = find_protocol_by_id(proto);
+ value->proto_id = proto;
+ value->ett = -1;
+ value->name = proto_get_protocol_short_name(value->proto);
+ value->opnum_hf = 0;
+
+ if (g_hash_table_contains(dcerpc_uuids, key)) {
+ g_hash_table_remove(dcerpc_uuids, key);
+ guids_delete_guid(uuid);
}
+
+ dcerpc_init_finalize(guid_handle, key, value);
}
/* Function to find the name of a registered protocol
diff --git a/epan/dissectors/packet-dcerpc.h b/epan/dissectors/packet-dcerpc.h
index f1759111e3..05159e8f73 100644
--- a/epan/dissectors/packet-dcerpc.h
+++ b/epan/dissectors/packet-dcerpc.h
@@ -392,6 +392,8 @@ typedef struct _dcerpc_sub_dissector {
WS_DLL_PUBLIC
void dcerpc_init_uuid (int proto, int ett, e_guid_t *uuid, guint16 ver, dcerpc_sub_dissector *procs, int opnum_hf);
WS_DLL_PUBLIC
+void dcerpc_init_from_handle(int proto, e_guid_t *uuid, guint16 ver, dissector_handle_t guid_handle);
+WS_DLL_PUBLIC
const char *dcerpc_get_proto_name(e_guid_t *uuid, guint16 ver);
WS_DLL_PUBLIC
int dcerpc_get_proto_hf_opnum(e_guid_t *uuid, guint16 ver);
diff --git a/epan/guid-utils.c b/epan/guid-utils.c
index 2e99085a04..fd0807dddd 100644
--- a/epan/guid-utils.c
+++ b/epan/guid-utils.c
@@ -106,6 +106,47 @@ guids_add_guid(const e_guid_t *guid, const gchar *name)
wmem_tree_insert32_array(guid_to_name_tree, &guidkey[0], (gchar *) name);
}
+/* remove a guid to name mapping */
+void
+guids_delete_guid(const e_guid_t *guid)
+{
+ wmem_tree_key_t guidkey[2];
+ guint32 g[4];
+
+ g[0] = guid->data1;
+
+ g[1] = guid->data2;
+ g[1] <<= 16;
+ g[1] |= guid->data3;
+
+ g[2] = guid->data4[0];
+ g[2] <<= 8;
+ g[2] |= guid->data4[1];
+ g[2] <<= 8;
+ g[2] |= guid->data4[2];
+ g[2] <<= 8;
+ g[2] |= guid->data4[3];
+
+ g[3] = guid->data4[4];
+ g[3] <<= 8;
+ g[3] |= guid->data4[5];
+ g[3] <<= 8;
+ g[3] |= guid->data4[6];
+ g[3] <<= 8;
+ g[3] |= guid->data4[7];
+
+ guidkey[0].key = g;
+ guidkey[0].length = 4;
+ guidkey[1].length = 0;
+
+ void *data = wmem_tree_lookup32_array(guid_to_name_tree, &guidkey[0]);
+
+ if (data != NULL) {
+ // This will "remove" the entry by setting its data to NULL
+ wmem_tree_insert32_array(guid_to_name_tree, &guidkey[0], NULL);
+ }
+
+}
/* retrieve the registered name for this GUID; uses the scope for the fallback case only */
const gchar *
diff --git a/epan/guid-utils.h b/epan/guid-utils.h
index 87e7c85aa1..f00cbf5dac 100644
--- a/epan/guid-utils.h
+++ b/epan/guid-utils.h
@@ -35,6 +35,9 @@ WS_DLL_PUBLIC void guids_init(void);
/* add a GUID */
WS_DLL_PUBLIC void guids_add_guid(const e_guid_t *guid, const gchar *name);
+/* remove a guid to name mapping */
+WS_DLL_PUBLIC void guids_delete_guid(const e_guid_t *guid);
+
/* try to get registered name for this GUID */
WS_DLL_PUBLIC const gchar *guids_get_guid_name(const e_guid_t *guid, wmem_allocator_t *scope);
diff --git a/epan/packet.c b/epan/packet.c
index 70507045af..d0690c61f6 100644
--- a/epan/packet.c
+++ b/epan/packet.c
@@ -1381,6 +1381,36 @@ void dissector_delete_uint_range(const char *name, range_t *range,
}
}
+/* Remove an entry from a guid dissector table. */
+void dissector_delete_guid(const char *name, guid_key* guid_val, dissector_handle_t handle)
+{
+ dissector_table_t sub_dissectors;
+ dtbl_entry_t *dtbl_entry;
+
+ sub_dissectors = find_dissector_table(name);
+
+ /* sanity check */
+ ws_assert(sub_dissectors);
+
+ /* Find the table entry */
+ dtbl_entry = (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table, guid_val);
+
+ if (dtbl_entry == NULL) {
+ fprintf(stderr, "OOPS: guid not found in dissector table \"%s\"\n", name);
+ return;
+ }
+
+ /* Make sure the handles match */
+ if (dtbl_entry->current != handle) {
+ fprintf(stderr, "OOPS: handle does not match for guid in dissector table \"%s\"\n", name);
+ return;
+ }
+
+ /* Remove the table entry */
+ g_hash_table_remove(sub_dissectors->hash_table, guid_val);
+}
+
+
static gboolean
dissector_delete_all_check (gpointer key _U_, gpointer value, gpointer user_data)
{
diff --git a/epan/packet.h b/epan/packet.h
index 2484cd6a14..805e99ac8d 100644
--- a/epan/packet.h
+++ b/epan/packet.h
@@ -383,6 +383,10 @@ WS_DLL_PUBLIC int dissector_try_guid(dissector_table_t sub_dissectors,
WS_DLL_PUBLIC int dissector_try_guid_new(dissector_table_t sub_dissectors,
guid_key* guid_val, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const gboolean add_proto_name, void *data);
+/* Delete a GUID from a dissector table. */
+WS_DLL_PUBLIC void dissector_delete_guid(const char *name, guid_key* guid_val,
+ dissector_handle_t handle);
+
/** Look for a given value in a given guid dissector table and, if found,
* return the current dissector handle for that value.
*
diff --git a/epan/wslua/wslua_dissector.c b/epan/wslua/wslua_dissector.c
index 5b18930827..b2a4330d9b 100644
--- a/epan/wslua/wslua_dissector.c
+++ b/epan/wslua/wslua_dissector.c
@@ -17,11 +17,15 @@
#include "config.h"
+#include "epan/guid-utils.h"
+#include "epan/proto.h"
#include "wslua.h"
#include <epan/decode_as.h>
#include <epan/exceptions.h>
#include <epan/show_exception.h>
+#include <epan/dissectors/packet-dcerpc.h>
+#include <string.h>
/* WSLUA_CONTINUE_MODULE Proto */
@@ -166,8 +170,8 @@ WSLUA_CONSTRUCTOR DissectorTable_new (lua_State *L) {
#define WSLUA_OPTARG_DissectorTable_new_UINAME 2 /* The name of the table in the user interface.
Defaults to the name given in `tablename`, but can be any string. */
#define WSLUA_OPTARG_DissectorTable_new_TYPE 3 /* One of `ftypes.UINT8`, `ftypes.UINT16`,
- `ftypes.UINT24`, `ftypes.UINT32`, or
- `ftypes.STRING`.
+ `ftypes.UINT24`, `ftypes.UINT32`,
+ `ftypes.STRING`, or `ftypes.GUID`.
Defaults to `ftypes.UINT32`. */
#define WSLUA_OPTARG_DissectorTable_new_BASE 4 /* One of `base.NONE`, `base.DEC`, `base.HEX`,
`base.OCT`, `base.DEC_HEX` or `base.HEX_DEC`.
@@ -194,12 +198,16 @@ WSLUA_CONSTRUCTOR DissectorTable_new (lua_State *L) {
case FT_UINT32:
break;
+ case FT_GUID:
+ base = BASE_HEX;
+ break;
+
default:
/* Calling WSLUA_OPTARG_ERROR raises a Lua error and
returns from this function. */
WSLUA_OPTARG_ERROR(
DissectorTable_new, TYPE,
- "must be ftypes.UINT{8,16,24,32}, ftypes.STRING or ftypes.NONE");
+ "must be ftypes.UINT{8,16,24,32}, ftypes.STRING, ftypes.GUID or ftypes.NONE");
break;
}
@@ -397,6 +405,21 @@ WSLUA_METHOD DissectorTable_add (lua_State *L) {
gchar* pattern = g_strdup(luaL_checkstring(L,WSLUA_ARG_DissectorTable_add_PATTERN));
dissector_add_string(dt->name, pattern,handle);
g_free (pattern);
+ } else if (type == FT_GUID) {
+ /* Handle GUID type (assuming it is represented as a string in Lua) */
+ const gchar* guid_str = luaL_checkstring(L,WSLUA_ARG_DissectorTable_add_PATTERN);
+ fvalue_t* fval = fvalue_from_literal(type, guid_str, 0, NULL);
+ const e_guid_t* guid = fvalue_get_guid(fval);
+ guid_key gk = {*guid, 0};
+ /* The dcerpc.uuid table requires its own initializer */
+ if(strcmp(DCERPC_TABLE_NAME, dt->name) == 0) {
+ e_guid_t uuid;
+ memcpy(&uuid, guid, sizeof(e_guid_t));
+ dcerpc_init_from_handle(dissector_handle_get_protocol_index(handle), &uuid, 0, handle);
+ } else {
+ dissector_add_guid(dt->name, &gk, handle);
+ guids_add_uuid(guid, dissector_handle_get_protocol_short_name(handle));
+ }
} else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
if (lua_isnumber(L, WSLUA_ARG_DissectorTable_add_PATTERN)) {
int port = (int)luaL_checkinteger(L, WSLUA_ARG_DissectorTable_add_PATTERN);
@@ -459,6 +482,21 @@ WSLUA_METHOD DissectorTable_set (lua_State *L) {
const gchar* pattern = luaL_checkstring(L,WSLUA_ARG_DissectorTable_set_PATTERN);
dissector_delete_all(dt->name, handle);
dissector_add_string(dt->name, pattern,handle);
+ } else if (type == FT_GUID) {
+ /* Handle GUID type (assuming it is represented as a string in Lua) */
+ const gchar* guid_str = luaL_checkstring(L,WSLUA_ARG_DissectorTable_set_PATTERN);
+ fvalue_t* fval = fvalue_from_literal(type, guid_str, 0, NULL);
+ const e_guid_t* guid = fvalue_get_guid(fval);
+ guid_key gk = {*guid, 0};
+ /* The dcerpc.uuid table requires its own initializer */
+ if(strcmp(DCERPC_TABLE_NAME, dt->name) == 0) {
+ e_guid_t uuid;
+ memcpy(&uuid, guid, sizeof(e_guid_t));
+ dcerpc_init_from_handle(dissector_handle_get_protocol_index(handle), &uuid, 0, handle);
+ } else {
+ dissector_add_guid(dt->name, &gk, handle);
+ guids_add_uuid(guid, dissector_handle_get_protocol_short_name(handle));
+ }
} else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
if (lua_isnumber(L, WSLUA_ARG_DissectorTable_set_PATTERN)) {
int port = (int)luaL_checkinteger(L, WSLUA_ARG_DissectorTable_set_PATTERN);
@@ -515,6 +553,14 @@ WSLUA_METHOD DissectorTable_remove (lua_State *L) {
gchar* pattern = g_strdup(luaL_checkstring(L,WSLUA_ARG_DissectorTable_remove_PATTERN));
dissector_delete_string(dt->name, pattern,handle);
g_free (pattern);
+ } else if (type == FT_GUID) {
+ // Handle GUID type (assuming it is represented as a string in Lua)
+ const gchar* guid_str = luaL_checkstring(L,WSLUA_ARG_DissectorTable_remove_PATTERN);
+ fvalue_t* fval = fvalue_from_literal(type, guid_str, 0, NULL);
+ const e_guid_t* guid = fvalue_get_guid(fval);
+ guid_key gk = {*guid, 0};
+ guids_delete_guid(guid);
+ dissector_delete_guid(dt->name, &gk, handle);
} else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
if (lua_isnumber(L, WSLUA_ARG_DissectorTable_remove_PATTERN)) {
int port = (int)luaL_checkinteger(L, WSLUA_ARG_DissectorTable_remove_PATTERN);
@@ -596,6 +642,16 @@ WSLUA_METHOD DissectorTable_try (lua_State *L) {
if (len > 0) {
handled = TRUE;
}
+ } else if ( type == FT_GUID ) {
+ const gchar* guid_str = luaL_checkstring(L,WSLUA_ARG_DissectorTable_try_PATTERN);
+ fvalue_t* fval = fvalue_from_literal(type, guid_str, 0, NULL);
+ const e_guid_t* guid = fvalue_get_guid(fval);
+ guid_key gk = {*guid, 0};
+
+ len = dissector_try_guid(dt->table, &gk,tvb->ws_tvb,pinfo->ws_pinfo,ti->tree);
+ if (len > 0) {
+ handled = TRUE;
+ }
} else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
int port = (int)luaL_checkinteger(L, WSLUA_ARG_DissectorTable_try_PATTERN);
@@ -639,6 +695,12 @@ WSLUA_METHOD DissectorTable_get_dissector (lua_State *L) {
if (type == FT_STRING) {
const gchar* pattern = luaL_checkstring(L,WSLUA_ARG_DissectorTable_get_dissector_PATTERN);
handle = dissector_get_string_handle(dt->table,pattern);
+ } else if ( type == FT_GUID ) {
+ const gchar* guid_str = luaL_checkstring(L,WSLUA_ARG_DissectorTable_get_dissector_PATTERN);
+ fvalue_t* fval = fvalue_from_literal(type, guid_str, 0, NULL);
+ const e_guid_t* guid = fvalue_get_guid(fval);
+ guid_key gk = {*guid, 0};
+ handle = dissector_get_guid_handle(dt->table,&gk);
} else if ( type == FT_UINT32 || type == FT_UINT16 || type == FT_UINT8 || type == FT_UINT24 ) {
int port = (int)luaL_checkinteger(L, WSLUA_ARG_DissectorTable_get_dissector_PATTERN);
handle = dissector_get_uint_handle(dt->table,port);
@@ -703,6 +765,11 @@ WSLUA_METAMETHOD DissectorTable__tostring(lua_State* L) {
g_string_append_printf(s,"%s Integer(%i):\n",dt->name,base);
break;
}
+ case FT_GUID:
+ {
+ g_string_append_printf(s,"%s GUID:\n",dt->name);
+ break;
+ }
case FT_NONE:
{
g_string_append_printf(s,"%s only for Decode As:\n",dt->name);