support starting suspended (-s)

This commit is contained in:
Pavel Yosifovich
2024-07-21 19:14:27 -04:00
parent 6262854131
commit e6185bff26
9 changed files with 833 additions and 9 deletions
+24 -6
View File
@@ -15,14 +15,29 @@ int Error(NTSTATUS status) {
int wmain(int argc, const wchar_t* argv[]) {
if (argc < 2) {
printf("Usage: nativerun [-d] <executable> [arguments...]\n");
printf("Usage: nativerun [-d] [-s] <executable> [arguments...]\n");
return 0;
}
int start = 1;
bool debug = _wcsicmp(argv[1], L"-d") == 0;
if (debug)
start = 2;
bool debug = false;
bool suspended = false;
for (int i = 0; i < 2; i++) {
if (!debug) {
debug = _wcsicmp(argv[start], L"-d") == 0;
if (debug) {
start++;
continue;
}
}
if (!suspended) {
suspended = _wcsicmp(argv[start], L"-s") == 0;
if (suspended) {
start++;
continue;
}
}
}
//
// build command line arguments
@@ -52,14 +67,17 @@ int wmain(int argc, const wchar_t* argv[]) {
RtlDestroyProcessParameters(params);
auto pid = HandleToULong(info.ClientId.UniqueProcess);
printf("Process 0x%X (%u) created successfully.\n", pid, pid);
if (debug) {
printf("Attach with a debugger. Press ENTER to resume thread...\n");
char dummy[3];
gets_s(dummy);
}
ResumeThread(info.ThreadHandle);
if (!suspended) {
ResumeThread(info.ThreadHandle);
}
printf("Process 0x%X (%u) created successfully%s.\n", pid, pid,
suspended ? " (Suspended)" : "");
CloseHandle(info.ThreadHandle);
CloseHandle(info.ProcessHandle);
+30
View File
@@ -7,6 +7,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimpleServer", "SimpleServe
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimpleClient", "SimpleClient\SimpleClient.vcxproj", "{48ECE792-7621-4AA1-8D1D-A0FAA4ECD478}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PortInfo", "PortInfo\PortInfo.vcxproj", "{DE441A62-95C8-40BE-B5E5-835A050987D0}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimpleClient2", "SimpleClient2\SimpleClient2.vcxproj", "{067FA417-3B01-463F-A87D-01DB8C5EB168}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimpleServer2", "SimpleServer2\SimpleServer2.vcxproj", "{AE32E82B-792D-4F3A-9B90-970FA845F23D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -31,6 +37,30 @@ Global
{48ECE792-7621-4AA1-8D1D-A0FAA4ECD478}.Release|x64.Build.0 = Release|x64
{48ECE792-7621-4AA1-8D1D-A0FAA4ECD478}.Release|x86.ActiveCfg = Release|Win32
{48ECE792-7621-4AA1-8D1D-A0FAA4ECD478}.Release|x86.Build.0 = Release|Win32
{DE441A62-95C8-40BE-B5E5-835A050987D0}.Debug|x64.ActiveCfg = Debug|x64
{DE441A62-95C8-40BE-B5E5-835A050987D0}.Debug|x64.Build.0 = Debug|x64
{DE441A62-95C8-40BE-B5E5-835A050987D0}.Debug|x86.ActiveCfg = Debug|Win32
{DE441A62-95C8-40BE-B5E5-835A050987D0}.Debug|x86.Build.0 = Debug|Win32
{DE441A62-95C8-40BE-B5E5-835A050987D0}.Release|x64.ActiveCfg = Release|x64
{DE441A62-95C8-40BE-B5E5-835A050987D0}.Release|x64.Build.0 = Release|x64
{DE441A62-95C8-40BE-B5E5-835A050987D0}.Release|x86.ActiveCfg = Release|Win32
{DE441A62-95C8-40BE-B5E5-835A050987D0}.Release|x86.Build.0 = Release|Win32
{067FA417-3B01-463F-A87D-01DB8C5EB168}.Debug|x64.ActiveCfg = Debug|x64
{067FA417-3B01-463F-A87D-01DB8C5EB168}.Debug|x64.Build.0 = Debug|x64
{067FA417-3B01-463F-A87D-01DB8C5EB168}.Debug|x86.ActiveCfg = Debug|Win32
{067FA417-3B01-463F-A87D-01DB8C5EB168}.Debug|x86.Build.0 = Debug|Win32
{067FA417-3B01-463F-A87D-01DB8C5EB168}.Release|x64.ActiveCfg = Release|x64
{067FA417-3B01-463F-A87D-01DB8C5EB168}.Release|x64.Build.0 = Release|x64
{067FA417-3B01-463F-A87D-01DB8C5EB168}.Release|x86.ActiveCfg = Release|Win32
{067FA417-3B01-463F-A87D-01DB8C5EB168}.Release|x86.Build.0 = Release|Win32
{AE32E82B-792D-4F3A-9B90-970FA845F23D}.Debug|x64.ActiveCfg = Debug|x64
{AE32E82B-792D-4F3A-9B90-970FA845F23D}.Debug|x64.Build.0 = Debug|x64
{AE32E82B-792D-4F3A-9B90-970FA845F23D}.Debug|x86.ActiveCfg = Debug|Win32
{AE32E82B-792D-4F3A-9B90-970FA845F23D}.Debug|x86.Build.0 = Debug|Win32
{AE32E82B-792D-4F3A-9B90-970FA845F23D}.Release|x64.ActiveCfg = Release|x64
{AE32E82B-792D-4F3A-9B90-970FA845F23D}.Release|x64.Build.0 = Release|x64
{AE32E82B-792D-4F3A-9B90-970FA845F23D}.Release|x86.ActiveCfg = Release|Win32
{AE32E82B-792D-4F3A-9B90-970FA845F23D}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
+4 -3
View File
@@ -6,7 +6,7 @@
#pragma comment(lib, "ntdll")
struct Message : PORT_MESSAGE {
char Text[100];
char Text[64];
};
void Delay(int seconds) {
@@ -30,7 +30,7 @@ int main() {
Delay(1);
}
if(!NT_SUCCESS(status))
return 1;
return status;
printf("Client port connected: 0x%p\n", hPort);
LARGE_INTEGER time;
@@ -44,7 +44,7 @@ int main() {
sprintf_s(msg.Text, "The Time is %02d:%02d:%02d.%03d",
tf.Hour, tf.Minute, tf.Second, tf.Milliseconds);
msg.u1.s1.DataLength = sizeof(msg.Text);
msg.u1.s1.TotalLength = msg.u1.s1.DataLength + sizeof(PORT_MESSAGE);
msg.u1.s1.TotalLength = sizeof(msg);
Message reply;
SIZE_T msgLen = sizeof(reply);
@@ -54,6 +54,7 @@ int main() {
printf("NtAlpcSendWaitReceivePort failed: 0x%X\n", status);
break;
}
printf("Sent message %s.\n", msg.Text);
printf("Received reply from PID: %u TID: %u\n",
HandleToULong(reply.ClientId.UniqueProcess),
+242
View File
@@ -0,0 +1,242 @@
#include <phnt_windows.h>
#include <phnt.h>
#include <stdio.h>
#include <memory>
#include <cassert>
#pragma comment(lib, "ntdll")
#define ALPC_FLG_MSG_SEC_ATTR 0x80000000
#define ALPC_FLG_MSG_DATAVIEW_ATTR 0x40000000
#define ALPC_FLG_MSG_CONTEXT_ATTR 0x20000000
#define ALPC_FLG_MSG_HANDLE_ATTR 0x10000000
#define ALPC_FLG_MSG_TOKEN_ATTR 0x08000000
#define ALPC_FLG_MSG_DIRECT_ATTR 0x04000000
#define ALPC_FLG_MSG_WORK_ON_BEHALF_ATTR 0x02000000
typedef enum _ALPC_DUP_OBJECT_TYPE {
ALPC_FILE_OBJECT_TYPE = 0x00000001,
ALPC_THREAD_OBJECT_TYPE = 0x00000004,
ALPC_SEMAPHORE_OBJECT_TYPE = 0x00000008,
ALPC_EVENT_OBJECT_TYPE = 0x00000010,
ALPC_PROCESS_OBJECT_TYPE = 0x00000020,
ALPC_MUTANT_OBJECT_TYPE = 0x00000040,
ALPC_SECTION_OBJECT_TYPE = 0x00000080,
ALPC_REG_KEY_OBJECT_TYPE = 0x00000100,
ALPC_TOKEN_OBJECT_TYPE = 0x00000200,
ALPC_COMPOSITION_OBJECT_TYPE = 0x00000400,
ALPC_JOB_OBJECT_TYPE = 0x00000800,
ALPC_ALL_OBJECT_TYPES = 0x00000FFD,
} DUP_OBJECT_TYPE;
#define OB_FILE_OBJECT_TYPE 0x00000001
#define OB_THREAD_OBJECT_TYPE 0x00000004
#define OB_SEMAPHORE_OBJECT_TYPE 0x00000008
#define OB_EVENT_OBJECT_TYPE 0x00000010
#define OB_PROCESS_OBJECT_TYPE 0x00000020
#define OB_MUTANT_OBJECT_TYPE 0x00000040
#define OB_SECTION_OBJECT_TYPE 0x00000080
#define OB_REG_KEY_OBJECT_TYPE 0x00000100
#define OB_TOKEN_OBJECT_TYPE 0x00000200
#define OB_COMPOSITION_OBJECT_TYPE 0x00000400
#define OB_JOB_OBJECT_TYPE 0x00000800
typedef struct _ALPC_HANDLE_ATTR32 {
union {
ULONG Flags;
struct {
ULONG Reserved0 : 16;
ULONG SameAccess : 1;
ULONG SameAttributes : 1;
ULONG Indirect : 1;
ULONG Inherit : 1;
ULONG Reserved1 : 12;
};
};
ULONG Handle;
ULONG ObjectType;
union {
ULONG DesiredAccess;
ULONG GrantedAccess;
};
} ALPC_HANDLE_ATTR32, * PALPC_HANDLE_ATTR32;
// the structure
typedef struct _ALPC_HANDLE_ATTR {
union {
ULONG Flags;
struct {
ULONG Reserved0 : 16;
ULONG SameAccess : 1;
ULONG SameAttributes : 1;
ULONG Indirect : 1;
ULONG Inherit : 1;
ULONG Reserved1 : 12;
};
};
union {
HANDLE Handle;
PALPC_HANDLE_ATTR32 HandleAttrArray;
};
union {
ULONG ObjectType;
ULONG HandleCount;
};
union {
ACCESS_MASK DesiredAccess;
ACCESS_MASK GrantedAccess;
};
} ALPC_HANDLE_ATTR, * PALPC_HANDLE_ATTR;
struct Message : PORT_MESSAGE {
char Text[64];
};
void Delay(int seconds) {
LARGE_INTEGER time;
time.QuadPart = -10000000LL * seconds;
NtDelayExecution(FALSE, &time);
}
PALPC_MESSAGE_ATTRIBUTES CreateMessageAttributes(ULONG attributes) {
SIZE_T size = AlpcGetHeaderSize(attributes);
auto msgAttr = (PALPC_MESSAGE_ATTRIBUTES)RtlAllocateHeap(NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, size);
assert(msgAttr);
auto status = AlpcInitializeMessageAttribute(attributes, msgAttr, size, &size);
if (NT_SUCCESS(status))
return msgAttr;
RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, msgAttr);
return nullptr;
}
void DestroyMessageAttributes(PALPC_MESSAGE_ATTRIBUTES msgAttr) {
RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, msgAttr);
}
int main() {
HANDLE hPort;
UNICODE_STRING portName;
RtlInitUnicodeString(&portName, L"\\SimpleServerPort2");
NTSTATUS status;
Message connMsg{};
strcpy_s(connMsg.Text, "Abracadabra");
connMsg.u1.s1.DataLength = sizeof(connMsg.Text);
connMsg.u1.s1.TotalLength = sizeof(connMsg);
Message replyMsg{};
auto msgAttr = CreateMessageAttributes(ALPC_FLG_MSG_HANDLE_ATTR | ALPC_FLG_MSG_DATAVIEW_ATTR | ALPC_FLG_MSG_SEC_ATTR);
assert(msgAttr);
msgAttr->ValidAttributes = ALPC_FLG_MSG_HANDLE_ATTR | ALPC_FLG_MSG_DATAVIEW_ATTR;
HANDLE hEvent;
status = NtCreateEvent(&hEvent, EVENT_ALL_ACCESS, nullptr, SynchronizationEvent, FALSE);
assert(NT_SUCCESS(status));
auto handleAttr = (PALPC_HANDLE_ATTR)AlpcGetMessageAttribute(msgAttr, ALPC_FLG_MSG_HANDLE_ATTR);
handleAttr->Flags = 0;
handleAttr->Handle = hEvent;
handleAttr->ObjectType = OB_EVENT_OBJECT_TYPE;
handleAttr->DesiredAccess = EVENT_MODIFY_STATE | SYNCHRONIZE;
for (int i = 0; i < 10; i++) {
status = NtAlpcConnectPort(&hPort, &portName, nullptr, nullptr,
ALPC_MSGFLG_SYNC_REQUEST, nullptr, &connMsg, nullptr,
nullptr, nullptr, nullptr);
if (NT_SUCCESS(status))
break;
printf("NtAlpcConnectPort failed: 0x%X\n", status);
Delay(1);
}
if (!NT_SUCCESS(status)) {
printf("Failed to connect (0x%X)\n", status);
return status;
}
printf("Client port connected: 0x%p\n", hPort);
LARGE_INTEGER time;
TIME_FIELDS tf;
ALPC_HANDLE hPortSection;
SIZE_T actualSize;
status = NtAlpcCreatePortSection(hPort, 0, nullptr, 1 << 12, &hPortSection, &actualSize);
assert(NT_SUCCESS(status));
auto dataView = (PALPC_DATA_VIEW_ATTR)AlpcGetMessageAttribute(msgAttr, ALPC_FLG_MSG_DATAVIEW_ATTR);
assert(dataView);
dataView->Flags = 0;
dataView->SectionHandle = hPortSection;
dataView->ViewSize = actualSize;
status = NtAlpcCreateSectionView(hPort, 0, dataView);
assert(NT_SUCCESS(status));
ALPC_PORT_ASSOCIATE_COMPLETION_PORT iocp{};
NtCreateIoCompletion(&iocp.CompletionPort, IO_COMPLETION_ALL_ACCESS, nullptr, 4);
//iocp.CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 4);
status = NtAlpcSetInformation(hPort, AlpcAssociateCompletionPortInformation, &iocp, sizeof(iocp));
assert(NT_SUCCESS(status));
for (;;) {
Message msg{};
NtQuerySystemTime(&time);
RtlSystemTimeToLocalTime(&time, &time);
RtlTimeToTimeFields(&time, &tf);
sprintf_s(msg.Text, "The Time is %02d:%02d:%02d.%03d",
tf.Hour, tf.Minute, tf.Second, tf.Milliseconds);
msg.u1.s1.DataLength = sizeof(msg.Text);
msg.u1.s1.TotalLength = sizeof(msg);
Message reply{};
LARGE_INTEGER li{};
SIZE_T msgLen = sizeof(reply);
status = NtAlpcSendWaitReceivePort(hPort, 0, &msg,
msgAttr, nullptr, nullptr, nullptr, nullptr);
if (!NT_SUCCESS(status)) {
printf("NtAlpcSendWaitReceivePort failed: 0x%X\n", status);
break;
}
printf("Sent message %s.\n", msg.Text);
printf("Waiting for reply...\n");
struct Context {
HANDLE hPort;
SIZE_T* MsgLen;
Message* Msg;
HANDLE hIocp;
};
Context ctx{ hPort, &msgLen, &reply, iocp.CompletionPort };
TrySubmitThreadpoolCallback([](auto, auto p) {
auto ctx = (Context*)p;
DWORD bytes;
ULONG_PTR key;
OVERLAPPED* ov;
GetQueuedCompletionStatus(ctx->hIocp, &bytes, &key, &ov, INFINITE);
auto status = NtAlpcSendWaitReceivePort(ctx->hPort, 0, nullptr,
nullptr, ctx->Msg, ctx->MsgLen, nullptr, nullptr);
printf("Received reply from PID: %u TID: %u: %s\n",
HandleToULong(ctx->Msg->ClientId.UniqueProcess),
HandleToULong(ctx->Msg->ClientId.UniqueThread),
ctx->Msg->Text);
}, &ctx, nullptr);
auto tick = GetTickCount();
while (GetTickCount() - tick < 6000) {
printf(".");
Sleep(300);
}
printf("\n");
if (GetAsyncKeyState(VK_ESCAPE) < 0)
break;
Delay(5);
}
NtClose(hPort);
return 0;
}
@@ -0,0 +1,135 @@
<?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>{067fa417-3b01-463f-a87d-01db8c5eb168}</ProjectGuid>
<RootNamespace>SimpleClient2</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">
</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="SimpleClient2.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,22 @@
<?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="SimpleClient2.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
+218
View File
@@ -0,0 +1,218 @@
#include <phnt_windows.h>
#include <phnt.h>
#include <cassert>
#include <stdio.h>
#pragma comment(lib, "ntdll")
#define ALPC_FLG_MSG_SEC_ATTR 0x80000000
#define ALPC_FLG_MSG_DATAVIEW_ATTR 0x40000000
#define ALPC_FLG_MSG_CONTEXT_ATTR 0x20000000
#define ALPC_FLG_MSG_HANDLE_ATTR 0x10000000
#define ALPC_FLG_MSG_TOKEN_ATTR 0x08000000
#define ALPC_FLG_MSG_DIRECT_ATTR 0x04000000
#define ALPC_FLG_MSG_WORK_ON_BEHALF_ATTR 0x02000000
#define ALPC_FLG_MSG_ALL_ATTR 0xff000000
#define LPC_CONNECTION_REPLY 11
#define LPC_CANCELED 12
#define LPC_UNREGISTER_PROCESS 13
typedef struct _ALPC_TOKEN_ATTR {
LUID TokenId;
LUID AuthenticationId;
LUID ModifiedId;
} ALPC_TOKEN_ATTR, * PALPC_TOKEN_ATTR;
typedef enum _ALPC_PORT_FLAGS {
ALPC_PORT_FLAG_ALLOW_IMPERSONATION = 0x00010000,
ALPC_PORT_FLAG_ACCEPT_REQUESTS = 0x00020000,
ALPC_PORT_FLAG_WAITABLE_PORT = 0x00040000,
ALPC_PORT_FLAG_ACCEPT_DUP_HANDLES = 0x00080000,
ALPC_PORT_FLAG_SYSTEM_PROCESS = 0x00100000,
ALPC_PORT_FLAG_SUPPRESS_WAKE = 0x00200000,
ALPC_PORT_FLAG_ALWAYS_WAKE = 0x00400000,
ALPC_PORT_FLAG_DO_NOT_DISTURB = 0x00800000,
ALPC_PORT_FLAG_NO_SHARED_SECTION = 0x01000000,
ALPC_PORT_FLAG_ACCEPT_INDIRECT_HANDLES = 0x02000000
} ALPC_PORT_FLAGS;
typedef enum _ALPC_OBJECT_TYPE {
ALPC_FILE_OBJECT_TYPE = 0x00000001,
ALPC_THREAD_OBJECT_TYPE = 0x00000004,
ALPC_SEMAPHORE_OBJECT_TYPE = 0x00000008,
ALPC_EVENT_OBJECT_TYPE = 0x00000010,
ALPC_PROCESS_OBJECT_TYPE = 0x00000020,
ALPC_MUTANT_OBJECT_TYPE = 0x00000040,
ALPC_SECTION_OBJECT_TYPE = 0x00000080,
ALPC_REG_KEY_OBJECT_TYPE = 0x00000100,
ALPC_TOKEN_OBJECT_TYPE = 0x00000200,
ALPC_COMPOSITION_OBJECT_TYPE = 0x00000400,
ALPC_JOB_OBJECT_TYPE = 0x00000800,
ALPC_ALL_OBJECT_TYPES = 0x00000FFD,
} ALPC_OBJECT_TYPE;
typedef struct _ALPC_HANDLE_ATTR32 {
union {
ULONG Flags;
struct {
ULONG Reserved0 : 16;
ULONG SameAccess : 1;
ULONG SameAttributes : 1;
ULONG Indirect : 1;
ULONG Inherit : 1;
ULONG Reserved1 : 12;
};
};
ULONG Handle;
ULONG ObjectType;
union {
ULONG DesiredAccess;
ULONG GrantedAccess;
};
} ALPC_HANDLE_ATTR32, * PALPC_HANDLE_ATTR32;
// the structure
typedef struct _ALPC_HANDLE_ATTR {
union {
ULONG Flags;
struct {
ULONG Reserved0 : 16;
ULONG SameAccess : 1;
ULONG SameAttributes : 1;
ULONG Indirect : 1;
ULONG Inherit : 1;
ULONG Reserved1 : 12;
};
};
union {
HANDLE Handle;
ALPC_HANDLE_ATTR32* HandleAttrArray;
};
union {
ULONG ObjectType;
ULONG HandleCount;
};
union {
ACCESS_MASK DesiredAccess;
ACCESS_MASK GrantedAccess;
};
} ALPC_HANDLE_ATTR, * PALPC_HANDLE_ATTR;
struct Message : PORT_MESSAGE {
char Text[64];
};
PALPC_MESSAGE_ATTRIBUTES CreateMessageAttributes(ULONG attributes) {
SIZE_T size = AlpcGetHeaderSize(attributes);
auto msgAttr = (PALPC_MESSAGE_ATTRIBUTES)RtlAllocateHeap(NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, size);
assert(msgAttr);
auto status = AlpcInitializeMessageAttribute(attributes, msgAttr, size, &size);
if (NT_SUCCESS(status))
return msgAttr;
RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, msgAttr);
return nullptr;
}
int main() {
HANDLE hServerPort;
UNICODE_STRING portName;
RtlInitUnicodeString(&portName, L"\\SimpleServerPort2");
OBJECT_ATTRIBUTES portAttr = RTL_CONSTANT_OBJECT_ATTRIBUTES(&portName, OBJ_CASE_INSENSITIVE);
ALPC_PORT_ATTRIBUTES alpcPortAttr{};
SECURITY_QUALITY_OF_SERVICE qos = { sizeof(qos) };
qos.ImpersonationLevel = SecurityIdentification;
qos.ContextTrackingMode = SECURITY_STATIC_TRACKING;
qos.EffectiveOnly = TRUE;
alpcPortAttr.SecurityQos = qos;
alpcPortAttr.Flags = ALPC_PORT_FLAG_ACCEPT_DUP_HANDLES | ALPC_PORT_FLAG_ALLOW_IMPERSONATION;
alpcPortAttr.DupObjectTypes = ALPC_ALL_OBJECT_TYPES;
alpcPortAttr.MaxMessageLength = sizeof(Message);
alpcPortAttr.MaxPoolUsage = 0x40000;
alpcPortAttr.MaxSectionSize = 0x400000;
alpcPortAttr.MaxTotalSectionSize = 0x400000 * 8;
auto status = NtAlpcCreatePort(&hServerPort, &portAttr, &alpcPortAttr);
if (!NT_SUCCESS(status)) {
printf("NtAlpcCreatePort failed: 0x%X\n", status);
return 1;
}
printf("Server port created: 0x%p\n", hServerPort);
Message sendMsg, recvMsg;
SIZE_T size = sizeof(sendMsg);
Message* sendMessage = nullptr;
Message* receiveMessage = &recvMsg;
auto recvMsgAttr = CreateMessageAttributes(ALPC_FLG_MSG_ALL_ATTR);
assert(recvMsgAttr);
HANDLE hCommPort = nullptr;
for (;;) {
status = NtAlpcSendWaitReceivePort(hServerPort, 0,
sendMessage, nullptr, receiveMessage, &size, recvMsgAttr, nullptr);
if (!NT_SUCCESS(status))
break;
printf("Received msg type: 0x%X (ID: 0x%X)\n",
receiveMessage->u2.s2.Type, receiveMessage->MessageId);
if (recvMsgAttr->ValidAttributes & ALPC_FLG_MSG_TOKEN_ATTR) {
auto tokenAttr = (PALPC_TOKEN_ATTR)AlpcGetMessageAttribute(recvMsgAttr, ALPC_FLG_MSG_TOKEN_ATTR);
printf("Token Attr: Logon session: 0x%X:%08X",
tokenAttr->AuthenticationId.HighPart, tokenAttr->AuthenticationId.LowPart);
}
if (recvMsgAttr->ValidAttributes & ALPC_FLG_MSG_HANDLE_ATTR) {
auto handleAttr = (PALPC_HANDLE_ATTR)AlpcGetMessageAttribute(recvMsgAttr, ALPC_FLG_MSG_HANDLE_ATTR);
printf("Handle available: 0x%p\n", handleAttr->Handle);
}
if (recvMsgAttr->ValidAttributes & ALPC_FLG_MSG_DATAVIEW_ATTR) {
auto dataView = (PALPC_DATA_VIEW_ATTR)AlpcGetMessageAttribute(recvMsgAttr, ALPC_FLG_MSG_DATAVIEW_ATTR);
printf("Section map base address: 0x%p\n", dataView->ViewBase);
}
switch (receiveMessage->u2.s2.Type & 0xff) {
case LPC_CONNECTION_REQUEST:
{
printf("Connection request received from PID: %u TID: %u Text: %s\n",
HandleToULong(receiveMessage->ClientId.UniqueProcess),
HandleToULong(receiveMessage->ClientId.UniqueThread),
receiveMessage->Text);
status = NtAlpcAcceptConnectPort(&hCommPort, hServerPort, 0, nullptr, nullptr, nullptr,
receiveMessage, nullptr, TRUE);
if (!NT_SUCCESS(status)) {
printf("NtAlpcAcceptConnectPort failed: 0x%X\n", status);
}
else {
printf("Client port connected: 0x%p\n", hCommPort);
}
sendMessage = nullptr;
break;
}
case LPC_REQUEST:
printf("\t%s\n", receiveMessage->Text);
sendMessage = receiveMessage;
strcpy_s(sendMessage->Text, "OK.");
sendMessage->u1.s1.DataLength = sizeof(sendMsg.Text);
sendMessage->u1.s1.TotalLength = sizeof(sendMsg);
Sleep(3000);
break;
case LPC_PORT_CLOSED:
case LPC_CLIENT_DIED:
NtClose(hCommPort);
break;
default:
printf("Other message type: 0x%X\n", receiveMessage->u2.s2.Type);
break;
}
}
NtClose(hServerPort);
return 0;
}
@@ -0,0 +1,136 @@
<?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>{ae32e82b-792d-4f3a-9b90-970fa845f23d}</ProjectGuid>
<RootNamespace>AsyncServer</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>SimpleServer2</ProjectName>
</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">
</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="SimpleServer2.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,22 @@
<?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="SimpleServer2.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>