Skip to content

Commit

Permalink
Version 2.12
Browse files Browse the repository at this point in the history
  • Loading branch information
ufrisk committed Aug 4, 2022
1 parent 2d9c1ab commit 7a8b693
Show file tree
Hide file tree
Showing 10 changed files with 63 additions and 46 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,3 +200,6 @@ v1.0-1.8
* Bug fixes.
* Visual Studio 2022 Support.
* New write fpga algorithm.

[v2.12](https://github.com/ufrisk/LeechCore/releases/tag/v2.12)
* Support for MemProcFS v5.
Binary file modified includes/lib32/leechcore.lib
Binary file not shown.
Binary file modified includes/lib64/leechcore.lib
Binary file not shown.
61 changes: 36 additions & 25 deletions leechagent/leechagent_procchild.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@

#define VMMDLL_VFS_FILELISTBLOB_VERSION 0xf88f0001

typedef struct tdVMM_HANDLE *VMM_HANDLE;

static VMM_HANDLE g_hVMM = NULL;

typedef struct tdVMMDLL_VFS_FILELISTBLOB_OPAQUE {
DWORD dwVersion; // VMMDLL_VFS_FILELISTBLOB_VERSION
DWORD cbStruct;
Expand All @@ -37,14 +41,15 @@ typedef struct tdPROCCHILD_CONTEXT {
HMODULE hDllPython3;
HMODULE hDllPython3X;
HMODULE hDllLeechCorePyC;
BOOL(*pfnVMMDLL_Initialize)(_In_ DWORD argc, _In_ LPSTR argv[]);
BOOL(*pfnVMMDLL_InitializePlugins)();
BOOL(*pfnVMMDLL_Close)();
PVMMDLL_VFS_FILELISTBLOB_OPAQUE(*pfnVMMDLL_VfsListBlobU)(LPSTR);
DWORD(*pfnVMMDLL_VfsReadU)(_In_ LPSTR uszFileName, _Out_writes_to_(cb, *pcbRead) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbRead, _In_ ULONG64 cbOffset);
DWORD(*pfnVMMDLL_VfsWriteU)(_In_ LPSTR uszFileName, _In_reads_(cb) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbWrite, _In_ ULONG64 cbOffset);
BOOL(*pfnVMMDLL_ConfigGet)(_In_ ULONG64 fOption, _Out_ PULONG64 pqwValue);
BOOL(*pfnVMMDLL_ConfigSet)(_In_ ULONG64 fOption, _In_ ULONG64 qwValue);
VMM_HANDLE(*pfnVMMDLL_Initialize)(_In_ DWORD argc, _In_ LPSTR argv[]);
BOOL(*pfnVMMDLL_InitializePlugins)(VMM_HANDLE);
BOOL(*pfnVMMDLL_Close)(VMM_HANDLE);
VOID(*pfnVMMDLL_MemFree)(PVOID);
PVMMDLL_VFS_FILELISTBLOB_OPAQUE(*pfnVMMDLL_VfsListBlobU)(VMM_HANDLE, LPSTR);
DWORD(*pfnVMMDLL_VfsReadU)(VMM_HANDLE, _In_ LPSTR uszFileName, _Out_writes_to_(cb, *pcbRead) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbRead, _In_ ULONG64 cbOffset);
DWORD(*pfnVMMDLL_VfsWriteU)(VMM_HANDLE, _In_ LPSTR uszFileName, _In_reads_(cb) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbWrite, _In_ ULONG64 cbOffset);
BOOL(*pfnVMMDLL_ConfigGet)(VMM_HANDLE, _In_ ULONG64 fOption, _Out_ PULONG64 pqwValue);
BOOL(*pfnVMMDLL_ConfigSet)(VMM_HANDLE, _In_ ULONG64 fOption, _In_ ULONG64 qwValue);
BOOL(*pfnLeechCorePyC_EmbPythonInitialize)(_In_ HMODULE hDllPython);
BOOL(*pfnLeechCorePyC_EmbExecPyInMem)(_In_ LPSTR szPythonProgram);
VOID(*pfnLeechCorePyC_EmbClose)();
Expand All @@ -69,29 +74,35 @@ BOOL LeechAgent_ProcChild_InitializeVmm()
szVMM_ARGUMENTS[2] = ctxProcChild.szDevice;
szVMM_ARGUMENTS[4] = ctxProcChild.szRemote;
ctxProcChild.hDllVmm = LoadLibraryExA("vmm.dll", NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR);
if(!ctxProcChild.hDllVmm) {
ctxProcChild.hDllVmm = LoadLibraryA("vmm.dll");
}
if(!ctxProcChild.hDllVmm) {
fprintf(stderr, "LeechAgent: FAIL: CHILD could not locate/load MemProcFS library vmm.dll\n");
return FALSE;
}
ctxProcChild.pfnVMMDLL_Initialize = (BOOL(*)(DWORD, LPSTR*))GetProcAddress(ctxProcChild.hDllVmm, "VMMDLL_Initialize");
ctxProcChild.pfnVMMDLL_InitializePlugins = (BOOL(*)())GetProcAddress(ctxProcChild.hDllVmm, "VMMDLL_InitializePlugins");
ctxProcChild.pfnVMMDLL_Close = (BOOL(*)())GetProcAddress(ctxProcChild.hDllVmm, "VMMDLL_Close");
ctxProcChild.pfnVMMDLL_VfsListBlobU = (PVMMDLL_VFS_FILELISTBLOB_OPAQUE(*)(LPSTR))GetProcAddress(ctxProcChild.hDllVmm, "VMMDLL_VfsListBlobU");
ctxProcChild.pfnVMMDLL_VfsReadU = (DWORD(*)(LPSTR, PBYTE, DWORD, PDWORD, ULONG64))GetProcAddress(ctxProcChild.hDllVmm, "VMMDLL_VfsReadU");
ctxProcChild.pfnVMMDLL_VfsWriteU = (DWORD(*)(LPSTR, PBYTE, DWORD, PDWORD, ULONG64))GetProcAddress(ctxProcChild.hDllVmm, "VMMDLL_VfsWriteU");
ctxProcChild.pfnVMMDLL_ConfigGet = (BOOL(*)(ULONG64, PULONG64))GetProcAddress(ctxProcChild.hDllVmm, "VMMDLL_ConfigGet");
ctxProcChild.pfnVMMDLL_ConfigSet = (BOOL(*)(ULONG64, ULONG64))GetProcAddress(ctxProcChild.hDllVmm, "VMMDLL_ConfigSet");
ctxProcChild.pfnVMMDLL_Initialize = (VMM_HANDLE(*)(DWORD, LPSTR*))GetProcAddress(ctxProcChild.hDllVmm, "VMMDLL_Initialize");
ctxProcChild.pfnVMMDLL_InitializePlugins = (BOOL(*)(VMM_HANDLE))GetProcAddress(ctxProcChild.hDllVmm, "VMMDLL_InitializePlugins");
ctxProcChild.pfnVMMDLL_Close = (BOOL(*)(VMM_HANDLE))GetProcAddress(ctxProcChild.hDllVmm, "VMMDLL_Close");
ctxProcChild.pfnVMMDLL_MemFree = (VOID(*)(PVOID))GetProcAddress(ctxProcChild.hDllVmm, "VMMDLL_MemFree");
ctxProcChild.pfnVMMDLL_VfsListBlobU = (PVMMDLL_VFS_FILELISTBLOB_OPAQUE(*)(VMM_HANDLE, LPSTR))GetProcAddress(ctxProcChild.hDllVmm, "VMMDLL_VfsListBlobU");
ctxProcChild.pfnVMMDLL_VfsReadU = (DWORD(*)(VMM_HANDLE, LPSTR, PBYTE, DWORD, PDWORD, ULONG64))GetProcAddress(ctxProcChild.hDllVmm, "VMMDLL_VfsReadU");
ctxProcChild.pfnVMMDLL_VfsWriteU = (DWORD(*)(VMM_HANDLE, LPSTR, PBYTE, DWORD, PDWORD, ULONG64))GetProcAddress(ctxProcChild.hDllVmm, "VMMDLL_VfsWriteU");
ctxProcChild.pfnVMMDLL_ConfigGet = (BOOL(*)(VMM_HANDLE, ULONG64, PULONG64))GetProcAddress(ctxProcChild.hDllVmm, "VMMDLL_ConfigGet");
ctxProcChild.pfnVMMDLL_ConfigSet = (BOOL(*)(VMM_HANDLE, ULONG64, ULONG64))GetProcAddress(ctxProcChild.hDllVmm, "VMMDLL_ConfigSet");
if(!ctxProcChild.pfnVMMDLL_Initialize || !ctxProcChild.pfnVMMDLL_InitializePlugins || !ctxProcChild.pfnVMMDLL_Close) {
fprintf(stderr, "LeechAgent: FAIL: CHILD could not load MemProcFS library functions.\n");
return FALSE;
}
result = ctxProcChild.pfnVMMDLL_Initialize((sizeof(szVMM_ARGUMENTS) / sizeof(LPCSTR)), szVMM_ARGUMENTS);
if(!result) {
g_hVMM = ctxProcChild.pfnVMMDLL_Initialize((sizeof(szVMM_ARGUMENTS) / sizeof(LPCSTR)), szVMM_ARGUMENTS);
if(!g_hVMM) {
fprintf(stderr, "LeechAgent: FAIL: CHILD could not initialize MemProcFS library.\n");
return FALSE;
}
result = ctxProcChild.pfnVMMDLL_InitializePlugins();
result = ctxProcChild.pfnVMMDLL_InitializePlugins(g_hVMM);
if(!result) {
ctxProcChild.pfnVMMDLL_Close(g_hVMM);
g_hVMM = NULL;
fprintf(stderr, "LeechAgent: FAIL: CHILD could not initialize MemProcFS Plugins.\n");
return FALSE;
}
Expand All @@ -113,7 +124,7 @@ BOOL LeechAgent_ProcChild_VmmVfsList(_In_ PLC_CMD_AGENT_VFS_REQ pReq, _Out_ PLC_
PVMMDLL_VFS_FILELISTBLOB_OPAQUE pBlob = NULL;
pReq->uszPathFile[_countof(pReq->uszPathFile) - 1] = 0;
if(!ctxProcChild.pfnVMMDLL_VfsListBlobU) { goto fail; }
if(!(pBlob = ctxProcChild.pfnVMMDLL_VfsListBlobU(pReq->uszPathFile))) { goto fail; }
if(!(pBlob = ctxProcChild.pfnVMMDLL_VfsListBlobU(g_hVMM, pReq->uszPathFile))) { goto fail; }
if((pBlob->dwVersion != VMMDLL_VFS_FILELISTBLOB_VERSION) || (pBlob->cbStruct > 0x04000000)) { goto fail; }
if(!(pRsp = LocalAlloc(0, sizeof(LC_CMD_AGENT_VFS_RSP) + pBlob->cbStruct))) { goto fail; }
ZeroMemory(pRsp, sizeof(LC_CMD_AGENT_VFS_RSP));
Expand All @@ -123,7 +134,7 @@ BOOL LeechAgent_ProcChild_VmmVfsList(_In_ PLC_CMD_AGENT_VFS_REQ pReq, _Out_ PLC_
*pcbRsp = sizeof(LC_CMD_AGENT_VFS_RSP) + pRsp->cb;
*ppRsp = pRsp;
fail:
LocalFree(pBlob);
ctxProcChild.pfnVMMDLL_MemFree(pBlob);
return pRsp ? TRUE : FALSE;
}

Expand All @@ -145,7 +156,7 @@ BOOL LeechAgent_ProcChild_VmmVfsRead(_In_ PLC_CMD_AGENT_VFS_REQ pReq, _Out_ PLC_
if(!(pRsp = LocalAlloc(0, sizeof(LC_CMD_AGENT_VFS_RSP) + pReq->dwLength))) { return FALSE; }
ZeroMemory(pRsp, sizeof(LC_CMD_AGENT_VFS_RSP));
pRsp->dwVersion = LC_CMD_AGENT_VFS_RSP_VERSION;
pRsp->dwStatus = ctxProcChild.pfnVMMDLL_VfsReadU(pReq->uszPathFile, pRsp->pb, pReq->dwLength, &pRsp->cbReadWrite, pReq->qwOffset);
pRsp->dwStatus = ctxProcChild.pfnVMMDLL_VfsReadU(g_hVMM, pReq->uszPathFile, pRsp->pb, pReq->dwLength, &pRsp->cbReadWrite, pReq->qwOffset);
pRsp->cb = pRsp->cbReadWrite;
*pcbRsp = sizeof(LC_CMD_AGENT_VFS_RSP) + pRsp->cb;
*ppRsp = pRsp;
Expand All @@ -168,7 +179,7 @@ BOOL LeechAgent_ProcChild_VmmVfsWrite(_In_ PLC_CMD_AGENT_VFS_REQ pReq, _Out_ PLC
pReq->uszPathFile[_countof(pReq->uszPathFile) - 1] = 0;
if(!(pRsp = LocalAlloc(LMEM_ZEROINIT, sizeof(LC_CMD_AGENT_VFS_RSP)))) { return FALSE; }
pRsp->dwVersion = LC_CMD_AGENT_VFS_RSP_VERSION;
pRsp->dwStatus = ctxProcChild.pfnVMMDLL_VfsWriteU(pReq->uszPathFile, pReq->pb, pReq->cb, &pRsp->cbReadWrite, pReq->qwOffset);
pRsp->dwStatus = ctxProcChild.pfnVMMDLL_VfsWriteU(g_hVMM, pReq->uszPathFile, pReq->pb, pReq->cb, &pRsp->cbReadWrite, pReq->qwOffset);
*pcbRsp = sizeof(LC_CMD_AGENT_VFS_RSP);
*ppRsp = pRsp;
return TRUE;
Expand All @@ -190,7 +201,7 @@ BOOL LeechAgent_ProcChild_VmmVfsConfigGet(_In_ PLC_CMD_AGENT_VFS_REQ pReq, _Out_
if(!ctxProcChild.pfnVMMDLL_ConfigGet) { return FALSE; }
if(!(pRsp = LocalAlloc(LMEM_ZEROINIT, sizeof(LC_CMD_AGENT_VFS_RSP) + sizeof(QWORD)))) { return FALSE; }
pRsp->dwVersion = LC_CMD_AGENT_VFS_RSP_VERSION;
pRsp->dwStatus = (DWORD)ctxProcChild.pfnVMMDLL_ConfigGet(pReq->fOption, (PULONG64)pRsp->pb);
pRsp->dwStatus = (DWORD)ctxProcChild.pfnVMMDLL_ConfigGet(g_hVMM, pReq->fOption, (PULONG64)pRsp->pb);
pRsp->cb = sizeof(QWORD);
*pcbRsp = sizeof(LC_CMD_AGENT_VFS_RSP) + sizeof(QWORD);
*ppRsp = pRsp;
Expand All @@ -214,7 +225,7 @@ BOOL LeechAgent_ProcChild_VmmVfsConfigSet(_In_ PLC_CMD_AGENT_VFS_REQ pReq, _Out_
if(!ctxProcChild.pfnVMMDLL_ConfigSet || (pReq->cb != sizeof(QWORD))) { return FALSE; }
if(!(pRsp = LocalAlloc(LMEM_ZEROINIT, sizeof(LC_CMD_AGENT_VFS_RSP)))) { return FALSE; }
pRsp->dwVersion = LC_CMD_AGENT_VFS_RSP_VERSION;
pRsp->dwStatus = (DWORD)ctxProcChild.pfnVMMDLL_ConfigSet(pReq->fOption, *(PULONG64)pReq->pb);
pRsp->dwStatus = (DWORD)ctxProcChild.pfnVMMDLL_ConfigSet(g_hVMM, pReq->fOption, *(PULONG64)pReq->pb);
*pcbRsp = sizeof(LC_CMD_AGENT_VFS_RSP);
*ppRsp = pRsp;
return TRUE;
Expand Down
6 changes: 3 additions & 3 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 11
#define VERSION_REVISION 1
#define VERSION_BUILD 48
#define VERSION_MINOR 12
#define VERSION_REVISION 0
#define VERSION_BUILD 49

#define VER_FILE_DESCRIPTION_STR "LeechAgent Memory Acquisition Service"
#define VER_FILE_VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_BUILD
Expand Down
22 changes: 14 additions & 8 deletions leechcore/device_pmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,24 +269,30 @@ VOID DevicePMEM_Close(_Inout_ PLC_CONTEXT ctxLC)
}

_Success_(return)
BOOL DevicePMEM_GetMemoryInformation(_Inout_ PLC_CONTEXT ctxLC)
BOOL DevicePMEM_GetMemoryInformation(_Inout_ PLC_CONTEXT ctxLC, _In_ BOOL fFirst)
{
PDEVICE_CONTEXT_PMEM ctx = (PDEVICE_CONTEXT_PMEM)ctxLC->hDevice;
DWORD i, cbRead, dwMode = PMEM_MODE_PTE;
// 1: retrieve information from kernel driver
if(!DeviceIoControl(ctx->hFile, PMEM_INFO_IOCTRL, NULL, 0, &ctx->MemoryInfo, sizeof(ctx->MemoryInfo), &cbRead, NULL)) {
lcprintf(ctxLC, "DEVICE: ERROR: Unable to communicate with winpmem driver.\n");
if(!fFirst) {
lcprintf(ctxLC, "DEVICE: ERROR: Unable to communicate with winpmem driver.\n");
}
return FALSE;
}
// 2: sanity checks
if((ctx->MemoryInfo.NumberOfRuns.QuadPart == 0) || (ctx->MemoryInfo.NumberOfRuns.QuadPart > 100)) {
lcprintf(ctxLC, "DEVICE: ERROR: too few/many memory segments reported from winpmem driver. (%lli)\n", ctx->MemoryInfo.NumberOfRuns.QuadPart);
if(!fFirst) {
lcprintf(ctxLC, "DEVICE: ERROR: too few/many memory segments reported from winpmem driver. (%lli)\n", ctx->MemoryInfo.NumberOfRuns.QuadPart);
}
return FALSE;
}
// 3: parse memory ranges
for(i = 0; i < ctx->MemoryInfo.NumberOfRuns.QuadPart; i++) {
if(!LcMemMap_AddRange(ctxLC, ctx->MemoryInfo.Run[i].start, ctx->MemoryInfo.Run[i].length, ctx->MemoryInfo.Run[i].start)) {
lcprintf(ctxLC, "DEVICE: FAIL: unable to add range to memory map. (%016llx %016llx %016llx)\n", ctx->MemoryInfo.Run[i].start, ctx->MemoryInfo.Run[i].length, ctx->MemoryInfo.Run[i].start);
if(!fFirst) {
lcprintf(ctxLC, "DEVICE: FAIL: unable to add range to memory map. (%016llx %016llx %016llx)\n", ctx->MemoryInfo.Run[i].start, ctx->MemoryInfo.Run[i].length, ctx->MemoryInfo.Run[i].start);
}
return FALSE;
}
}
Expand Down Expand Up @@ -342,7 +348,7 @@ BOOL DevicePMEM_GetOption(_In_ PLC_CONTEXT ctxLC, _In_ QWORD fOption, _Out_ PQWO
}

_Success_(return)
BOOL DevicePMEM_Open2(_Inout_ PLC_CONTEXT ctxLC, _Out_opt_ PPLC_CONFIG_ERRORINFO ppLcCreateErrorInfo)
BOOL DevicePMEM_Open2(_Inout_ PLC_CONTEXT ctxLC, _Out_opt_ PPLC_CONFIG_ERRORINFO ppLcCreateErrorInfo, _In_ BOOL fFirst)
{
BOOL result;
PDEVICE_CONTEXT_PMEM ctx;
Expand All @@ -360,7 +366,7 @@ BOOL DevicePMEM_Open2(_Inout_ PLC_CONTEXT ctxLC, _Out_opt_ PPLC_CONFIG_ERRORINFO
g_cDevicePMEM++;
result = DevicePMEM_SvcStatusRunning(ctxLC) || DevicePMEM_SvcStart(ctxLC);
// 3: retrieve memory map.
result = result && DevicePMEM_GetMemoryInformation(ctxLC);
result = result && DevicePMEM_GetMemoryInformation(ctxLC, fFirst);
if(!result) {
DevicePMEM_Close(ctxLC);
return FALSE;
Expand All @@ -375,9 +381,9 @@ BOOL DevicePMEM_Open(_Inout_ PLC_CONTEXT ctxLC, _Out_opt_ PPLC_CONFIG_ERRORINFO
// Sometimes communication with PMEM driver will fail even though the driver
// is loaded. It's unknown why this is happening. But it always helps trying
// again so wrap the open function to perform a retry if there is a fail.
if(DevicePMEM_Open2(ctxLC, ppLcCreateErrorInfo)) { return TRUE; }
if(DevicePMEM_Open2(ctxLC, ppLcCreateErrorInfo, TRUE)) { return TRUE; }
Sleep(100);
return DevicePMEM_Open2(ctxLC, ppLcCreateErrorInfo);
return DevicePMEM_Open2(ctxLC, ppLcCreateErrorInfo, FALSE);
}

#endif /* _WIN32 */
Expand Down
3 changes: 0 additions & 3 deletions leechcore/oscompatibility.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,6 @@ HMODULE LoadLibraryA(LPSTR lpFileName)
if(lpFileName && (0 == memcmp(lpFileName, "FTD2XX.dll", 10))) {
lpFileName = "libftd2xx.so";
}
if(!strstr(lpFileName, "/")) {
Util_GetPathLib(szFileName);
}
strncat(szFileName, lpFileName, MAX_PATH);
return dlopen(szFileName, RTLD_NOW);
}
Expand Down
6 changes: 3 additions & 3 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 11
#define VERSION_REVISION 1
#define VERSION_BUILD 48
#define VERSION_MINOR 12
#define VERSION_REVISION 0
#define VERSION_BUILD 49

#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.11.1', # VERSION_END
version='2.12.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
6 changes: 3 additions & 3 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 11
#define VERSION_REVISION 1
#define VERSION_BUILD 48
#define VERSION_MINOR 12
#define VERSION_REVISION 0
#define VERSION_BUILD 49

#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 7a8b693

Please sign in to comment.