forked from ufrisk/MemProcFS
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
61 changed files
with
3,117 additions
and
457 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -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__ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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: | ||
//------------------------------------------------------------------------------- | ||
|
@@ -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, | ||
|
@@ -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; | ||
|
@@ -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; | ||
|
@@ -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; | ||
|
@@ -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) { | ||
|
@@ -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; | ||
|
@@ -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); | ||
|
Oops, something went wrong.