mirror of
https://github.com/ufrisk/pcileech.git
synced 2026-06-05 16:09:51 +08:00
Version 4.1
This commit is contained in:
@@ -23,13 +23,23 @@
|
||||
// kerberos. If not possible or desirable the 'insecure' value may be specified
|
||||
// to disable authentication and security.
|
||||
// Syntax:
|
||||
// rpc://<remote_spn>:<host>:<port> (port = optional, remote_spn = kerberos)
|
||||
// (SPN of remote service or 'insecure' )
|
||||
// rpc://<remote_spn>:<host>[:<options>] (remote_spn = kerberos SPN of )
|
||||
// (remote service or 'insecure' )
|
||||
//
|
||||
// Valid options: (optional comma-separated list )
|
||||
// port=<port> (RPC TCP port of the remote system)
|
||||
// nocompress (disable transport compression )
|
||||
//
|
||||
// Examples:
|
||||
// rpc://insecure:remotehost.example.com (connect insecure to remote host )
|
||||
// rpc://user@ad.domain.com:192.0.0.5 (connect secure to remote host )
|
||||
// rpc://insecure:127.0.0.0:6666 (connect insecure non-default port)
|
||||
//
|
||||
// The remote connector may also connect to pipe handles provided in the config
|
||||
// string. This is only used internally by the LeechAgent for communication for
|
||||
// parent/child process and may not be used by external applications. Syntax is
|
||||
// pipe://<handle_id_input>:<handle_id_output>.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Device to connect to: szDevice contains the device to capture memory from.
|
||||
@@ -107,11 +117,16 @@
|
||||
// Syntax:
|
||||
// EXISTING
|
||||
//
|
||||
// EXISTINGREMOTE : Same as EXISTING but applying the EXISTING device on the
|
||||
// remote system. Use only in conjunction with a remote system.
|
||||
// Syntax:
|
||||
// EXISTINGREMOTE
|
||||
//
|
||||
//
|
||||
// (c) Ulf Frisk, 2018-2019
|
||||
// Author: Ulf Frisk, pcileech@frizk.net
|
||||
//
|
||||
// Header Version: 1.1.0
|
||||
// Header Version: 1.2.0
|
||||
//
|
||||
#ifndef __LEECHCORE_H__
|
||||
#define __LEECHCORE_H__
|
||||
@@ -127,8 +142,12 @@ extern "C" {
|
||||
#include <Windows.h>
|
||||
typedef unsigned __int64 QWORD, *PQWORD;
|
||||
#define DLLEXPORT __declspec(dllexport)
|
||||
#ifdef _WIN64
|
||||
#define ARCH_64
|
||||
#endif /* _WIN64 */
|
||||
#endif /* _WIN32 */
|
||||
#ifdef LINUX
|
||||
#define ARCH_X64
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
typedef void VOID, *PVOID, *LPVOID;
|
||||
@@ -163,6 +182,7 @@ typedef long long unsigned int QWORD, *PQWORD, ULONG64, *PULONG64;
|
||||
#define MEM_IO_SCATTER_HEADER_MAGIC 0xffff6548
|
||||
#define MEM_IO_SCATTER_HEADER_VERSION 0x0003
|
||||
|
||||
#ifdef ARCH_64
|
||||
typedef struct tdMEM_IO_SCATTER_HEADER {
|
||||
DWORD magic; // magic
|
||||
WORD version; // version
|
||||
@@ -175,6 +195,26 @@ typedef struct tdMEM_IO_SCATTER_HEADER {
|
||||
PVOID pvReserved2; // reserved for use by caller.
|
||||
PVOID Future2[8];
|
||||
} MEM_IO_SCATTER_HEADER, *PMEM_IO_SCATTER_HEADER, **PPMEM_IO_SCATTER_HEADER;
|
||||
#endif /* ARCH_64 */
|
||||
|
||||
#ifndef ARCH_64
|
||||
typedef struct tdMEM_IO_SCATTER_HEADER {
|
||||
DWORD magic; // magic
|
||||
WORD version; // version
|
||||
WORD Future1;
|
||||
ULONG64 qwA; // base address.
|
||||
DWORD cbMax; // bytes to read (DWORD boundry, max 0x1000); pb must have room for this.
|
||||
DWORD cb; // bytes read into result buffer.
|
||||
PBYTE pb; // ptr to 0x1000 sized buffer to receive read bytes.
|
||||
DWORD dwFiller64_1;
|
||||
PVOID pvReserved1; // reserved for use by caller.
|
||||
DWORD dwFiller64_2;
|
||||
PVOID pvReserved2; // reserved for use by caller.
|
||||
DWORD dwFiller64_3;
|
||||
PVOID Future2[8];
|
||||
DWORD dwFiller64_4[8];
|
||||
} MEM_IO_SCATTER_HEADER, *PMEM_IO_SCATTER_HEADER, **PPMEM_IO_SCATTER_HEADER;
|
||||
#endif /* ARCH_64 */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LEECHCORE INITIALIZATION / CLOSE FUNCTIONALITY BELOW:
|
||||
@@ -221,12 +261,26 @@ typedef struct tdLEECHCORE_CONFIG {
|
||||
// optional 'printf' function pointer. if set to non null value 'printf'
|
||||
// calls will be redirected. useful when logging to files.
|
||||
_Check_return_opt_ int(*pfn_printf_opt)(_In_z_ _Printf_format_string_ char const* const _Format, ...); // set by caller.
|
||||
#ifndef ARCH_64
|
||||
DWORD dwFiller64_1;
|
||||
#endif /* ARCH_64 */
|
||||
} LEECHCORE_CONFIG, *PLEECHCORE_CONFIG;
|
||||
|
||||
#ifdef ARCH_64
|
||||
typedef struct tdLEECHCORE_PAGESTAT_MINIMAL {
|
||||
HANDLE h;
|
||||
VOID(*pfnPageStatUpdate)(HANDLE h, ULONG64 pa, ULONG64 cPageSuccessAdd, ULONG64 cPageFailAdd);
|
||||
} LEECHCORE_PAGESTAT_MINIMAL, *PLEECHCORE_PAGESTAT_MINIMAL;
|
||||
#endif /* ARCH_64 */
|
||||
|
||||
#ifndef ARCH_64
|
||||
typedef struct tdLEECHCORE_PAGESTAT_MINIMAL {
|
||||
HANDLE h;
|
||||
DWORD dwFiller64_1;
|
||||
VOID(*pfnPageStatUpdate)(HANDLE h, ULONG64 pa, ULONG64 cPageSuccessAdd, ULONG64 cPageFailAdd);
|
||||
DWORD dwFiller64_2;
|
||||
} LEECHCORE_PAGESTAT_MINIMAL, *PLEECHCORE_PAGESTAT_MINIMAL;
|
||||
#endif /* ARCH_64 */
|
||||
|
||||
/*
|
||||
* Open a connection to the target device. The LeechCore initialization may fail
|
||||
@@ -306,7 +360,7 @@ DLLEXPORT DWORD LeechCore_ReadEx(_In_ ULONG64 pa, _Out_writes_(cb) PBYTE pb, _In
|
||||
* -- return
|
||||
*/
|
||||
_Success_(return)
|
||||
DLLEXPORT BOOL LeechCore_Write(_In_ ULONG64 pa, _In_ PBYTE pb, _In_ DWORD cb);
|
||||
DLLEXPORT BOOL LeechCore_Write(_In_ ULONG64 pa, _In_reads_(cb) PBYTE pb, _In_ DWORD cb);
|
||||
|
||||
/*
|
||||
* Write data to the target system if supported by the device.
|
||||
@@ -317,7 +371,7 @@ DLLEXPORT BOOL LeechCore_Write(_In_ ULONG64 pa, _In_ PBYTE pb, _In_ DWORD cb);
|
||||
* -- return
|
||||
*/
|
||||
_Success_(return)
|
||||
DLLEXPORT BOOL LeechCore_WriteEx(_In_ ULONG64 pa, _In_ PBYTE pb, _In_ DWORD cb, _In_ DWORD flags);
|
||||
DLLEXPORT BOOL LeechCore_WriteEx(_In_ ULONG64 pa, _In_reads_(cb) PBYTE pb, _In_ DWORD cb, _In_ DWORD flags);
|
||||
|
||||
/*
|
||||
* Probe the memory of the target system to check whether it's readable or not.
|
||||
@@ -350,6 +404,7 @@ DLLEXPORT BOOL LeechCore_Probe(_In_ QWORD pa, _In_ DWORD cPages, _Inout_updates_
|
||||
#define LEECHCORE_OPT_CORE_VERSION_MAJOR 0x01000001 // R
|
||||
#define LEECHCORE_OPT_CORE_VERSION_MINOR 0x01000002 // R
|
||||
#define LEECHCORE_OPT_CORE_VERSION_REVISION 0x01000003 // R
|
||||
#define LEECHCORE_OPT_CORE_FLAG_BACKEND_FUNCTIONS 0x01000004 // R
|
||||
|
||||
#define LEECHCORE_OPT_MEMORYINFO_VALID 0x02000001 // R
|
||||
#define LEECHCORE_OPT_MEMORYINFO_ADDR_MAX 0x02000002 // R
|
||||
@@ -420,7 +475,8 @@ DLLEXPORT BOOL LeechCore_SetOption(_In_ ULONG64 fOption, _In_ ULONG64 qwValue);
|
||||
#define LEECHCORE_STATISTICS_ID_GETOPTION 0x04
|
||||
#define LEECHCORE_STATISTICS_ID_SETOPTION 0x05
|
||||
#define LEECHCORE_STATISTICS_ID_COMMANDDATA 0x06
|
||||
#define LEECHCORE_STATISTICS_ID_MAX 0x06
|
||||
#define LEECHCORE_STATISTICS_ID_COMMANDSVC 0x07
|
||||
#define LEECHCORE_STATISTICS_ID_MAX 0x07
|
||||
|
||||
static const LPSTR LEECHCORE_STATISTICS_NAME[] = {
|
||||
"LeechCore_Open",
|
||||
@@ -429,7 +485,8 @@ static const LPSTR LEECHCORE_STATISTICS_NAME[] = {
|
||||
"LeechCore_Probe",
|
||||
"LeechCore_GetOption",
|
||||
"LeechCore_SetOption",
|
||||
"LeechCore_CommandData"
|
||||
"LeechCore_CommandData",
|
||||
"LeechCore_CommandSvc"
|
||||
};
|
||||
|
||||
typedef struct tdLEECHCORE_STATISTICS {
|
||||
@@ -465,6 +522,30 @@ DLLEXPORT BOOL LeechCore_CommandData(
|
||||
_Out_opt_ PDWORD pcbDataOut
|
||||
);
|
||||
|
||||
#define LEECHCORE_AGENTCOMMAND_EXEC_PYTHON_INMEM 0x1166000000000001
|
||||
#define LEECHCORE_AGENTCOMMAND_EXITPROCESS 0x1166000000000010
|
||||
|
||||
/*
|
||||
* Transfer commands/data to/from the remote agent (if it exists).
|
||||
* NB! USER-FREE: ppbDataOut (LocalFree)
|
||||
* -- fCommand = the option / command to the remote service as defined in LEECHCORE_AGENTCOMMAND_*
|
||||
* -- fDataIn = optional 64-bit tiny input value
|
||||
* -- cbDataIn
|
||||
* -- pbDataIn
|
||||
* -- ppbDataOut = ptr to receive function allocated output - must be LocalFree'd by caller!
|
||||
* -- pcbDataOut = ptr to receive length of *pbDataOut.
|
||||
* -- return
|
||||
*/
|
||||
_Success_(return)
|
||||
DLLEXPORT BOOL LeechCore_AgentCommand(
|
||||
_In_ ULONG64 fCommand,
|
||||
_In_ ULONG64 fDataIn,
|
||||
_In_reads_(cbDataIn) PBYTE pbDataIn,
|
||||
_In_ DWORD cbDataIn,
|
||||
_Out_writes_opt_(*pcbDataOut) PBYTE *ppbDataOut,
|
||||
_Out_opt_ PDWORD pcbDataOut
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
Binary file not shown.
21
pcileech.sln
21
pcileech.sln
@@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.28307.421
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.28729.10
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcileech", "pcileech\pcileech.vcxproj", "{DFFA1B4C-279B-4356-ADB1-08A6F4795931}"
|
||||
EndProject
|
||||
@@ -41,15 +41,14 @@ Global
|
||||
ReleaseMT|x64 = ReleaseMT|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{DFFA1B4C-279B-4356-ADB1-08A6F4795931}.Debug|x64.ActiveCfg = Release|x64
|
||||
{DFFA1B4C-279B-4356-ADB1-08A6F4795931}.Debug|x64.Build.0 = Release|x64
|
||||
{DFFA1B4C-279B-4356-ADB1-08A6F4795931}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{DFFA1B4C-279B-4356-ADB1-08A6F4795931}.Debug|x64.Build.0 = Debug|x64
|
||||
{DFFA1B4C-279B-4356-ADB1-08A6F4795931}.Release|x64.ActiveCfg = Release|x64
|
||||
{DFFA1B4C-279B-4356-ADB1-08A6F4795931}.Release|x64.Build.0 = Release|x64
|
||||
{DFFA1B4C-279B-4356-ADB1-08A6F4795931}.ReleaseMT|x64.ActiveCfg = ReleaseMT|x64
|
||||
{DFFA1B4C-279B-4356-ADB1-08A6F4795931}.ReleaseMT|x64.Build.0 = ReleaseMT|x64
|
||||
{C55314C6-71A0-4AE2-A4F0-E5E531A5E065}.Debug|x64.ActiveCfg = Release|x64
|
||||
{C55314C6-71A0-4AE2-A4F0-E5E531A5E065}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{C55314C6-71A0-4AE2-A4F0-E5E531A5E065}.Release|x64.ActiveCfg = Release|x64
|
||||
{C55314C6-71A0-4AE2-A4F0-E5E531A5E065}.Release|x64.Build.0 = ReleaseMT|x64
|
||||
{C55314C6-71A0-4AE2-A4F0-E5E531A5E065}.ReleaseMT|x64.ActiveCfg = ReleaseMT|x64
|
||||
{5C698F13-6E9F-46F3-95FC-55376A65D8BF}.Debug|x64.ActiveCfg = Release|x64
|
||||
{5C698F13-6E9F-46F3-95FC-55376A65D8BF}.Release|x64.ActiveCfg = Release|x64
|
||||
@@ -61,17 +60,11 @@ Global
|
||||
{3476ABD2-5DEA-43E6-A676-8BE25F74535A}.ReleaseMT|x64.ActiveCfg = ReleaseMT|x64
|
||||
{3476ABD2-5DEA-43E6-A676-8BE25F74535A}.ReleaseMT|x64.Build.0 = ReleaseMT|x64
|
||||
{E11BECC1-685F-41B9-A352-A6127FAB3758}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{E11BECC1-685F-41B9-A352-A6127FAB3758}.Debug|x64.Build.0 = Debug|x64
|
||||
{E11BECC1-685F-41B9-A352-A6127FAB3758}.Release|x64.ActiveCfg = Debug|x64
|
||||
{E11BECC1-685F-41B9-A352-A6127FAB3758}.Release|x64.Build.0 = Debug|x64
|
||||
{E11BECC1-685F-41B9-A352-A6127FAB3758}.Release|x64.ActiveCfg = Release|x64
|
||||
{E11BECC1-685F-41B9-A352-A6127FAB3758}.ReleaseMT|x64.ActiveCfg = ReleaseMT|x64
|
||||
{E11BECC1-685F-41B9-A352-A6127FAB3758}.ReleaseMT|x64.Build.0 = ReleaseMT|x64
|
||||
{F2F4AA4A-BEFE-4738-9412-820007919334}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F2F4AA4A-BEFE-4738-9412-820007919334}.Debug|x64.Build.0 = Debug|x64
|
||||
{F2F4AA4A-BEFE-4738-9412-820007919334}.Release|x64.ActiveCfg = Debug|x64
|
||||
{F2F4AA4A-BEFE-4738-9412-820007919334}.Release|x64.Build.0 = Debug|x64
|
||||
{F2F4AA4A-BEFE-4738-9412-820007919334}.Release|x64.ActiveCfg = Release|x64
|
||||
{F2F4AA4A-BEFE-4738-9412-820007919334}.ReleaseMT|x64.ActiveCfg = ReleaseMT|x64
|
||||
{F2F4AA4A-BEFE-4738-9412-820007919334}.ReleaseMT|x64.Build.0 = ReleaseMT|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
CC=gcc
|
||||
CFLAGS=-I. -D LINUX -L. -l:../files/leechcore.so -pthread `pkg-config libusb-1.0 --libs --cflags`
|
||||
CFLAGS=-I. -D LINUX -L. -l:leechcore.so -pthread `pkg-config libusb-1.0 --libs --cflags`
|
||||
LDFLAGS=-Wl,-rpath,'$$ORIGIN'
|
||||
DEPS = pcileech.h
|
||||
OBJ = pcileech oscompatibility.o pcileech.o device.o executor.o extra.o help.o kmd.o memdump.o mempatch.o statistics.o umd.o util.o vfs.o vmmprx.o
|
||||
@@ -8,9 +8,12 @@ OBJ = pcileech oscompatibility.o pcileech.o device.o executor.o extra.o help.o k
|
||||
$(CC) -c -o $@ $< $(CFLAGS)
|
||||
|
||||
pcileech: $(OBJ)
|
||||
cp ../files/leechcore.so . |true
|
||||
cp ../../LeechCore-dev/files/leechcore.so . |true
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
|
||||
rm *.o
|
||||
mv pcileech ../files/
|
||||
mv leechcore.so ../files/
|
||||
|
||||
clean:
|
||||
rm *.o
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "device.h"
|
||||
#include "util.h"
|
||||
#include "vmmprx.h"
|
||||
#include "leechcore.h"
|
||||
|
||||
#define EXEC_IO_MAGIC 0x12651232dfef9521
|
||||
#define EXEC_IO_CONSOLE_BUFFER_SIZE 0x800
|
||||
@@ -387,3 +388,50 @@ fail:
|
||||
LocalFree(szBufferText);
|
||||
if(pFile) { fclose(pFile); }
|
||||
}
|
||||
|
||||
VOID ActionSvcExecPy()
|
||||
{
|
||||
BOOL result;
|
||||
DWORD cb = 0;
|
||||
PBYTE pb = NULL;
|
||||
FILE *pFile = NULL;
|
||||
if(!ctxMain->cfg.pbIn || (ctxMain->cfg.cbIn < 4)) {
|
||||
printf("AGENT-PYEXEC: Failed. Input file not valid. Please supply input file in -in option.\n");
|
||||
return;
|
||||
}
|
||||
printf("AGENT-PYEXEC: Sending script to remote LeechAgent for processing.\n");
|
||||
printf("AGENT-PYEXEC: Waiting for result ...\n");
|
||||
result = LeechCore_AgentCommand(LEECHCORE_AGENTCOMMAND_EXEC_PYTHON_INMEM, 0, ctxMain->cfg.pbIn, (DWORD)ctxMain->cfg.cbIn, &pb, &cb);
|
||||
if(!result) {
|
||||
printf("AGENT-PYEXEC: Failed.\n");
|
||||
return;
|
||||
}
|
||||
if(pb && (cb > 0)) {
|
||||
// write to out file
|
||||
if(ctxMain->cfg.szFileOut[0]) {
|
||||
// open output file
|
||||
if(!fopen_s(&pFile, ctxMain->cfg.szFileOut, "r") || pFile) {
|
||||
printf("AGENT-PYEXEC: Error writing output to file. File already exists: %s\n", ctxMain->cfg.szFileOut);
|
||||
goto fail;
|
||||
}
|
||||
if(fopen_s(&pFile, ctxMain->cfg.szFileOut, "wb") || !pFile) {
|
||||
printf("AGENT-PYEXEC: Error writing output to file.\n");
|
||||
goto fail;
|
||||
}
|
||||
if(cb != fwrite(pb, 1, cb, pFile)) {
|
||||
printf("AGENT-PYEXEC: Error writing output to file.\n");
|
||||
goto fail;
|
||||
}
|
||||
printf("AGENT-PYEXEC: Wrote %i bytes to file %s.\n", cb, ctxMain->cfg.szFileOut);
|
||||
}
|
||||
// print to screen
|
||||
printf("AGENT-PYEXEC: Please see result below: \n================================ \n");
|
||||
Util_AsciiFilter(pb, cb); // filter away potentially harmful chars from untrusted remote input
|
||||
printf("%s\n", (LPSTR)pb);
|
||||
}
|
||||
|
||||
fail:
|
||||
if(pFile) { fclose(pFile); }
|
||||
LocalFree(pb);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,4 +52,9 @@ BOOL Exec_ExecSilent(_In_ LPSTR szShellcodeName, _In_ PBYTE pbIn, _In_ QWORD cbI
|
||||
*/
|
||||
VOID ActionExecShellcode();
|
||||
|
||||
/*
|
||||
* Try execute python code on a remote host in the context of the LeechSvc.
|
||||
*/
|
||||
VOID ActionSvcExecPy();
|
||||
|
||||
#endif /* __EXECUTOR_H__ */
|
||||
|
||||
@@ -63,6 +63,7 @@ VOID Help_ShowGeneral()
|
||||
" probe NATIVE [ min, max ] (FPGA) \n" \
|
||||
" pslist NATIVE (MemProcFS/Windows) \n" \
|
||||
" psvirt2phys NATIVE [ 0, 1 ] (MemProcFS/Windows) \n" \
|
||||
" agent-execpy NATIVE [ in, out ] (Remote LeechAgent) \n" \
|
||||
" System specific commands and valid MODEs [ and options ]: \n" \
|
||||
" mac_fvrecover NATIVE (USB3380) \n" \
|
||||
" mac_fvrecover2 NATIVE (USB3380) \n" \
|
||||
@@ -582,6 +583,23 @@ VOID Help_ShowDetailed()
|
||||
" -0 632 -1 0x08000000 -s c:\\windows\\system32\\cmd.exe \n" \
|
||||
);
|
||||
break;
|
||||
case AGENT_EXEC_PY:
|
||||
printf(
|
||||
" EXECUTE A PYTHON SCRIPT ON A REMOTE HOST RUNNING LeechAgent \n" \
|
||||
" MODES : NATIVE \n" \
|
||||
" REQUIRE : Windows/Remote LeechSvc \n" \
|
||||
" OPTIONS : -in, -out \n" \
|
||||
" Execute a Python script contained in the -in parameter on a remote host having\n" \
|
||||
" the LeechAgent installed. The script will be executed in an embedded Python\n" \
|
||||
" and the MemProcFS/LeechCore python APIs will be available and initialized. \n" \
|
||||
" Outout will be displayed on screen unless -out parameter is specified. \n" \
|
||||
" EXAMPLE: \n" \
|
||||
" 1) Execute the script 'myscript.py' on the remote host test1.contoso.com using\n" \
|
||||
" physical memory acquired from WinPmem: \n" \
|
||||
" pcileech.exe agent-execpy -in myscript.py -device pmem \n" \
|
||||
" -remote rpc://test1$@contoso.com:test1.contoso.com \n" \
|
||||
);
|
||||
break;
|
||||
case EXEC_KMD:
|
||||
_HelpShowExecCommand();
|
||||
break;
|
||||
|
||||
@@ -23,13 +23,23 @@
|
||||
// kerberos. If not possible or desirable the 'insecure' value may be specified
|
||||
// to disable authentication and security.
|
||||
// Syntax:
|
||||
// rpc://<remote_spn>:<host>:<port> (port = optional, remote_spn = kerberos)
|
||||
// (SPN of remote service or 'insecure' )
|
||||
// rpc://<remote_spn>:<host>[:<options>] (remote_spn = kerberos SPN of )
|
||||
// (remote service or 'insecure' )
|
||||
//
|
||||
// Valid options: (optional comma-separated list )
|
||||
// port=<port> (RPC TCP port of the remote system)
|
||||
// nocompress (disable transport compression )
|
||||
//
|
||||
// Examples:
|
||||
// rpc://insecure:remotehost.example.com (connect insecure to remote host )
|
||||
// rpc://user@ad.domain.com:192.0.0.5 (connect secure to remote host )
|
||||
// rpc://insecure:127.0.0.0:6666 (connect insecure non-default port)
|
||||
//
|
||||
// The remote connector may also connect to pipe handles provided in the config
|
||||
// string. This is only used internally by the LeechAgent for communication for
|
||||
// parent/child process and may not be used by external applications. Syntax is
|
||||
// pipe://<handle_id_input>:<handle_id_output>.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Device to connect to: szDevice contains the device to capture memory from.
|
||||
@@ -107,11 +117,16 @@
|
||||
// Syntax:
|
||||
// EXISTING
|
||||
//
|
||||
// EXISTINGREMOTE : Same as EXISTING but applying the EXISTING device on the
|
||||
// remote system. Use only in conjunction with a remote system.
|
||||
// Syntax:
|
||||
// EXISTINGREMOTE
|
||||
//
|
||||
//
|
||||
// (c) Ulf Frisk, 2018-2019
|
||||
// Author: Ulf Frisk, pcileech@frizk.net
|
||||
//
|
||||
// Header Version: 1.1.0
|
||||
// Header Version: 1.2.0
|
||||
//
|
||||
#ifndef __LEECHCORE_H__
|
||||
#define __LEECHCORE_H__
|
||||
@@ -127,8 +142,12 @@ extern "C" {
|
||||
#include <Windows.h>
|
||||
typedef unsigned __int64 QWORD, *PQWORD;
|
||||
#define DLLEXPORT __declspec(dllexport)
|
||||
#ifdef _WIN64
|
||||
#define ARCH_64
|
||||
#endif /* _WIN64 */
|
||||
#endif /* _WIN32 */
|
||||
#ifdef LINUX
|
||||
#define ARCH_X64
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
typedef void VOID, *PVOID, *LPVOID;
|
||||
@@ -163,6 +182,7 @@ typedef long long unsigned int QWORD, *PQWORD, ULONG64, *PULONG64;
|
||||
#define MEM_IO_SCATTER_HEADER_MAGIC 0xffff6548
|
||||
#define MEM_IO_SCATTER_HEADER_VERSION 0x0003
|
||||
|
||||
#ifdef ARCH_64
|
||||
typedef struct tdMEM_IO_SCATTER_HEADER {
|
||||
DWORD magic; // magic
|
||||
WORD version; // version
|
||||
@@ -175,6 +195,26 @@ typedef struct tdMEM_IO_SCATTER_HEADER {
|
||||
PVOID pvReserved2; // reserved for use by caller.
|
||||
PVOID Future2[8];
|
||||
} MEM_IO_SCATTER_HEADER, *PMEM_IO_SCATTER_HEADER, **PPMEM_IO_SCATTER_HEADER;
|
||||
#endif /* ARCH_64 */
|
||||
|
||||
#ifndef ARCH_64
|
||||
typedef struct tdMEM_IO_SCATTER_HEADER {
|
||||
DWORD magic; // magic
|
||||
WORD version; // version
|
||||
WORD Future1;
|
||||
ULONG64 qwA; // base address.
|
||||
DWORD cbMax; // bytes to read (DWORD boundry, max 0x1000); pb must have room for this.
|
||||
DWORD cb; // bytes read into result buffer.
|
||||
PBYTE pb; // ptr to 0x1000 sized buffer to receive read bytes.
|
||||
DWORD dwFiller64_1;
|
||||
PVOID pvReserved1; // reserved for use by caller.
|
||||
DWORD dwFiller64_2;
|
||||
PVOID pvReserved2; // reserved for use by caller.
|
||||
DWORD dwFiller64_3;
|
||||
PVOID Future2[8];
|
||||
DWORD dwFiller64_4[8];
|
||||
} MEM_IO_SCATTER_HEADER, *PMEM_IO_SCATTER_HEADER, **PPMEM_IO_SCATTER_HEADER;
|
||||
#endif /* ARCH_64 */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LEECHCORE INITIALIZATION / CLOSE FUNCTIONALITY BELOW:
|
||||
@@ -221,12 +261,26 @@ typedef struct tdLEECHCORE_CONFIG {
|
||||
// optional 'printf' function pointer. if set to non null value 'printf'
|
||||
// calls will be redirected. useful when logging to files.
|
||||
_Check_return_opt_ int(*pfn_printf_opt)(_In_z_ _Printf_format_string_ char const* const _Format, ...); // set by caller.
|
||||
#ifndef ARCH_64
|
||||
DWORD dwFiller64_1;
|
||||
#endif /* ARCH_64 */
|
||||
} LEECHCORE_CONFIG, *PLEECHCORE_CONFIG;
|
||||
|
||||
#ifdef ARCH_64
|
||||
typedef struct tdLEECHCORE_PAGESTAT_MINIMAL {
|
||||
HANDLE h;
|
||||
VOID(*pfnPageStatUpdate)(HANDLE h, ULONG64 pa, ULONG64 cPageSuccessAdd, ULONG64 cPageFailAdd);
|
||||
} LEECHCORE_PAGESTAT_MINIMAL, *PLEECHCORE_PAGESTAT_MINIMAL;
|
||||
#endif /* ARCH_64 */
|
||||
|
||||
#ifndef ARCH_64
|
||||
typedef struct tdLEECHCORE_PAGESTAT_MINIMAL {
|
||||
HANDLE h;
|
||||
DWORD dwFiller64_1;
|
||||
VOID(*pfnPageStatUpdate)(HANDLE h, ULONG64 pa, ULONG64 cPageSuccessAdd, ULONG64 cPageFailAdd);
|
||||
DWORD dwFiller64_2;
|
||||
} LEECHCORE_PAGESTAT_MINIMAL, *PLEECHCORE_PAGESTAT_MINIMAL;
|
||||
#endif /* ARCH_64 */
|
||||
|
||||
/*
|
||||
* Open a connection to the target device. The LeechCore initialization may fail
|
||||
@@ -306,7 +360,7 @@ DLLEXPORT DWORD LeechCore_ReadEx(_In_ ULONG64 pa, _Out_writes_(cb) PBYTE pb, _In
|
||||
* -- return
|
||||
*/
|
||||
_Success_(return)
|
||||
DLLEXPORT BOOL LeechCore_Write(_In_ ULONG64 pa, _In_ PBYTE pb, _In_ DWORD cb);
|
||||
DLLEXPORT BOOL LeechCore_Write(_In_ ULONG64 pa, _In_reads_(cb) PBYTE pb, _In_ DWORD cb);
|
||||
|
||||
/*
|
||||
* Write data to the target system if supported by the device.
|
||||
@@ -317,7 +371,7 @@ DLLEXPORT BOOL LeechCore_Write(_In_ ULONG64 pa, _In_ PBYTE pb, _In_ DWORD cb);
|
||||
* -- return
|
||||
*/
|
||||
_Success_(return)
|
||||
DLLEXPORT BOOL LeechCore_WriteEx(_In_ ULONG64 pa, _In_ PBYTE pb, _In_ DWORD cb, _In_ DWORD flags);
|
||||
DLLEXPORT BOOL LeechCore_WriteEx(_In_ ULONG64 pa, _In_reads_(cb) PBYTE pb, _In_ DWORD cb, _In_ DWORD flags);
|
||||
|
||||
/*
|
||||
* Probe the memory of the target system to check whether it's readable or not.
|
||||
@@ -350,6 +404,7 @@ DLLEXPORT BOOL LeechCore_Probe(_In_ QWORD pa, _In_ DWORD cPages, _Inout_updates_
|
||||
#define LEECHCORE_OPT_CORE_VERSION_MAJOR 0x01000001 // R
|
||||
#define LEECHCORE_OPT_CORE_VERSION_MINOR 0x01000002 // R
|
||||
#define LEECHCORE_OPT_CORE_VERSION_REVISION 0x01000003 // R
|
||||
#define LEECHCORE_OPT_CORE_FLAG_BACKEND_FUNCTIONS 0x01000004 // R
|
||||
|
||||
#define LEECHCORE_OPT_MEMORYINFO_VALID 0x02000001 // R
|
||||
#define LEECHCORE_OPT_MEMORYINFO_ADDR_MAX 0x02000002 // R
|
||||
@@ -420,7 +475,8 @@ DLLEXPORT BOOL LeechCore_SetOption(_In_ ULONG64 fOption, _In_ ULONG64 qwValue);
|
||||
#define LEECHCORE_STATISTICS_ID_GETOPTION 0x04
|
||||
#define LEECHCORE_STATISTICS_ID_SETOPTION 0x05
|
||||
#define LEECHCORE_STATISTICS_ID_COMMANDDATA 0x06
|
||||
#define LEECHCORE_STATISTICS_ID_MAX 0x06
|
||||
#define LEECHCORE_STATISTICS_ID_COMMANDSVC 0x07
|
||||
#define LEECHCORE_STATISTICS_ID_MAX 0x07
|
||||
|
||||
static const LPSTR LEECHCORE_STATISTICS_NAME[] = {
|
||||
"LeechCore_Open",
|
||||
@@ -429,7 +485,8 @@ static const LPSTR LEECHCORE_STATISTICS_NAME[] = {
|
||||
"LeechCore_Probe",
|
||||
"LeechCore_GetOption",
|
||||
"LeechCore_SetOption",
|
||||
"LeechCore_CommandData"
|
||||
"LeechCore_CommandData",
|
||||
"LeechCore_CommandSvc"
|
||||
};
|
||||
|
||||
typedef struct tdLEECHCORE_STATISTICS {
|
||||
@@ -465,6 +522,30 @@ DLLEXPORT BOOL LeechCore_CommandData(
|
||||
_Out_opt_ PDWORD pcbDataOut
|
||||
);
|
||||
|
||||
#define LEECHCORE_AGENTCOMMAND_EXEC_PYTHON_INMEM 0x1166000000000001
|
||||
#define LEECHCORE_AGENTCOMMAND_EXITPROCESS 0x1166000000000010
|
||||
|
||||
/*
|
||||
* Transfer commands/data to/from the remote agent (if it exists).
|
||||
* NB! USER-FREE: ppbDataOut (LocalFree)
|
||||
* -- fCommand = the option / command to the remote service as defined in LEECHCORE_AGENTCOMMAND_*
|
||||
* -- fDataIn = optional 64-bit tiny input value
|
||||
* -- cbDataIn
|
||||
* -- pbDataIn
|
||||
* -- ppbDataOut = ptr to receive function allocated output - must be LocalFree'd by caller!
|
||||
* -- pcbDataOut = ptr to receive length of *pbDataOut.
|
||||
* -- return
|
||||
*/
|
||||
_Success_(return)
|
||||
DLLEXPORT BOOL LeechCore_AgentCommand(
|
||||
_In_ ULONG64 fCommand,
|
||||
_In_ ULONG64 fDataIn,
|
||||
_In_reads_(cbDataIn) PBYTE pbDataIn,
|
||||
_In_ DWORD cbDataIn,
|
||||
_Out_writes_opt_(*pcbDataOut) PBYTE *ppbDataOut,
|
||||
_Out_opt_ PDWORD pcbDataOut
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
@@ -168,6 +168,15 @@ DWORD InterlockedAdd(DWORD *Addend, DWORD Value)
|
||||
return __sync_add_and_fetch(Addend, Value);
|
||||
}
|
||||
|
||||
BOOL IsWow64Process(HANDLE hProcess, PBOOL Wow64Process)
|
||||
{
|
||||
if(Wow64Process) {
|
||||
*Wow64Process = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Facade implementation of FTDI functions using functionality provided by
|
||||
// kernel driver ft60x by @key2fr in the backend. NB! functionality below
|
||||
|
||||
@@ -123,6 +123,7 @@ typedef struct tdEXCEPTION_RECORD64 { CHAR sz[152]; } EXCEPTION_RECORD64
|
||||
#define _fileno(f) (fileno(f))
|
||||
#define InterlockedAdd64(p, v) (__sync_fetch_and_add(p, v))
|
||||
#define InterlockedIncrement64(p) (__sync_fetch_and_add(p, 1))
|
||||
#define GetCurrentProcess() ((HANDLE)-1)
|
||||
|
||||
typedef struct tdCRITICAL_SECTION {
|
||||
pthread_mutex_t mutex;
|
||||
@@ -159,6 +160,7 @@ BOOL QueryPerformanceCounter(_Out_ LARGE_INTEGER *lpPerformanceCount);
|
||||
VOID GetLocalTime(LPSYSTEMTIME lpSystemTime);
|
||||
DWORD InterlockedAdd(DWORD *Addend, DWORD Value);
|
||||
BOOL WinUsb_Free(WINUSB_INTERFACE_HANDLE InterfaceHandle);
|
||||
BOOL IsWow64Process(HANDLE hProcess, PBOOL Wow64Process);
|
||||
|
||||
HANDLE CreateThread(
|
||||
PVOID lpThreadAttributes,
|
||||
|
||||
@@ -44,6 +44,7 @@ BOOL PCILeechConfigIntialize(_In_ DWORD argc, _In_ char* argv[])
|
||||
{.tp = PROBE,.sz = "probe" },
|
||||
{.tp = PSLIST,.sz = "pslist" },
|
||||
{.tp = PSVIRT2PHYS,.sz = "psvirt2phys" },
|
||||
{.tp = AGENT_EXEC_PY,.sz = "agent-execpy" },
|
||||
};
|
||||
DWORD j, i = 1;
|
||||
ctxMain = LocalAlloc(LMEM_ZEROINIT, sizeof(PCILEECH_CONTEXT));
|
||||
@@ -59,19 +60,19 @@ BOOL PCILeechConfigIntialize(_In_ DWORD argc, _In_ char* argv[])
|
||||
// fetch command line actions/options
|
||||
loop:
|
||||
while(i < argc) {
|
||||
for(j = 0; j < sizeof(ACTIONS) / sizeof(ACTION); j++) { // parse command (if found)
|
||||
if(0 == strcmp(argv[i], ACTIONS[j].sz)) {
|
||||
ctxMain->cfg.tpAction = ACTIONS[j].tp;
|
||||
i++;
|
||||
goto loop;
|
||||
for(j = 0; j < sizeof(ACTIONS) / sizeof(ACTION); j++) { // parse command (if found)
|
||||
if(0 == _stricmp(argv[i], ACTIONS[j].sz)) {
|
||||
ctxMain->cfg.tpAction = ACTIONS[j].tp;
|
||||
i++;
|
||||
goto loop;
|
||||
}
|
||||
}
|
||||
if(ctxMain->cfg.tpAction == NA && 0 != memcmp(argv[i], "-", 1)) {
|
||||
ctxMain->cfg.tpAction = ((strlen(argv[i]) > 3) && !_strnicmp("umd", argv[i], 3)) ? EXEC_UMD : EXEC_KMD;
|
||||
strcpy_s(ctxMain->cfg.szShellcodeName, MAX_PATH, argv[i]);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(ctxMain->cfg.tpAction == NA && 0 != memcmp(argv[i], "-", 1)) {
|
||||
ctxMain->cfg.tpAction = ((strlen(argv[i]) > 3) && !_strnicmp("umd", argv[i], 3)) ? EXEC_UMD : EXEC_KMD;
|
||||
strcpy_s(ctxMain->cfg.szShellcodeName, MAX_PATH, argv[i]);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
// parse options (command not found)
|
||||
if(0 == strcmp(argv[i], "-pt")) {
|
||||
ctxMain->cfg.fPageTableScan = TRUE;
|
||||
@@ -113,7 +114,7 @@ BOOL PCILeechConfigIntialize(_In_ DWORD argc, _In_ char* argv[])
|
||||
ctxMain->cfg.qwAddrMax = Util_GetNumeric(argv[i + 1]);
|
||||
} else if(0 == strcmp(argv[i], "-cr3")) {
|
||||
ctxMain->cfg.qwCR3 = Util_GetNumeric(argv[i + 1]);
|
||||
}else if(0 == strcmp(argv[i], "-efibase")) {
|
||||
} else if(0 == strcmp(argv[i], "-efibase")) {
|
||||
ctxMain->cfg.qwEFI_IBI_SYST = Util_GetNumeric(argv[i + 1]);
|
||||
} else if(0 == strcmp(argv[i], "-iosize")) {
|
||||
ctxMain->cfg.qwMaxSizeDmaIo = Util_GetNumeric(argv[i + 1]);
|
||||
@@ -195,6 +196,50 @@ VOID PCILeechFreeContext()
|
||||
ctxMain = NULL;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* Call the free context functionality in a separate thread (in case it gets stuck).
|
||||
* -- pv
|
||||
*/
|
||||
VOID PCILeechCtrlHandler_TryShutdownThread(PVOID pv)
|
||||
{
|
||||
__try {
|
||||
PCILeechFreeContext();
|
||||
} __except(EXCEPTION_EXECUTE_HANDLER) { ; }
|
||||
}
|
||||
|
||||
/*
|
||||
* SetConsoleCtrlHandler for PCILeech - clean up whenever CTRL+C is pressed.
|
||||
* -- fdwCtrlType
|
||||
* -- return
|
||||
*/
|
||||
BOOL WINAPI PCILeechCtrlHandler(DWORD fdwCtrlType)
|
||||
{
|
||||
if(fdwCtrlType == CTRL_C_EVENT) {
|
||||
printf("CTRL+C detected - shutting down ...\n");
|
||||
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PCILeechCtrlHandler_TryShutdownThread, NULL, 0, NULL);
|
||||
Sleep(500);
|
||||
TerminateProcess(GetCurrentProcess(), 1);
|
||||
Sleep(1000);
|
||||
ExitProcess(1);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VOID PCILeechCtrlHandlerInitialize()
|
||||
{
|
||||
SetConsoleCtrlHandler(PCILeechCtrlHandler, TRUE);
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#ifdef LINUX
|
||||
VOID PCILeechCtrlHandlerInitialize()
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif /* LINUX */
|
||||
|
||||
int main(_In_ int argc, _In_ char* argv[])
|
||||
{
|
||||
BOOL result;
|
||||
@@ -245,6 +290,9 @@ int main(_In_ int argc, _In_ char* argv[])
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// enable ctrl+c event handler if remote (to circumvent blocking thread)
|
||||
PCILeechCtrlHandlerInitialize();
|
||||
// main dispatcher
|
||||
switch(ctxMain->cfg.tpAction) {
|
||||
case DUMP:
|
||||
ActionMemoryDump();
|
||||
@@ -298,6 +346,9 @@ int main(_In_ int argc, _In_ char* argv[])
|
||||
case PSVIRT2PHYS:
|
||||
Action_UmdPsVirt2Phys();
|
||||
break;
|
||||
case AGENT_EXEC_PY:
|
||||
ActionSvcExecPy();
|
||||
break;
|
||||
case KMDLOAD:
|
||||
if(ctxMain->cfg.qwKMD) {
|
||||
printf("KMD: Successfully loaded at address: 0x%08x\n", (DWORD)ctxMain->cfg.qwKMD);
|
||||
|
||||
@@ -44,7 +44,8 @@ typedef enum tdActionType {
|
||||
TLP,
|
||||
PROBE,
|
||||
PSLIST,
|
||||
PSVIRT2PHYS
|
||||
PSVIRT2PHYS,
|
||||
AGENT_EXEC_PY
|
||||
} ACTION_TYPE;
|
||||
|
||||
typedef struct tdCONFIG_OPTION {
|
||||
|
||||
@@ -60,20 +60,20 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{DFFA1B4C-279B-4356-ADB1-08A6F4795931}</ProjectGuid>
|
||||
<RootNamespace>pcileech</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
@@ -81,7 +81,7 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
@@ -132,11 +132,11 @@
|
||||
<SubSystem>Console</SubSystem>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>copy $(SolutionDir)\files\leechcore.h $(ProjectDir)\ /y</Command>
|
||||
<Command>copy "$(OutDir)leechcore.h" "$(ProjectDir)" /y</Command>
|
||||
</PreBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Command>del "$(SolutionDir)\files\pcileech_files.zip"
|
||||
powershell Compress-Archive -Path '$(SolutionDir)\files\*.*','$(SolutionDir)\files\pcileech' -DestinationPath '$(SolutionDir)\files\pcileech_files.zip' -Force -CompressionLevel Optimal</Command>
|
||||
<Command>del "$(OutDir)pcileech_files.zip"
|
||||
powershell Compress-Archive -Path '$(OutDir)*.*','$(OutDir)pcileech' -DestinationPath '$(OutDir)pcileech_files.zip' -Force -CompressionLevel Optimal</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
@@ -163,11 +163,11 @@ powershell Compress-Archive -Path '$(SolutionDir)\files\*.*','$(SolutionDir)\fil
|
||||
<AdditionalDependencies>$(SolutionDir)\files\leechcore.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>copy $(SolutionDir)\files\leechcore.h $(ProjectDir)\ /y</Command>
|
||||
<Command>copy "$(OutDir)leechcore.h" "$(ProjectDir)" /y</Command>
|
||||
</PreBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Command>del "$(SolutionDir)\files\pcileech_files.zip"
|
||||
powershell Compress-Archive -Path '$(SolutionDir)\files\*.*','$(SolutionDir)\files\pcileech' -DestinationPath '$(SolutionDir)\files\pcileech_files.zip' -Force -CompressionLevel Optimal</Command>
|
||||
<Command>del "$(OutDir)pcileech_files.zip"
|
||||
powershell Compress-Archive -Path '$(OutDir)*.*','$(OutDir)pcileech' -DestinationPath '$(OutDir)pcileech_files.zip' -Force -CompressionLevel Optimal</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">
|
||||
@@ -196,11 +196,11 @@ powershell Compress-Archive -Path '$(SolutionDir)\files\*.*','$(SolutionDir)\fil
|
||||
<AdditionalDependencies>$(SolutionDir)\files\leechcore.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>copy $(SolutionDir)\files\leechcore.h $(ProjectDir)\ /y</Command>
|
||||
<Command>copy "$(OutDir)leechcore.h" "$(ProjectDir)" /y</Command>
|
||||
</PreBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Command>del "$(SolutionDir)\files\pcileech_files.zip"
|
||||
powershell Compress-Archive -Path '$(SolutionDir)\files\*.*','$(SolutionDir)\files\pcileech' -DestinationPath '$(SolutionDir)\files\pcileech_files.zip' -Force -CompressionLevel Optimal</Command>
|
||||
<Command>del "$(OutDir)pcileech_files.zip"
|
||||
powershell Compress-Archive -Path '$(OutDir)*.*','$(OutDir)pcileech' -DestinationPath '$(OutDir)pcileech_files.zip' -Force -CompressionLevel Optimal</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
||||
@@ -693,41 +693,97 @@ VOID Util_WaitForPowerCycle()
|
||||
Util_WaitForPowerOn();
|
||||
}
|
||||
|
||||
VOID Util_PrintHexAscii(_In_ PBYTE pb, _In_ DWORD cb, _In_ DWORD cbInitialOffset)
|
||||
#define Util_2HexChar(x) (((((x) & 0xf) <= 9) ? '0' : ('a' - 10)) + ((x) & 0xf))
|
||||
|
||||
#define UTIL_PRINTASCII \
|
||||
"................................ !\"#$%&'()*+,-./0123456789:;<=>?" \
|
||||
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz`{|}~" \
|
||||
"................................................................" \
|
||||
"................................................................" \
|
||||
|
||||
BOOL Util_FillHexAscii(_In_ PBYTE pb, _In_ DWORD cb, _In_ DWORD cbInitialOffset, _Inout_opt_ LPSTR sz, _Out_ PDWORD pcsz)
|
||||
{
|
||||
DWORD i, j;
|
||||
if(cb > 0x10000) {
|
||||
printf("Large output. Only displaying first 65kB.\n");
|
||||
cb = 0x10000 - cbInitialOffset;
|
||||
}
|
||||
cb += cbInitialOffset;
|
||||
DWORD i, j, o = 0, szMax, iMod;
|
||||
// checks
|
||||
if((cbInitialOffset > cb) || (cbInitialOffset > 0x1000) || (cbInitialOffset & 0xf)) { return FALSE; }
|
||||
*pcsz = szMax = cb * 5 + 80;
|
||||
if(cb > szMax) { return FALSE; }
|
||||
if(!sz) { return TRUE; }
|
||||
// fill buffer with bytes
|
||||
for(i = cbInitialOffset; i < cb + ((cb % 16) ? (16 - cb % 16) : 0); i++)
|
||||
{
|
||||
// address
|
||||
if(0 == i % 16) {
|
||||
printf("%04x ", i % 0x10000);
|
||||
iMod = i % 0x10000;
|
||||
sz[o++] = Util_2HexChar(iMod >> 12);
|
||||
sz[o++] = Util_2HexChar(iMod >> 8);
|
||||
sz[o++] = Util_2HexChar(iMod >> 4);
|
||||
sz[o++] = Util_2HexChar(iMod);
|
||||
sz[o++] = ' ';
|
||||
sz[o++] = ' ';
|
||||
sz[o++] = ' ';
|
||||
sz[o++] = ' ';
|
||||
} else if(0 == i % 8) {
|
||||
putchar(' ');
|
||||
sz[o++] = ' ';
|
||||
}
|
||||
// hex
|
||||
if(i < cb) {
|
||||
printf("%02x ", pb[i]);
|
||||
sz[o++] = Util_2HexChar(pb[i] >> 4);
|
||||
sz[o++] = Util_2HexChar(pb[i]);
|
||||
sz[o++] = ' ';
|
||||
} else {
|
||||
printf(" ");
|
||||
sz[o++] = ' ';
|
||||
sz[o++] = ' ';
|
||||
sz[o++] = ' ';
|
||||
}
|
||||
// ascii
|
||||
if(15 == i % 16) {
|
||||
printf(" ");
|
||||
sz[o++] = ' ';
|
||||
sz[o++] = ' ';
|
||||
for(j = i - 15; j <= i; j++) {
|
||||
if(j >= cb) {
|
||||
putchar(' ');
|
||||
sz[o++] = ' ';
|
||||
} else {
|
||||
putchar(isprint(pb[j]) ? pb[j] : '.');
|
||||
sz[o++] = UTIL_PRINTASCII[pb[j]];
|
||||
}
|
||||
}
|
||||
putchar('\n');
|
||||
sz[o++] = '\n';
|
||||
}
|
||||
}
|
||||
sz[o++] = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID Util_PrintHexAscii(_In_ PBYTE pb, _In_ DWORD cb, _In_ DWORD cbInitialOffset)
|
||||
{
|
||||
DWORD szMax;
|
||||
LPSTR sz;
|
||||
if(cb > 0x10000) {
|
||||
printf("Large output. Only displaying first 65kB.\n");
|
||||
cb = 0x10000 - cbInitialOffset;
|
||||
}
|
||||
Util_FillHexAscii(pb, cb, cbInitialOffset, NULL, &szMax);
|
||||
if(!(sz = LocalAlloc(0, szMax))) { return; }
|
||||
Util_FillHexAscii(pb, cb, cbInitialOffset, sz, &szMax);
|
||||
printf("%s", sz);
|
||||
LocalFree(sz);
|
||||
}
|
||||
|
||||
#define UTIL_PRINTABLE_CHARACTERS_MAP "" \
|
||||
"0000000001100100000000000000000011111111111111111111111111111111" \
|
||||
"1111111111111111111111111111111111111111111111111111111111111110" \
|
||||
"1111111111111111111111111111111111111111111111111111111111111111" \
|
||||
"1111111111111111111111111111111111111111111111111111111111111110"
|
||||
|
||||
VOID Util_AsciiFilter(_In_reads_(cb) PBYTE pb, _In_ DWORD cb)
|
||||
{
|
||||
DWORD i;
|
||||
CHAR ch;
|
||||
for(i = 0; i < cb; i++) {
|
||||
ch = pb[i];
|
||||
if(0xff & UTIL_PRINTABLE_CHARACTERS_MAP[ch]) { continue; }
|
||||
pb[i] = '?';
|
||||
}
|
||||
}
|
||||
|
||||
VOID Util_SplitString2(_In_ LPSTR sz, _In_ CHAR chSplit, _Out_writes_(MAX_PATH) PCHAR _szBuf, _Out_ LPSTR *psz1, _Out_ LPSTR *psz2)
|
||||
|
||||
@@ -231,6 +231,14 @@ VOID Util_WaitForPowerOn();
|
||||
*/
|
||||
VOID Util_PrintHexAscii(_In_ PBYTE pb, _In_ DWORD cb, _In_ DWORD cbInitialOffset);
|
||||
|
||||
/*
|
||||
* Filter away (replace with '?') potentially harmful characters from an ascii
|
||||
* string / text.
|
||||
* -- pb
|
||||
* -- cb
|
||||
*/
|
||||
VOID Util_AsciiFilter(_In_reads_(cb) PBYTE pb, _In_ DWORD cb);
|
||||
|
||||
/*
|
||||
* Split a string into two at the first 'chSplit' character. If no 2nd string
|
||||
* is found then it's returned as null character '\0' (i.e. not as NULL).
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define STRINGIZE(s) STRINGIZE2(s)
|
||||
|
||||
#define VERSION_MAJOR 4
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_MINOR 1
|
||||
#define VERSION_REVISION 0
|
||||
#define VERSION_BUILD 0
|
||||
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{C55314C6-71A0-4AE2-A4F0-E5E531A5E065}</ProjectGuid>
|
||||
<RootNamespace>pcileech_gensig</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>
|
||||
</WholeProgramOptimization>
|
||||
@@ -32,7 +32,7 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
@@ -40,7 +40,7 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{5C698F13-6E9F-46F3-95FC-55376A65D8BF}</ProjectGuid>
|
||||
<RootNamespace>pcileech_shellcode</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
|
||||
15
readme.md
15
readme.md
@@ -30,7 +30,9 @@ Capabilities:
|
||||
* Pull and Push files [Linux, FreeBSD, Windows, macOS Sierra*].
|
||||
* Patch / Unlock (remove password requirement) [Windows, macOS Sierra*].
|
||||
* Easy to create own kernel shellcode and/or custom signatures.
|
||||
* Connect to a remote LeechService over the network.
|
||||
* Connect to a remote LeechAgent over the network to remotely:
|
||||
* Dump physical memory over the network.
|
||||
* Execute Python memory analysis scripts on the remote host.
|
||||
* Even more features not listed here ...
|
||||
|
||||
\*) macOS High Sierra and above are not supported.
|
||||
@@ -126,8 +128,11 @@ Dump all memory between addresses min and max, don't stop on failed pages. Nativ
|
||||
Force the usage of a specific device (instead of default auto detecting it). The pmem device is not auto detected.
|
||||
* ` pcileech.exe pagedisplay -min 0x1000 -device pmem `
|
||||
|
||||
Dump remote memory from a remote LeechService using connection encrypted and mutually authenticated by kerberos.
|
||||
* ` pcileech.exe dump -device pmem -remote rpc://computer$@ad.contoso.com `
|
||||
Dump remote memory from a remote LeechAgent running as `SYSTEM` on the computer `computer.ad.contoso.com` using connection encrypted and mutually authenticated by kerberos.
|
||||
* ` pcileech.exe dump -device pmem -remote rpc://computer$@ad.contoso.com:computer.ad.contoso.com `
|
||||
|
||||
Execute the Python analysis script `example-find-rwx.py` on the remote computer `computer.ad.contoso.com` using the LeechAgent embedded Python environment.
|
||||
* ` pcileech.exe agent-execpy -in example-find-rwx.py -device pmem -remote rpc://computer$@ad.contoso.com:computer.ad.contoso.com `
|
||||
|
||||
Dump memory using the the reported "TotalMeltdown" [Windows 7/2008R2 x64 PML4 page table permission vulnerability](https://blog.frizk.net/2018/03/total-meltdown.html).
|
||||
* ` pcileech.exe dump -out memdump_win7.raw -device totalmeltdown -v -force `
|
||||
@@ -146,6 +151,7 @@ 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.
|
||||
* File system mount support only exists for Windows.
|
||||
* Remote connectivity support only exists for Windows.
|
||||
|
||||
Building:
|
||||
=========
|
||||
@@ -183,3 +189,6 @@ v1.1-v3.6
|
||||
* remote devices via -remote setting.
|
||||
* Removal of API and built-in _Memory Process File System_ - please use the more capable APIs in the [LeechCore](https://github.com/ufrisk/LeechCore) and [Memory Process File System](https://github.com/ufrisk/MemProcFS) instead.
|
||||
* Multiple other changes and syntax updates.
|
||||
|
||||
v4.1
|
||||
* LeechAgent support - remote memory acquisition and analysis.
|
||||
|
||||
@@ -18,21 +18,21 @@
|
||||
<ProjectGuid>{F2F4AA4A-BEFE-4738-9412-820007919334}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>PCILeechFlash_Installer</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>USB3380Flash_installer</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
@@ -40,7 +40,7 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
|
||||
Reference in New Issue
Block a user