From dffbf426edaa3da6931d7d8a317a5f73eeb4a8a4 Mon Sep 17 00:00:00 2001 From: Sinaei Date: Thu, 12 Oct 2023 12:45:50 +0900 Subject: [PATCH] add support to modules in the event forwarding --- CHANGELOG.md | 1 + .../commands/debugging-commands/output.cpp | 23 ++++++- .../debugger/communication/forwarding.cpp | 66 +++++++++++++++++-- hyperdbg/hprdbgctrl/header/forwarding.h | 32 ++++++--- 4 files changed, 108 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b80cd0e5..2de3bb4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ New release of the HyperDbg Debugger. ### Added - **!crwrite** - Control Register Modification Event ([link](https://docs.hyperdbg.org/commands/extension-commands/crwrite)) - The Event Forwarding mechanism is now supported in the Debugger Mode ([link](https://docs.hyperdbg.org/tips-and-tricks/misc/event-forwarding)) +- The Event Forwarding mechanism now supports external modules (DLLs) ([link](https://docs.hyperdbg.org/tips-and-tricks/misc/event-forwarding)) ### Changed - Fix the problem with the "less than" and the "greater than" operators for signed numbers thanks to [@xmaple555](https://github.com/xmaple555) ([link](https://github.com/HyperDbg/HyperDbg/pull/279)) diff --git a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/output.cpp b/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/output.cpp index e45d9a91..7c02e311 100644 --- a/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/output.cpp +++ b/hyperdbg/hprdbgctrl/code/debugger/commands/debugging-commands/output.cpp @@ -37,6 +37,8 @@ CommandOutputHelp() ShowMessages("\t\te.g : output create MyOutputName2 tcp 192.168.1.10:8080\n"); ShowMessages("\t\te.g : output create MyOutputName3 namedpipe " "\\\\.\\Pipe\\HyperDbgOutput\n"); + ShowMessages("\t\te.g : output create MyOutputName1 module " + "c:\\rev\\event_forwarding.dll\n"); ShowMessages("\t\te.g : output open MyOutputName1\n"); ShowMessages("\t\te.g : output close MyOutputName1\n"); } @@ -60,6 +62,7 @@ CommandOutput(vector SplittedCommand, string Command) BOOLEAN OutputSourceFound = FALSE; HANDLE SourceHandle = INVALID_HANDLE_VALUE; SOCKET Socket = NULL; + HMODULE Module = NULL; vector SplittedCommandCaseSensitive {Split(Command, ' ')}; // @@ -116,6 +119,10 @@ CommandOutput(vector SplittedCommand, string Command) { TempTypeString = "tcp "; } + else if (CurrentOutputSourceDetails->Type == EVENT_FORWARDING_MODULE) + { + TempTypeString = "module "; + } ShowMessages("%x %s %s\t%s\n", IndexToShowList, TempTypeString.c_str(), TempStateString.c_str(), CurrentOutputSourceDetails->Name); } @@ -169,6 +176,10 @@ CommandOutput(vector SplittedCommand, string Command) { Type = EVENT_FORWARDING_TCP; } + else if (!SplittedCommand.at(3).compare("module")) + { + Type = EVENT_FORWARDING_MODULE; + } else { ShowMessages("incorrect type near '%s'\n\n", @@ -240,7 +251,7 @@ CommandOutput(vector SplittedCommand, string Command) SplittedCommandCaseSensitive.at(3).size() + 1, Command.size()); - SourceHandle = ForwardingCreateOutputSource(Type, DetailsOfSource, &Socket); + SourceHandle = ForwardingCreateOutputSource(Type, DetailsOfSource, &Socket, &Module); // // Check if it's a valid handle or not @@ -283,11 +294,21 @@ CommandOutput(vector SplittedCommand, string Command) // // Set the handle or in the case of TCP, set the socket + // or if it's a module the set the module handle // if (Type == EVENT_FORWARDING_TCP) { EventForwardingObject->Socket = Socket; } + else if (Type == EVENT_FORWARDING_MODULE) + { + EventForwardingObject->Module = Module; + + // + // Handle is the function address + // + EventForwardingObject->Handle = SourceHandle; + } else { EventForwardingObject->Handle = SourceHandle; diff --git a/hyperdbg/hprdbgctrl/code/debugger/communication/forwarding.cpp b/hyperdbg/hprdbgctrl/code/debugger/communication/forwarding.cpp index 2fa33277..903a53ee 100644 --- a/hyperdbg/hprdbgctrl/code/debugger/communication/forwarding.cpp +++ b/hyperdbg/hprdbgctrl/code/debugger/communication/forwarding.cpp @@ -88,6 +88,14 @@ ForwardingOpenOutputSource(PDEBUGGER_EVENT_FORWARDING SourceDescriptor) // return DEBUGGER_OUTPUT_SOURCE_STATUS_SUCCESSFULLY_OPENED; } + else if (SourceDescriptor->Type == EVENT_FORWARDING_MODULE) + { + // + // Nothing special to do here, function is found previously + // and nothing should be called to open the module + // + return DEBUGGER_OUTPUT_SOURCE_STATUS_SUCCESSFULLY_OPENED; + } return DEBUGGER_OUTPUT_SOURCE_STATUS_UNKNOWN_ERROR; } @@ -170,6 +178,18 @@ ForwardingCloseOutputSource(PDEBUGGER_EVENT_FORWARDING SourceDescriptor) // return DEBUGGER_OUTPUT_SOURCE_STATUS_SUCCESSFULLY_CLOSED; } + else if (SourceDescriptor->Type == EVENT_FORWARDING_MODULE) + { + // + // Free the library + // + FreeLibrary(SourceDescriptor->Module); + + // + // Return the status + // + return DEBUGGER_OUTPUT_SOURCE_STATUS_SUCCESSFULLY_CLOSED; + } return DEBUGGER_OUTPUT_SOURCE_STATUS_UNKNOWN_ERROR; } @@ -179,6 +199,7 @@ ForwardingCloseOutputSource(PDEBUGGER_EVENT_FORWARDING SourceDescriptor) * @param SourceType Type of the source * @param Description Description of the source * @param Socket Socket object in the case of TCP connection + * @param Module Module object in the case of loading modules * * @details If the target connection is a tcp connection then there * is no handle and instead there is a socket, this way we pass a @@ -190,10 +211,11 @@ ForwardingCloseOutputSource(PDEBUGGER_EVENT_FORWARDING SourceDescriptor) * * @return HANDLE returns handle of the source */ -HANDLE +VOID * ForwardingCreateOutputSource(DEBUGGER_EVENT_FORWARDING_TYPE SourceType, const string & Description, - SOCKET * Socket) + SOCKET * Socket, + HMODULE * Module) { string IpPortDelimiter; string Ip; @@ -210,7 +232,35 @@ ForwardingCreateOutputSource(DEBUGGER_EVENT_FORWARDING_TYPE SourceType, // The handle might be INVALID_HANDLE_VALUE which will be // checked by the caller // - return FileHandle; + return (void *)FileHandle; + } + else if (SourceType == EVENT_FORWARDING_MODULE) + { + HMODULE ModuleHandle = LoadLibraryA(Description.c_str()); + + if (ModuleHandle == NULL) + { + ShowMessages("err, unable to load the module\n"); + return INVALID_HANDLE_VALUE; + } + + hyperdbg_event_forwarding_t hyperdbg_event_forwarding = (hyperdbg_event_forwarding_t)GetProcAddress(ModuleHandle, "hyperdbg_event_forwarding"); + + if (hyperdbg_event_forwarding == NULL) + { + ShowMessages("err, unable to find the 'hyperdbg_event_forwarding' function\n"); + return INVALID_HANDLE_VALUE; + } + + // + // Set the module handle + // + *Module = ModuleHandle; + + // + // The handle is the location of the hyperdbg_event_forwarding function + // + return (void *)hyperdbg_event_forwarding; } else if (SourceType == EVENT_FORWARDING_NAMEDPIPE) { @@ -224,7 +274,7 @@ ForwardingCreateOutputSource(DEBUGGER_EVENT_FORWARDING_TYPE SourceType, return INVALID_HANDLE_VALUE; } - return PipeHandle; + return (void *)PipeHandle; } else if (SourceType == EVENT_FORWARDING_TCP) { @@ -252,7 +302,7 @@ ForwardingCreateOutputSource(DEBUGGER_EVENT_FORWARDING_TYPE SourceType, // because this functionality doesn't work with handlers; however, // send 1 or TRUE is a valid handle // - return (HANDLE)TRUE; + return (void *)TRUE; } else { @@ -353,6 +403,12 @@ ForwardingPerformEventForwarding(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetail, Message, MessageLength); break; + case EVENT_FORWARDING_MODULE: + ((hyperdbg_event_forwarding_t)CurrentOutputSourceDetails->Handle)( + Message, + MessageLength); + Result = TRUE; + break; default: break; } diff --git a/hyperdbg/hprdbgctrl/header/forwarding.h b/hyperdbg/hprdbgctrl/header/forwarding.h index 3b855ecf..9b74bda5 100644 --- a/hyperdbg/hprdbgctrl/header/forwarding.h +++ b/hyperdbg/hprdbgctrl/header/forwarding.h @@ -11,6 +11,16 @@ */ #pragma once +////////////////////////////////////////// +// Forwarding Types // +////////////////////////////////////////// + +/** + * @brief maximum characters for event forwarding source names + * + */ +typedef void (*hyperdbg_event_forwarding_t)(const char *, unsigned int); + ////////////////////////////////////////// // Output Source Forwarding // ////////////////////////////////////////// @@ -29,7 +39,9 @@ typedef enum _DEBUGGER_EVENT_FORWARDING_TYPE { EVENT_FORWARDING_NAMEDPIPE, EVENT_FORWARDING_FILE, - EVENT_FORWARDING_TCP + EVENT_FORWARDING_TCP, + EVENT_FORWARDING_MODULE, + } DEBUGGER_EVENT_FORWARDING_TYPE; /** @@ -40,7 +52,8 @@ typedef enum _DEBUGGER_EVENT_FORWARDING_STATE { EVENT_FORWARDING_STATE_NOT_OPENED, EVENT_FORWARDING_STATE_OPENED, - EVENT_FORWARDING_CLOSED + EVENT_FORWARDING_CLOSED, + } DEBUGGER_EVENT_FORWARDING_STATE; /** @@ -56,6 +69,7 @@ typedef enum _DEBUGGER_OUTPUT_SOURCE_STATUS DEBUGGER_OUTPUT_SOURCE_STATUS_ALREADY_OPENED, DEBUGGER_OUTPUT_SOURCE_STATUS_ALREADY_CLOSED, DEBUGGER_OUTPUT_SOURCE_STATUS_UNKNOWN_ERROR, + } DEBUGGER_OUTPUT_SOURCE_STATUS; /** @@ -66,8 +80,9 @@ typedef struct _DEBUGGER_EVENT_FORWARDING { DEBUGGER_EVENT_FORWARDING_TYPE Type; DEBUGGER_EVENT_FORWARDING_STATE State; - HANDLE Handle; + VOID * Handle; SOCKET Socket; + HMODULE Module; UINT64 OutputUniqueTag; LIST_ENTRY OutputSourcesList; // Linked-list of output sources list @@ -88,11 +103,6 @@ ForwardingOpenOutputSource(PDEBUGGER_EVENT_FORWARDING SourceDescriptor); DEBUGGER_OUTPUT_SOURCE_STATUS ForwardingCloseOutputSource(PDEBUGGER_EVENT_FORWARDING SourceDescriptor); -HANDLE -ForwardingCreateOutputSource(DEBUGGER_EVENT_FORWARDING_TYPE SourceType, - const string & Description, - SOCKET * Socket); - BOOLEAN ForwardingCheckAndPerformEventForwarding(UINT32 OperationCode, CHAR * Message, @@ -106,3 +116,9 @@ ForwardingSendToNamedPipe(HANDLE NamedPipeHandle, CHAR * Message, UINT32 Message BOOLEAN ForwardingSendToTcpSocket(SOCKET TcpSocket, CHAR * Message, UINT32 MessageLength); + +VOID * +ForwardingCreateOutputSource(DEBUGGER_EVENT_FORWARDING_TYPE SourceType, + const string & Description, + SOCKET * Socket, + HMODULE * Module);