diff --git a/Android.md b/Android.md
deleted file mode 100644
index abcb264..0000000
--- a/Android.md
+++ /dev/null
@@ -1,39 +0,0 @@
-Android Information:
-====================
-This page contains specific information about PCILeech with regards to installing and building for Android. For general information about PCIleech please check the [readme](README.md).
-
-PCILeech is able to run on Android devices - such as phones and tablets. The device must be rooted and PCIleech must be run as root. The Android device must have a USB port which the PCILeech hardware can be connected to. Most devices, such as phones, supports OTG which will allow connecting PCILeech with an OTG adapter.
-
-
-
-PCILeech on the Nexus 5x dumping memory from a Lenovo T430.
-
-Installing
-==========
-Please ensure you do have the most recent version of PCILeech by downloading it from: https://github.com/ufrisk/pcileech
-
-Either build your own binaries, or download the pre-built [PCILeech v2.1.1 Android binaries](https://gist.github.com/ufrisk/d783ef49813a269704f3bce1c022cefb/raw/044100b923fd652411326bc8825b16700287905b/pcileech_android_v211.zip). SHA-256: `bd92d16d20acb0bd8a51ef3873d9ea9341064319e190ecf7ca5b91194522dc04`
-
-Run the commands below as root on Android device to install PCILeech:
-* Remount system file system as read/write: `mount -o remount,rw /system`
-* Copy `/libusb1.0.so` from the downloaded or built Android binaries to `/system/lib/` or `/system/lib64/` (depending on device cpu architecture).
-* Remount system file system as read-only: `mount -o remount,ro /system`
-* Create PCILeech directory: `mkdir /data/pcileech/`
-* Copy `/pcileech` from the downloaded or built Android binaries to `/data/pcileech/`.
-* Copy from `pcileech_files/`: *.sig, *.ksh, *.kmd *.bin files to `/data/pcileech/`
-
-Finished! PCILeech should now be able to run on the phone!
-
-Tested on Nexus 5x with Apple USB-C to USB OTG adapter.
-
-Building
-========
-Building PCILeech for Android has been tested on a Linux x64-system (Kali and Ubuntu amd64 versions). Please follow the instructions below for building PCILeech for Android:
-* Download and install the Android NDK.
-* Ensure ndk-build is on the current path.
-* Get the latest libusb source from: `https://github.com/libusb/libusb`
-* Get the latest pcileech source from: `https://github.com/ufrisk/pcileech`
-* Set environment variable PATH_TO_LIBUSB_SRC: `export PATH_TO_LIBUSB_SRC=`
-* Move into: `/pcileech/`
-* Execute: `ndk-build APP_BUILD_SCRIPT=./Android.mk NDK_PROJECT_PATH=.`
-* Finished! PCIleech and Libusb Android binaries should now be found in the libs folder.
diff --git a/pcileech/device.c b/pcileech/device.c
index 281aa4e..97849b4 100644
--- a/pcileech/device.c
+++ b/pcileech/device.c
@@ -96,7 +96,7 @@ DWORD DeviceReadDMAEx_DoWork(_Inout_ PPCILEECH_CONTEXT ctx, _In_ QWORD qwAddr, _
cbRd = ((i == cChunkTotal - 1) && (cb % cbChunk)) ? (cb % cbChunk) : cbChunk; // (last chunk may be smaller)
if(ctx->cfg->dev.fScatterReadSupported) {
// scatter read, if available
- cbSuccess = DeviceReadDMAEx_DoWork_Scatter(ctx, qwAddr + cbRdOff, pb + cbRdOff, cbRd, pPageStat);
+ cbSuccess += DeviceReadDMAEx_DoWork_Scatter(ctx, qwAddr + cbRdOff, pb + cbRdOff, cbRd, pPageStat);
} else {
// traditional read
result = DeviceReadDMA(ctx, qwAddr + cbRdOff, pb + cbRdOff, cbRd, 0);
diff --git a/pcileech/devicefpga.c b/pcileech/devicefpga.c
index 48b5fbf..f5e1c2d 100644
--- a/pcileech/devicefpga.c
+++ b/pcileech/devicefpga.c
@@ -6,7 +6,6 @@
// (c) Ulf Frisk, 2017-2018
// Author: Ulf Frisk, pcileech@frizk.net
//
-#ifdef WIN32
#include "devicefpga.h"
#include "device.h"
@@ -567,7 +566,7 @@ VOID DeviceFPGA_ReadScatterDMA_Impl(_Inout_ PPCILEECH_CONTEXT ctxPcileech, _Inou
rxbuf.cbReadTotal = 0;
rxbuf.cph = cpDMAs - i;
rxbuf.pph = ppDMAs + i;
- ctx->hRxTlpCallbackFn = TLP_CallbackMRd_Scatter;
+ ctx->hRxTlpCallbackFn = (VOID(*)(PVOID, PBYTE, DWORD))TLP_CallbackMRd_Scatter;
// Transmit TLPs
cbFlush = 0;
cbTotalInCycle = 0;
@@ -632,12 +631,14 @@ VOID DeviceFPGA_ReadScatterDMA(_Inout_ PPCILEECH_CONTEXT ctxPcileech, _Inout_ PP
{
PDEVICE_CONTEXT_FPGA ctx = (PDEVICE_CONTEXT_FPGA)ctxPcileech->hDevice;
DWORD i = 0, c = 0;
+ BOOL fRetry = FALSE;
DeviceFPGA_ReadScatterDMA_Impl(ctxPcileech, ppDMAs, cpDMAs);
if(pchDMAsRead || ctx->perf.RETRY_ON_ERROR) {
while(i < cpDMAs) {
- if((ppDMAs[i]->cb < ppDMAs[i]->cbMax) && ctx->perf.RETRY_ON_ERROR) {
+ if((ppDMAs[i]->cb < ppDMAs[i]->cbMax) && ctx->perf.RETRY_ON_ERROR && !fRetry) {
Sleep(100);
DeviceFPGA_ReadScatterDMA_Impl(ctxPcileech, ppDMAs, cpDMAs);
+ fRetry = TRUE;
}
c += (ppDMAs[i]->cb >= ppDMAs[i]->cbMax) ? 1 : 0;
i++;
@@ -669,7 +670,7 @@ VOID DeviceFPGA_ProbeDMA_Impl(_Inout_ PPCILEECH_CONTEXT ctxPcileech, _In_ QWORD
bufMRd.pb = pbResultMap;
bufMRd.cbMax = cPages;
ctx->pMRdBufferX = &bufMRd;
- ctx->hRxTlpCallbackFn = TLP_CallbackMRdProbe;
+ ctx->hRxTlpCallbackFn = (VOID(*)(PVOID, PBYTE, DWORD))TLP_CallbackMRdProbe;
// transmit TLPs
for(i = 0; i < cPages; i++) {
if(pbResultMap[i]) { continue; } // skip over if page already marked as ok
@@ -853,7 +854,7 @@ BOOL DeviceFPGA_Open(_Inout_ PPCILEECH_CONTEXT ctxPcileech)
// return
if(ctxPcileech->cfg->fVerbose) {
printf(
- "FPGA: Device Info: %s PCIe gen%i x%i [%i,%i,%i] [v%i.%i]\n",
+ "FPGA: Device Info: %s PCIe gen%i x%i [%i,%i,%i] [v%i.%i,%04x]\n",
ctx->perf.SZ_DEVICE_NAME,
DeviceFPGA_PHY_GetPCIeGen(ctx),
DeviceFPGA_PHY_GetLinkWidth(ctx),
@@ -861,28 +862,20 @@ BOOL DeviceFPGA_Open(_Inout_ PPCILEECH_CONTEXT ctxPcileech)
ctx->perf.DELAY_WRITE,
ctx->perf.DELAY_PROBE_READ,
ctx->wFpgaVersionMajor,
- ctx->wFpgaVersionMinor);
+ ctx->wFpgaVersionMinor,
+ ctx->wDeviceId);
}
return TRUE;
fail:
if(szDeviceError && (ctxPcileech->cfg->fVerbose || (ctxPcileech->cfg->dev.tp == PCILEECH_DEVICE_FPGA))) {
- printf("FPGA: ERROR: %s.\n", szDeviceError);
+ printf(
+ "FPGA: ERROR: %s [%i,v%i.%i,%04x]\n",
+ szDeviceError,
+ ctx->wFpgaID,
+ ctx->wFpgaVersionMajor,
+ ctx->wFpgaVersionMinor,
+ ctx->wDeviceId);
}
DeviceFPGA_Close(ctxPcileech);
return FALSE;
}
-
-#endif /* WIN32 */
-#if defined(LINUX) || defined(ANDROID)
-
-#include "devicefpga.h"
-
-BOOL DeviceFPGA_Open(_Inout_ PPCILEECH_CONTEXT ctx)
-{
- if(ctx->cfg->dev.tp == PCILEECH_DEVICE_FPGA) {
- printf("FPGA: Failed. FPGA device currently only supported in PCILeech for Windows.");
- }
- return FALSE;
-}
-
-#endif /* LINUX || ANDROID */
diff --git a/pcileech/extra.c b/pcileech/extra.c
index 9733fae..929b278 100644
--- a/pcileech/extra.c
+++ b/pcileech/extra.c
@@ -223,7 +223,7 @@ VOID Action_TlpTx(_Inout_ PPCILEECH_CONTEXT ctx)
printf("Action_TlpTx: Invalid TLP (length not multiple of 4).\n");
return;
}
- printf("TLP: Transmitting PCIe TLP.%s\n", ctx->cfg->fVerboseExtra ? "" : " (use -vv option for detailed info).");
+ printf("TLP: Transmitting PCIe TLP.%s\n", ctx->cfg->fVerboseExtra ? "" : " (use -vvv option for detailed info).");
DeviceWriteTlp(ctx, ctx->cfg->pbIn, (DWORD)ctx->cfg->cbIn);
DeviceListenTlp(ctx, 100);
}
diff --git a/pcileech/help.c b/pcileech/help.c
index 5110c74..5525f38 100644
--- a/pcileech/help.c
+++ b/pcileech/help.c
@@ -33,9 +33,9 @@ VOID Help_ShowGeneral()
" contains a kernel mode signature the kernel module will be loaded and then un-\n" \
" loaded on program exit ( except for the kmdload command ). \n" \
" KMD mode may access all memory (available to the kernel of the target system).\n" \
- " DMA mode may only access lower 4GB of memory if USB3380 hardware is used. \n" \
+ " DMA mode may access 4GB memory if USB3380 hardware is used. \n" \
" DMA mode may access all memory if FPGA based hardware is used such as the: \n" \
- " SP605, AC701 and PCIeScreamer. \n" \
+ " SP605/FT601, AC701/FT601 and PCIeScreamer. \n" \
" For detailed help about a specific command type: pcileech -help \n" \
" General syntax: pcileech [- ] ... \n" \
" Valid commands and valid MODEs [ and options ] \n" \
@@ -47,7 +47,7 @@ VOID Help_ShowGeneral()
" [implant] KMD [ in, out, s, 0..9 ] \n" \
" kmdload DMA [ pt, cr3 ] \n" \
" kmdexit KMD \n" \
- " mount KMD [ s, cr3 ] (Windows only feature) \n" \
+ " mount DMA,KMD [ s, cr3 ] (Windows only feature) \n" \
" display DMA,KMD [ min, max ] \n" \
" pagedisplay DMA,KMD [ min ] \n" \
" pt_phys2virt DMA,KMD [ cr3, 0 ] \n" \
@@ -62,9 +62,9 @@ VOID Help_ShowGeneral()
" tlp DMA [ in ] (FPGA) \n" \
" probe DMA [ in ] (FPGA) \n" \
" System specific commands and valid MODEs [ and options ]: \n" \
- " mac_fvrecover DMA \n" \
- " mac_fvrecover2 DMA \n" \
- " mac_disablevtd DMA \n" \
+ " mac_fvrecover DMA (USB3380) \n" \
+ " mac_fvrecover2 DMA (USB3380) \n" \
+ " mac_disablevtd DMA (USB3380) \n" \
" Valid options: \n" \
" -min : memory min address, valid range: 0x0 .. 0xffffffffffffffff \n" \
" default: 0x0 \n" \
@@ -110,12 +110,10 @@ VOID Help_ShowGeneral()
" -0..9: QWORD input value. Example: -0 0xff , -3 0x7fffffff00001000 or -2 13 \n" \
" default: 0 \n" \
" -pt : trigger KMD insertion by automatic page table hijack. \n" \
- " Option has no value. Example: -pt \n" \
- " Used in conjunction with -kmd option to trigger KMD insertion by page\n" \
- " table hijack. Only recommended to use with care on computers with \n" \
- " 4GB+ RAM when kernel is located in high-memory (Windows 10). \n" \
- " -cr3 : base address of system page table / CR3 CPU register. \n" \
- " -efibase : base address of EFI_SYSTEM_TABLE (IBI SYST) used when inserting \n" \
+ " Option has no value. Example: -pt. Used in conjunction with \n" \
+ " -kmd option to trigger KMD insertion by page table hijack. \n" \
+ " -cr3 : base address of page table (PML4) / CR3 CPU register. \n" \
+ " -efibase : base address of EFI_SYSTEM_TABLE (IBI SYST). Used when inserting \n" \
" UEFI 'kernel' modules. \n" \
" -kmd : address of already loaded kernel module helper (KMD). \n" \
" ALTERNATIVELY \n" \
@@ -144,7 +142,7 @@ VOID Help_ShowInfo()
printf(
" PCILEECH INFORMATION \n" \
" PCILeech (c) 2016-2018 Ulf Frisk \n" \
- " Version: 3.0 \n" \
+ " Version: 3.1 \n" \
" License: GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 \n" \
" Contact information: pcileech@frizk.net \n" \
" System requirements: 64-bit Windows 7, 10 or Linux. \n" \
@@ -153,12 +151,12 @@ VOID Help_ShowInfo()
" PCILeech-FPGA - https://github.com/ufrisk/pcileech-fpga \n" \
" Google USB Driver - https://developer.android.com/sdk/win-usb.html \n" \
" FTDI FT601 Driver - http://www.ftdichip.com/Drivers/D3XX.htm \n" \
+ " PCIe Injector - https://github.com/enjoy-digital/pcie_injector \n" \
" Dokany - https://github.com/dokan-dev/dokany/releases/latest \n" \
" ---------------- \n" \
" Use with memory dump files in read-only mode. \n" \
" Use with USB3380 hardware programmed as a PCILeech device. \n" \
- " Use with FPGA harware programmed as a PCILeech FPGA device. \n" \
- " Use with SP605 hardware / 'PCI Express DIY hacking toolkit' by cr4sh/@d_olex. \n\n" \
+ " Use with FPGA harware programmed as a PCILeech FPGA device. \n\n" \
" ---------------- \n" \
" Driver information (USB3380/Windows): \n" \
" The USB3380 HW requires a dummy driver to function properly. The PCILeech \n" \
@@ -175,9 +173,15 @@ VOID Help_ShowInfo()
" memory file access PCILeech requires Dokany to be installed for virtual file\n" \
" system support. Please download and install Dokany on your computer before \n" \
" using the mount functionality. \n" \
- " Driver information (Libusb/Linux): \n" \
+ " Driver information (USB3380/Linux): \n" \
" PCILeech on Linux requires that libusb is installed. Libusb is most probably\n" \
" installed by default, if not install by running:apt-get install libusb-1.0-0\n" \
+ " Driver information (FPGA/FT601/Linux): \n" \
+ " The PCILeech programmed FPGA board with FT601 USB3 requires drivers for USB.\n" \
+ " The driver is a small kernel driver found in the drivers/ft60x folder in the\n" \
+ " PCIe Injector Github repository. Once loaded the driver will expose a device\n" \
+ " named /dev/ft60x[0-3] Please note that this device file must be read/write \n" \
+ " for the current user for PCILeech to find and use it automatically. \n" \
" ---------------- \n" \
" Notes about the PCILeech USB3380 device: \n" \
" Usage: connect USB3380 device to target computer and USB cable to the computer\n" \
diff --git a/pcileech/oscompatibility.c b/pcileech/oscompatibility.c
index 965ab0a..f49a3f2 100644
--- a/pcileech/oscompatibility.c
+++ b/pcileech/oscompatibility.c
@@ -1,160 +1,278 @@
// oscompatibility.c : pcileech windows/linux/android compatibility layer.
//
-// (c) Ulf Frisk, 2017
+// (c) Ulf Frisk, 2017-2018
// Author: Ulf Frisk, pcileech@frizk.net
//
+
#ifdef WIN32
#include "oscompatibility.h"
VOID usleep(_In_ DWORD us)
{
- QWORD tmFreq, tmStart, tmNow, tmThreshold;
- if(us == 0) { return; }
- QueryPerformanceFrequency((PLARGE_INTEGER)&tmFreq);
- tmThreshold = tmFreq * us / (1000 * 1000); // dw_uS uS
- QueryPerformanceCounter((PLARGE_INTEGER)&tmStart);
- while(QueryPerformanceCounter((PLARGE_INTEGER)&tmNow) && ((tmNow - tmStart) < tmThreshold)) {
- ;
- }
+ QWORD tmFreq, tmStart, tmNow, tmThreshold;
+ if(us == 0) { return; }
+ QueryPerformanceFrequency((PLARGE_INTEGER)&tmFreq);
+ tmThreshold = tmFreq * us / (1000 * 1000); // dw_uS uS
+ QueryPerformanceCounter((PLARGE_INTEGER)&tmStart);
+ while(QueryPerformanceCounter((PLARGE_INTEGER)&tmNow) && ((tmNow - tmStart) < tmThreshold)) {
+ ;
+ }
}
#endif /* WIN32 */
#if defined(LINUX) || defined(ANDROID)
#include "oscompatibility.h"
+#include
+#include
-#define INTERNAL_HANDLE_TYPE_THREAD 0xdeadbeeffedfed01
+#define INTERNAL_HANDLE_TYPE_THREAD 0xdeadbeeffedfed01
typedef struct tdINTERNAL_HANDLE {
- QWORD type;
- HANDLE handle;
+ QWORD type;
+ HANDLE handle;
} INTERNAL_HANDLE, *PINTERNAL_HANDLE;
HANDLE LocalAlloc(DWORD uFlags, SIZE_T uBytes)
{
- HANDLE h = malloc(uBytes);
- if(h && (uFlags & LMEM_ZEROINIT)) {
- memset(h, 0, uBytes);
- }
- return h;
+ HANDLE h = malloc(uBytes);
+ if(h && (uFlags & LMEM_ZEROINIT)) {
+ memset(h, 0, uBytes);
+ }
+ return h;
}
VOID LocalFree(HANDLE hMem)
{
- free(hMem);
+ free(hMem);
}
QWORD GetTickCount64()
{
- struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC_COARSE, &ts);
- return ts.tv_sec * 1000 + ts.tv_nsec / (1000 * 1000);
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC_COARSE, &ts);
+ return ts.tv_sec * 1000 + ts.tv_nsec / (1000 * 1000);
}
HANDLE CreateThread(
- PVOID lpThreadAttributes,
- SIZE_T dwStackSize,
- PVOID lpStartAddress,
- PVOID lpParameter,
- DWORD dwCreationFlags,
- PDWORD lpThreadId
+ PVOID lpThreadAttributes,
+ SIZE_T dwStackSize,
+ PVOID lpStartAddress,
+ PVOID lpParameter,
+ DWORD dwCreationFlags,
+ PDWORD lpThreadId
) {
- PINTERNAL_HANDLE ph;
- pthread_t thread;
- int status;
- status = pthread_create(&thread, NULL, lpStartAddress, lpParameter);
- if(status) { return NULL;}
- ph = malloc(sizeof(INTERNAL_HANDLE));
- ph->type = INTERNAL_HANDLE_TYPE_THREAD;
- ph->handle = (HANDLE)thread;
- return ph;
+ PINTERNAL_HANDLE ph;
+ pthread_t thread;
+ int status;
+ status = pthread_create(&thread, NULL, lpStartAddress, lpParameter);
+ if(status) { return NULL;}
+ ph = malloc(sizeof(INTERNAL_HANDLE));
+ ph->type = INTERNAL_HANDLE_TYPE_THREAD;
+ ph->handle = (HANDLE)thread;
+ return ph;
}
VOID GetLocalTime(LPSYSTEMTIME lpSystemTime)
{
- time_t curtime;
- struct tm *t;
- curtime = time(NULL);
- t = localtime(&curtime);
- lpSystemTime->wYear = t->tm_year;
- lpSystemTime->wMonth = t->tm_mon;
- lpSystemTime->wDayOfWeek = t->tm_wday;
- lpSystemTime->wDay = t->tm_yday;
- lpSystemTime->wHour = t->tm_hour;
- lpSystemTime->wMinute = t->tm_min;
- lpSystemTime->wSecond = t->tm_sec;
- lpSystemTime->wMilliseconds = 0;
+ time_t curtime;
+ struct tm *t;
+ curtime = time(NULL);
+ t = localtime(&curtime);
+ lpSystemTime->wYear = t->tm_year;
+ lpSystemTime->wMonth = t->tm_mon;
+ lpSystemTime->wDayOfWeek = t->tm_wday;
+ lpSystemTime->wDay = t->tm_yday;
+ lpSystemTime->wHour = t->tm_hour;
+ lpSystemTime->wMinute = t->tm_min;
+ lpSystemTime->wSecond = t->tm_sec;
+ lpSystemTime->wMilliseconds = 0;
}
HANDLE FindFirstFileA(LPSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData)
{
- DWORD i;
- DIR *hDir;
- CHAR szDirName[MAX_PATH];
- memset(szDirName, 0, MAX_PATH);
- strcpy_s(lpFindFileData->__cExtension, 5, lpFileName + strlen(lpFileName) - 4);
- strcpy_s(szDirName, MAX_PATH, lpFileName);
- for(i = strlen(szDirName) - 1; i > 0; i--) {
- if(szDirName[i] == '/') {
- szDirName[i] = 0;
- break;
- }
- }
- hDir = opendir(szDirName);
- if(!hDir) { return NULL; }
- return FindNextFileA((HANDLE)hDir, lpFindFileData) ? (HANDLE)hDir : INVALID_HANDLE_VALUE;
+ DWORD i;
+ DIR *hDir;
+ CHAR szDirName[MAX_PATH];
+ memset(szDirName, 0, MAX_PATH);
+ strcpy_s(lpFindFileData->__cExtension, 5, lpFileName + strlen(lpFileName) - 4);
+ strcpy_s(szDirName, MAX_PATH, lpFileName);
+ for(i = strlen(szDirName) - 1; i > 0; i--) {
+ if(szDirName[i] == '/') {
+ szDirName[i] = 0;
+ break;
+ }
+ }
+ hDir = opendir(szDirName);
+ if(!hDir) { return NULL; }
+ return FindNextFileA((HANDLE)hDir, lpFindFileData) ? (HANDLE)hDir : INVALID_HANDLE_VALUE;
}
BOOL FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData)
{
- DIR *hDir = (DIR*)hFindFile;
- struct dirent *dir;
- char* sz;
- if(!hDir) { return FALSE; }
- while ((dir = readdir(hDir)) != NULL) {
- sz = dir->d_name;
- if((strlen(sz) > 4) && !strcasecmp(sz + strlen(sz) - 4, lpFindFileData->__cExtension)) {
- strcpy_s(lpFindFileData->cFileName, MAX_PATH, sz);
- return TRUE;
- }
+ DIR *hDir = (DIR*)hFindFile;
+ struct dirent *dir;
+ char* sz;
+ if(!hDir) { return FALSE; }
+ while ((dir = readdir(hDir)) != NULL) {
+ sz = dir->d_name;
+ if((strlen(sz) > 4) && !strcasecmp(sz + strlen(sz) - 4, lpFindFileData->__cExtension)) {
+ strcpy_s(lpFindFileData->cFileName, MAX_PATH, sz);
+ return TRUE;
+ }
}
closedir(hDir);
- return FALSE;
+ return FALSE;
}
BOOL __WinUsb_ReadWritePipe(
- WINUSB_INTERFACE_HANDLE InterfaceHandle,
- UCHAR PipeID,
- PUCHAR Buffer,
- ULONG BufferLength,
- PULONG LengthTransferred,
- PVOID Overlapped
+ WINUSB_INTERFACE_HANDLE InterfaceHandle,
+ UCHAR PipeID,
+ PUCHAR Buffer,
+ ULONG BufferLength,
+ PULONG LengthTransferred,
+ PVOID Overlapped
) {
- int result, cbTransferred;
- result = libusb_bulk_transfer(
- InterfaceHandle,
- PipeID,
- Buffer,
- BufferLength,
- &cbTransferred,
- 500);
- *LengthTransferred = (ULONG)cbTransferred;
- return result ? FALSE : TRUE;
+ int result, cbTransferred;
+ result = libusb_bulk_transfer(
+ InterfaceHandle,
+ PipeID,
+ Buffer,
+ BufferLength,
+ &cbTransferred,
+ 500);
+ *LengthTransferred = (ULONG)cbTransferred;
+ return result ? FALSE : TRUE;
}
BOOL WinUsb_Free(WINUSB_INTERFACE_HANDLE InterfaceHandle)
{
- if(!InterfaceHandle) { return TRUE; }
- libusb_release_interface(InterfaceHandle, 0);
- libusb_reset_device(InterfaceHandle);
- libusb_close(InterfaceHandle);
- return TRUE;
+ if(!InterfaceHandle) { return TRUE; }
+ libusb_release_interface(InterfaceHandle, 0);
+ libusb_reset_device(InterfaceHandle);
+ libusb_close(InterfaceHandle);
+ return TRUE;
}
DWORD InterlockedAdd(DWORD *Addend, DWORD Value)
{
- return __sync_add_and_fetch(Addend, Value);
+ return __sync_add_and_fetch(Addend, Value);
+}
+
+// ----------------------------------------------------------------------------
+// Facade implementation of FTDI functions using functionality provided by
+// kernel driver ft60x by @key2fr in the backend. NB! functionality below
+// is by no way complete - only minimal functionality required by PCILeech
+// use is implemented ...
+// ----------------------------------------------------------------------------
+
+ULONG FT60x_FT_Create(PVOID pvArg, DWORD dwFlags, HANDLE *pftHandle)
+{
+ int i, result;
+ // NB! underlying driver will create a device object at /dev/ft60x[0-3]
+ // when loaded. Iterate through possible combinations at load time.
+ CHAR szDevice[12] = { '/', 'd', 'e', 'v', '/', 'f', 't', '6', '0', 'x', '0', 0 };
+ for(i = 0; i < 4; i++) {
+ szDevice[10] = '0' + i;
+ result = open(szDevice, O_RDWR | O_CLOEXEC);
+ if(result > 0) {
+ *pftHandle = (HANDLE)(QWORD)result;
+ return 0;
+ }
+ }
+ return 0x20;
+}
+
+ULONG FT60x_FT_Close(HANDLE ftHandle)
+{
+ close((int)(QWORD)ftHandle);
+ return 0;
+}
+
+ULONG FT60x_FT_GetChipConfiguration(HANDLE ftHandle, PVOID pvConfiguration)
+{
+ return ioctl((int)(QWORD)ftHandle, 0, pvConfiguration) ? 0x20 : 0;
+}
+
+ULONG FT60x_FT_SetChipConfiguration(HANDLE ftHandle, PVOID pvConfiguration)
+{
+ return ioctl((int)(QWORD)ftHandle, 1, pvConfiguration) ? 0x20 : 0;
+}
+
+ULONG FT60x_FT_AbortPipe(HANDLE ftHandle, UCHAR ucPipeID)
+{
+ // dummy function, only here for compatibility in Linux case
+ return 0;
+}
+
+ULONG FT60x_FT_WritePipe(HANDLE ftHandle, UCHAR ucPipeID, PUCHAR pucBuffer, ULONG ulBufferLength, PULONG pulBytesTransferred, PVOID pOverlapped)
+{
+ int result, cbTxTotal = 0;
+ // NB! underlying ft60x driver cannot handle more than 0x800 bytes per write,
+ // split larger writes into smaller writes if required.
+ while(cbTxTotal < ulBufferLength) {
+ result = write((int)(QWORD)ftHandle, pucBuffer + cbTxTotal, min(0x800, ulBufferLength - cbTxTotal));
+ if(!result) { return 0x20; } // no bytes transmitted -> error
+ cbTxTotal += result;
+ }
+ *pulBytesTransferred = cbTxTotal;
+ return 0;
+}
+
+ULONG FT60x_FT_ReadPipe2(HANDLE ftHandle, UCHAR ucPipeID, PUCHAR pucBuffer, ULONG ulBufferLength, PULONG pulBytesTransferred, PVOID pOverlapped)
+{
+ int result;
+ *pulBytesTransferred = 0;
+ // NB! underlying driver have a max tranfer size in one go, multiple reads may be
+ // required to retrieve all data - hence the loop.
+ do {
+ result = read((int)(QWORD)ftHandle, pucBuffer + *pulBytesTransferred, ulBufferLength - *pulBytesTransferred);
+ if(result > 0) {
+ *pulBytesTransferred += result;
+ }
+ } while((result > 0) && (0 == (result % 0x1000)) && (ulBufferLength > *pulBytesTransferred));
+ return (result > 0) ? 0 : 0x20;
+}
+
+ULONG FT60x_FT_ReadPipe(HANDLE ftHandle, UCHAR ucPipeID, PUCHAR pucBuffer, ULONG ulBufferLength, PULONG pulBytesTransferred, PVOID pOverlapped)
+{
+ // NB! underlying driver won't return all data on the USB core queue in first
+ // read so we have to read two times.
+ ULONG i, result, cbRx, cbRxTotal = 0;
+ for(i = 0; i < 2; i++) {
+ result = FT60x_FT_ReadPipe2(ftHandle, ucPipeID, pucBuffer + cbRxTotal, ulBufferLength - cbRxTotal, &cbRx, pOverlapped);
+ cbRxTotal += cbRx;
+ }
+ *pulBytesTransferred = cbRxTotal;
+ return result;
+}
+
+// ----------------------------------------------------------------------------
+// LoadLibrary / GetProcAddress facades (for FPGA functionality) below:
+// ----------------------------------------------------------------------------
+
+#define MAGIC_HMODULE_FTD3XX 0x00eeffee81635432
+
+HMODULE LoadLibrary(LPWSTR lpFileName)
+{
+ if(lpFileName && (0 == memcmp(lpFileName, L"FTD3XX.dll", 20))) {
+ return (HMODULE)MAGIC_HMODULE_FTD3XX;
+ }
+ return NULL;
+}
+
+FARPROC GetProcAddress(HMODULE hModule, LPSTR lpProcName)
+{
+ if(MAGIC_HMODULE_FTD3XX != (QWORD)hModule) { return NULL; }
+ if(0 == strcmp("FT_AbortPipe", lpProcName)) { return (FARPROC)FT60x_FT_AbortPipe; }
+ if(0 == strcmp("FT_Close", lpProcName)) { return (FARPROC)FT60x_FT_Close; }
+ if(0 == strcmp("FT_Create", lpProcName)) { return (FARPROC)FT60x_FT_Create; }
+ if(0 == strcmp("FT_GetChipConfiguration", lpProcName)) { return (FARPROC)FT60x_FT_GetChipConfiguration; }
+ if(0 == strcmp("FT_SetChipConfiguration", lpProcName)) { return (FARPROC)FT60x_FT_SetChipConfiguration; }
+ if(0 == strcmp("FT_ReadPipe", lpProcName)) { return (FARPROC)FT60x_FT_ReadPipe; }
+ if(0 == strcmp("FT_WritePipe", lpProcName)) { return (FARPROC)FT60x_FT_WritePipe; }
+ return NULL;
}
#endif /* LINUX || ANDROID */
@@ -162,10 +280,10 @@ DWORD InterlockedAdd(DWORD *Addend, DWORD Value)
BOOL GetExitCodeThread(HANDLE hThread, PDWORD lpExitCode)
{
- PINTERNAL_HANDLE ph = (PINTERNAL_HANDLE)hThread;
- if(ph->type != INTERNAL_HANDLE_TYPE_THREAD) { return FALSE; }
- *lpExitCode = (pthread_tryjoin_np((pthread_t)ph->handle, NULL) == EBUSY) ? STILL_ACTIVE : 0;
- return TRUE;
+ PINTERNAL_HANDLE ph = (PINTERNAL_HANDLE)hThread;
+ if(ph->type != INTERNAL_HANDLE_TYPE_THREAD) { return FALSE; }
+ *lpExitCode = (pthread_tryjoin_np((pthread_t)ph->handle, NULL) == EBUSY) ? STILL_ACTIVE : 0;
+ return TRUE;
}
#endif /* LINUX */
@@ -173,7 +291,7 @@ BOOL GetExitCodeThread(HANDLE hThread, PDWORD lpExitCode)
BOOL GetExitCodeThread(HANDLE hThread, PDWORD lpExitCode)
{
- return FALSE;
+ return FALSE;
}
#endif /* ANDROID */
diff --git a/pcileech/oscompatibility.h b/pcileech/oscompatibility.h
index 5ba0805..675be74 100644
--- a/pcileech/oscompatibility.h
+++ b/pcileech/oscompatibility.h
@@ -19,7 +19,7 @@
#pragma comment (lib, "setupapi.lib")
#pragma comment (lib, "bcrypt.lib")
-typedef unsigned __int64 QWORD, *PQWORD;
+typedef unsigned __int64 QWORD, *PQWORD;
#pragma warning( disable : 4477)
@@ -52,42 +52,44 @@ VOID usleep(_In_ DWORD us);
#include
#include
-typedef void VOID, *PVOID;
-typedef void *HANDLE, **PHANDLE;
-typedef uint32_t BOOL, *PBOOL;
-typedef uint8_t BYTE, *PBYTE;
-typedef uint8_t UCHAR, *PUCHAR;
-typedef char CHAR, *PCHAR, *PSTR, *LPSTR;
-typedef uint16_t WORD, *PWORD;
-typedef wchar_t WCHAR, *PWCHAR, *LPWSTR;
-typedef uint32_t DWORD, *PDWORD;
-typedef uint32_t ULONG, *PULONG;
-typedef long long unsigned int QWORD, *PQWORD;
-typedef uint64_t SIZE_T, *PSIZE_T;
-#define TRUE 1
-#define FALSE 0
-#define MAX_PATH 260
-#define LMEM_ZEROINIT 0x0040
-#define INVALID_HANDLE_VALUE ((HANDLE)-1)
-#define STD_INPUT_HANDLE ((DWORD)-10)
-#define STD_OUTPUT_HANDLE ((DWORD)-11)
-#define GENERIC_WRITE (0x40000000L)
-#define GENERIC_READ (0x80000000L)
-#define FILE_SHARE_READ (0x00000001L)
-#define CREATE_NEW (0x00000001L)
-#define OPEN_EXISTING (0x00000003L)
-#define FILE_ATTRIBUTE_NORMAL (0x00000080L)
-#define STILL_ACTIVE (0x00000103L)
-#define CRYPT_STRING_HEX_ANY (0x00000008L)
-#define CRYPT_STRING_HEXASCIIADDR (0x00000008L)
-#define STILL_ACTIVE (0x00000103L)
-#define INVALID_FILE_SIZE (0xffffffffL)
-#define _TRUNCATE ((SIZE_T)-1LL)
-#define LPTHREAD_START_ROUTINE PVOID
-#define WINUSB_INTERFACE_HANDLE libusb_device_handle*
-#define PIPE_TRANSFER_TIMEOUT 0x03
-#define CONSOLE_SCREEN_BUFFER_INFO PVOID // TODO: remove this dummy
-#define CRITICAL_SECTION HANDLE
+typedef void VOID, *PVOID;
+typedef void *HANDLE, **PHANDLE;
+typedef void *HMODULE, *FARPROC;
+typedef uint32_t BOOL, *PBOOL;
+typedef uint8_t BYTE, *PBYTE;
+typedef uint8_t UCHAR, *PUCHAR;
+typedef char CHAR, *PCHAR, *PSTR, *LPSTR;
+typedef uint16_t WORD, *PWORD, USHORT, *PUSHORT;
+typedef wchar_t WCHAR, *PWCHAR, *LPWSTR;
+typedef uint32_t DWORD, *PDWORD;
+typedef uint32_t ULONG, *PULONG;
+typedef long long unsigned int QWORD, *PQWORD;
+typedef uint64_t SIZE_T, *PSIZE_T;
+typedef void *LPOVERLAPPED;
+#define TRUE 1
+#define FALSE 0
+#define MAX_PATH 260
+#define LMEM_ZEROINIT 0x0040
+#define INVALID_HANDLE_VALUE ((HANDLE)-1)
+#define STD_INPUT_HANDLE ((DWORD)-10)
+#define STD_OUTPUT_HANDLE ((DWORD)-11)
+#define GENERIC_WRITE (0x40000000L)
+#define GENERIC_READ (0x80000000L)
+#define FILE_SHARE_READ (0x00000001L)
+#define CREATE_NEW (0x00000001L)
+#define OPEN_EXISTING (0x00000003L)
+#define FILE_ATTRIBUTE_NORMAL (0x00000080L)
+#define STILL_ACTIVE (0x00000103L)
+#define CRYPT_STRING_HEX_ANY (0x00000008L)
+#define CRYPT_STRING_HEXASCIIADDR (0x00000008L)
+#define STILL_ACTIVE (0x00000103L)
+#define INVALID_FILE_SIZE (0xffffffffL)
+#define _TRUNCATE ((SIZE_T)-1LL)
+#define LPTHREAD_START_ROUTINE PVOID
+#define WINUSB_INTERFACE_HANDLE libusb_device_handle*
+#define PIPE_TRANSFER_TIMEOUT 0x03
+#define CONSOLE_SCREEN_BUFFER_INFO PVOID // TODO: remove this dummy
+#define CRITICAL_SECTION HANDLE
#define _In_
#define _Out_
@@ -101,47 +103,48 @@ typedef uint64_t SIZE_T, *PSIZE_T;
#define _Success_(return)
-#define max(a, b) (((a) > (b)) ? (a) : (b))
-#define min(a, b) (((a) < (b)) ? (a) : (b))
-#define _byteswap_ulong(v) (bswap_32(v))
-#define strnlen_s(s, maxcount) (strnlen(s, maxcount))
-#define strcpy_s(dst, len, src) (strncpy(dst, src, len))
-#define _stricmp(s1, s2) (strcasecmp(s1, s2))
-#define _strnicmp(s1, s2, maxcount) (strncasecmp(s1, s2, maxcount))
-#define strtok_s(s, d, c) (strtok_r(s, d, c))
-#define _snprintf_s(s, l, _l, f, ...) (snprintf(s, l, f, __VA_ARGS__))
-#define sscanf_s(s, f, ...) (sscanf(s, f, __VA_ARGS__))
-#define SwitchToThread() (sched_yield())
-#define ExitThread(dwExitCode) (pthread_exit(dwExitCode))
-#define ExitProcess(c) (exit(c ? EXIT_SUCCESS : EXIT_FAILURE))
-#define Sleep(dwMilliseconds) (usleep(1000*dwMilliseconds))
-#define fopen_s(ppFile, szFile, szAttr) ((*ppFile = fopen(szFile, szAttr)) ? 0 : 1)
-#define GetModuleFileNameA(m, f, l) (readlink("/proc/self/exe", f, l))
-#define ZeroMemory(pb, cb) (memset(pb, 0, cb))
-#define WinUsb_SetPipePolicy(h, p, t, cb, pb) // TODO: implement this for better USB2 performance.
-#define CloseHandle(h) // TODO: remove this dummy implementation & replace with WARN.
-#define _ftelli64(f) (ftello(f))
-#define _fseeki64(f, o, w) (fseeko(f, o, w))
-
-#define InitializeCriticalSection(x) // no dma transfer critical section in linux yet
-#define DeleteCriticalSection(x) // no dma transfer critical section in linux yet
-#define EnterCriticalSection(x) // no dma transfer critical section in linux yet
-#define LeaveCriticalSection(x) // no dma transfer critical section in linux yet
+#define max(a, b) (((a) > (b)) ? (a) : (b))
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+#define _byteswap_ulong(v) (bswap_32(v))
+#define _byteswap_uint64(v) (bswap_64(v))
+#define strnlen_s(s, maxcount) (strnlen(s, maxcount))
+#define strcpy_s(dst, len, src) (strncpy(dst, src, len))
+#define _stricmp(s1, s2) (strcasecmp(s1, s2))
+#define _strnicmp(s1, s2, maxcount) (strncasecmp(s1, s2, maxcount))
+#define strtok_s(s, d, c) (strtok_r(s, d, c))
+#define _snprintf_s(s, l, _l, f, ...) (snprintf(s, l, f, __VA_ARGS__))
+#define sscanf_s(s, f, ...) (sscanf(s, f, __VA_ARGS__))
+#define SwitchToThread() (sched_yield())
+#define ExitThread(dwExitCode) (pthread_exit(dwExitCode))
+#define ExitProcess(c) (exit(c ? EXIT_SUCCESS : EXIT_FAILURE))
+#define Sleep(dwMilliseconds) (usleep(1000*dwMilliseconds))
+#define fopen_s(ppFile, szFile, szAttr) ((*ppFile = fopen(szFile, szAttr)) ? 0 : 1)
+#define GetModuleFileNameA(m, f, l) (readlink("/proc/self/exe", f, l))
+#define ZeroMemory(pb, cb) (memset(pb, 0, cb))
+#define WinUsb_SetPipePolicy(h, p, t, cb, pb) // TODO: implement this for better USB2 performance.
+#define CloseHandle(h) // TODO: remove this dummy implementation & replace with WARN.
+#define _ftelli64(f) (ftello(f))
+#define _fseeki64(f, o, w) (fseeko(f, o, w))
+
+#define InitializeCriticalSection(x) // TODO: add linux support for CriticalSection (not required yet)
+#define DeleteCriticalSection(x) // TODO: add linux support for CriticalSection (not required yet)
+#define EnterCriticalSection(x) // TODO: add linux support for CriticalSection (not required yet)
+#define LeaveCriticalSection(x) // TODO: add linux support for CriticalSection (not required yet)
typedef struct _SYSTEMTIME {
- WORD wYear;
- WORD wMonth;
- WORD wDayOfWeek;
- WORD wDay;
- WORD wHour;
- WORD wMinute;
- WORD wSecond;
- WORD wMilliseconds;
+ WORD wYear;
+ WORD wMonth;
+ WORD wDayOfWeek;
+ WORD wDay;
+ WORD wHour;
+ WORD wMinute;
+ WORD wSecond;
+ WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;
typedef struct _WIN32_FIND_DATAA {
- CHAR __cExtension[5];
- CHAR cFileName[MAX_PATH];
+ CHAR __cExtension[5];
+ CHAR cFileName[MAX_PATH];
} WIN32_FIND_DATAA, *PWIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
HANDLE FindFirstFileA(LPSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData);
@@ -154,29 +157,33 @@ DWORD InterlockedAdd(DWORD *Addend, DWORD Value);
BOOL WinUsb_Free(WINUSB_INTERFACE_HANDLE InterfaceHandle);
HANDLE CreateThread(
- PVOID lpThreadAttributes,
- SIZE_T dwStackSize,
- PVOID lpStartAddress,
- PVOID lpParameter,
- DWORD dwCreationFlags,
- PDWORD lpThreadId
+ PVOID lpThreadAttributes,
+ SIZE_T dwStackSize,
+ PVOID lpStartAddress,
+ PVOID lpParameter,
+ DWORD dwCreationFlags,
+ PDWORD lpThreadId
);
BOOL GetExitCodeThread(
- HANDLE hThread,
- PDWORD lpExitCode
+ HANDLE hThread,
+ PDWORD lpExitCode
);
BOOL __WinUsb_ReadWritePipe(
- WINUSB_INTERFACE_HANDLE InterfaceHandle,
- UCHAR PipeID,
- PUCHAR Buffer,
- ULONG BufferLength,
- PULONG LengthTransferred,
- PVOID Overlapped
+ WINUSB_INTERFACE_HANDLE InterfaceHandle,
+ UCHAR PipeID,
+ PUCHAR Buffer,
+ ULONG BufferLength,
+ PULONG LengthTransferred,
+ PVOID Overlapped
);
-#define WinUsb_ReadPipe(h, p, b, l, t, o) (__WinUsb_ReadWritePipe(h, p, b, l, t, o))
-#define WinUsb_WritePipe(h, p, b, l, t, o) (__WinUsb_ReadWritePipe(h, p, b, l, t, o))
+#define WinUsb_ReadPipe(h, p, b, l, t, o) (__WinUsb_ReadWritePipe(h, p, b, l, t, o))
+#define WinUsb_WritePipe(h, p, b, l, t, o) (__WinUsb_ReadWritePipe(h, p, b, l, t, o))
+
+FARPROC GetProcAddress(HMODULE hModule, LPSTR lpProcName);
+HMODULE LoadLibrary(LPWSTR lpFileName);
+#define FreeLibrary(hModule) (TRUE)
#endif /* LINUX || ANDROID */
diff --git a/pcileech/vfs.c b/pcileech/vfs.c
index 9f9182c..cde0358 100644
--- a/pcileech/vfs.c
+++ b/pcileech/vfs.c
@@ -1090,7 +1090,7 @@ VOID ActionMount(_Inout_ PPCILEECH_CONTEXT ctx)
VOID ActionMount(_Inout_ PPCILEECH_CONTEXT ctx)
{
- printf("MOUNT: Failed. Operation only supported in PCILeech for Windows.");
+ printf("MOUNT: Failed. Operation only supported in PCILeech for Windows.\n");
}
#endif /* LINUX || ANDROID */
diff --git a/pcileech/vmm.c b/pcileech/vmm.c
index f32ec6f..8193181 100644
--- a/pcileech/vmm.c
+++ b/pcileech/vmm.c
@@ -658,7 +658,7 @@ VOID VmmReadScatterVirtual(_Inout_ PVMM_CONTEXT ctxVmm, _In_ PVMM_PROCESS pProce
}
// 2: translate virt2phys and retrieve data loop
cpDMAsPhys = 0;
- cPagesPerScatterRead = min(0x48, ((ctxVmm->ctxPcileech->cfg->dev.qwMaxSizeDmaIo & ~0xfff) >> 12));
+ cPagesPerScatterRead = min(0x48, ((ctxVmm->ctxPcileech->cfg->qwMaxSizeDmaIo & ~0xfff) >> 12));
for(i = 0; i < cpDMAsVirt; i++) {
// retrieve from cache (if found)
pDMA_Virt = ppDMAsVirt[i];
diff --git a/pcileech/vmmproc.c b/pcileech/vmmproc.c
index 3fa5e45..6232065 100644
--- a/pcileech/vmmproc.c
+++ b/pcileech/vmmproc.c
@@ -741,6 +741,13 @@ DWORD VmmProcCacheUpdaterThread(_Inout_ PVMM_CONTEXT ctxVmm)
// spider TLB and set up initial system process and enumerate EPROCESS
VmmTlbSpider(ctxVmm, paSystemPML4, FALSE);
pSystemProcess = VmmProcessCreateEntry(ctxVmm, 4, 0, paSystemPML4, "System", FALSE, TRUE);
+ if(!pSystemProcess) {
+ printf("VmmProc: Failed to refresh memory process file system - aborting.\n");
+ VmmProcessCreateFinish(ctxVmm);
+ ctxVmm->ThreadProcCache.fEnabled = FALSE;
+ LeaveCriticalSection(&ctxVmm->MasterLock);
+ goto fail;
+ }
VmmProcessCreateFinish(ctxVmm);
pSystemProcess->os.win.vaEPROCESS = vaSystemEPROCESS;
VmmProcWindows_EnumerateEPROCESS(ctxVmm, pSystemProcess);
@@ -757,6 +764,7 @@ DWORD VmmProcCacheUpdaterThread(_Inout_ PVMM_CONTEXT ctxVmm)
}
LeaveCriticalSection(&ctxVmm->MasterLock);
}
+ fail:
if(ctxVmm->ctxPcileech->cfg->fVerbose) {
printf("VmmProc: Exit periodic cache flushing.\n");
}
diff --git a/pcileech/vmmvfs.c b/pcileech/vmmvfs.c
index 3047487..124b6ef 100644
--- a/pcileech/vmmvfs.c
+++ b/pcileech/vmmvfs.c
@@ -106,6 +106,7 @@ NTSTATUS VmmVfsReadFile(_Inout_ PPCILEECH_CONTEXT ctx, _In_opt_ DWORD dwPID, _In
{
NTSTATUS nt;
PVMM_CONTEXT ctxVmm = (PVMM_CONTEXT)ctx->hVMM;
+ if(!ctxVmm || !ctxVmm->ptPROC) { return STATUS_FILE_INVALID; }
EnterCriticalSection(&ctxVmm->MasterLock);
nt = VmmVfsReadFileDo(ctx, dwPID, wszPath1, qwPath2, pb, cb, pcbRead, cbOffset);
LeaveCriticalSection(&ctxVmm->MasterLock);
@@ -192,6 +193,7 @@ NTSTATUS VmmVfsWriteFile(_Inout_ PPCILEECH_CONTEXT ctx, _In_opt_ DWORD dwPID, _I
{
NTSTATUS nt;
PVMM_CONTEXT ctxVmm = (PVMM_CONTEXT)ctx->hVMM;
+ if(!ctxVmm || !ctxVmm->ptPROC) { return STATUS_FILE_INVALID; }
EnterCriticalSection(&ctxVmm->MasterLock);
nt = VmmVfsWriteFileDo(ctx, dwPID, wszPath1, qwPath2, pb, cb, pcbWrite, cbOffset);
LeaveCriticalSection(&ctxVmm->MasterLock);
@@ -242,7 +244,7 @@ BOOL VmmVfsListFilesDo(_Inout_ PPCILEECH_CONTEXT ctx, _In_ BOOL fRoot, _In_ BOOL
PVMM_PROCESS pProcess;
WORD iProcess;
DWORD i, cMax;
- if(!ctxVmm) { return FALSE; }
+ if(!ctxVmm || !ctxVmm->ptPROC) { return FALSE; }
// populate root node - list processes as directories
if(fRoot) {
*ppfi = LocalAlloc(LMEM_ZEROINIT, ctxVmm->ptPROC->c * sizeof(VFS_RESULT_FILEINFO));
@@ -327,6 +329,7 @@ BOOL VmmVfsListFiles(_Inout_ PPCILEECH_CONTEXT ctx, _In_ BOOL fRoot, _In_ BOOL f
{
BOOL result;
PVMM_CONTEXT ctxVmm = (PVMM_CONTEXT)ctx->hVMM;
+ if(!ctxVmm || !ctxVmm->ptPROC) { return FALSE; }
EnterCriticalSection(&ctxVmm->MasterLock);
result = VmmVfsListFilesDo(ctx, fRoot, fNamesPid, dwPID, wszPath1, qwPath2, ppfi, pcfi);
LeaveCriticalSection(&ctxVmm->MasterLock);
diff --git a/pcileech_files/pcileech b/pcileech_files/pcileech
index 03d3496..86e8b92 100644
Binary files a/pcileech_files/pcileech and b/pcileech_files/pcileech differ
diff --git a/pcileech_files/pcileech.exe b/pcileech_files/pcileech.exe
index 85e7078..490c9fc 100644
Binary files a/pcileech_files/pcileech.exe and b/pcileech_files/pcileech.exe differ
diff --git a/readme.md b/readme.md
index 68ce99d..c335c87 100644
--- a/readme.md
+++ b/readme.md
@@ -28,7 +28,6 @@ Capabilities:
* Execute kernel code on the target system.
* Spawn system shell [Windows].
* Spawn any executable [Windows].
-* Load unsigned drivers [Windows].
* Pull files [Linux, FreeBSD, Windows, macOS*].
* Push files [Linux, Windows, macOS*].
* Patch / Unlock (remove password requirement) [Windows, macOS*].
@@ -69,17 +68,15 @@ Please ensure you do have the most recent version of PCILeech by visiting the PC
Clone the PCILeech Github repository. The binaries are found in pcileech_files and should work on 64-bit Windows and Linux. Please copy all files from pcileech_files since some files contains additional modules and signatures.
#### Windows:
-The Google Android USB driver also have to be installed if USB3380 hardware is used. Download the Google Android USB driver from: http://developer.android.com/sdk/win-usb.html#download Unzip the driver. Open Device Manager. Right click on the computer, choose add legacy hardware. Select install the hardware manually. Click Have Disk. Navigate to the Android Driver, select android_winusb.inf and install.
-FTDI drivers have to be installed if FPGA is used with FT601 USB3 addon card. FTDI drivers will installed automatically on Windows from Windows Update at first connection. PCILeech also requires 64-bit [`FTD3XX.dll`](http://www.ftdichip.com/Drivers/D3XX/FTD3XXLibrary_v1.2.0.6.zip) which must be downloaded from FTDI and placed alongside `pcileech.exe`.
+Please see the [PCILeech-on-Windows](https://github.com/ufrisk/pcileech/wiki/PCILeech-on-Windows) guide for information about running PCILeech on Windows.
+The Google Android USB driver have to be installed if USB3380 hardware is used. Download the Google Android USB driver from: http://developer.android.com/sdk/win-usb.html#download Unzip the driver.
+FTDI drivers have to be installed if FPGA is used with FT601 USB3 addon card. Download the 64-bit [`FTD3XX.dll`](http://www.ftdichip.com/Drivers/D3XX/FTD3XXLibrary_v1.2.0.6.zip) from FTDI and place it alongside `pcileech.exe`.
To mount live ram and target file system as drive in Windows the Dokany file system library must be installed. Please download and install the latest version of Dokany at: https://github.com/dokan-dev/dokany/releases/latest
-#### Linux:
-PCILeech on Linux must be run as root. PCILeech also requires libusb. Libusb is probably installed by default - if not install it by running: `apt-get install libusb-1.0-0`.
-
-#### Android:
-Separate instructions for [Android](Android.md).
+#### Linux and Android:
+Please see the [PCILeech-on-Linux](https://github.com/ufrisk/pcileech/wiki/PCILeech-on-Linux) guide for information about running PCILeech on Linux or [PCILeech-on-Android](https://github.com/ufrisk/pcileech/wiki/PCILeech-on-Android) for Android information.
Examples:
=========
@@ -128,16 +125,11 @@ Limitations/Known Issues:
* Some Linux kernels does not work. Sometimes a required symbol is not exported in the kernel and PCILeech fails.
* Linux based on the 4.8 kernel and later might not work with the USB3380 hardware. As an alternative, if target root access exists, compile and insert .ko (pcileech_kmd/linux). If the system is EFI booted an alternative signature exists.
* Windows 7: signatures are not published.
-* The Linux/Android versions of PCILeech dumps memory slightly slower than the Windows version (USB3380 hardware). Mount target file system, process file system and live RAM are also not availabe in the Linux/Android versions.
-* FPGA and file system mount support only exists for Windows. Linux and Android support is planned for the future.
+* File system mount, including the Memory Process File System, support only exists for Windows.
Building:
=========
-The binaries are found in the pcileech_files folder. If one wish to build an own version it is possible to do so. Compile the pcileech and pcileech_gensig projects from within Visual Studio. Tested with Visual Studio 2015.
-
-To compile kernel- and shellcode, located in the pcileech_shellcode project, please look into the individual files for instructions. These files are usually compiled command line. To compile for Linux make sure the dependencies are met my running: `apt-get install libusb-1.0-0-dev pkg-config` then move into the pcileech/pcileech directory and build by running: `make`. Download the shellcode module and configuration files separately from the binary download link and put them alongside the pcileech executable.
-
-Separate instructions for [Android](Android.md).
+The binaries are found in the pcileech_files folder. If one wish to build an own version it is possible to do so. Please see the [PCILeech-on-Windows](https://github.com/ufrisk/pcileech/wiki/PCILeech-on-Windows), [PCILeech-on-Linux](https://github.com/ufrisk/pcileech/wiki/PCILeech-on-Linux) or [PCILeech-on-Android](https://github.com/ufrisk/pcileech/wiki/PCILeech-on-Android) for more information about building PCILeech.
Links:
======
@@ -150,17 +142,14 @@ Changelog:
v1.0
* Initial release.
-v1.1-v1.5
+v1.1-v2.6
* Various updates. please see individual relases for more information.
-v2.0-2.6
-* Mount as a drive functionality.
-* Linux and Android support.
-* UEFI target support.
-* FPGA hardware support.
-* Various other updates. please see individual relases for more information.
-
v3.0
* PCILeech Memory Process File System.
* Internal refactorings.
* Various bug fixes.
+
+v3.1
+* Linux FPGA support.
+* Various bug fixes.