Skip to content

Commit a3a4a81

Browse files
committed
Update plugin
1 parent 8ead01e commit a3a4a81

File tree

8 files changed

+411
-148
lines changed

8 files changed

+411
-148
lines changed

leechcore_device_hvmm/README.md

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
This is MemProcFs plugin for reading Hyper-V Memory using LiveCloudKdSdk
1+
This is MemProcFS plugin for reading Hyper-V memory using Hyper-V Memory Manager library
22

3-
Sources was taken from https://github.com/ufrisk/LeechCore-plugin
3+
Sources was taken from https://github.com/ufrisk/LeechCore
44

55
- MemProcFs can be found on https://github.com/ufrisk/MemProcFS by @ulfrisk
66

7-
- LiveCloudKd (original version) https://github.com/comaeio/LiveCloudKd by @msuiche
7+
- LiveCloudKd: https://github.com/gerhart01/LiveCloudKd
88

9-
For starting copy leechcore_device_hvmm.dll with LiveCloudKdSdk.dll and hvmm.sys to MemProcFs folder
9+
Copy leechcore_device_hvmm.dll with hvlib.dll and hvmm.sys to MemProcFS folder
1010

1111
start MemProcFs:
12-
1312
```
14-
.\MemProcFS.exe -device hvmm -v
13+
MemProcFS.exe -device hvmm -v
1514
```
1615

1716
you must see something like that:
@@ -21,9 +20,3 @@ you must see something like that:
2120
Next you can go to M: driver and use pypykatz plugin, f.e.
2221

2322
![](./images/2.png)
24-
25-
26-
27-
28-
29-

leechcore_device_hvmm/images/1.png

30 KB
Loading

leechcore_device_hvmm/images/2.png

-597 KB
Loading

leechcore_device_hvmm/leechcore_device_hvmm.c

Lines changed: 140 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
1-
// hvmm.c : implementation of the Hyper-V Virtual Machines leechcore plugin based on LiveCloudKdSdk
1+
// leechcore_device_hvmm.c : implementation for Hyper-V memory access using Hyper-V memory access library
22
// Please refer to the hvmm/ folder for more information or its original repository:
3-
// https://github.com/comaeio/LiveCloudKd
3+
// https://github.com/gerhart01/LiveCloudKd
44
//
5-
// (c) Ulf Frisk, 2018
5+
// (c) Ulf Frisk, 2018-2024
66
// Author: Ulf Frisk, pcileech@frizk.net
77
//
8-
// (c) Arthur Khudyaev, 2020
8+
// (c) Arthur Khudyaev, 2018-2024
99
// Author: Arthur Khudyaev, @gerhart_x
1010
//
11-
// (c) Matt Suiche, 2019
12-
// Author: Matt Suiche, msuiche@comae.com
11+
// (c) Matt Suiche, 2018-2024
12+
// Author: Matt Suiche, www.msuiche.com
1313
//
1414

1515

16-
17-
#include "LiveCloudKdSdkHandle.h"
16+
#include "HvlibHandle.h"
1817
#include "leechcore_device.h"
1918
#include "util.h"
2019
#include "leechcore_device_hvmm.h"
@@ -168,15 +167,14 @@ BOOL DeviceHVMM_GetOption(_In_ PLC_CONTEXT ctxLC, _In_ QWORD fOption, _Out_ PQWO
168167
/*
169168
* Unload the HVMM kernel driver and also delete the driver-loading service.
170169
*/
170+
171171
VOID DeviceHVMM_SvcClose()
172172
{
173173
SC_HANDLE hSCM, hSvcHvmm;
174174
SERVICE_STATUS SvcStatus;
175175

176176
// 1: shut down and delete service.
177177

178-
SdkDestroyPartitions();
179-
180178
if ((g_MemoryReadInterfaceType == ReadInterfaceHvmmDrvInternal) || (g_MemoryReadInterfaceType == ReadInterfaceWinHv))
181179
{
182180
if ((hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE))) {
@@ -194,79 +192,121 @@ VOID DeviceHVMM_SvcClose()
194192
}
195193
}
196194

197-
BOOL DeviceHVMM_CheckParams(_In_ PLC_CONTEXT ctxLC)
195+
ULONG GetNumberFromParam(_In_ PLC_CONTEXT ctxLC, PCHAR pId, _In_ PCSTR pszSrch)
198196
{
199-
ULONG64 uVmidLength = 0;
200-
CHAR szVmid[10] = { 0 };
201-
PCHAR pVmid = NULL;
202197
PCHAR pDelim = NULL;
203-
PCHAR pListVm = NULL;
204198
BOOLEAN bResult = FALSE;
199+
ULONG64 uParamIdLength = 0;
200+
CHAR szParamId[10] = { 0 };
201+
ULONG64 sizeOfParam = strlen(pszSrch);
202+
ULONG szResult = 0;
203+
204+
PDEVICE_CONTEXT_HVMM ctx = (PDEVICE_CONTEXT_HVMM)ctxLC->hDevice;
205205

206-
ULONG64 device_size = sizeof(HVMM_PARAM_NAME) - 1;
207-
ULONG64 id_size = sizeof(ID_PARAM_NAME) - 1;
206+
pId = StrStrIA(ctxLC->Config.szDevice, pszSrch);
208207

209-
PDEVICE_CONTEXT_HVMM ctx = (PDEVICE_CONTEXT_HVMM)ctxLC->hDevice;
210-
211-
pVmid = StrStrIA(ctxLC->Config.szDevice, ID_PARAM_NAME);
212-
if (pVmid)
208+
if (pId)
213209
{
214-
pDelim = StrStrIA(pVmid, HVMM_PARAM_DELIMITER);
210+
pDelim = StrStrIA(pId, HVMM_PARAM_DELIMITER);
215211

216212
if (pDelim)
217213
{
218-
uVmidLength = pVmid - pDelim;
219-
if (uVmidLength < 6)
220-
{
221-
memcpy(szVmid, pVmid + id_size, uVmidLength);
214+
uParamIdLength = pDelim - pId - sizeOfParam;
215+
if (uParamIdLength < 6)
216+
{
217+
memcpy(szParamId, pId + sizeOfParam, uParamIdLength);
222218

223-
if (!IsDigital(ctxLC, szVmid, uVmidLength))
224-
return FALSE;
219+
if (!IsDigital(ctxLC, szParamId, uParamIdLength))
220+
return -1;
225221

226-
ctx->Vmid = atoi(szVmid);
222+
szResult = atoi(szParamId);
227223
ctx->VmidPreselected = TRUE;
228224
bResult = TRUE;
229225
}
230226
else
231227
{
232228
lcprintf(ctxLC,
233229
"DEVICE_HVMM: ERROR: vmid length is too big: %d\n",
234-
uVmidLength);
235-
return FALSE;
230+
uParamIdLength);
231+
return -1;
236232
}
237233
}
238234
else
239-
{
240-
uVmidLength = strlen(ctxLC->Config.szDevice) - device_size - id_size;
241-
strcpy_s(szVmid, _countof(szVmid), pVmid + id_size);
235+
{
236+
uParamIdLength = strlen(ctxLC->Config.szDevice) - (pId - ctxLC->Config.szDevice) - sizeOfParam;
237+
238+
strcpy_s(szParamId, _countof(szParamId), pId + sizeOfParam);
242239

243-
if (!IsDigital(ctxLC, szVmid, uVmidLength))
240+
if (!IsDigital(ctxLC, szParamId, uParamIdLength))
244241
return FALSE;
245242

246-
if (uVmidLength < 6)
243+
if (uParamIdLength < 6)
247244
{
248-
ctx->Vmid = atoi(szVmid);
245+
szResult = atoi(szParamId);
249246
ctx->VmidPreselected = TRUE;
250247
bResult = TRUE;
251248
}
252249
else
253250
{
254251
lcprintf(ctxLC,
255252
"DEVICE_HVMM: ERROR: vmid length is too big: %d\n",
256-
uVmidLength);
257-
return FALSE;
253+
uParamIdLength);
254+
return -1;
258255
}
259256
}
260257
}
258+
return szResult;
259+
}
261260

262-
pListVm = StrStrIA(ctxLC->Config.szDevice, LISTVM_PARAM_NAME);
261+
BOOL DeviceHVMM_CheckParams(_In_ PLC_CONTEXT ctxLC)
262+
{
263+
ULONG64 uVmidLength = 0;
264+
CHAR szVmid[10] = { 0 };
265+
PCHAR pVmid = NULL;
266+
PCHAR pLogLevel = NULL;
267+
PCHAR pDelim = NULL;
268+
BOOLEAN bResult = FALSE;
269+
270+
ULONG64 id_size = sizeof(HVMM_ID_PARAM_NAME) - 1;
271+
PDEVICE_CONTEXT_HVMM ctx = (PDEVICE_CONTEXT_HVMM)ctxLC->hDevice;
272+
273+
pVmid = StrStrIA(ctxLC->Config.szDevice, HVMM_ID_PARAM_NAME);
263274

264-
if (pListVm)
275+
if (pVmid)
276+
{
277+
ctx->Vmid = GetNumberFromParam(ctxLC, pLogLevel, HVMM_ID_PARAM_NAME);
278+
279+
if (ctx->Vmid != -1)
280+
ctx->VmidPreselected = TRUE;
281+
282+
bResult = TRUE;
283+
}
284+
285+
pLogLevel = StrStrIA(ctxLC->Config.szDevice, HVMM_LOGLEVEL_PARAM_NAME);
286+
287+
if (pLogLevel)
288+
{
289+
ctx->LogLevel = GetNumberFromParam(ctxLC, pLogLevel, HVMM_LOGLEVEL_PARAM_NAME);
290+
bResult = TRUE;
291+
}
292+
293+
if (StrStrIA(ctxLC->Config.szDevice, HVMM_UNIX_PARAM_NAME))
294+
{
295+
ctx->SimpleMemory = TRUE;
296+
bResult = TRUE;
297+
}
298+
299+
if (StrStrIA(ctxLC->Config.szDevice, HVMM_LISTVM_PARAM_NAME))
265300
{
266301
ctx->ListVm = TRUE;
267302
bResult = TRUE;
268303
}
269-
304+
305+
if (StrStrIA(ctxLC->Config.szDevice, HVMM_ENUM_GUEST_OS_BUILD_PARAM_NAME))
306+
{
307+
ctx->EnumGuestOsBuild = TRUE;
308+
bResult = TRUE;
309+
}
270310

271311
return bResult;
272312
}
@@ -276,6 +316,41 @@ BOOL DeviceHVMM_CheckParams(_In_ PLC_CONTEXT ctxLC)
276316
* into the kernel. Upon fail it's guaranteed that no lingering service exists.
277317
*/
278318

319+
HANDLE GetHvmmHandle(_In_ PLC_CONTEXT ctxLC)
320+
{
321+
HANDLE hDevice = INVALID_HANDLE_VALUE;
322+
323+
hDevice = CreateFileA(DEVICEHVMM_OBJECT,
324+
GENERIC_READ | GENERIC_WRITE,
325+
FILE_SHARE_READ |
326+
FILE_SHARE_WRITE,
327+
NULL,
328+
OPEN_EXISTING,
329+
FILE_ATTRIBUTE_NORMAL,
330+
0);
331+
332+
if (hDevice == INVALID_HANDLE_VALUE)
333+
return NULL;
334+
335+
lcprintf(ctxLC, "DEVICE_HVMM: driver is already loaded\n");
336+
337+
return hDevice;
338+
}
339+
340+
BOOLEAN GetHvmmPresent(_In_ PLC_CONTEXT ctxLC)
341+
{
342+
HANDLE hDevice = GetHvmmHandle(ctxLC);
343+
BOOLEAN bResult = FALSE;
344+
345+
if (hDevice)
346+
{
347+
CloseHandle(hDevice);
348+
return TRUE;
349+
}
350+
351+
return FALSE;
352+
}
353+
279354
_Success_(return)
280355
BOOL DeviceHVMM_SvcStart(_In_ PLC_CONTEXT ctxLC)
281356
{
@@ -288,10 +363,14 @@ BOOL DeviceHVMM_SvcStart(_In_ PLC_CONTEXT ctxLC)
288363

289364
SC_HANDLE hSCM = 0, hSvcHvmm = 0;
290365

366+
ctx->hFile = GetHvmmHandle(ctxLC);
367+
368+
if (ctx->hFile)
369+
return TRUE;
370+
291371
// 1: verify that driver file exists.
292372
if ((g_MemoryReadInterfaceType == ReadInterfaceHvmmDrvInternal) || (g_MemoryReadInterfaceType == ReadInterfaceWinHv))
293373
{
294-
295374
hModuleLeechCore = LoadLibraryA("leechcore.dll");
296375
// NB! defaults to locating 'hvmm.sys' relative to the loaded
297376
// 'leechcore.dll' - if unable to locate library (for whatever reason)
@@ -359,7 +438,7 @@ BOOL DeviceHVMM_SvcStart(_In_ PLC_CONTEXT ctxLC)
359438
// 3: open file handle
360439

361440
ctx->hFile = CreateFileA(
362-
DEVICEHVMM_MEMORYFILE,
441+
DEVICEHVMM_OBJECT,
363442
GENERIC_READ | GENERIC_WRITE,
364443
FILE_SHARE_READ | FILE_SHARE_WRITE,
365444
NULL,
@@ -386,13 +465,18 @@ BOOL DeviceHVMM_SvcStart(_In_ PLC_CONTEXT ctxLC)
386465
VOID DeviceHVMM_Close(_Inout_ PLC_CONTEXT ctxLC)
387466
{
388467
PDEVICE_CONTEXT_HVMM ctx = (PDEVICE_CONTEXT_HVMM)ctxLC->hDevice;
389-
DeviceHVMM_SvcClose();
390-
468+
391469
if (ctx) {
392-
CloseHandle(ctx->hFile);
470+
SdkClosePartition((ULONG64)ctx->Partition);
471+
472+
if (ctx->hFile)
473+
CloseHandle(ctx->hFile);
474+
393475
LocalFree(ctx);
394476
}
395477

478+
DeviceHVMM_SvcClose();
479+
396480
ctxLC->hDevice = 0;
397481
}
398482

@@ -445,10 +529,7 @@ EXPORTED_FUNCTION BOOL LcPluginCreate(_Inout_ PLC_CONTEXT ctxLC, _Out_opt_ PPLC_
445529
ctx = (PDEVICE_CONTEXT_HVMM)LocalAlloc(LMEM_ZEROINIT, sizeof(DEVICE_CONTEXT_HVMM));
446530
if (!ctx) { return FALSE; }
447531

448-
// 1: terminate any lingering HVMM service.
449-
DeviceHVMM_SvcClose();
450-
451-
// 2: initialize core context.
532+
// 1: initialize core context.
452533

453534
ctxLC->hDevice = (HANDLE)ctx;
454535
// set callback functions and fix up config
@@ -531,15 +612,16 @@ EXPORTED_FUNCTION BOOL LcPluginCreate(_Inout_ PLC_CONTEXT ctxLC, _Out_opt_ PPLC_
531612
else
532613
{
533614
DeviceHVMM_CheckParams(ctxLC);
534-
}
535615

536-
// 3: load hvmm kernel driver.
537-
result = DeviceHVMM_SvcStart(ctxLC);
538-
if (!result) {
539-
lcprintf(ctxLC, "DEVICE_HVMM: FAILED: Failed to initialize the driver.\n");
540-
goto fail;
541-
}
616+
// 3: load hvmm kernel driver.
542617

618+
result = DeviceHVMM_SvcStart(ctxLC);
619+
if (!result) {
620+
lcprintf(ctxLC, "DEVICE_HVMM: FAILED: Failed to initialize the driver.\n");
621+
goto fail;
622+
}
623+
}
624+
543625
// 4: retrieve memory map.
544626
result = DeviceHVMM_GetMemoryInformation(ctxLC);
545627
if (!result) {

0 commit comments

Comments
 (0)