metasploit-framework/external/source/vncdll/loader/context.c

274 lines
9.6 KiB
C

#include "loader.h"
#include "context.h"
AGENT_CTX AgentContext = {0};
/*
*
*/
VOID context_init( VOID )
{
memset( &AgentContext, 0, sizeof(AGENT_CTX) );
AgentContext.bDisableCourtesyShell = FALSE;
AgentContext.bInit = TRUE;
AgentContext.hCloseEvent = NULL;
AgentContext.dwEncoding = 0;
AgentContext.dwCompressLevel = 6;
AgentContext.dwQualityLevel = -1;
AgentContext.bUseCopyRect = FALSE;
AgentContext.bEncodingRichCursor = FALSE;
AgentContext.bEncodingPointerPos = FALSE;
AgentContext.bEncodingLastRect = FALSE;
AgentContext.bEncodingNewfbSize = FALSE;
AgentContext.bEncodingXCursor = FALSE;
/*AgentContext.dictionaries[0] = NULL;
AgentContext.dictionaries[1] = NULL;
AgentContext.dictionaries[2] = NULL;
AgentContext.dictionaries[3] = NULL;*/
AgentContext.dwPipeName = ( GetTickCount() ^ (DWORD)&AgentContext );
}
/*
* Try to read an exact ammount of data from a pipe and return
* when either the data has been read or a failure occurs.
*/
DWORD _readexact( HANDLE hPipe, DWORD dwLength, BYTE * pBuffer )
{
DWORD dwTotal = 0;
DWORD dwRead = 0;
do
{
while( dwTotal < dwLength )
{
if( !PeekNamedPipe( hPipe, NULL, 0, NULL, &dwRead, NULL ) )
break;
if( !dwRead )
{
Sleep( 50 );
continue;
}
if( ReadFile( hPipe, (LPVOID)((LPBYTE)pBuffer + dwTotal), (dwLength - dwTotal), &dwRead, NULL ) )
dwTotal += dwRead;
}
} while( 0 );
return dwTotal;
}
/*
* A thread to pick up any messages being posted back to the loader (such as an encoder change in the stream)
*/
DWORD WINAPI context_message_thread( LPVOID lpParameter )
{
DWORD dwResult = ERROR_SUCCESS;
HANDLE hServerPipe = NULL;
BYTE * pBuffer = NULL;
char cNamedPipe[MAX_PATH] = {0};
__try
{
do
{
_snprintf( cNamedPipe, MAX_PATH, "\\\\.\\pipe\\%08X", AgentContext.dwPipeName );
dprintf("[LOADER] loader_message_thread. cNamedPipe=%s", cNamedPipe );
hServerPipe = CreateNamedPipe( cNamedPipe, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE|PIPE_READMODE_BYTE|PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 0, 0, 0, NULL );
if( !hServerPipe )
BREAK_ON_ERROR( "[LOADER] loader_message_thread. CreateNamedPipe failed" );
while( TRUE )
{
struct _hdr {
DWORD dwMessage;
DWORD dwLength;
} header = {0};
DWORD dwTotal = 0;
if( !ConnectNamedPipe( hServerPipe, NULL ) )
{
if( GetLastError() != ERROR_PIPE_CONNECTED )
continue;
}
dwTotal = _readexact( hServerPipe, 8, (BYTE *)&header );
if( dwTotal != sizeof( struct _hdr ) )
BREAK_WITH_ERROR( "[LOADER] loader_message_thread. _readexact header failed", ERROR_INVALID_HANDLE );
pBuffer = (BYTE *)malloc( header.dwLength );
if( !pBuffer )
BREAK_WITH_ERROR( "[LOADER] loader_message_thread. pBuffer malloc failed", ERROR_INVALID_HANDLE );
dwTotal = _readexact( hServerPipe, header.dwLength, pBuffer );
if( dwTotal != header.dwLength )
BREAK_WITH_ERROR( "[LOADER] loader_message_thread. _readexact pBuffer failed", ERROR_INVALID_HANDLE );
DisconnectNamedPipe( hServerPipe );
switch( header.dwMessage )
{
case MESSAGE_SETENCODING:
if( header.dwLength != sizeof(DWORD) )
{
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODING, not enought data (got %d bytes)", header.dwLength );
break;
}
AgentContext.dwEncoding = *(DWORD *)pBuffer;
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODING, new encoding is %d", AgentContext.dwEncoding );
break;
case MESSAGE_SETPIXELFORMAT:
if( header.dwLength != sizeof(PIXELFORMAT) )
{
dprintf("[LOADER] loader_message_thread. MESSAGE_SETPIXELFORMAT, not enought data (got %d bytes)", header.dwLength );
break;
}
memcpy( &AgentContext.PixelFormat, pBuffer, sizeof(PIXELFORMAT) );
dprintf("[LOADER] loader_message_thread. MESSAGE_SETPIXELFORMAT" );
break;
case MESSAGE_SETCOMPRESSLEVEL:
if( header.dwLength != sizeof(DWORD) )
{
dprintf("[LOADER] loader_message_thread. MESSAGE_SETCOMPRESSLEVEL, not enought data (got %d bytes)", header.dwLength );
break;
}
AgentContext.dwCompressLevel = *(DWORD *)pBuffer;
dprintf("[LOADER] loader_message_thread. MESSAGE_SETCOMPRESSLEVEL, new compress level is %d", AgentContext.dwCompressLevel );
break;
case MESSAGE_SETQUALITYLEVEL:
if( header.dwLength != sizeof(DWORD) )
{
dprintf("[LOADER] loader_message_thread. MESSAGE_SETQUALITYLEVEL, not enought data (got %d bytes)", header.dwLength );
break;
}
AgentContext.dwQualityLevel = *(DWORD *)pBuffer;
dprintf("[LOADER] loader_message_thread. MESSAGE_SETQUALITYLEVEL, new quality level is %d", AgentContext.dwQualityLevel );
break;
case MESSAGE_SETCOPYRECTUSE:
if( header.dwLength != sizeof(BOOL) )
{
dprintf("[LOADER] loader_message_thread. MESSAGE_SETCOPYRECTUSE, not enought data (got %d bytes)", header.dwLength );
break;
}
AgentContext.bUseCopyRect = *(BOOL *)pBuffer;
dprintf("[LOADER] loader_message_thread. MESSAGE_SETCOPYRECTUSE, new bUseCopyRect is %d", AgentContext.bUseCopyRect );
break;
case MESSAGE_SETENCODINGRICHCURSOR:
if( header.dwLength != sizeof(BOOL) )
{
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODINGRICHCURSOR, not enought data (got %d bytes)", header.dwLength );
break;
}
AgentContext.bEncodingRichCursor = *(BOOL *)pBuffer;
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODINGRICHCURSOR, new dwEncodingRichCursor is %d", AgentContext.bEncodingRichCursor );
break;
case MESSAGE_SETENCODINGPOINTERPOS:
if( header.dwLength != sizeof(BOOL) )
{
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODINGPOINTERPOS, not enought data (got %d bytes)", header.dwLength );
break;
}
AgentContext.bEncodingPointerPos = *(BOOL *)pBuffer;
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODINGPOINTERPOS, new dwEncodingPointerPos is %d", AgentContext.bEncodingPointerPos );
break;
case MESSAGE_SETENCODINGLASTRECT:
if( header.dwLength != sizeof(BOOL) )
{
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODINGLASTRECT, not enought data (got %d bytes)", header.dwLength );
break;
}
AgentContext.bEncodingLastRect = *(BOOL *)pBuffer;
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODINGLASTRECT, new dwEncodingLastRect is %d", AgentContext.bEncodingLastRect );
break;
case MESSAGE_SETENCODINGNEWFBSIZE:
if( header.dwLength != sizeof(BOOL) )
{
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODINGNEWFBSIZE, not enought data (got %d bytes)", header.dwLength );
break;
}
AgentContext.bEncodingNewfbSize = *(BOOL *)pBuffer;
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODINGNEWFBSIZE, new bEncodingNewfbSize is %d", AgentContext.bEncodingNewfbSize );
break;
case MESSAGE_SETENCODINGXCURSOR:
if( header.dwLength != sizeof(BOOL) )
{
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODINGXCURSOR, not enought data (got %d bytes)", header.dwLength );
break;
}
AgentContext.bEncodingXCursor = *(BOOL *)pBuffer;
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODINGXCURSOR, new bEncodingXCursor is %d", AgentContext.bEncodingXCursor );
break;
/*
case MESSAGE_SETZLIBDICTIONARY:
if( header.dwLength < sizeof(DICTMSG) )
{
dprintf("[LOADER] loader_message_thread. MESSAGE_SETZLIBDICTIONARY, not enought data (got %d bytes)", header.dwLength );
break;
}
else
{
DICTMSG * dmsg = (DICTMSG *)pBuffer;
if( dmsg->dwId > 4 )
{
dprintf("[LOADER] loader_message_thread. MESSAGE_SETZLIBDICTIONARY, invalid id (got %d)", dmsg->dwId );
break;
}
if( AgentContext.dictionaries[dmsg->dwId] )
free( AgentContext.dictionaries[dmsg->dwId] );
AgentContext.dictionaries[dmsg->dwId] = (DICTMSG *)malloc( sizeof(DICTMSG) + dmsg->dwDictLength );
if( !AgentContext.dictionaries[dmsg->dwId] )
{
dprintf("[LOADER] loader_message_thread. MESSAGE_SETZLIBDICTIONARY, malloc failed" );
break;
}
AgentContext.dictionaries[dmsg->dwId]->dwId = dmsg->dwId;
AgentContext.dictionaries[dmsg->dwId]->dwDictLength = dmsg->dwDictLength;
memcpy( &AgentContext.dictionaries[dmsg->dwId]->bDictBuffer, &dmsg->bDictBuffer, dmsg->dwDictLength );
dprintf("[LOADER] loader_message_thread. MESSAGE_SETZLIBDICTIONARY, id=%d, length=%d", dmsg->dwId, dmsg->dwDictLength );
}
break;
*/
default:
dprintf("[LOADER] loader_message_thread. Unknown message 0x%08X", header.dwMessage );
break;
}
if( pBuffer )
{
free( pBuffer );
pBuffer = NULL;
}
}
} while( 0 );
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
dprintf( "[LOADER] loader_message_thread. EXCEPTION_EXECUTE_HANDLER\n\n" );
}
dprintf("[LOADER] loader_message_thread. thread finishing...");
if( hServerPipe )
{
DisconnectNamedPipe( hServerPipe );
CLOSE_HANDLE( hServerPipe );
}
if( pBuffer )
free( pBuffer );
return dwResult;
}