Skip to content

Commit

Permalink
Version 3.2
Browse files Browse the repository at this point in the history
  • Loading branch information
ufrisk committed Mar 17, 2020
1 parent 13f7300 commit f2d15cf
Show file tree
Hide file tree
Showing 61 changed files with 3,117 additions and 457 deletions.
66 changes: 40 additions & 26 deletions MemProcFS/leechcore.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,36 +49,49 @@
// Android WinUSB drivers to be installed. Download and install from:
// http://developer.android.com/sdk/win-usb.html#download
// Syntax:
// USB3380
// USB3380://USB2 (force USB2 connection speed)
// USB3380
// USB3380://USB2 (force USB2 connection speed)
//
// FPGA : hardware, read/write - requires a PCILeech FPGA flashed hardware
// device as shown at: https://github.com/ufrisk/pcileech-fpga
// Also requires the FTD3XX.DLL from ftdichip to be placed in the
// same directory as the executable. Download from ftdichip at:
// http://www.ftdichip.com/Drivers/D3XX/FTD3XXLibrary_v1.2.0.6.zip
// https://www.ftdichip.com/Drivers/D3XX/FTD3XXLibrary_v1.3.0.2.zip
// Syntax:
// FGPA
// FPGA://pcie_gen:[<read_uS>[:<write_uS>[:<probe_uS>]]]
// FGPA
// FPGA://<comma_separated_options_list>
// Example: FPGA://pciegen=1,deviceindex=1
// Options:
// pciegen= PCIe generation to use, 1 or 2
// tmread= Read delay in uS
// tmwrite= Write delay in uS
// tmprobe= Probe delay in uS
// algo= 1 (normal) or 2 (tiny)
// readsize= max chunk read size in bytes
// readretry= number of retries on fail
// deviceindex= device index to open
//
// RAWUDP : hardware, read/write - connect to a remote FPGA over the network
// using a rudimentary UDP implmentation of the FPGA USB protocol.
// Supported devices: NeTV2 - https://github.com/ufrisk/pcileech-fpga
// Syntax:
// RAWUDP://<target_ipv4>:[pcie_gen:[<read_uS>[:<write_uS>[:<probe_uS>]]]]
// Example: RAWUDP://192.168.0.222
// RAWUDP://<comma_separated_options_list>
// Example: RAWUDP://ip=192.168.0.222
// Options:
// ip= ip address or host name to connect to.
// (options for fpga device type also applies).
//
// SP605TCP : hardware, read/write - connect to a remote SP605 FPGA over the
// network using the implementation created by @d_olex.
// https://github.com/Cr4sh/s6_pcie_microblaze
// Syntax:
// SP605TCP://<target_ip>[:<target_port>] (port is optional)
// SP605TCP://<target_ip>[:<target_port>] (port is optional)
//
// RAWTCP : read/write - connect to a remote raw tcp device - such as HPE iLO
// that have been patched to support DMA as per blog entry below:
// https://www.synacktiv.com/posts/exploit/using-your-bmc-as-a-dma-device-plugging-pcileech-to-hpe-ilo-4.html
// Syntax:
// RAWTCP://<target_ip>[:<target_port>] (port is optional)
// RAWTCP://<target_ip>[:<target_port>] (port is optional)
//
// HvSavedState : read-only - connect to a Hyper-V saved state file. In order
// to do so the .dll file 'vmsavedstatedumpprovider.dll' must be
Expand All @@ -91,50 +104,51 @@
// directory of leechcore.dll and run executable as elevated admin
// using syntax below:
// Syntax:
// PMEM (use att_winpmem_64.sys in directory of executable)
// PMEM://<non_default_path_to_file_winpmem_64.sys>
// PMEM (use att_winpmem_64.sys in directory of executable)
// PMEM://<non_default_path_to_file_winpmem_64.sys>
//
// TOTALMELTDOWN : read/write - requires a Windows 7 system vulnerable to the
// "Total Meltdown" vulnerability - CVE-2018-1038.
// Syntax:
// TOTALMELTDOWN
// TOTALMELTDOWN
//
// FILE : use dump file, either a raw linear memory dump, full crash dump or
// full elf core dump (virtualbox).
// Which format to use is auto-detected. If it looks like a full cash
// dump or full elf core dump those formats will be used, otherwise
// it will be assumed that a raw linear memory dump is to be used.
// FILE : use dump file of any of the below listed formats:
// - raw linear memory dump.
// - full microsoft crash dump (DumpIt).
// - full elf core dump (VirtualBox).
// - VMware save/dump file (.vmem + .vmss/.vmsn).
// The format to use is auto-detected.
// Syntax:
// <filename> (no device-type prefix - just use the file name)
// FILE://<filename>
// <filename> (no device-type prefix - just use the file name)
// FILE://<filename>
//
// DumpIt : DumpIt is a "virtual" device. It's only possible to use the DumpIt
// device if the main process containing LeechCore has been started
// with DumpIt in LiveKD mode.
// Example 1:
// DumpIt.exe /LIVEKD /A MemProcFS.exe
// DumpIt.exe /LIVEKD /A MemProcFS.exe
// Example 2:
// DumpIt.exe /LIVEKD /A LeechSvc.exe /C "interactive insecure"
// and then connect to remote service by:
// MemProcFS.exe -remote rpc://insecure:192.168.x.x -device DumpIt
// DumpIt.exe /LIVEKD /A LeechSvc.exe /C "interactive insecure"
// and then connect to remote service by:
// MemProcFS.exe -remote rpc://insecure:192.168.x.x -device DumpIt
//
// EXISTING : Attach to existing already loaded configuration. This is done
// instead of the default behaviour of closing any existing devices
// and initializing the new requested device. If no existing device
// exists the call to LeechCore_Open will fail.
// Syntax:
// EXISTING
// EXISTING
//
// EXISTINGREMOTE : Same as EXISTING but applying the EXISTING device on the
// remote system. Use only in conjunction with a remote system.
// Syntax:
// EXISTINGREMOTE
// EXISTINGREMOTE
//
//
// (c) Ulf Frisk, 2018-2020
// Author: Ulf Frisk, [email protected]
//
// Header Version: 1.6
// Header Version: 1.7
//
#ifndef __LEECHCORE_H__
#define __LEECHCORE_H__
Expand Down
4 changes: 2 additions & 2 deletions MemProcFS/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 3
#define VERSION_MINOR 1
#define VERSION_MINOR 2
#define VERSION_REVISION 0
#define VERSION_BUILD 5
#define VERSION_BUILD 6

#define VER_FILE_DESCRIPTION_STR "MemProcFS"
#define VER_FILE_VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_BUILD
Expand Down
76 changes: 52 additions & 24 deletions MemProcFS/vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,21 @@ VOID Vfs_UtilSplitPathFile(_Out_writes_(MAX_PATH) PWCHAR wszPath, _Out_ LPWSTR *
*pwcsFile = wszPath + iSplitFilePath + 1;
}

DWORD Vfs_UtilHashStringUpperW(_In_opt_ LPCWSTR wsz)
{
WCHAR c;
DWORD i = 0, dwHash = 0;
if(!wsz) { return 0; }
while(TRUE) {
c = wsz[i++];
if(!c) { return dwHash; }
if(c >= 'a' && c <= 'z') {
c += 'A' - 'a';
}
dwHash = ((dwHash >> 13) | (dwHash << 19)) + c;
}
}

//-------------------------------------------------------------------------------
// DOKAN CALLBACK FUNCTIONS BELOW:
//-------------------------------------------------------------------------------
Expand Down Expand Up @@ -347,6 +362,8 @@ VfsCallback_GetFileInformation(_In_ LPCWSTR wcsFileName, _Inout_ LPBY_HANDLE_FIL
hfi->ftLastWriteTime = FindData.ftLastWriteTime;
hfi->nFileSizeHigh = FindData.nFileSizeHigh;
hfi->nFileSizeLow = FindData.nFileSizeLow;
hfi->nFileIndexHigh = Vfs_UtilHashStringUpperW(wcsFileName);
hfi->nFileIndexLow = Vfs_UtilHashStringUpperW(FindData.cFileName);
dbg_wprintf(L"DEBUG::%08x %8x VfsCallback_GetFileInformation:\t 0x%08x %s\t [ %08x %08x%08x %016llx %016llx %016llx ]\n",
(DWORD)(dbg_GetTickCount64() - tmStart),
STATUS_SUCCESS,
Expand Down Expand Up @@ -382,7 +399,7 @@ VfsCallback_ReadFile(LPCWSTR wcsFileName, LPVOID Buffer, DWORD BufferLength, LPD
{
UINT64 tmStart = dbg_GetTickCount64();
NTSTATUS nt;
dbg_wprintf_init(L"DEBUG:: -------- VfsCallback_ReadFile:\t\t\t 0x%08x %s\n", 0, wcsFileName);
dbg_wprintf_init(L"DEBUG::%08x -------- VfsCallback_ReadFile:\t\t\t 0x%08x %s\n", 0, wcsFileName);
nt = ctxVfs->pVmmDll->VfsRead(wcsFileName, Buffer, BufferLength, ReadLength, Offset);
dbg_wprintf(L"DEBUG::%08x %8x VfsCallback_ReadFile:\t\t\t 0x%08x %s\t [ %016llx %08x %08x ]\n", (DWORD)(dbg_GetTickCount64() - tmStart), nt, wcsFileName, Offset, BufferLength, *ReadLength);
return nt;
Expand All @@ -393,7 +410,7 @@ VfsCallback_WriteFile(LPCWSTR wcsFileName, LPCVOID Buffer, DWORD NumberOfBytesTo
{
UINT64 tmStart = dbg_GetTickCount64();
NTSTATUS nt;
dbg_wprintf_init(L"DEBUG:: -------- VfsCallback_WriteFile:\t\t\t 0x%08x %s\n", 0, wcsFileName);
dbg_wprintf_init(L"DEBUG::%08x -------- VfsCallback_WriteFile:\t\t\t 0x%08x %s\n", 0, wcsFileName);
nt = ctxVfs->pVmmDll->VfsWrite(wcsFileName, (PBYTE)Buffer, NumberOfBytesToWrite, NumberOfBytesWritten, Offset);
dbg_wprintf(L"DEBUG::%08x %8x VfsCallback_WriteFile:\t\t\t 0x%08x %s\t [ %016llx %08x %08x ]\n", (DWORD)(dbg_GetTickCount64() - tmStart), nt, wcsFileName, Offset, NumberOfBytesToWrite, *NumberOfBytesWritten);
return nt;
Expand Down Expand Up @@ -426,6 +443,35 @@ VOID VfsClose(_In_ CHAR chMountPoint)
ctxVfs = NULL;
}

VOID VfsInitializeAndMount_DisplayInfo(LPWSTR wszMountPoint, _In_ PVMMDLL_FUNCTIONS pVmmDll)
{
ULONG64 qwVersionVmmMajor = 0, qwVersionVmmMinor = 0, qwVersionVmmRevision = 0;
ULONG64 qwVersionWinMajor = 0, qwVersionWinMinor = 0, qwVersionWinBuild = 0, iMemoryModel;
// get vmm.dll versions
pVmmDll->ConfigGet(VMMDLL_OPT_CONFIG_VMM_VERSION_MAJOR, &qwVersionVmmMajor);
pVmmDll->ConfigGet(VMMDLL_OPT_CONFIG_VMM_VERSION_MINOR, &qwVersionVmmMinor);
pVmmDll->ConfigGet(VMMDLL_OPT_CONFIG_VMM_VERSION_REVISION, &qwVersionVmmRevision);
// get operating system versions
pVmmDll->ConfigGet(VMMDLL_OPT_CORE_MEMORYMODEL, &iMemoryModel);
pVmmDll->ConfigGet(VMMDLL_OPT_WIN_VERSION_MAJOR, &qwVersionWinMajor);
pVmmDll->ConfigGet(VMMDLL_OPT_WIN_VERSION_MINOR, &qwVersionWinMinor);
pVmmDll->ConfigGet(VMMDLL_OPT_WIN_VERSION_BUILD, &qwVersionWinBuild);
printf("\n" \
"=============== MemProcFS - THE MEMORY PROCESS FILE SYSTEM ===============\n" \
" - Author: Ulf Frisk - [email protected] - https://frizk.net \n" \
" - Info: https://github.com/ufrisk/MemProcFS \n" \
" - VmmDll Version: %i.%i.%i \n" \
" - Mount Point: %S \n",
(DWORD)qwVersionVmmMajor, (DWORD)qwVersionVmmMinor, (DWORD)qwVersionVmmRevision, wszMountPoint);
if(qwVersionWinMajor && (iMemoryModel < (sizeof(VMMDLL_MEMORYMODEL_TOSTRING) / sizeof(LPSTR)))) {
printf(" - Operating System: Windows %i.%i.%i (%s)\n",
(DWORD)qwVersionWinMajor, (DWORD)qwVersionWinMinor, (DWORD)qwVersionWinBuild, VMMDLL_MEMORYMODEL_TOSTRING[iMemoryModel]);
} else {
printf(" - Operating System: Unknown\n");
}
printf("==========================================================================\n\n");
}

VOID VfsInitializeAndMount(_In_ CHAR chMountPoint, _In_ PVMMDLL_FUNCTIONS pVmmDll)
{
int status;
Expand All @@ -435,11 +481,6 @@ VOID VfsInitializeAndMount(_In_ CHAR chMountPoint, _In_ PVMMDLL_FUNCTIONS pVmmDl
WCHAR wszMountPoint[] = { 'M', ':', '\\', 0 };
SYSTEMTIME SystemTimeNow;
int(*fnDokanMain)(PDOKAN_OPTIONS, PDOKAN_OPERATIONS);
ULONG64 qwVersionMajor = 0, qwVersionMinor = 0, qwVersionRevision = 0;
// get versions
pVmmDll->ConfigGet(VMMDLL_OPT_CONFIG_VMM_VERSION_MAJOR, &qwVersionMajor);
pVmmDll->ConfigGet(VMMDLL_OPT_CONFIG_VMM_VERSION_MINOR, &qwVersionMinor);
pVmmDll->ConfigGet(VMMDLL_OPT_CONFIG_VMM_VERSION_REVISION, &qwVersionRevision);
// allocate
hModuleDokan = LoadLibraryExA("dokan1.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
if(!hModuleDokan) {
Expand Down Expand Up @@ -472,7 +513,7 @@ VOID VfsInitializeAndMount(_In_ CHAR chMountPoint, _In_ PVMMDLL_FUNCTIONS pVmmDl
// set options
pDokanOptions->Version = DOKAN_VERSION;
pDokanOptions->Options |= DOKAN_OPTION_NETWORK;
pDokanOptions->UNCName = L"MemoryProcessFileSystem";
pDokanOptions->UNCName = L"MemProcFS";
wszMountPoint[0] = chMountPoint;
pDokanOptions->MountPoint = wszMountPoint;
pDokanOptions->Timeout = 60000;
Expand All @@ -482,22 +523,9 @@ VOID VfsInitializeAndMount(_In_ CHAR chMountPoint, _In_ PVMMDLL_FUNCTIONS pVmmDl
pDokanOperations->FindFiles = VfsCallback_FindFiles;
pDokanOperations->ReadFile = VfsCallback_ReadFile;
pDokanOperations->WriteFile = VfsCallback_WriteFile;
// enable
printf(
"MOUNTING THE MEMORY PROCESS FILE SYSTEM \n" \
"===============================================================================\n" \
"The Memory Process File System is mounted as: %S \n" \
"Loaded VmmDll Version: %i.%i.%i \n" \
"Memory from dump files or PCILeech supported devices are analyzed to provide \n" \
"a convenient process file system for analysis purposes. \n" \
" - File system is read-only when dump files are used. \n" \
" - File system is read-write when FPGA hardware acquisition devices are used. \n" \
" - Full support exists for Windows XP to Windows 10 (x86 and x64). \n" \
" - Limited support for other x64 operating systems. \n" \
" - Memory Process File System: https://github.com/ufrisk/MemProcFS \n" \
" - File system by: Ulf Frisk - [email protected] - https://frizk.net \n" \
"===============================================================================\n",
pDokanOptions->MountPoint, (DWORD)qwVersionMajor, (DWORD)qwVersionMinor, (DWORD)qwVersionRevision);
// print system information to console
VfsInitializeAndMount_DisplayInfo(wszMountPoint, pVmmDll);
// mount file system
status = fnDokanMain(pDokanOptions, pDokanOperations);
while(status == DOKAN_SUCCESS) {
printf("MOUNT: ReMounting as drive %S\n", pDokanOptions->MountPoint);
Expand Down
Loading

0 comments on commit f2d15cf

Please sign in to comment.