From 6a07fa7145cd3fc4ec09d6df179ca02cf76323ce Mon Sep 17 00:00:00 2001 From: Martin Drab Date: Mon, 1 Mar 2021 14:50:49 +0100 Subject: [PATCH] [irpmonc]: Hyper_V support --- irpmonc/guid-api.c | 102 ++++++++++++++++++++++++++++++++ irpmonc/guid-api.h | 27 +++++++++ irpmonc/irpmonc.cpp | 80 +++++++++++++++++++------ irpmonc/irpmonc.vcxproj | 2 + irpmonc/irpmonc.vcxproj.filters | 6 ++ 5 files changed, 200 insertions(+), 17 deletions(-) create mode 100644 irpmonc/guid-api.c create mode 100644 irpmonc/guid-api.h diff --git a/irpmonc/guid-api.c b/irpmonc/guid-api.c new file mode 100644 index 00000000..4d93280c --- /dev/null +++ b/irpmonc/guid-api.c @@ -0,0 +1,102 @@ + +#include +#include +#include +#include +#include +#include "guid-api.h" + + + +typedef void (NTAPI RTLINITUNICODESTRING)(PUNICODE_STRING String, const wchar_t *WS); +typedef NTSTATUS (WINAPI RTLSTRINGFROMGUID)(const GUID *Guid, PUNICODE_STRING GuidString); +typedef NTSTATUS (NTAPI RTLGUIDFROMSTRING)(PCUNICODE_STRING GuidString, GUID *Guid); + +static RTLINITUNICODESTRING *_RtlInitUnicodeString = NULL; +static RTLSTRINGFROMGUID *_RtlStringFromGUID = NULL; +static RTLGUIDFROMSTRING *_RtlGUIDFromString = NULL; + + + + + +int GAGUIDToStringW(const GUID *G, wchar_t *Buffer, size_t MaxCount) +{ + int ret = 0; + UNICODE_STRING us; + wchar_t buf[100]; + + us.MaximumLength = sizeof(buf); + us.Length = 0; + us.Buffer = buf; + ret = _RtlStringFromGUID(G, &us); + if (NT_SUCCESS(ret)) { + if (MaxCount - 1 >= us.Length / sizeof(wchar_t)) { + memcpy(Buffer, us.Buffer, us.Length); + Buffer[us.Length / sizeof(wchar_t)] = L'\0'; + ret = 0; + } else ret = ERROR_INSUFFICIENT_BUFFER; + } + + return ret; +} + + +int GAGUIDToStringA(const GUID *G, char *Buffer, size_t MaxCount) +{ + int ret = 0; + wchar_t buf[100]; + + ret = GAGUIDToStringW(G, buf, sizeof(buf) / sizeof(buf[0])); + if (ret == 0) { + ret = snprintf(Buffer, MaxCount, "%ls", buf); + if (ret > 0 && ret < MaxCount) + ret = 0; + else ret = ERROR_INSUFFICIENT_BUFFER; + } + + return ret; +} + + +int GAStringToGUIDW(const wchar_t *S, GUID *G) +{ + int ret = 0; + UNICODE_STRING us; + + _RtlInitUnicodeString(&us, S); + ret = _RtlGUIDFromString(&us, G); + + return ret; +} + + +int GAStringToGUIDA(const char *S, GUID *G) +{ + int ret = 0; + wchar_t buf[100]; + + swprintf(buf, sizeof(buf) / sizeof(buf[0]) - 1, L"%hs", S); + ret = GAStringToGUIDW(buf, G); + + return ret; +} + + +int GUIDApiInit(void) +{ + int ret = 0; + HMODULE hLib = NULL; + + hLib = GetModuleHandleW(L"ntdll.dll"); + if (hLib != NULL) { + _RtlInitUnicodeString = (RTLINITUNICODESTRING *)GetProcAddress(hLib, "RtlInitUnicodeString"); + _RtlStringFromGUID = (RTLSTRINGFROMGUID *)GetProcAddress(hLib, "RtlStringFromGUID"); + _RtlGUIDFromString = (RTLGUIDFROMSTRING *)GetProcAddress(hLib, "RtlGUIDFromString"); + if (_RtlInitUnicodeString == NULL || _RtlStringFromGUID == NULL || + _RtlGUIDFromString == NULL) + ret = GetLastError(); + } else ret = GetLastError(); + + return ret; +} diff --git a/irpmonc/guid-api.h b/irpmonc/guid-api.h new file mode 100644 index 00000000..acbd1629 --- /dev/null +++ b/irpmonc/guid-api.h @@ -0,0 +1,27 @@ + +#ifndef __GUID_API_H__ +#define __GUID_API_H__ + + +#include + + + +#ifdef __cplusplus +extern "C" { +#endif + +int GAGUIDToStringW(const GUID *G, wchar_t *Buffer, size_t MaxCount); +int GAGUIDToStringA(const GUID *G, char *Buffer, size_t MaxCount); +int GAStringToGUIDW(const wchar_t *S, GUID *G); +int GAStringToGUIDA(const char *S, GUID *G); + +int GUIDApiInit(void); + +#ifdef __cplusplus +} +#endif + + + +#endif diff --git a/irpmonc/irpmonc.cpp b/irpmonc/irpmonc.cpp index 2e69d7dd..741ac045 100644 --- a/irpmonc/irpmonc.cpp +++ b/irpmonc/irpmonc.cpp @@ -24,6 +24,7 @@ #include "request-output.h" #include "stop-event.h" #include "libvsock.h" +#include "guid-api.h" #include "irpmonc.h" @@ -33,6 +34,7 @@ // N:localhost:1234 // L:C:\binarylog.log // V:: +// H:: // // --output=: // T = text lines @@ -166,6 +168,7 @@ static int _parse_input(const wchar_t *Value) case L'D': _initInfo.ConnectorType = ictDevice; break; case L'N': _initInfo.ConnectorType = ictNetwork; break; case L'V': _initInfo.ConnectorType = ictVSockets; break; + case L'H': _initInfo.ConnectorType = ictHyperV; break; default: ret = -9; fprintf(stderr, "[ERROR]: Unknown input modifier \"%lc\"\n", *Value); @@ -237,6 +240,45 @@ static int _parse_input(const wchar_t *Value) fprintf(stderr, "[INFO]: vSock address: 0x%x (%u)\n", _initInfo.Data.VSockets.CID, _initInfo.Data.VSockets.CID); fprintf(stderr, "[INFO]: vSock port: 0x%x (%u)\n", _initInfo.Data.VSockets.Port, _initInfo.Data.VSockets.Port); } break; + case ictHyperV: { + wchar_t vmIdBuffer[100]; + wchar_t appIdBuffer[100]; + + memset(vmIdBuffer, 0, sizeof(vmIdBuffer)); + memset(appIdBuffer, 0, sizeof(appIdBuffer)); + delimiter = wcschr(Value, L':'); + if (delimiter == NULL) + delimiter = Value + wcslen(Value); + + if (delimiter - Value > sizeof(vmIdBuffer) / sizeof(vmIdBuffer[0]) + 1) { + ret = -1; + fprintf(stderr, "[ERROR]: Argument \"%ls\" is too long\n", Value); + goto Exit; + } + + memcpy(vmIdBuffer, Value, (delimiter - Value)*sizeof(wchar_t)); + if (wcslen(delimiter) - 1 > sizeof(vmIdBuffer) / sizeof(vmIdBuffer[0]) + 1) { + ret = -1; + fprintf(stderr, "[ERROR]: Argument \"%ls\" is too long\n", delimiter + 1); + goto Exit; + } + + if (*delimiter == L'\0') + memcpy(appIdBuffer, delimiter + 1, (wcslen(delimiter) - 1) * sizeof(wchar_t)); + else wcscpy(appIdBuffer, L"{5629ad96-eb15-4906-855b-388b49877838}"); + + ret = GAStringToGUIDW(vmIdBuffer, &_initInfo.Data.HyperV.VMId); + if (ret != 0) { + fprintf(stderr, "[ERROR]: Unable to convert \"%ls\" to GUID: %u\n", vmIdBuffer, ret); + goto Exit; + } + + ret = GAStringToGUIDW(appIdBuffer, &_initInfo.Data.HyperV.AppId); + if (ret != 0) { + fprintf(stderr, "[ERROR]: Unable to convert \"%ls\" to GUID: %u\n", appIdBuffer, ret); + goto Exit; + } + } break; } if (ret != 0) { @@ -956,33 +998,36 @@ static int _init_dlls(void) { int ret = 0; - ret = DPListModuleInit(L"dparser.dll"); + ret = GUIDApiInit(); if (ret == 0) { - ret = ReqListModuleInit(L"reqlist.dll"); + ret = DPListModuleInit(L"dparser.dll"); if (ret == 0) { - ret = CallbackStreamModuleInit(L"callbackstream.dll"); + ret = ReqListModuleInit(L"reqlist.dll"); if (ret == 0) { - ret = SymbolsModuleInit(L"symbols.dll"); + ret = CallbackStreamModuleInit(L"callbackstream.dll"); if (ret == 0) { - ret = SymStoreCreate(NULL, &_symStore); - if (ret != 0) - fprintf(stderr, "[ERROR]: Unable to initialize the symbol store: %u\n", ret); + ret = SymbolsModuleInit(L"symbols.dll"); + if (ret == 0) { + ret = SymStoreCreate(NULL, &_symStore); + if (ret != 0) + fprintf(stderr, "[ERROR]: Unable to initialize the symbol store: %u\n", ret); + + if (ret != 0) + SymbolsModuleFinit(); + } else fprintf(stderr, "[ERROR]: Unable to initialize symbols.dll: %u\n", ret); if (ret != 0) SymbolsModuleFinit(); - } else fprintf(stderr, "[ERROR]: Unable to initialize symbols.dll: %u\n", ret); + } else fprintf(stderr, "[ERROR]: Unable to initialize callbackstream.dll: %u\n", ret); if (ret != 0) - SymbolsModuleFinit(); - } else fprintf(stderr, "[ERROR]: Unable to initialize callbackstream.dll: %u\n", ret); + ReqListModuleFinit(); + } else fprintf(stderr, "[ERROR]: Unable to initialize reqlist.dll: %u\n", ret); if (ret != 0) - ReqListModuleFinit(); - } else fprintf(stderr, "[ERROR]: Unable to initialize reqlist.dll: %u\n", ret); - - if (ret != 0) - DPListModuleFinit(); - } else fprintf(stderr, "[ERROR]: Unable to initialize dparser.dll: %u\n", ret); + DPListModuleFinit(); + } else fprintf(stderr, "[ERROR]: Unable to initialize dparser.dll: %u\n", ret); + } else fprintf(stderr, "[ERROR]: Unable to initialize GUID API Library: %u\n", ret); return ret; } @@ -1201,7 +1246,8 @@ int wmain(int argc, wchar_t *argv[]) switch (_initInfo.ConnectorType) { case ictDevice: case ictNetwork: - case ictVSockets: { + case ictVSockets: + case ictHyperV: { fprintf(stderr, "[INFO]: Connecting to the driver...\n"); ret = IRPMonDllConnect(); if (ret == 0) { diff --git a/irpmonc/irpmonc.vcxproj b/irpmonc/irpmonc.vcxproj index 4be3e273..5168c75e 100644 --- a/irpmonc/irpmonc.vcxproj +++ b/irpmonc/irpmonc.vcxproj @@ -28,6 +28,7 @@ + @@ -57,6 +58,7 @@ + diff --git a/irpmonc/irpmonc.vcxproj.filters b/irpmonc/irpmonc.vcxproj.filters index 275da4bf..bb485b8a 100644 --- a/irpmonc/irpmonc.vcxproj.filters +++ b/irpmonc/irpmonc.vcxproj.filters @@ -24,6 +24,9 @@ Source Files + + Source Files + @@ -44,6 +47,9 @@ Header Files + + Header Files +