example: rewrite and replace api's debug rundll32 functionality

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Jason A. Donenfeld 2020-11-02 22:09:52 +01:00
parent 0d7b9c7319
commit 9a937c7a49
9 changed files with 248 additions and 228 deletions

View File

@ -101,11 +101,6 @@
<RunCodeAnalysis>true</RunCodeAnalysis> <RunCodeAnalysis>true</RunCodeAnalysis>
<IgnoreImportLibrary>true</IgnoreImportLibrary> <IgnoreImportLibrary>true</IgnoreImportLibrary>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<LocalDebuggerCommand>rundll32.exe</LocalDebuggerCommand>
<LocalDebuggerCommandArguments>$(OutDir)$(TargetName)$(TargetExt),DoThingsForDebugging</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<ItemDefinitionGroup> <ItemDefinitionGroup>
<ClCompile> <ClCompile>
<PreprocessorDefinitions>_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@ -171,7 +166,6 @@ lib.exe /def:nci.def /out:"$(IntDir)nci.lib" /machine:$(PlatformTarget) /nologo
<ClInclude Include="ntldr.h" /> <ClInclude Include="ntldr.h" />
<ClInclude Include="registry.h" /> <ClInclude Include="registry.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
<ClInclude Include="session.h" />
<ClInclude Include="wintun.h" /> <ClInclude Include="wintun.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -58,9 +58,6 @@
<ClInclude Include="entry.h"> <ClInclude Include="entry.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="session.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="namespace.c"> <ClCompile Include="namespace.c">

View File

@ -5,7 +5,6 @@
#include "adapter.h" #include "adapter.h"
#include "logger.h" #include "logger.h"
#include "session.h"
#include "wintun.h" #include "wintun.h"
#include <Windows.h> #include <Windows.h>
@ -17,12 +16,6 @@
#if defined(ACCEPT_WOW64) || defined(_DEBUG) #if defined(ACCEPT_WOW64) || defined(_DEBUG)
static
#ifndef _DEBUG
const
#endif
BOOL WriteToConsole = FALSE;
static DWORD static DWORD
WriteFormatted(_In_ DWORD StdHandle, _In_z_ const WCHAR *Template, ...) WriteFormatted(_In_ DWORD StdHandle, _In_z_ const WCHAR *Template, ...)
{ {
@ -38,9 +31,6 @@ WriteFormatted(_In_ DWORD StdHandle, _In_z_ const WCHAR *Template, ...)
(void *)&FormattedMessage, (void *)&FormattedMessage,
0, 0,
&Arguments); &Arguments);
if (WriteToConsole)
WriteConsoleW(GetStdHandle(StdHandle), FormattedMessage, Len, &SizeWritten, NULL);
else
WriteFile(GetStdHandle(StdHandle), FormattedMessage, Len * sizeof(WCHAR), &SizeWritten, NULL); WriteFile(GetStdHandle(StdHandle), FormattedMessage, Len * sizeof(WCHAR), &SizeWritten, NULL);
LocalFree(FormattedMessage); LocalFree(FormattedMessage);
va_end(Arguments); va_end(Arguments);
@ -158,30 +148,4 @@ VOID __stdcall DeleteDriver(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int n
Done(); Done();
} }
#ifdef _DEBUG
VOID __stdcall DoThingsForDebugging(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
{
# pragma EXPORT
UNREFERENCED_PARAMETER(hwnd);
UNREFERENCED_PARAMETER(hinst);
UNREFERENCED_PARAMETER(lpszCmdLine);
UNREFERENCED_PARAMETER(nCmdShow);
AllocConsole();
WriteToConsole = TRUE;
Init();
GUID TestGuid = { 0xdeadbabe, 0xcafe, 0xbeef, { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef } };
WINTUN_ADAPTER *Adapter;
BOOL RebootRequired;
assert(WintunCreateAdapter(L"Wintun", L"Test", &TestGuid, &Adapter, &RebootRequired) == ERROR_SUCCESS);
assert(!RebootRequired);
TUN_SESSION *Session;
assert(WintunStartSession(Adapter, WINTUN_MIN_RING_CAPACITY, &Session) == ERROR_SUCCESS);
WintunEndSession(Session);
assert(WintunDeleteAdapter(Adapter, TRUE, &RebootRequired) == ERROR_SUCCESS);
assert(!RebootRequired);
system("pause");
}
#endif
#endif #endif

View File

@ -7,7 +7,6 @@
#include "elevate.h" #include "elevate.h"
#include "entry.h" #include "entry.h"
#include "logger.h" #include "logger.h"
#include "session.h"
#include "wintun.h" #include "wintun.h"
#include <Windows.h> #include <Windows.h>

View File

@ -1,59 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved.
*/
#pragma once
#include "wintun.h"
#include <Windows.h>
typedef struct _TUN_SESSION TUN_SESSION;
/**
* @copydoc WINTUN_START_SESSION_FUNC
*/
WINTUN_STATUS WINAPI
WintunStartSession(
_In_ const WINTUN_ADAPTER *Adapter,
_In_ DWORD Capacity,
_Out_ TUN_SESSION **Session);
/**
* @copydoc WINTUN_END_SESSION_FUNC
*/
void WINAPI
WintunEndSession(_In_ TUN_SESSION *Session);
/**
* @copydoc WINTUN_GET_READ_WAIT_EVENT_FUNC
*/
HANDLE WINAPI
WintunGetReadWaitEvent(_In_ TUN_SESSION *Session);
/**
* @copydoc WINTUN_RECEIVE_PACKET_FUNC
*/
WINTUN_STATUS WINAPI
WintunReceivePacket(_In_ TUN_SESSION *Session, _Out_bytecapcount_(*PacketSize) BYTE **Packet, _Out_ DWORD *PacketSize);
/**
* @copydoc WINTUN_RECEIVE_RELEASE_FUNC
*/
void WINAPI
WintunReceiveRelease(_In_ TUN_SESSION *Session, _In_ const BYTE *Packet);
/**
* @copydoc WINTUN_ALLOCATE_SEND_PACKET
*/
WINTUN_STATUS WINAPI
WintunAllocateSendPacket(
_In_ TUN_SESSION *Session,
_In_ DWORD PacketSize,
_Out_bytecapcount_(PacketSize) BYTE **Packet);
/**
* @copydoc WINTUN_SEND_PACKET
*/
void WINAPI
WintunSendPacket(_In_ TUN_SESSION *Session, _In_ const BYTE *Packet);

View File

@ -3,16 +3,31 @@
* Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved. * Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved.
*/ */
#include "../api/wintun.h" #include <winsock2.h>
#include <Windows.h>
#include <ws2ipdef.h>
#include <iphlpapi.h>
#include <ip2string.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include "wintun.h"
static WINTUN_GET_VERSION_FUNC WintunGetVersion;
static WINTUN_SET_LOGGER_FUNC WintunSetLogger;
static WINTUN_CREATE_ADAPTER_FUNC WintunCreateAdapter; static WINTUN_CREATE_ADAPTER_FUNC WintunCreateAdapter;
static WINTUN_DELETE_ADAPTER_FUNC WintunDeleteAdapter; static WINTUN_DELETE_ADAPTER_FUNC WintunDeleteAdapter;
static WINTUN_DELETE_DRIVER_FUNC WintunDeleteDriver;
static WINTUN_ENUM_ADAPTERS_FUNC WintunEnumAdapters;
static WINTUN_FREE_ADAPTER_FUNC WintunFreeAdapter;
static WINTUN_GET_ADAPTER_FUNC WintunGetAdapter;
static WINTUN_GET_ADAPTER_DEVICE_OBJECT_FUNC WintunGetAdapterDeviceObject;
static WINTUN_GET_ADAPTER_GUID_FUNC WintunGetAdapterGUID;
static WINTUN_GET_ADAPTER_LUID_FUNC WintunGetAdapterLUID;
static WINTUN_GET_ADAPTER_NAME_FUNC WintunGetAdapterName;
static WINTUN_SET_ADAPTER_NAME_FUNC WintunSetAdapterName;
static WINTUN_GET_VERSION_FUNC WintunGetVersion;
static WINTUN_SET_LOGGER_FUNC WintunSetLogger;
static WINTUN_START_SESSION_FUNC WintunStartSession; static WINTUN_START_SESSION_FUNC WintunStartSession;
static WINTUN_END_SESSION_FUNC WintunEndSession; static WINTUN_END_SESSION_FUNC WintunEndSession;
static WINTUN_GET_READ_WAIT_EVENT_FUNC WintunGetReadWaitEvent;
static WINTUN_RECEIVE_PACKET_FUNC WintunReceivePacket; static WINTUN_RECEIVE_PACKET_FUNC WintunReceivePacket;
static WINTUN_RECEIVE_RELEASE_FUNC WintunReceiveRelease; static WINTUN_RECEIVE_RELEASE_FUNC WintunReceiveRelease;
static WINTUN_ALLOCATE_SEND_PACKET_FUNC WintunAllocateSendPacket; static WINTUN_ALLOCATE_SEND_PACKET_FUNC WintunAllocateSendPacket;
@ -59,9 +74,8 @@ ConsoleLogger(_In_ WINTUN_LOGGER_LEVEL Level, _In_z_ const WCHAR *LogLine)
} }
static DWORD static DWORD
LogLastError(_In_z_ const WCHAR *Prefix) LogError(_In_z_ const WCHAR *Prefix, _In_ DWORD Error)
{ {
DWORD Error = GetLastError();
WCHAR *SystemMessage = NULL, *FormattedMessage = NULL; WCHAR *SystemMessage = NULL, *FormattedMessage = NULL;
FormatMessageW( FormatMessageW(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_MAX_WIDTH_MASK, FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_MAX_WIDTH_MASK,
@ -84,7 +98,6 @@ LogLastError(_In_z_ const WCHAR *Prefix)
ConsoleLogger(WINTUN_LOG_ERR, FormattedMessage); ConsoleLogger(WINTUN_LOG_ERR, FormattedMessage);
LocalFree(FormattedMessage); LocalFree(FormattedMessage);
LocalFree(SystemMessage); LocalFree(SystemMessage);
SetLastError(Error);
return Error; return Error;
} }
@ -100,7 +113,7 @@ Log(_In_ WINTUN_LOGGER_LEVEL Level, _In_z_ const WCHAR *Format, ...)
} }
static BOOL WINAPI static BOOL WINAPI
CtrlHandler(DWORD CtrlType) CtrlHandler(_In_ DWORD CtrlType)
{ {
switch (CtrlType) switch (CtrlType)
{ {
@ -109,6 +122,7 @@ CtrlHandler(DWORD CtrlType)
case CTRL_CLOSE_EVENT: case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT: case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT: case CTRL_SHUTDOWN_EVENT:
Log(WINTUN_LOG_INFO, L"Cleaning up and shutting down...");
HaveQuit = TRUE; HaveQuit = TRUE;
SetEvent(QuitEvent); SetEvent(QuitEvent);
return TRUE; return TRUE;
@ -116,143 +130,249 @@ CtrlHandler(DWORD CtrlType)
return FALSE; return FALSE;
} }
static DWORD WINAPI static void
TestAdapter(_Inout_ DWORD_PTR Index) PrintPacket(_In_ const BYTE *Packet, _In_ DWORD PacketSize)
{ {
/* Create adapter. */ if (PacketSize < 20)
WCHAR AdapterName[MAX_ADAPTER_NAME];
_snwprintf_s(
AdapterName,
_countof(AdapterName),
_TRUNCATE,
L"test-%d.%d-%zu",
WINTUN_VERSION_MAJ,
WINTUN_VERSION_MIN,
Index);
const GUID AdapterGuid = { 0xeef7ebf,
WINTUN_VERSION_MAJ,
WINTUN_VERSION_MIN,
{ (BYTE)Index & 0xff, 0xa, 0x33, 0xbf, 0x5c, 0x8, 0x4a, 0xc6 } };
while (!HaveQuit)
{ {
WINTUN_ADAPTER_HANDLE Adapter; Log(WINTUN_LOG_INFO, L"Received packet without room for an IP header");
BOOL RebootRequired = FALSE; return;
DWORD Result = WintunCreateAdapter(L"Example", AdapterName, &AdapterGuid, &Adapter, &RebootRequired);
if (Result != ERROR_SUCCESS)
{
Log(WINTUN_LOG_ERR, L"%s adapter creation failed.\n", AdapterName);
return Result;
} }
BYTE IpVersion = Packet[0] >> 4, Proto;
DWORDLONG WintunVersion = WintunGetVersion(); WCHAR Src[46], Dst[46];
Log(WINTUN_LOG_INFO, if (IpVersion == 4)
L"%s adapter created (Wintun %d.%d.%d.%d, reboot: %d).\n",
AdapterName,
(WintunVersion >> 48) & 0xffff,
(WintunVersion >> 32) & 0xffff,
(WintunVersion >> 16) & 0xffff,
(WintunVersion >> 0) & 0xffff,
RebootRequired ? 1 : 0);
WINTUN_SESSION_HANDLE Session;
HANDLE WaitHandles[2] = { NULL, QuitEvent };
Result = WintunStartSession(Adapter, 0x100000, &Session, &WaitHandles[0]);
if (Result != ERROR_SUCCESS)
{ {
Log(WINTUN_LOG_ERR, L"%s session creation failed.\n", AdapterName); RtlIpv4AddressToStringW((struct in_addr *)&Packet[12], Src);
goto cleanupAdapter; RtlIpv4AddressToStringW((struct in_addr *)&Packet[16], Dst);
Proto = Packet[9];
Packet += 20, PacketSize -= 20;
} }
else if (IpVersion == 6 && PacketSize < 40)
{
Log(WINTUN_LOG_INFO, L"Received packet without room for an IP header");
return;
}
else if (IpVersion == 6)
{
RtlIpv6AddressToStringW((struct in6_addr *)&Packet[8], Src);
RtlIpv6AddressToStringW((struct in6_addr *)&Packet[24], Dst);
Proto = Packet[6];
Packet += 40, PacketSize -= 40;
}
else
{
Log(WINTUN_LOG_INFO, L"Received packet that was not IP");
return;
}
if (Proto == 1 && PacketSize >= 8 && Packet[0] == 0)
Log(WINTUN_LOG_INFO, L"Received IPv%d ICMP echo reply from %s to %s", IpVersion, Src, Dst);
else
Log(WINTUN_LOG_INFO, L"Received IPv%d proto 0x%x packet from %s to %s", IpVersion, Proto, Src, Dst);
}
static USHORT
IPChecksum(BYTE *Buffer, DWORD Len)
{
ULONG Sum = 0;
for (; Len > 1; Len -= 2, Buffer += 2)
Sum += *(USHORT *)Buffer;
if (Len)
Sum += *Buffer;
Sum = (Sum >> 16) + (Sum & 0xffff);
Sum += (Sum >> 16);
return (USHORT)(~Sum);
}
static void
MakeICMP(_Inout_ BYTE Packet[28])
{
memset(Packet, 0, 28);
Packet[0] = 0x45;
*(USHORT *)&Packet[2] = htons(28);
Packet[8] = 255;
Packet[9] = 1;
*(ULONG *)&Packet[12] = htonl((10 << 24) | (6 << 16) | (7 << 8) | (8 << 0)); /* 10.6.7.8 */
*(ULONG *)&Packet[16] = htonl((10 << 24) | (6 << 16) | (7 << 8) | (7 << 0)); /* 10.6.7.7 */
*(USHORT *)&Packet[10] = IPChecksum(Packet, 20);
Packet[20] = 8;
*(USHORT *)&Packet[22] = IPChecksum(&Packet[20], 8);
Log(WINTUN_LOG_INFO, L"Sending IPv4 ICMP echo request to 10.6.7.8 from 10.6.7.7");
}
static DWORD WINAPI
ReceivePackets(_Inout_ DWORD_PTR SessionPtr)
{
WINTUN_SESSION_HANDLE Session = (WINTUN_SESSION_HANDLE)SessionPtr;
HANDLE WaitHandles[] = { WintunGetReadWaitEvent(Session), QuitEvent };
while (!HaveQuit) while (!HaveQuit)
{ {
BYTE *Packet; BYTE *Packet;
DWORD PacketSize; DWORD PacketSize;
Result = WintunReceivePacket(Session, &Packet, &PacketSize); DWORD Result = WintunReceivePacket(Session, &Packet, &PacketSize);
switch (Result) switch (Result)
{ {
case ERROR_SUCCESS: case ERROR_SUCCESS:
// TODO: Process packet. PrintPacket(Packet, PacketSize);
WintunReceiveRelease(Session, Packet); WintunReceiveRelease(Session, Packet);
continue; continue;
case ERROR_NO_MORE_ITEMS: case ERROR_NO_MORE_ITEMS:
if (WaitForMultipleObjects(_countof(WaitHandles), WaitHandles, FALSE, INFINITE) == WAIT_OBJECT_0) if (WaitForMultipleObjects(_countof(WaitHandles), WaitHandles, FALSE, INFINITE) == WAIT_OBJECT_0)
continue; continue;
goto cleanupSession; return ERROR_SUCCESS;
default:
LogError(L"Packet read failed", Result);
return Result;
} }
Log(WINTUN_LOG_ERR, L"%s packet read failed (Code 0x%08X).\n", AdapterName, Result);
goto cleanupSession;
}
cleanupSession:
WintunEndSession(Session);
cleanupAdapter:
WintunDeleteAdapter(Adapter, TRUE, &RebootRequired);
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static DWORD WINAPI
SendPackets(_Inout_ DWORD_PTR SessionPtr)
{
WINTUN_SESSION_HANDLE Session = (WINTUN_SESSION_HANDLE)SessionPtr;
while (!HaveQuit)
{
BYTE *Packet;
WintunAllocateSendPacket(Session, 28, &Packet);
MakeICMP(Packet);
WintunSendPacket(Session, Packet);
switch (WaitForSingleObject(QuitEvent, 1000 /* 1 second */))
{
case WAIT_ABANDONED:
case WAIT_OBJECT_0:
return ERROR_SUCCESS;
}
}
return ERROR_SUCCESS;
}
static HMODULE
InitializeWintun(void)
{
HMODULE Wintun =
LoadLibraryExW(L"wintun.dll", NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!Wintun)
return NULL;
#define X(Name, Type) ((Name = (Type)GetProcAddress(Wintun, #Name)) == NULL)
if (X(WintunCreateAdapter, WINTUN_CREATE_ADAPTER_FUNC) || X(WintunDeleteAdapter, WINTUN_DELETE_ADAPTER_FUNC) ||
X(WintunDeleteDriver, WINTUN_DELETE_DRIVER_FUNC) || X(WintunEnumAdapters, WINTUN_ENUM_ADAPTERS_FUNC) ||
X(WintunFreeAdapter, WINTUN_FREE_ADAPTER_FUNC) || X(WintunGetAdapter, WINTUN_GET_ADAPTER_FUNC) ||
X(WintunGetAdapterDeviceObject, WINTUN_GET_ADAPTER_DEVICE_OBJECT_FUNC) ||
X(WintunGetAdapterGUID, WINTUN_GET_ADAPTER_GUID_FUNC) ||
X(WintunGetAdapterLUID, WINTUN_GET_ADAPTER_LUID_FUNC) ||
X(WintunGetAdapterName, WINTUN_GET_ADAPTER_NAME_FUNC) ||
X(WintunSetAdapterName, WINTUN_SET_ADAPTER_NAME_FUNC) || X(WintunGetVersion, WINTUN_GET_VERSION_FUNC) ||
X(WintunSetLogger, WINTUN_SET_LOGGER_FUNC) || X(WintunStartSession, WINTUN_START_SESSION_FUNC) ||
X(WintunEndSession, WINTUN_END_SESSION_FUNC) || X(WintunGetReadWaitEvent, WINTUN_GET_READ_WAIT_EVENT_FUNC) ||
X(WintunReceivePacket, WINTUN_RECEIVE_PACKET_FUNC) || X(WintunReceiveRelease, WINTUN_RECEIVE_RELEASE_FUNC) ||
X(WintunAllocateSendPacket, WINTUN_ALLOCATE_SEND_PACKET_FUNC) || X(WintunSendPacket, WINTUN_SEND_PACKET_FUNC))
#undef X
{
DWORD Result = GetLastError();
FreeLibrary(Wintun);
SetLastError(Result);
return NULL;
}
SetLastError(ERROR_SUCCESS);
return Wintun;
}
int int
main(void) main(void)
{ {
Log(WINTUN_LOG_INFO, L"Wintun Test v%d.%d\n", WINTUN_VERSION_MAJ, WINTUN_VERSION_MIN); HMODULE Wintun = InitializeWintun();
HMODULE Wintun =
LoadLibraryExW(L"wintun.dll", NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!Wintun) if (!Wintun)
return LogLastError(L"Failed to load wintun.dll"); return LogError(L"Failed to initialize Wintun", GetLastError());
DWORD Result; WintunSetLogger(ConsoleLogger);
if ((WintunGetVersion = (WINTUN_GET_VERSION_FUNC)GetProcAddress(Wintun, "WintunGetVersion")) == NULL || Log(WINTUN_LOG_INFO, L"Wintun library loaded");
(WintunSetLogger = (WINTUN_SET_LOGGER_FUNC)GetProcAddress(Wintun, "WintunSetLogger")) == NULL ||
(WintunCreateAdapter = (WINTUN_CREATE_ADAPTER_FUNC)GetProcAddress(Wintun, "WintunCreateAdapter")) == NULL ||
(WintunDeleteAdapter = (WINTUN_DELETE_ADAPTER_FUNC)GetProcAddress(Wintun, "WintunDeleteAdapter")) == NULL ||
(WintunStartSession = (WINTUN_START_SESSION_FUNC)GetProcAddress(Wintun, "WintunStartSession")) == NULL ||
(WintunEndSession = (WINTUN_END_SESSION_FUNC)GetProcAddress(Wintun, "WintunEndSession")) == NULL ||
(WintunReceivePacket = (WINTUN_RECEIVE_PACKET_FUNC)GetProcAddress(Wintun, "WintunReceivePacket")) == NULL ||
(WintunReceiveRelease = (WINTUN_RECEIVE_RELEASE_FUNC)GetProcAddress(Wintun, "WintunReceiveRelease")) == NULL ||
(WintunAllocateSendPacket =
(WINTUN_ALLOCATE_SEND_PACKET_FUNC)GetProcAddress(Wintun, "WintunAllocateSendPacket")) == NULL ||
(WintunSendPacket = (WINTUN_SEND_PACKET_FUNC)GetProcAddress(Wintun, "WintunSendPacket")) == NULL)
{
Result = LogLastError(L"Failed to get wintun.dll entries");
goto cleanupWintun;
}
DWORD Result;
HaveQuit = FALSE; HaveQuit = FALSE;
QuitEvent = CreateEventW(NULL, TRUE, FALSE, NULL); QuitEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
if (!QuitEvent) if (!QuitEvent)
{ {
Result = LogLastError(L"Failed to create event"); Result = LogError(L"Failed to create event", GetLastError());
goto cleanupWintun; goto cleanupWintun;
} }
WintunSetLogger(ConsoleLogger);
if (!SetConsoleCtrlHandler(CtrlHandler, TRUE)) if (!SetConsoleCtrlHandler(CtrlHandler, TRUE))
{ {
Result = LogLastError(L"Failed to set console handler"); Result = LogError(L"Failed to set console handler", GetLastError());
goto cleanupQuit; goto cleanupQuit;
} }
HANDLE Workers[MAXIMUM_WAIT_OBJECTS] = { 0 }; GUID ExampleGuid = { 0xdeadbabe, 0xcafe, 0xbeef, { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef } };
for (size_t i = 0; i < _countof(Workers); ++i) WINTUN_ADAPTER_HANDLE Adapter;
if (!Workers[i]) Result = WintunGetAdapter(L"Example", L"Demo", &Adapter);
if (Result != ERROR_SUCCESS)
Result = WintunCreateAdapter(L"Example", L"Demo", &ExampleGuid, &Adapter, NULL);
if (Result != ERROR_SUCCESS)
{ {
Workers[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TestAdapter, (LPVOID)i, 0, NULL); LogError(L"Failed to create adapter", Result);
if (!Workers[i]) goto cleanupQuit;
{
Result = LogLastError(L"Failed to create thread");
goto cleanupWorkers;
} }
DWORDLONG Version = WintunGetVersion();
Log(WINTUN_LOG_INFO,
L"Wintun v%d.%d.%d.%d loaded",
(Version >> 48) & 0xff,
(Version >> 32) & 0xff,
(Version >> 16) & 0xff,
(Version >> 0) & 0xff,
WINTUN_VERSION_MIN);
MIB_UNICASTIPADDRESS_ROW AddressRow;
InitializeUnicastIpAddressEntry(&AddressRow);
WintunGetAdapterLUID(Adapter, &AddressRow.InterfaceLuid);
AddressRow.Address.Ipv4.sin_family = AF_INET;
AddressRow.Address.Ipv4.sin_addr.S_un.S_addr = htonl((10 << 24) | (6 << 16) | (7 << 8) | (7 << 0)); /* 10.6.7.7 */
AddressRow.OnLinkPrefixLength = 24; /* This is a /24 network */
Result = CreateUnicastIpAddressEntry(&AddressRow);
if (Result != ERROR_SUCCESS)
{
LogError(L"Failed to set IP address", Result);
goto cleanupAdapter;
}
WINTUN_SESSION_HANDLE Session;
Result = WintunStartSession(Adapter, 0x40000, &Session);
if (Result != ERROR_SUCCESS)
{
LogError(L"Failed to create adapter", Result);
goto cleanupAdapter;
}
Log(WINTUN_LOG_INFO, L"Launching threads and mangling packets...");
HANDLE Workers[] = { CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReceivePackets, (LPVOID)Session, 0, NULL),
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SendPackets, (LPVOID)Session, 0, NULL) };
if (!Workers[0] || !Workers[1])
{
Result = LogError(L"Failed to create threads", GetLastError());
goto cleanupWorkers;
} }
WaitForMultipleObjectsEx(_countof(Workers), Workers, TRUE, INFINITE, TRUE); WaitForMultipleObjectsEx(_countof(Workers), Workers, TRUE, INFINITE, TRUE);
Result = ERROR_SUCCESS; Result = ERROR_SUCCESS;
cleanupWorkers: cleanupWorkers:
HaveQuit = TRUE; HaveQuit = TRUE;
SetEvent(QuitEvent); SetEvent(QuitEvent);
for (size_t i = 0; i < _countof(Workers); ++i) for (size_t i = 0; i < _countof(Workers); ++i)
{
if (Workers[i]) if (Workers[i])
{ {
WaitForSingleObject(Workers[i], INFINITE); WaitForSingleObject(Workers[i], INFINITE);
CloseHandle(Workers[i]); CloseHandle(Workers[i]);
} }
SetConsoleCtrlHandler(CtrlHandler, FALSE); }
WintunEndSession(Session);
cleanupAdapter:
WintunDeleteAdapter(Adapter, FALSE, NULL);
WintunFreeAdapter(Adapter);
cleanupQuit: cleanupQuit:
SetConsoleCtrlHandler(CtrlHandler, FALSE);
CloseHandle(QuitEvent); CloseHandle(QuitEvent);
cleanupWintun: cleanupWintun:
FreeLibrary(Wintun); FreeLibrary(Wintun);

View File

@ -52,17 +52,14 @@
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>false</SpectreMitigation>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>false</SpectreMitigation> <SpectreMitigation>false</SpectreMitigation>
</PropertyGroup> </PropertyGroup>
@ -107,6 +104,14 @@
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup>
<Link>
<AdditionalDependencies>iphlpapi.lib;kernel32.lib;ntdll.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<ClCompile>
<AdditionalIncludeDirectories>..\api</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>

View File

@ -5,14 +5,6 @@
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions> <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter> </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>
<ItemGroup> <ItemGroup>
<ClCompile Include="example.c"> <ClCompile Include="example.c">

View File

@ -64,13 +64,21 @@ Global
{F7679B65-2FEC-469A-8BAC-B07BF4439422}.Release|x86.ActiveCfg = Release|Win32 {F7679B65-2FEC-469A-8BAC-B07BF4439422}.Release|x86.ActiveCfg = Release|Win32
{F7679B65-2FEC-469A-8BAC-B07BF4439422}.Release|x86.Build.0 = Release|Win32 {F7679B65-2FEC-469A-8BAC-B07BF4439422}.Release|x86.Build.0 = Release|Win32
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|amd64.ActiveCfg = Debug|x64 {2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|amd64.ActiveCfg = Debug|x64
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|amd64.Build.0 = Debug|x64
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|arm.ActiveCfg = Debug|ARM {2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|arm.ActiveCfg = Debug|ARM
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|arm.Build.0 = Debug|ARM
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|arm64.ActiveCfg = Debug|ARM64 {2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|arm64.ActiveCfg = Debug|ARM64
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|arm64.Build.0 = Debug|ARM64
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|x86.ActiveCfg = Debug|Win32 {2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|x86.ActiveCfg = Debug|Win32
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|x86.Build.0 = Debug|Win32
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|amd64.ActiveCfg = Release|x64 {2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|amd64.ActiveCfg = Release|x64
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|amd64.Build.0 = Release|x64
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|arm.ActiveCfg = Release|ARM {2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|arm.ActiveCfg = Release|ARM
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|arm.Build.0 = Release|ARM
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|arm64.ActiveCfg = Release|ARM64 {2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|arm64.ActiveCfg = Release|ARM64
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|arm64.Build.0 = Release|ARM64
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|x86.ActiveCfg = Release|Win32 {2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|x86.ActiveCfg = Release|Win32
{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|x86.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE