Skip to content

Commit

Permalink
Version 2.14
Browse files Browse the repository at this point in the history
  • Loading branch information
ufrisk committed Nov 16, 2022
1 parent 7b26fdf commit eef82c1
Show file tree
Hide file tree
Showing 15 changed files with 154 additions and 12 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,3 +207,6 @@ v1.0-1.8
[v2.13](https://github.com/ufrisk/LeechCore/releases/tag/v2.13)
* FPGA performance improvements.
* ARM64 Windows support.

[v2.14](https://github.com/ufrisk/LeechCore/releases/tag/v2.14)
* VMM loopback device.
2 changes: 2 additions & 0 deletions includes/leechcore.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,8 @@ extern "C" {
#define LC_OPT_CORE_ADDR_MAX 0x1000000800000000 // R
#define LC_OPT_CORE_STATISTICS_CALL_COUNT 0x4000000900000000 // R [lo-dword: LC_STATISTICS_ID_*]
#define LC_OPT_CORE_STATISTICS_CALL_TIME 0x4000000a00000000 // R [lo-dword: LC_STATISTICS_ID_*]
#define LC_OPT_CORE_VOLATILE 0x1000000b00000000 // R
#define LC_OPT_CORE_READONLY 0x1000000c00000000 // R

#define LC_OPT_MEMORYINFO_VALID 0x0200000100000000 // R
#define LC_OPT_MEMORYINFO_FLAG_32BIT 0x0200000300000000 // R
Expand Down
4 changes: 2 additions & 2 deletions leechagent/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
#define STRINGIZE(s) STRINGIZE2(s)

#define VERSION_MAJOR 2
#define VERSION_MINOR 13
#define VERSION_MINOR 14
#define VERSION_REVISION 0
#define VERSION_BUILD 51
#define VERSION_BUILD 52

#define VER_FILE_DESCRIPTION_STR "LeechAgent Memory Acquisition Service"
#define VER_FILE_VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_BUILD
Expand Down
9 changes: 7 additions & 2 deletions leechcore/Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
CC=gcc
CFLAGS += -I. -D LINUX -D _GNU_SOURCE -shared -fPIC -fvisibility=hidden -pthread `pkg-config libusb-1.0 --libs --cflags`
#CFLAGS += -g -O0 -Wextra -Wno-unused-parameter
# DEBUG FLAGS BELOW
# export ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:detect_invalid_pointer_pairs=2
# CFLAGS += -g -O0 -Wextra -Wno-unused-parameter -Wno-cast-function-type
# CFLAGS += -fsanitize=address -fsanitize=leak -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=bounds-strict -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow
# CFLAGS += -fsanitize=pointer-compare -fsanitize=pointer-subtract -fanalyzer
# DEBUG FLAGS ABOVE
CFLAGS += -fPIE -fPIC -pie -fstack-protector -D_FORTIFY_SOURCE=2 -O1 -Wl,-z,noexecstack
CFLAGS += -Wall -Wno-unused-result -Wno-unused-variable -Wno-unused-value -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast
LDFLAGS += -g -ldl -shared
DEPS = leechcore.h
OBJ = oscompatibility.o leechcore.o util.o memmap.o device_file.o device_fpga.o device_pmem.o device_tmd.o device_usb3380.o device_vmware.o leechrpcclient.o
OBJ = oscompatibility.o leechcore.o util.o memmap.o device_file.o device_fpga.o device_pmem.o device_tmd.o device_usb3380.o device_vmm.o device_vmware.o leechrpcclient.o

%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
Expand Down
11 changes: 8 additions & 3 deletions leechcore/device_fpga.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ typedef struct tdDEVICE_CONTEXT_FPGA {
} dev;
struct {
BOOL fEnabled;
BOOL fOldAsync;
OVERLAPPED oOverlapped;
} async;
PVOID pMRdBufferX; // NULL || PTLP_CALLBACK_BUF_MRd || PTLP_CALLBACK_BUF_MRd_2
Expand Down Expand Up @@ -2369,6 +2370,7 @@ VOID DeviceFPGA_ReadScatter_NewAsync_Impl(_In_ PLC_CONTEXT ctxLC, _In_ PDEVICE_C
// 6.1: check no-read ops and update buffer pointer with previously read data
cbBuffer += cbRead;
if((cbRead == 0) || (cbRead == 0x14)) {
usleep(5);
cEmptyRead++;
if(cEmptyRead >= 0x30) {
break;
Expand Down Expand Up @@ -2439,7 +2441,7 @@ VOID DeviceFPGA_ReadScatter(_In_ PLC_CONTEXT ctxLC, _In_ DWORD cMEMs, _Inout_ PP
MEM_SCATTER_STACK_PUSH(pMEM, 0);
}
}
if(ctx->async.fEnabled) {
if(ctx->async.fEnabled && !ctx->async.fOldAsync) {
DeviceFPGA_ReadScatter_NewAsync_Impl(ctxLC, ctx, cMEMs, ppMEMs);
} else {
DeviceFPGA_ReadScatter_Impl(ctxLC, cMEMs, ppMEMs);
Expand Down Expand Up @@ -2899,8 +2901,9 @@ BOOL DeviceFPGA_SetOption(_In_ PLC_CONTEXT ctxLC, _In_ QWORD fOption, _In_ QWORD
#define FPGA_PARAMETER_DEVICE_INDEX "devindex"
#define FPGA_PARAMETER_DEVICE_ID "bdf"

#define FPGA_PARAMETER_ALGO_TINY 0x01
#define FPGA_PARAMETER_ALGO_SYNCHRONOUS 0x02
#define FPGA_PARAMETER_ALGO_TINY 0x01
#define FPGA_PARAMETER_ALGO_SYNCHRONOUS 0x02
#define FPGA_PARAMETER_ALGO_OLDASYNCHRONOUS 0x04

_Success_(return)
BOOL DeviceFPGA_Open(_Inout_ PLC_CONTEXT ctxLC, _Out_opt_ PPLC_CONFIG_ERRORINFO ppLcCreateErrorInfo)
Expand Down Expand Up @@ -2963,6 +2966,8 @@ BOOL DeviceFPGA_Open(_Inout_ PLC_CONTEXT ctxLC, _Out_opt_ PPLC_CONFIG_ERRORINFO
v = LcDeviceParameterGetNumeric(ctxLC, FPGA_PARAMETER_READ_ALGORITHM);
ctx->fAlgorithmReadTiny = ((v & FPGA_PARAMETER_ALGO_TINY) ? TRUE : FALSE) || ctx->perf.F_TINY;
ctx->async.fEnabled = ctx->async.fEnabled && !(v & FPGA_PARAMETER_ALGO_SYNCHRONOUS);
ctx->async.fOldAsync = ctx->async.fEnabled && (v & FPGA_PARAMETER_ALGO_OLDASYNCHRONOUS);

// return
lcprintfv(ctxLC,
"DEVICE: FPGA: %s PCIe gen%i x%i [%i,%i,%i] [v%i.%i,%04x] [%s,%s]\n",
Expand Down
103 changes: 103 additions & 0 deletions leechcore/device_vmm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// device_vmm.c : implementation of the vmm loopback device.
// this is typically used for virtual machines.
//
// Syntax: vmm://hvmm=0x<VMM_HANDLE>,hvm=0x<VMMVM_HANDLE>,max=<MAX_ADDRESS>
//
// (c) Ulf Frisk, 2022
// Author: Ulf Frisk, [email protected]
//
#include "leechcore.h"
#include "leechcore_device.h"
#include "leechcore_internal.h"
#include "util.h"

typedef struct tdVMM_HANDLE *VMM_HANDLE;
typedef struct tdVMMVM_HANDLE *VMMVM_HANDLE;
typedef BOOL(*FN_VMMDLL_ConfigGet)(_In_ VMM_HANDLE hVMM, _In_ ULONG64 fOption, _Out_ PULONG64 pqwValue);
typedef DWORD(*FN_VMMDLL_VmMemReadScatter)(_In_ VMM_HANDLE hVMM, _In_ VMMVM_HANDLE hVM, _Inout_ PPMEM_SCATTER ppMEMsGPA, _In_ DWORD cpMEMsGPA, _In_ DWORD flags);
typedef DWORD(*FN_VMMDLL_VmMemWriteScatter)(_In_ VMM_HANDLE hVMM, _In_ VMMVM_HANDLE hVM, _Inout_ PPMEM_SCATTER ppMEMsGPA, _In_ DWORD cpMEMsGPA);

typedef struct tdDEVICE_CONTEXT_VMM {
HMODULE hModuleVMM;
VMM_HANDLE hVMM;
VMMVM_HANDLE hVM;
FN_VMMDLL_ConfigGet pfnFN_VMMDLL_ConfigGet;
FN_VMMDLL_VmMemReadScatter pfnVMMDLL_VmMemReadScatter;
FN_VMMDLL_VmMemWriteScatter pfnVMMDLL_VmMemWriteScatter;
} DEVICE_CONTEXT_VMM , *PDEVICE_CONTEXT_VMM;

//-----------------------------------------------------------------------------
// GENERAL FUNCTIONALITY BELOW:
//-----------------------------------------------------------------------------

VOID DeviceVMM_ReadScatter(_In_ PLC_CONTEXT ctxLC, _In_ DWORD cpMEMs, _Inout_ PPMEM_SCATTER ppMEMs)
{
PDEVICE_CONTEXT_VMM ctx = (PDEVICE_CONTEXT_VMM)ctxLC->hDevice;
ctx->pfnVMMDLL_VmMemReadScatter(ctx->hVMM, ctx->hVM, ppMEMs, cpMEMs, 0);
}

VOID DeviceVMM_WriteScatter(_In_ PLC_CONTEXT ctxLC, _In_ DWORD cpMEMs, _Inout_ PPMEM_SCATTER ppMEMs)
{
PDEVICE_CONTEXT_VMM ctx = (PDEVICE_CONTEXT_VMM)ctxLC->hDevice;
ctx->pfnVMMDLL_VmMemWriteScatter(ctx->hVMM, ctx->hVM, ppMEMs, cpMEMs);
}

VOID DeviceVMM_Close(_Inout_ PLC_CONTEXT ctxLC)
{
PDEVICE_CONTEXT_VMM ctx = (PDEVICE_CONTEXT_VMM)ctxLC->hDevice;
if(ctx) {
ctxLC->hDevice = 0;
if(ctx->hModuleVMM) { FreeLibrary(ctx->hModuleVMM); }
LocalFree(ctx);
}
}

#define VMM_PARAMETER_HANDLE_VMM "hvmm"
#define VMM_PARAMETER_HANDLE_VM "hvm"

_Success_(return)
BOOL DeviceVMM_Open(_Inout_ PLC_CONTEXT ctxLC, _Out_opt_ PPLC_CONFIG_ERRORINFO ppLcCreateErrorInfo)
{
PDEVICE_CONTEXT_VMM ctx;
QWORD qwReadOnly = 0, qwVolatile = 0;
if(ppLcCreateErrorInfo) { *ppLcCreateErrorInfo = NULL; }
// 1: initialize core context:
if(sizeof(PVOID) < 8) { return FALSE; } // only supported on 64-bit os (due to resource constraints)
ctx = (PDEVICE_CONTEXT_VMM)LocalAlloc(LMEM_ZEROINIT, sizeof(DEVICE_CONTEXT_VMM));
if(!ctx) { return FALSE; }
ctxLC->hDevice = (HANDLE)ctx;
// 2: initialize vmm references:
ctx->hModuleVMM = LoadLibraryA("vmm.dll");
if(!ctx->hModuleVMM) {
lcprintfv(ctxLC, "DEVICE: VMM: Unable to open loopback device #1.\n");
goto fail;
}
ctx->pfnFN_VMMDLL_ConfigGet = (FN_VMMDLL_ConfigGet)GetProcAddress(ctx->hModuleVMM, "VMMDLL_ConfigGet");
ctx->pfnVMMDLL_VmMemReadScatter = (FN_VMMDLL_VmMemReadScatter)GetProcAddress(ctx->hModuleVMM, "VMMDLL_VmMemReadScatter");
ctx->pfnVMMDLL_VmMemWriteScatter = (FN_VMMDLL_VmMemWriteScatter)GetProcAddress(ctx->hModuleVMM, "VMMDLL_VmMemWriteScatter");
if(!ctx->pfnFN_VMMDLL_ConfigGet || !ctx->pfnVMMDLL_VmMemReadScatter || !ctx->pfnVMMDLL_VmMemReadScatter) {
lcprintfv(ctxLC, "DEVICE: VMM: Unable to open loopback device #2.\n");
goto fail;
}
// 3: fetch config parameters:
ctx->hVMM = (VMM_HANDLE)LcDeviceParameterGetNumeric(ctxLC, VMM_PARAMETER_HANDLE_VMM);
ctx->hVM = (VMMVM_HANDLE)LcDeviceParameterGetNumeric(ctxLC, VMM_PARAMETER_HANDLE_VM);
if(!ctx->pfnFN_VMMDLL_ConfigGet(ctx->hVMM, LC_OPT_CORE_VOLATILE, &qwVolatile)) { // inherit from vm parent vmm
lcprintfv(ctxLC, "DEVICE: VMM: Unable to communicate with loopback device #1.\n");
goto fail;
}
if(!ctx->pfnFN_VMMDLL_ConfigGet(ctx->hVMM, LC_OPT_CORE_READONLY, &qwReadOnly)) { // inherit from vm parent vmm
lcprintfv(ctxLC, "DEVICE: VMM: Unable to communicate with loopback device #2.\n");
goto fail;
}
// 4: set callback functions and fix up config
ctxLC->fMultiThread = TRUE;
ctxLC->Config.fVolatile = qwVolatile ? TRUE : FALSE;
ctxLC->pfnClose = DeviceVMM_Close;
ctxLC->pfnReadScatter = DeviceVMM_ReadScatter;
ctxLC->pfnWriteScatter = qwReadOnly ? NULL : DeviceVMM_WriteScatter;
return TRUE;
fail:
DeviceVMM_Close(ctxLC);
return FALSE;
}
12 changes: 12 additions & 0 deletions leechcore/leechcore.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ _Success_(return) BOOL Device3380_Open(_Inout_ PLC_CONTEXT ctxLC, _Out_opt_ PPLC
_Success_(return) BOOL DeviceFile_Open(_Inout_ PLC_CONTEXT ctxLC, _Out_opt_ PPLC_CONFIG_ERRORINFO ppLcCreateErrorInfo);
_Success_(return) BOOL DeviceFPGA_Open(_Inout_ PLC_CONTEXT ctxLC, _Out_opt_ PPLC_CONFIG_ERRORINFO ppLcCreateErrorInfo);
_Success_(return) BOOL DevicePMEM_Open(_Inout_ PLC_CONTEXT ctxLC, _Out_opt_ PPLC_CONFIG_ERRORINFO ppLcCreateErrorInfo);
_Success_(return) BOOL DeviceVMM_Open(_Inout_ PLC_CONTEXT ctxLC, _Out_opt_ PPLC_CONFIG_ERRORINFO ppLcCreateErrorInfo);
_Success_(return) BOOL DeviceVMWare_Open(_Inout_ PLC_CONTEXT ctxLC, _Out_opt_ PPLC_CONFIG_ERRORINFO ppLcCreateErrorInfo);
_Success_(return) BOOL DeviceTMD_Open(_Inout_ PLC_CONTEXT ctxLC, _Out_opt_ PPLC_CONFIG_ERRORINFO ppLcCreateErrorInfo);
_Success_(return) BOOL LeechRpc_Open(_Inout_ PLC_CONTEXT ctxLC, _Out_opt_ PPLC_CONFIG_ERRORINFO ppLcCreateErrorInfo);
Expand Down Expand Up @@ -242,6 +243,11 @@ VOID LcCreate_FetchDevice(_Inout_ PLC_CONTEXT ctx)
ctx->pfnCreate = DevicePMEM_Open;
return;
}
if(0 == _strnicmp("vmm://", ctx->Config.szDevice, 6)) {
strncpy_s(ctx->Config.szDeviceName, sizeof(ctx->Config.szDeviceName), "vmm", _TRUNCATE);
ctx->pfnCreate = DeviceVMM_Open;
return;
}
if(0 == _strnicmp("vmware", ctx->Config.szDevice, 4)) {
strncpy_s(ctx->Config.szDeviceName, sizeof(ctx->Config.szDeviceName), "vmware", _TRUNCATE);
ctx->pfnCreate = DeviceVMWare_Open;
Expand Down Expand Up @@ -1027,6 +1033,12 @@ BOOL LcGetOption_DoWork(_In_ PLC_CONTEXT ctxLC, _In_ QWORD fOption, _Out_ PQWORD
if((DWORD)fOption > LC_STATISTICS_ID_MAX) { return FALSE; }
*pqwValue = ctxLC->CallStat.Call[(DWORD)fOption].tm;
return TRUE;
case LC_OPT_CORE_VOLATILE:
*pqwValue = ctxLC->Config.fVolatile ? 1 : 0;
return TRUE;
case LC_OPT_CORE_READONLY:
*pqwValue = ctxLC->Config.fWritable ? 0 : 1;
return TRUE;
}
if(ctxLC->pfnGetOption) {
return ctxLC->pfnGetOption(ctxLC, fOption, pqwValue);
Expand Down
2 changes: 2 additions & 0 deletions leechcore/leechcore.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,8 @@ extern "C" {
#define LC_OPT_CORE_ADDR_MAX 0x1000000800000000 // R
#define LC_OPT_CORE_STATISTICS_CALL_COUNT 0x4000000900000000 // R [lo-dword: LC_STATISTICS_ID_*]
#define LC_OPT_CORE_STATISTICS_CALL_TIME 0x4000000a00000000 // R [lo-dword: LC_STATISTICS_ID_*]
#define LC_OPT_CORE_VOLATILE 0x1000000b00000000 // R
#define LC_OPT_CORE_READONLY 0x1000000c00000000 // R

#define LC_OPT_MEMORYINFO_VALID 0x0200000100000000 // R
#define LC_OPT_MEMORYINFO_FLAG_32BIT 0x0200000300000000 // R
Expand Down
1 change: 1 addition & 0 deletions leechcore/leechcore.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ copy "$(ProjectDir)\leechcore.h" "$(SolutionDir)\includes\" /y
<ClCompile Include="device_pmem.c" />
<ClCompile Include="device_tmd.c" />
<ClCompile Include="device_usb3380.c" />
<ClCompile Include="device_vmm.c" />
<ClCompile Include="device_vmware.c" />
<ClCompile Include="leechcore.c" />
<ClCompile Include="leechrpcshared.c" />
Expand Down
3 changes: 3 additions & 0 deletions leechcore/leechcore.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
<ClCompile Include="device_vmware.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="device_vmm.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="leechrpc.h">
Expand Down
3 changes: 3 additions & 0 deletions leechcore/leechrpcclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,9 @@ VOID LeechRPC_Close(_Inout_ PLC_CONTEXT ctxLC)
if(LeechRPC_SubmitCommand(ctxLC, &Msg, LEECHRPC_MSGTYPE_CLOSE_RSP, &pMsgRsp)) {
LocalFree(pMsgRsp);
}
while(ctx->fHousekeeperThreadIsRunning) {
SwitchToThread();
}
if(ctx->hPipeMem_Rd) {
CloseHandle(ctx->hPipeMem_Rd);
ctx->hPipeMem_Rd = NULL;
Expand Down
3 changes: 3 additions & 0 deletions leechcore/oscompatibility.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ HMODULE LoadLibraryA(LPSTR lpFileName)
if(lpFileName && (0 == memcmp(lpFileName, "FTD2XX.dll", 10))) {
lpFileName = "libftd2xx.so";
}
if(lpFileName && (0 == memcmp(lpFileName, "vmm.dll", 7))) {
lpFileName = "vmm.so";
}
strncat(szFileName, lpFileName, MAX_PATH);
return dlopen(szFileName, RTLD_NOW);
}
Expand Down
4 changes: 2 additions & 2 deletions leechcore/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
#define STRINGIZE(s) STRINGIZE2(s)

#define VERSION_MAJOR 2
#define VERSION_MINOR 13
#define VERSION_MINOR 14
#define VERSION_REVISION 0
#define VERSION_BUILD 51
#define VERSION_BUILD 52

#define VER_FILE_DESCRIPTION_STR "LeechCore Memory Acquisition Library"
#define VER_FILE_VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_BUILD
Expand Down
2 changes: 1 addition & 1 deletion leechcorepyc/pkggen_linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ leechcorepyc = Extension(
setup(
name='leechcorepyc',
version='2.13.0', # VERSION_END
version='2.14.0', # VERSION_END
description='LeechCore for Python',
long_description='LeechCore for Python : native extension for physical memory access',
url='https://github.com/ufrisk/LeechCore',
Expand Down
4 changes: 2 additions & 2 deletions leechcorepyc/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
#define STRINGIZE(s) STRINGIZE2(s)

#define VERSION_MAJOR 2
#define VERSION_MINOR 13
#define VERSION_MINOR 14
#define VERSION_REVISION 0
#define VERSION_BUILD 51
#define VERSION_BUILD 52

#define VER_FILE_DESCRIPTION_STR "LeechCore Memory Acquisition Library : Python API"
#define VER_FILE_VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_BUILD
Expand Down

0 comments on commit eef82c1

Please sign in to comment.