Skip to content

Commit 5596817

Browse files
authored
Add Linux character device plugin
Add Linux character device plugin
2 parents f46d680 + 20e3ac1 commit 5596817

File tree

4 files changed

+128
-0
lines changed

4 files changed

+128
-0
lines changed

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ all:
77
$(MAKE) -C leechcore_device_qemu
88
$(MAKE) -C leechcore_device_qemu_pcileech
99
$(MAKE) -C leechcore_device_skeleton
10+
$(MAKE) -C leechcore_device_devmem
1011

1112
clean:
1213
$(MAKE) -C leechcore_ft601_driver_linux clean
@@ -15,3 +16,4 @@ clean:
1516
$(MAKE) -C leechcore_device_qemu clean
1617
$(MAKE) -C leechcore_device_qemu_pcileech clean
1718
$(MAKE) -C leechcore_device_skeleton clean
19+
$(MAKE) -C leechcore_device_devmem clean

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Plugins are related to various kinds of device drivers allowing for modular exte
1515
- [leechcore_device_qemu](#leechcore_device_qemu)
1616
- [leechcore_device_skeleton](#leechcore_device_skeleton)
1717
- [leechcore_device_qemupcileech](#leechcore_device_qemupcileech)
18+
- [leechcore_device_devmem](#leechcore_device_devmem)
1819

1920

2021
## leechcore_device_hvsavedstate
@@ -264,3 +265,26 @@ Place leechcore_ft601_driver_macos.dylib and libftd3xx.dylib (from ftdichip) alo
264265
#### Overview:
265266

266267
The LeechDMA linux kernel driver allows the user to compile a kernel module (.ko) which may be inserted into the kernel. When a LeechDMA device (ZDMA or similar) is connected a device will show up as `/dev/leechdma*` where `*` is a number. User mode programs can then communicate with the LeechDMA linux kernel driver and its connected device.
268+
269+
270+
271+
## leechcore_device_devmem
272+
273+
#### Authors:
274+
- Brendan Heinonen ([@staticinvocation](https://github.com/staticinvocation))
275+
276+
#### Supported Platforms:
277+
- Linux
278+
279+
#### Overview:
280+
Allows LeechCore to access physical memory through a character device (i.e. `/dev/mem`) on the system.
281+
282+
#### Plugin documentation:
283+
This plugin has an optional `path` parameter. When specified, the plugin will use the character device specified. By default this value is set to `/dev/mem`.
284+
285+
Example commands:
286+
- `./pcileech dump -min 0x0 -max 0x10000 -device 'devmem://path=/dev/mem'`
287+
288+
289+
#### Installation instructions:
290+
Place leechcore_device_devmem.so alongside leechcore.so.

leechcore_device_devmem/Makefile

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
CC=gcc
2+
# -Wno-unused-variable -> unused variable in leechcore.h
3+
CFLAGS += -I. -I../includes -D LINUX -shared -fPIC -lrt -l:leechcore.so -L. -lm -fvisibility=hidden -g -Wall -Werror -Wextra -Wno-unused-variable
4+
LDFLAGS += -Wl,-rpath,'$$ORIGIN' -g -ldl -shared
5+
OBJ = leechcore_device_devmem.o
6+
7+
%.o: %.c $(DEPS)
8+
$(CC) -c -o $@ $< $(CFLAGS)
9+
10+
leechcore_device_devmem: $(OBJ)
11+
cp ../files/leechcore.so . || cp ../../LeechCore*/files/leechcore.so . || true
12+
$(CC) -o $@ $^ $(CFLAGS) -o leechcore_device_devmem.so $(LDFLAGS)
13+
mkdir -p ../filess
14+
mv leechcore_device_devmem.so ../files/
15+
rm -f *.o || true
16+
rm -f *.so || true
17+
true
18+
19+
20+
clean:
21+
rm -f *.o
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Author: Brendan Heinonen
3+
*/
4+
#include "leechcore.h"
5+
#include <errno.h>
6+
#include <fcntl.h>
7+
#include <stdbool.h>
8+
#include <limits.h>
9+
10+
#include <leechcore_device.h>
11+
#include <unistd.h>
12+
13+
14+
static VOID DeviceDevmem_ReadContigious(PLC_READ_CONTIGIOUS_CONTEXT ctxRC) {
15+
int bytes_read;
16+
int fd = (intptr_t)ctxRC->ctxLC->hDevice;
17+
18+
lseek(fd, ctxRC->paBase, SEEK_SET);
19+
if ((bytes_read = read(fd, ctxRC->pb, ctxRC->cb)) < 0) {
20+
lcprintfvvv(ctxRC->ctxLC, "Failed to read physical memory at 0x%llx (error %d)\n",
21+
ctxRC->paBase, bytes_read);
22+
}
23+
ctxRC->cbRead = (DWORD)bytes_read;
24+
}
25+
26+
static BOOL DeviceDevmem_WriteContigious(_In_ PLC_CONTEXT ctxLC,
27+
_In_ QWORD qwAddr, _In_ DWORD cb,
28+
_In_reads_(cb) PBYTE pb) {
29+
int bytes_written;
30+
int fd = (intptr_t)ctxLC->hDevice;
31+
lseek(fd, qwAddr, SEEK_SET);
32+
if ((bytes_written = write(fd, pb, cb)) < 0) {
33+
lcprintfvvv(ctxLC, "Failed to write physical memory at 0x%llx (error %d)\n",
34+
qwAddr, bytes_written);
35+
return false;
36+
}
37+
return true;
38+
}
39+
40+
VOID DeviceDevmem_Close(_Inout_ PLC_CONTEXT ctxLC)
41+
{
42+
close((intptr_t)ctxLC->hDevice);
43+
}
44+
45+
_Success_(return) EXPORTED_FUNCTION
46+
BOOL LcPluginCreate(_Inout_ PLC_CONTEXT ctxLC, _Out_opt_ PPLC_CONFIG_ERRORINFO ppLcCreateErrorInfo)
47+
{
48+
int ret = 0;
49+
PLC_DEVICE_PARAMETER_ENTRY pPathParameter = NULL;
50+
CHAR szPath[MAX_PATH];
51+
int fd;
52+
53+
lcprintf(ctxLC, "DEVICE: devmem: Initializing\n");
54+
55+
/* Sanity checks */
56+
if(ppLcCreateErrorInfo) { *ppLcCreateErrorInfo = NULL; }
57+
if(ctxLC->version != LC_CONTEXT_VERSION) { return false; }
58+
59+
/* Parse path parameter, or default to /dev/mem */
60+
if((pPathParameter = LcDeviceParameterGet(ctxLC, "path"))) {
61+
strncpy(szPath, pPathParameter->szValue, sizeof(szPath));
62+
} else {
63+
strncpy(szPath, "/dev/mem", sizeof(szPath));
64+
}
65+
66+
/* Open the device */
67+
fd = open(szPath, O_RDWR | O_SYNC);
68+
if(fd < 0) {
69+
lcprintf(ctxLC, "DEVICE: devmem: Failed to open device %s (error %d)\n", szPath, errno);
70+
return false;
71+
}
72+
73+
/* Assign info and handles for LeechCore */
74+
ctxLC->hDevice = (HANDLE)(intptr_t)fd;
75+
ctxLC->fMultiThread = false;
76+
ctxLC->Config.fVolatile = true;
77+
ctxLC->pfnClose = DeviceDevmem_Close;
78+
ctxLC->pfnReadContigious = DeviceDevmem_ReadContigious;
79+
ctxLC->pfnWriteContigious = DeviceDevmem_WriteContigious;
80+
return true;
81+
}

0 commit comments

Comments
 (0)