/*! * @file common_base.h * @brief Declarations of macros and types that apply to almost any Meterpreter component. */ #ifndef _METERPRETER_COMMON_BASE_H #define _METERPRETER_COMMON_BASE_H #include "common_core.h" /*! @brief Function pointer type that defines the interface for a dispatch handler. */ typedef DWORD(*DISPATCH_ROUTINE)(Remote *remote, Packet *packet); typedef BOOL(*INLINE_DISPATCH_ROUTINE)(Remote *remote, Packet *packet, DWORD* result); /*! @brief Specifies the maximum number of arguments that are checked/handled * in a request/response packet dispatcher. */ #define MAX_CHECKED_ARGUMENTS 16 /*! @brief Flag indicating that the command arguments repeat. */ #define ARGUMENT_FLAG_REPEAT (1 << 28) /*! @brief Mask indicating the range numbers allowed for command arguments. */ #define ARGUMENT_FLAG_MASK 0x0fffffff /*! @brief Helper macro that contains the required NULL initialisations for a command handler TLV info. */ #define EMPTY_TLV { 0 }, 0 /*! @brief Helper macro which defines an empty dispatch handler. */ #define EMPTY_DISPATCH_HANDLER NULL, NULL, EMPTY_TLV /*! @brief Helper macro that defines terminator for command lists. */ #define COMMAND_TERMINATOR { 0, { EMPTY_DISPATCH_HANDLER }, { EMPTY_DISPATCH_HANDLER } } /*! * @brief Helper macro that defines a command instance with a request handler only. * @remarks The request handler will be executed on a separate thread. */ #define COMMAND_REQ(command_id, reqHandler) { command_id, { reqHandler, NULL, EMPTY_TLV }, { EMPTY_DISPATCH_HANDLER } } /*! * @brief Helper macro that defines a command instance with a response handler only. * @remarks The request handler will be executed on a separate thread. */ #define COMMAND_REP(command_id, repHandler) { command_id, { EMPTY_DISPATCH_HANDLER }, { repHandler, NULL, EMPTY_TLV } } /*! * @brief Helper macro that defines a command instance with both a request and response handler. * @remarks The request handler will be executed on a separate thread. */ #define COMMAND_REQ_REP(command_id, reqHandler, repHandler) { command_id, { reqHandler, NULL, EMPTY_TLV }, { repHandler, NULL, EMPTY_TLV } } /*! * @brief Helper macro that defines a command instance with an inline request handler only. * @remarks The request handler will be executed on the server thread. */ #define COMMAND_INLINE_REQ(command_id, reqHandler) { command_id, { NULL, reqHandler, EMPTY_TLV }, { EMPTY_DISPATCH_HANDLER } } /*! * @brief Helper macro that defines a command instance with an inline response handler only. * @remarks The response handler will be executed on the server thread. */ #define COMMAND_INLINE_REP(command_id, reqHandler) { command_id, { EMPTY_DISPATCH_HANDLER }, { NULL, reqHandler, EMPTY_TLV } } /*! * @brief Defines a command handler for requests and responses. */ typedef struct { /*! @brief Pointer to the routine that will be called to handle the request/response. */ DISPATCH_ROUTINE handler; /*! * @brief Pointer to the routine that will be called on the _current thread_. * @remark If this function is specified then it will be invoked on the current server * thread rather than having a new thread allocated to it for processing. * The result of this routine will indicate whether the server should continue. * If this value is specified (ie. non-NULL) then the \c handler value is ignored. */ INLINE_DISPATCH_ROUTINE inline_handler; /*! @brief Array of types that match the expected arguments for this response/request routine. */ TlvMetaType argumentTypes[MAX_CHECKED_ARGUMENTS]; /*! @brief The number of entries in the \c argumentTypes array. */ DWORD numArgumentTypes; } PacketDispatcher; /*! * @brief Container for a command definition. */ typedef struct command { UINT command_id; ///< Identifier for the command. PacketDispatcher request; ///< Defines the request handler. PacketDispatcher response; ///< Defines the response handler. // Internal -- not stored struct command *next; ///< Pointer to the next command in the command list. struct command *prev; ///< Pointer to the previous command in the command list. } Command; #endif