Remove rzk and gprobe IO plugins (#3654)

This commit is contained in:
Anton Kochkov 2023-07-12 00:21:43 +08:00 committed by GitHub
parent 8e41d975bf
commit f29171ceb1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 1 additions and 2749 deletions

View file

@ -1,59 +0,0 @@
What is GProbe?
===============
GProbe is a protocol to communicate with various parts from
Genesis/STMicro/MegaChips that are mostly used in video chipsets.
These chips have an integrated Turbo186 core. With GProbe you can read and write
RAM, reset the CPU, execute code in RAM, ...
There is a proprietary Windows tool to do this, but rizin offers much more
functionality.
Gprobe got some public attention with the
[MonitorDarkly exploit](https://github.com/RedBalloonShenanigans/MonitorDarkly).
What is implemented?
--------------------
- Serial1 protocol wrapper
- DDC2Bi3 protocol wrapper (Linux only)
- RAM read-/write-access
- Reset
- DebugOn/DebugOff
- RunCode
- GetDeviceId
- GetInformation
TODOs
-----
- DisplayPort AUX Channel protocol wrapper
- Flash commands
What is tested?
---------------
- running rizin on Linux and Windows
- communication via FTDI USB serial adaptor
- communication via DDC2Bi3
- controlling a MegaChips RD1-4320 DisplayPort 1.2a splitter reference board
- controlling a DELL U2410 connected via DVI
How to use for dummies?
-----------------------
rizin -n -w gprobe:///dev/ttyUSB0
- "/dev/ttyUSB0" is the serial connection, use something like "COM3" on Windows
- "-n" is important to avoid an initial 32k read to identify the binary type
- "-w" if you want to allow writing to RAM
rizin -n -w gprobe://i2c-4
- i2c-4 is the i2c bus where the GProbe device is connected
- find the appropriate bus with "ddcutil detect"
- make sure the i2c-dev kernel module is loaded
Setup for Turbo186 processor core:
- e asm.bits=16
- e asm.seggrn=8
Now enjoy all the great stuff that rizin offers, like:
- run grobe commands with =!?
- dump memory with px
- Visual mode with V, including cursor mode and insert hexpairs
- dumping segments to file
- disassembly and analysis

View file

@ -471,13 +471,11 @@ extern RzIOPlugin rz_io_plugin_winkd;
extern RzIOPlugin rz_io_plugin_rzpipe;
extern RzIOPlugin rz_io_plugin_rzweb;
extern RzIOPlugin rz_io_plugin_qnx;
extern RzIOPlugin rz_io_plugin_rzk;
extern RzIOPlugin rz_io_plugin_tcp;
extern RzIOPlugin rz_io_plugin_bochs;
extern RzIOPlugin rz_io_plugin_null;
extern RzIOPlugin rz_io_plugin_ar;
extern RzIOPlugin rz_io_plugin_winedbg;
extern RzIOPlugin rz_io_plugin_gprobe;
extern RzIOPlugin rz_io_plugin_fd;
#if __cplusplus

View file

@ -7,7 +7,6 @@ io_plugins_list = [
'default',
'dmp',
'gdb',
'gprobe',
'gzip',
'http',
'ihex',
@ -17,7 +16,6 @@ io_plugins_list = [
'null',
'procpid',
'ptrace',
'rzk',
'rzpipe',
'rzweb',
'rap',
@ -67,7 +65,6 @@ rz_io_sources = [
'p/io_dmp.c',
'p/io_default.c',
'p/io_gdb.c',
'p/io_gprobe.c',
'p/io_gzip.c',
'p/io_http.c',
'p/io_ihex.c',
@ -76,7 +73,6 @@ rz_io_sources = [
'p/io_null.c',
'p/io_procpid.c',
'p/io_ptrace.c',
'p/io_rzk.c',
'p/io_rzpipe.c',
'p/io_rzweb.c',
'p/io_rap.c',
@ -92,7 +88,6 @@ rz_io_sources = [
if host_machine.system() == 'windows'
rz_io_sources += [
'p/io_rzk_windows.c',
'p/io_windbg.c',
'p/io_w32.c',
'p/io_w32dbg.c',
@ -123,14 +118,6 @@ if host_machine.system() == 'windows'
rz_io_deps += dependency('rzw32dbg_wrap')
endif
if host_machine.system() == 'linux' or host_machine.system() == 'android'
rz_io_sources += [
'p/io_rzk_linux.c',
]
## only for shm_open
# rz_io_deps += meson.get_compiler('c').find_library('rt')
endif
if use_ptrace_wrap
rz_io_deps += dependency('ptrace-wrap', default_options: ['is_static_build=' + is_static_build.to_string()])
endif

File diff suppressed because it is too large Load diff

View file

@ -1,23 +0,0 @@
// SPDX-FileCopyrightText: 2018-2020 pancake <pancake@nopcode.org>
// SPDX-License-Identifier: LGPL-3.0-only
#define Timercmp(tvp, uvp, cmp) \
(((tvp)->tv_sec == (uvp)->tv_sec) ? ((tvp)->tv_usec cmp(uvp)->tv_usec) : ((tvp)->tv_sec cmp(uvp)->tv_sec))
#define Timeradd(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \
if ((vvp)->tv_usec >= 1000000) { \
(vvp)->tv_sec++; \
(vvp)->tv_usec -= 1000000; \
} \
} while (0)
#define Timersub(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
if ((vvp)->tv_usec < 0) { \
(vvp)->tv_sec--; \
(vvp)->tv_usec += 1000000; \
} \
} while (0)

View file

@ -1,157 +0,0 @@
// SPDX-FileCopyrightText: 2016-2018 SkUaTeR <skuater@hotmail.com>
// SPDX-FileCopyrightText: 2016-2018 panda
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_io.h>
#include <rz_lib.h>
#include <rz_types.h>
#include <rz_util.h>
#include <sys/types.h>
#if __WINDOWS__
#include "io_rzk_windows.h"
#elif defined(__linux__) && !defined(__GNU__)
#include "io_rzk_linux.h"
struct io_rzk_linux rzk_struct; // TODO: move this into desc->data
#endif
int rzk__write(RzIO *io, RzIODesc *fd, const ut8 *buf, int count) {
#if __WINDOWS__
// eprintf("writing to: 0x%"PFMT64x" len: %x\n",io->off, count);
return WriteKernelMemory(io->off, buf, count);
#elif defined(__linux__) && !defined(__GNU__)
switch (rzk_struct.beid) {
case 0:
return WriteMemory(io, fd, IOCTL_WRITE_KERNEL_MEMORY, rzk_struct.pid, io->off, buf, count);
case 1:
return WriteMemory(io, fd, IOCTL_WRITE_PROCESS_ADDR, rzk_struct.pid, io->off, buf, count);
case 2:
return WriteMemory(io, fd, IOCTL_WRITE_PHYSICAL_ADDR, rzk_struct.pid, io->off, buf, count);
default:
io->cb_printf("ERROR: Undefined beid in rzk__write.\n");
return -1;
}
#else
io->cb_printf("TODO: rzk not implemented for this plataform.\n");
return -1;
#endif
}
static int rzk__read(RzIO *io, RzIODesc *fd, ut8 *buf, int count) {
#if __WINDOWS__
return ReadKernelMemory(io->off, buf, count);
#elif defined(__linux__) && !defined(__GNU__)
switch (rzk_struct.beid) {
case 0:
return ReadMemory(io, fd, IOCTL_READ_KERNEL_MEMORY, rzk_struct.pid, io->off, buf, count);
case 1:
return ReadMemory(io, fd, IOCTL_READ_PROCESS_ADDR, rzk_struct.pid, io->off, buf, count);
case 2:
return ReadMemory(io, fd, IOCTL_READ_PHYSICAL_ADDR, rzk_struct.pid, io->off, buf, count);
default:
io->cb_printf("ERROR: Undefined beid in rzk__read.\n");
memset(buf, 0xff, count);
return count;
}
#else
io->cb_printf("TODO: rzk not implemented for this plataform.\n");
memset(buf, 0xff, count);
return count;
#endif
}
static int rzk__close(RzIODesc *fd) {
#if __WINDOWS__
if (gHandleDriver) {
CloseHandle(gHandleDriver);
StartStopService(TEXT("rzk"), TRUE);
}
#elif defined(__linux__) && !defined(__GNU__)
if (fd) {
close((int)(size_t)fd->data);
}
#else
eprintf("TODO: rzk not implemented for this plataform.\n");
#endif
return 0;
}
static ut64 rzk__lseek(RzIO *io, RzIODesc *fd, ut64 offset, int whence) {
return (!whence) ? offset : whence == 1 ? io->off + offset
: UT64_MAX;
}
static bool rzk__plugin_open(RzIO *io, const char *pathname, bool many) {
return (!strncmp(pathname, "rzk://", 6));
}
static char *rzk__system(RzIO *io, RzIODesc *fd, const char *cmd) {
if (!strcmp(cmd, "")) {
return NULL;
}
if (!strncmp(cmd, "mod", 3)) {
#if __WINDOWS__
GetSystemModules(io);
#endif
} else {
#if defined(__linux__) && !defined(__GNU__)
(void)run_ioctl_command(io, fd, cmd);
return NULL;
#else
eprintf("Try: 'R!mod'\n '.R!mod'\n");
#endif
}
return NULL;
}
static RzIODesc *rzk__open(RzIO *io, const char *pathname, int rw, int mode) {
if (!strncmp(pathname, "rzk://", 6)) {
rw |= RZ_PERM_WX;
#if __WINDOWS__
RzIOW32 *w32 = RZ_NEW0(RzIOW32);
if (Init(&pathname[6]) == FALSE) {
eprintf("rzk__open: Error cant init driver: %s\n", &pathname[6]);
free(w32);
return NULL;
}
// return rz_io_desc_new (&rz_io_plugin_rzk, -1, pathname, rw, mode, w32);
return rz_io_desc_new(io, &rz_io_plugin_rzk, pathname, rw, mode, w32);
#elif defined(__linux__) && !defined(__GNU__)
int fd = open("/dev/rzk", O_RDONLY);
if (fd == -1) {
io->cb_printf("rzk__open: Error in opening /dev/rzk.");
return NULL;
}
rzk_struct.beid = 0;
rzk_struct.pid = 0;
rzk_struct.wp = 1;
return rz_io_desc_new(io, &rz_io_plugin_rzk, pathname, rw, mode, (void *)(size_t)fd);
#else
io->cb_printf("Not supported on this platform\n");
#endif
}
return NULL;
}
RzIOPlugin rz_io_plugin_rzk = {
.name = "rzk",
.desc = "Kernel access API io",
.uris = "rzk://",
.license = "LGPL3",
.open = rzk__open,
.close = rzk__close,
.read = rzk__read,
.check = rzk__plugin_open,
.lseek = rzk__lseek,
.system = rzk__system,
.write = rzk__write,
};
#ifndef RZ_PLUGIN_INCORE
RZ_API RzLibStruct rizin_plugin = {
.type = RZ_LIB_TYPE_IO,
.data = &rz_io_plugin_rzk,
.version = RZ_VERSION
};
#endif

View file

@ -1,851 +0,0 @@
// SPDX-FileCopyrightText: 2016 Rakholiya Jenish
// SPDX-FileCopyrightText: 2016 NighterMan <jpenalbae@gmail.com>
// SPDX-FileCopyrightText: 2017-2020 pancake <pancake@nopcode.org>
// SPDX-License-Identifier: LGPL-3.0-only
#ifndef __GNU__
#include "io_rzk_linux.h"
#define fset(num, shift) ((((num) & (((ut64)1) << (shift))) == 0) ? 0 : 1)
#if __i386__ || __x86_64__
static void x86_ctrl_reg_pretty_print(RzIO *io, struct rzk_control_reg ctrl) {
io->cb_printf("CR0: 0x%" PFMT64x "\n", (ut64)ctrl.cr0);
io->cb_printf(" [*] PG: %d\n"
" [*] CD: %d\n"
" [*] NW: %d\n"
" [*] AM: %d\n"
" [*] WP: %d\n"
" [*] NE: %d\n"
" [*] ET: %d\n"
" [*] TS: %d\n"
" [*] EM: %d\n"
" [*] MP: %d\n"
" [*] PE: %d\n",
fset(ctrl.cr0, 31), fset(ctrl.cr0, 30), fset(ctrl.cr0, 29), fset(ctrl.cr0, 18),
fset(ctrl.cr0, 16), fset(ctrl.cr0, 5), fset(ctrl.cr0, 4), fset(ctrl.cr0, 3),
fset(ctrl.cr0, 2), fset(ctrl.cr0, 1), fset(ctrl.cr0, 1));
io->cb_printf("\n");
io->cb_printf("CR2: 0x%" PFMT64x "\n", (ut64)ctrl.cr2);
io->cb_printf("Page-Fault Linear Address: 0x%" PFMT64x "\n", (ut64)ctrl.cr2);
io->cb_printf("\n");
io->cb_printf("CR3: 0x%" PFMT64x "\n", (ut64)ctrl.cr3);
io->cb_printf(" [*] Page-Directory Base: 0x%" PFMT64x "\n"
" [*] PCD: %d\n"
" [*] PWT: %d\n",
(((ut64)ctrl.cr3) & 0xfffffffffffff000), fset(ctrl.cr3, 4), fset(ctrl.cr3, 3));
io->cb_printf("\n");
io->cb_printf("CR4: 0x%" PFMT64x "\n", (ut64)ctrl.cr4);
io->cb_printf(" [*] PKE: %d\n"
" [*] SMAP: %d\n"
" [*] SMEP: %d\n"
" [*] OSXSAVE: %d\n"
" [*] PCIDE: %d\n"
" [*] FSGSBASE: %d\n"
" [*] SMXE: %d\n"
" [*] VMXE: %d\n"
" [*] UMIP: %d\n"
" [*] OSXMMEXCPT: %d\n"
" [*] OSFXSR: %d\n"
" [*] PCE: %d\n"
" [*] PGE: %d\n"
" [*] MCE: %d\n"
" [*] PAE: %d\n"
" [*] PSE: %d\n"
" [*] DE: %d\n"
" [*] TSD: %d\n"
" [*] PVI: %d\n"
" [*] VME: %d\n",
fset(ctrl.cr4, 22), fset(ctrl.cr4, 21), fset(ctrl.cr4, 20), fset(ctrl.cr4, 18),
fset(ctrl.cr4, 17), fset(ctrl.cr4, 16), fset(ctrl.cr4, 14), fset(ctrl.cr4, 13),
fset(ctrl.cr4, 11), fset(ctrl.cr4, 10), fset(ctrl.cr4, 9), fset(ctrl.cr4, 8),
fset(ctrl.cr4, 7), fset(ctrl.cr4, 6), fset(ctrl.cr4, 5), fset(ctrl.cr4, 4),
fset(ctrl.cr4, 3), fset(ctrl.cr4, 2), fset(ctrl.cr4, 1), fset(ctrl.cr4, 0));
io->cb_printf("\n");
#if __x86_64__
io->cb_printf("CR8: 0x%" PFMT64x "\n", (ut64)ctrl.cr8);
io->cb_printf(" [*] TPL: %zu\n", ctrl.cr8 & 0xf);
#endif
}
#elif __arm__
static void arm_ctrl_reg_pretty_print(RzIO *io, struct rzk_control_reg ctrl) {
io->cb_printf("TTBR0: 0x%" PFMT64x "\n", (ut64)ctrl.ttbr0);
io->cb_printf(" [*] Translation table base 0: 0x%" PFMT64x "\n"
" [*] UNP/SBZ: 0x%" PFMT64x "\n"
" [*] RGN: 0x%" PFMT64x "\n"
" [*] P: %d\n"
" [*] S: %d\n"
" [*] C: %d\n",
(ut64)((ctrl.ttbr0 & (0xffffffff << (14 - (ctrl.ttbcr & 7)))) >> (14 - (ctrl.ttbcr & 7))),
(ut64)((ctrl.ttbr0 & ((1 << (13 - (ctrl.ttbcr & 7) + 1)) - (1 << 5))) >> 6),
(ut64)((ctrl.ttbr0 & 0x18) >> 3), fset(ctrl.ttbr0, 2), fset(ctrl.ttbr0, 1), fset(ctrl.ttbr0, 0));
io->cb_printf("\n");
io->cb_printf("TTBR1: 0x%" PFMT64x "\n", (ut64)ctrl.ttbr1);
io->cb_printf(" [*] Translation table base 1: 0x%" PFMT64x "\n"
" [*] UNP/SBZ: 0x%" PFMT64x "\n"
" [*] RGN: 0x%" PFMT64x "\n"
" [*] P: %d\n"
" [*] S: %d\n"
" [*] C: %d\n",
(ut64)((ctrl.ttbr1 & (0xffffffff << 14)) >> 14), (ut64)((ctrl.ttbr1 & ((1 << (13 + 1)) - (1 << 5))) >> 6),
(ut64)((ctrl.ttbr1 & 0x18) >> 3), fset(ctrl.ttbr1, 2), fset(ctrl.ttbr1, 1), fset(ctrl.ttbr1, 0));
io->cb_printf("\n");
io->cb_printf("TTBCR: 0x%" PFMT64x "\n", (ut64)ctrl.ttbcr);
io->cb_printf(" [*] N: %d\n", ctrl.ttbcr & 7);
io->cb_printf("\n");
io->cb_printf("C1: 0x%" PFMT64x "\n", (ut64)ctrl.c1);
io->cb_printf(" [*] AFE: %d\n"
" [*] TRE: %d\n"
" [*] EE: %d\n"
" [*] VE: %d\n"
" [*] XP: %d\n"
" [*] U: %d\n"
" [*] FI: %d\n"
" [*] IT: %d\n"
" [*] DT: %d\n"
" [*] L4: %d\n"
" [*] RR: %d\n"
" [*] V: %d\n"
" [*] I: %d\n"
" [*] Z: %d\n"
" [*] F: %d\n"
" [*] R: %d\n"
" [*] S: %d\n"
" [*] B: %d\n"
" [*] W: %d\n"
" [*] C: %d\n"
" [*] A: %d\n"
" [*] M: %d\n",
fset(ctrl.c1, 29), fset(ctrl.c1, 28), fset(ctrl.c1, 25), fset(ctrl.c1, 24),
fset(ctrl.c1, 23), fset(ctrl.c1, 22), fset(ctrl.c1, 21), fset(ctrl.c1, 18),
fset(ctrl.c1, 16), fset(ctrl.c1, 15), fset(ctrl.c1, 14), fset(ctrl.c1, 13),
fset(ctrl.c1, 12), fset(ctrl.c1, 11), fset(ctrl.c1, 10), fset(ctrl.c1, 9),
fset(ctrl.c1, 8), fset(ctrl.c1, 7), fset(ctrl.c1, 3), fset(ctrl.c1, 2),
fset(ctrl.c1, 1), fset(ctrl.c1, 0));
io->cb_printf("\n");
io->cb_printf("C3: 0x%" PFMT64x "\n", (ut64)ctrl.c3);
}
#elif __arm64__ || __aarch64__
/*ARM Cortex-A57 and ARM Cortex-A72. This might show some wrong values for other processor.*/
static void arm64_ctrl_reg_pretty_print(RzIO *io, struct rzk_control_reg ctrl) {
io->cb_printf("SCTLR_EL1: 0x%" PFMTSZx "\n", ctrl.sctlr_el1);
io->cb_printf(" [*] UCI: %d\n"
" [*] EE: %d\n"
" [*] E0E: %d\n"
" [*] WXN: %d\n"
" [*] nTWE: %d\n"
" [*] nTWI: %d\n"
" [*] UCT: %d\n"
" [*] DZE: %d\n"
" [*] I: %d\n"
" [*] UMA: %d\n"
" [*] SED: %d\n"
" [*] ITD: %d\n"
" [*] THEE: %d\n"
" [*] CP15BEN: %d\n"
" [*] SAO: %d\n"
" [*] SA: %d\n"
" [*] C: %d\n"
" [*] A: %d\n"
" [*] M: %d\n",
fset(ctrl.sctlr_el1, 26), fset(ctrl.sctlr_el1, 25), fset(ctrl.sctlr_el1, 24), fset(ctrl.sctlr_el1, 19),
fset(ctrl.sctlr_el1, 18), fset(ctrl.sctlr_el1, 16), fset(ctrl.sctlr_el1, 15), fset(ctrl.sctlr_el1, 14),
fset(ctrl.sctlr_el1, 12), fset(ctrl.sctlr_el1, 9), fset(ctrl.sctlr_el1, 8), fset(ctrl.sctlr_el1, 7),
fset(ctrl.sctlr_el1, 6), fset(ctrl.sctlr_el1, 5), fset(ctrl.sctlr_el1, 4), fset(ctrl.sctlr_el1, 3),
fset(ctrl.sctlr_el1, 2), fset(ctrl.sctlr_el1, 1), fset(ctrl.sctlr_el1, 0));
io->cb_printf("\n");
io->cb_printf("TTBR0_EL1: 0x%" PFMTSZx "\n", ctrl.ttbr0_el1);
io->cb_printf(" [*] ASID [63:48]: 0x%" PFMT64x "\n"
" [*] BADDR [47:10]: 0x%" PFMT64x "\n",
(ctrl.ttbr0_el1 & 0xffff000000000000LLU) >> 48, (ctrl.ttbr0_el1 & ((((ut64)1) << (47 + 1)) - (1 << 10))) >> 10);
io->cb_printf("\n");
io->cb_printf("TTBR1_EL1: 0x%" PFMTSZx "\n", ctrl.ttbr1_el1);
io->cb_printf(" [*] ASID [63:48]: 0x%" PFMT64x "\n"
" [*] BADDR [47:10]: 0x%" PFMT64x "\n",
(ctrl.ttbr1_el1 & 0xffff000000000000LLU) >> 48, (ctrl.ttbr1_el1 & ((((ut64)1) << (47 + 1)) - (1 << 10))) >> 10);
io->cb_printf("\n");
io->cb_printf("TCR_EL1: 0x%" PFMTSZx "\n", ctrl.tcr_el1);
io->cb_printf(" [*] TBI1: %d\n"
" [*] TBI0: %d\n"
" [*] AS: %d\n"
" [*] IPS: %d\n"
" [*] TG1: %d\n"
" [*] SH1: %d\n"
" [*] ORGN1: %d\n"
" [*] IRGN1: %d\n"
" [*] EPD1: %d\n"
" [*] A1: %d\n"
" [*] T1SZ: %d\n"
" [*] TG0: %d\n"
" [*] SH0: %d\n"
" [*] ORGN0: %d\n"
" [*] IRGN0: %d\n"
" [*] EPD0: %d\n"
" [*] T0SZ: %d\n",
fset(ctrl.tcr_el1, 38), fset(ctrl.tcr_el1, 37), fset(ctrl.tcr_el1, 36),
(int)(ctrl.tcr_el1 >> 32) & 0x7, fset(ctrl.tcr_el1, 30), (int)(ctrl.tcr_el1 >> 28) & 0x3,
(int)(ctrl.tcr_el1 >> 26) & 0x3, (int)(ctrl.tcr_el1 >> 24) & 0x3, fset(ctrl.tcr_el1, 23),
fset(ctrl.tcr_el1, 22), (int)(ctrl.tcr_el1 >> 16) & 0x3f, fset(ctrl.tcr_el1, 14),
(int)(ctrl.tcr_el1 >> 12) & 0x3, (int)(ctrl.tcr_el1 >> 10) & 0x3, (int)(ctrl.tcr_el1 >> 8) & 0x3,
fset(ctrl.tcr_el1, 7), (int)ctrl.tcr_el1 & 0x3f);
}
#endif
static const char *getargpos(const char *buf, int pos) {
int i;
for (i = 0; buf && i < pos; i++) {
buf = strchr(buf, ' ');
if (!buf) {
break;
}
buf = rz_str_ichr((char *)buf, ' ');
}
return buf;
}
static size_t getvalue(const char *buf, int pos) {
size_t ret;
buf = getargpos(buf, pos);
if (buf) {
ret = strtoul(buf, 0, 0);
} else {
ret = -1;
}
return ret;
}
static void print_help(RzIO *io, char *cmd, int p_usage) {
int i = 0;
int cmd_len = cmd ? strlen(cmd) : 0;
const char *usage = "Usage: \\[MprRw][lpP] [args...]";
const char *help_msg[] = {
"\\dm Print kernel memory map (or process if rzk.io==1)",
"\\dr Print control registers",
"\\dR Print control registers in detailed mode",
"\\dp [pid] Print current selected pid or change it",
"\\e rzk.io=[012] Read/Write from 0: Linear, 1: Process, 2: Physical addresses"
};
const char *help_msg_old[] = {
"\\M Print kernel memory map",
"\\b beid [pid] Change rzk backend. pid is required when beid is 1.",
" 0: linear address; 1: process address; 2: physical address",
"\\p pid Print process information",
"\\rl addr len Read from linear address",
"\\rp pid addr len Read from process address",
"\\rP addr len Read physical address",
"\\R[p] Print control registers. Use R!Rp for detailed description",
"\\wl[x] addr input Write at linear address. Use R!wlx for input in hex",
"\\wp[x] pid addr input Write at process address. Use R!wpx for input in hex",
"\\wP[x] addr input Write at physical address. Use R!wPx for input in hex",
"\\W 1|0 Honor arch write protect (1 enable WP, 0 disable WP)"
};
if (p_usage) {
io->cb_printf("%s\n", usage);
}
for (i = 0; i < (sizeof(help_msg) / sizeof(char *)); i++) {
if (!cmd || !strncmp(cmd, help_msg[i] + 1, cmd_len)) {
io->cb_printf("%s\n", help_msg[i]);
}
}
io->cb_printf("\nOld Commands: (deprecated)\n");
for (i = 0; i < (sizeof(help_msg_old) / sizeof(char *)); i++) {
if (!cmd || !strncmp(cmd, help_msg_old[i] + 1, cmd_len)) {
io->cb_printf("%s\n", help_msg_old[i]);
}
}
}
int ReadMemory(RzIO *io, RzIODesc *iodesc, int ioctl_n, size_t pid, size_t address, ut8 *buf, int len) {
int ret = -1;
int pagesize, newlen;
ut64 pageaddr, offset;
bool flag = 0;
ut8 garbage;
if (iodesc && iodesc->data > 0 && buf) {
struct rzk_data data;
data.pid = pid;
data.addr = address;
data.len = len;
data.buff = (ut8 *)calloc(len + 1, 1);
if (!data.buff) {
return -1;
}
ret = ioctl((int)(size_t)iodesc->data, ioctl_n, &data);
if (!ret) {
memcpy(buf, data.buff, len);
ret = len;
} else {
garbage = 0xff;
flag = 0;
offset = 0;
pagesize = getpagesize();
pageaddr = address + pagesize;
pageaddr -= (pageaddr % pagesize);
if ((len - (int)(pageaddr - address)) > 0) {
data.len = pageaddr - address;
ret = ioctl((int)(size_t)iodesc->data, ioctl_n, &data);
if (!ret) {
memcpy(buf + offset, data.buff, pageaddr - address);
flag = 1;
} else {
memset(buf + offset, garbage, pageaddr - address);
}
offset = pageaddr - address;
newlen = len - offset;
while (newlen >= pagesize) {
data.addr = pageaddr;
data.len = pagesize;
ret = ioctl((int)(size_t)iodesc->data, ioctl_n, &data);
if (!ret) {
memcpy(buf + offset, data.buff, pagesize);
flag = 1;
} else {
memset(buf + offset, garbage, pagesize);
}
pageaddr += pagesize;
offset += pagesize;
newlen -= pagesize;
}
data.addr = pageaddr;
data.len = newlen;
ret = ioctl((int)(size_t)iodesc->data, ioctl_n, &data);
if (!ret) {
memcpy(buf + offset, data.buff, newlen);
flag = 1;
} else {
memset(buf + offset, garbage, newlen);
}
}
ret = flag ? len : -1;
}
free(data.buff);
} else if (!buf) {
io->cb_printf("Invalid input buffer.\n");
} else {
io->cb_printf("IOCTL device not initialized.\n");
}
return ret;
}
int WriteMemory(RzIO *io, RzIODesc *iodesc, int ioctl_n, size_t pid, ut64 address, const ut8 *buf, int len) {
int ret = -1;
if (iodesc && iodesc->data > 0 && buf) {
struct rzk_data data;
data.pid = pid;
data.addr = address;
data.len = len;
data.buff = (ut8 *)calloc(len + 1, 1);
data.wp = rzk_struct.wp;
if (!data.buff) {
return -1;
}
memcpy(data.buff, buf, len);
ret = ioctl((int)(size_t)iodesc->data, ioctl_n, &data);
if (!ret) {
ret = len;
} else {
io->cb_printf("Write failed. ioctl err: %s\n", strerror(errno));
ret = -1;
}
free(data.buff);
} else if (!buf) {
io->cb_printf("Invalid input buffer.\n");
} else {
io->cb_printf("IOCTL device not initialized.\n");
}
return ret;
}
int run_old_command(RzIO *io, RzIODesc *iodesc, const char *buf) {
int ret, inphex, ioctl_n;
size_t pid, addr, len;
ut8 *databuf = NULL;
switch (*buf) {
case 'W': {
if (buf[1] != ' ') {
io->cb_printf("Write Protect: %d\n", rzk_struct.wp);
io->cb_printf("Usage:\n");
print_help(io, "W", 0);
break;
}
int wp = getvalue(buf, 1);
if (wp < 0 || wp > 1) {
io->cb_printf("Invalid usage of W\n");
print_help(io, "W", 0);
break;
}
rzk_struct.wp = (ut8)wp;
} break;
case 'b': {
char *cmd = NULL;
if (buf[1] != ' ') {
io->cb_printf("beid: %d\n", rzk_struct.beid);
io->cb_printf("pid: %d\n", rzk_struct.pid);
io->cb_printf("Usage:\n");
print_help(io, "b", 0);
goto end;
}
int beid = getvalue(buf, 1);
int pid = getvalue(buf, 2);
if (beid < 0 || beid > 2) {
io->cb_printf("Invalid usage of b\n");
print_help(io, "b", 0);
break;
}
if (beid == 1 && pid < 0) {
io->cb_printf("Invalid pid read.\n");
print_help(io, "b", 0);
break;
}
rzk_struct.beid = beid;
rzk_struct.pid = (beid == 1) ? pid : 0;
cmd = (char *)malloc(27);
if (!cmd) {
io->cb_printf("io_rzk_linux : Malloc failed. Seeking to 0x0\n");
io->corebind.cmd(io->corebind.core, "s 0");
} else {
sprintf(cmd, "s 0x%" PFMT64x, io->off);
io->corebind.cmd(io->corebind.core, cmd);
free(cmd);
}
} break;
case 'r': {
RzPrint *print = rz_print_new();
switch (buf[1]) {
case 'l':
// read linear address
// R! rl addr len
if (buf[2] != ' ') {
print_help(io, "rl", 0);
goto end;
}
pid = 0;
addr = getvalue(buf, 1);
len = getvalue(buf, 2);
if (addr == -1 || len == -1) {
io->cb_printf("Invalid number of arguments.\n");
print_help(io, "rl", 0);
goto end;
}
ioctl_n = IOCTL_READ_KERNEL_MEMORY;
break;
case 'p':
// read process address
// R! rp pid address len
if (buf[2] != ' ') {
print_help(io, "rp", 0);
goto end;
}
pid = getvalue(buf, 1);
addr = getvalue(buf, 2);
len = getvalue(buf, 3);
if (pid == -1 || addr == -1 || len == -1) {
io->cb_printf("Invalid number of arguments.\n");
print_help(io, "rp", 0);
goto end;
;
}
ioctl_n = IOCTL_READ_PROCESS_ADDR;
break;
case 'P':
// read physical address
// R! rP address len
if (buf[2] != ' ') {
print_help(io, "rP", 0);
goto end;
}
pid = 0;
addr = getvalue(buf, 1);
len = getvalue(buf, 2);
if (addr == -1 || len == -1) {
io->cb_printf("Invalid number of arguments.\n");
print_help(io, "rP", 0);
goto end;
}
ioctl_n = IOCTL_READ_PHYSICAL_ADDR;
break;
default:
print_help(io, "r", 0);
rz_print_free(print);
goto end;
}
databuf = (ut8 *)calloc(len + 1, 1);
if (databuf) {
ret = ReadMemory(io, iodesc, ioctl_n, pid, addr, databuf, len);
if (ret > 0) {
char *dump = rz_print_hexdump_str(print, addr, (const ut8 *)databuf, ret, 16, 1, 1);
rz_cons_print(dump);
free(dump);
}
} else {
io->cb_printf("Failed to allocate buffer\n");
}
rz_print_free(print);
} break;
case 'w':
inphex = (buf[2] == 'x') ? 1 : 0;
switch (buf[1]) {
case 'l':
// write linear address
// R! wl addr str
if ((inphex && buf[3] != ' ') || (!inphex && buf[2] != ' ')) {
print_help(io, "wl", 0);
goto end;
}
pid = 0;
addr = getvalue(buf, 1);
buf = getargpos(buf, 2);
if (addr == -1 || !buf) {
io->cb_printf("Invalid number of arguments.\n");
print_help(io, "wl", 0);
goto end;
}
ioctl_n = IOCTL_WRITE_KERNEL_MEMORY;
break;
case 'p':
// write process address
// R! wp pid address str
if ((inphex && buf[3] != ' ') || (!inphex && buf[2] != ' ')) {
print_help(io, "wp", 0);
goto end;
}
pid = getvalue(buf, 1);
addr = getvalue(buf, 2);
buf = getargpos(buf, 3);
if (pid == -1 || addr == -1 || !buf) {
io->cb_printf("Invalid number of arguments.\n");
print_help(io, "wp", 0);
goto end;
}
ioctl_n = IOCTL_WRITE_PROCESS_ADDR;
break;
case 'P':
// write physical address
// R! wP address str
if ((inphex && buf[3] != ' ') || (!inphex && buf[2] != ' ')) {
print_help(io, "wP", 0);
goto end;
}
pid = 0;
addr = getvalue(buf, 1);
buf = getargpos(buf, 2);
if (addr == -1 || !buf) {
io->cb_printf("Invalid number of arguments.\n");
print_help(io, "wP", 0);
goto end;
}
ioctl_n = IOCTL_WRITE_PHYSICAL_ADDR;
break;
default:
print_help(io, "w", 0);
goto end;
}
// coverity says this cant happen, but it doesnt hurts to add a check
if (!buf) {
break;
}
len = strlen(buf);
databuf = (ut8 *)calloc(len + 1, 1);
if (databuf) {
if (inphex) {
len = rz_hex_str2bin(buf, databuf);
} else {
memcpy(databuf, buf, strlen(buf) + 1);
len = rz_str_unescape((char *)databuf);
}
WriteMemory(io, iodesc, ioctl_n, pid, addr, (const ut8 *)databuf, len);
} else {
eprintf("Failed to allocate buffer.\n");
}
break;
case 'M': {
// Print kernel memory map.
// R! M
int i, j;
struct rzk_kernel_maps map_data;
struct rzk_kernel_map_info *info;
long page_size = sysconf(_SC_PAGESIZE);
ioctl_n = IOCTL_GET_KERNEL_MAP;
ret = ioctl((int)(size_t)iodesc->data, ioctl_n, &map_data);
if (ret < 0) {
io->cb_printf("ioctl err: %s\n", strerror(errno));
break;
}
io->cb_printf("map_data.size: %d, map_data.n_entries: %d\n", map_data.size, map_data.n_entries);
info = mmap(0, map_data.size, PROT_READ, MAP_SHARED, (int)(size_t)iodesc->data, 0);
if (info == MAP_FAILED) {
io->cb_printf("mmap err: %s\n", strerror(errno));
break;
}
for (i = 0; i < map_data.n_entries; i++) {
struct rzk_kernel_map_info *in = &info[i];
io->cb_printf("start_addr: 0x%" PFMT64x "\n", (ut64)in->start_addr);
io->cb_printf("end_addr: 0x%" PFMT64x "\n", (ut64)in->end_addr);
io->cb_printf("n_pages: %d (%ld Kbytes)\n", in->n_pages, (in->n_pages * page_size) / 1024);
io->cb_printf("n_phys_addr: %d\n", in->n_phys_addr);
for (j = 0; j < in->n_phys_addr; j++) {
io->cb_printf("\tphys_addr: 0x%" PFMT64x "\n", (ut64)in->phys_addr[j]);
}
io->cb_printf("\n");
}
if (munmap(info, map_data.size) == -1) {
io->cb_printf("munmap failed.\n");
}
} break;
case 'R': {
// Read control registers
// R! R[p]
struct rzk_control_reg reg_data;
ioctl_n = IOCTL_READ_CONTROL_REG;
ret = ioctl((int)(size_t)iodesc->data, ioctl_n, &reg_data);
if (ret) {
io->cb_printf("ioctl err: %s\n", strerror(errno));
break;
}
#if __i386__ || __x86_64__
// Print cr1 as null instead of random value from kernel land.
reg_data.cr1 = 0;
if (buf[1] != 0 && buf[1] == 'p') {
x86_ctrl_reg_pretty_print(io, reg_data);
} else {
io->cb_printf("cr0 = 0x%" PFMT64x "\n", (ut64)reg_data.cr0);
io->cb_printf("cr1 = 0x%" PFMT64x "\n", (ut64)reg_data.cr1);
io->cb_printf("cr2 = 0x%" PFMT64x "\n", (ut64)reg_data.cr2);
io->cb_printf("cr3 = 0x%" PFMT64x "\n", (ut64)reg_data.cr3);
io->cb_printf("cr4 = 0x%" PFMT64x "\n", (ut64)reg_data.cr4);
#if __x86_64__
io->cb_printf("cr8 = 0x%" PFMT64x "\n", (ut64)reg_data.cr8);
#endif
}
#elif __arm__
if (buf[1] != 0 && buf[1] == 'p') {
arm_ctrl_reg_pretty_print(io, reg_data);
} else {
io->cb_printf("ttbr0 = 0x%" PFMT64x "\n", (ut64)reg_data.ttbr0);
io->cb_printf("ttbr1 = 0x%" PFMT64x "\n", (ut64)reg_data.ttbr1);
io->cb_printf("ttbcr = 0x%" PFMT64x "\n", (ut64)reg_data.ttbcr);
io->cb_printf("c1 = 0x%" PFMT64x "\n", (ut64)reg_data.c1);
io->cb_printf("c3 = 0x%" PFMT64x "\n", (ut64)reg_data.c3);
}
#elif __arm64__ || __aarch64__
if (buf[1] != 0 && buf[1] == 'p') {
arm64_ctrl_reg_pretty_print(io, reg_data);
} else {
io->cb_printf("sctlr_el1 = 0x%" PFMT64x "\n", (ut64)reg_data.sctlr_el1);
io->cb_printf("ttbr0_el1 = 0x%" PFMT64x "\n", (ut64)reg_data.ttbr0_el1);
io->cb_printf("ttbr1_el1 = 0x%" PFMT64x "\n", (ut64)reg_data.ttbr1_el1);
io->cb_printf("tcr_el1 = 0x%" PFMT64x "\n", (ut64)reg_data.tcr_el1);
}
#endif
} break;
case 'p': {
// Print process info
// R! p pid
ut64 i;
ut64 nextstart;
ut64 buffsize;
bool fflag = 0;
struct rzk_proc_info proc_data;
if (*(buf + 1) == '*') {
fflag = 1;
}
switch (*(buf + 1)) {
case '*':
fflag = 1;
if (*(buf + 2) != ' ') {
print_help(io, "p*", 0);
goto end;
}
break;
case ' ':
break;
default:
print_help(io, "p", 0);
goto end;
}
pid = getvalue(buf, 1);
if (pid == -1) {
io->cb_printf("Invalid number of arguments.\n");
print_help(io, "p", 0);
break;
}
proc_data.pid = pid;
ioctl_n = IOCTL_PRINT_PROC_INFO;
ret = ioctl((int)(size_t)iodesc->data, ioctl_n, &proc_data);
if (ret) {
io->cb_printf("ioctl err: %s\n", strerror(errno));
break;
}
buffsize = (ut64)(sizeof(proc_data.vmareastruct) / sizeof(proc_data.vmareastruct[0]));
if (fflag) {
int j = 0;
for (i = 0; i + 1 < buffsize;) {
nextstart = 0;
if (i + 7 < buffsize) {
nextstart = i + 7 + (strlen((const char *)&(proc_data.vmareastruct[i + 7])) - 1 + sizeof(size_t)) / sizeof(size_t);
}
if (!proc_data.vmareastruct[i] && (i + 1 < buffsize) &&
!proc_data.vmareastruct[i + 1] &&
nextstart > 0 && nextstart - 1 < buffsize) {
break;
}
io->cb_printf("f pid.%d.%s.%d.start @ 0x%" PFMT64x "\n", proc_data.pid, (char *)&(proc_data.vmareastruct[i + 7]), j, (ut64)proc_data.vmareastruct[i]);
io->cb_printf("f pid.%d.%s.%d.end @ 0x%" PFMT64x "\n", proc_data.pid, (char *)&(proc_data.vmareastruct[i + 7]), j, (ut64)proc_data.vmareastruct[i + 1]);
j += 1;
i = nextstart;
}
io->cb_printf("f pid.%d.task_struct @ 0x%08zu\n", proc_data.pid, proc_data.task);
} else {
io->cb_printf("pid = %d\nprocess name = %s\n", proc_data.pid, proc_data.comm);
io->cb_printf("task_struct = 0x%08zu\n", proc_data.task);
for (i = 0; i < buffsize;) {
nextstart = 0;
if (i + 7 < buffsize) {
nextstart = i + 7 + (strlen((const char *)&(proc_data.vmareastruct[i + 7])) - 1 + sizeof(size_t)) / sizeof(size_t);
}
if (!proc_data.vmareastruct[i] && !proc_data.vmareastruct[i + 1] &&
nextstart > 0 && nextstart - 1 < buffsize) {
break;
}
io->cb_printf("0x%08" PFMT64x " - 0x%08" PFMT64x " %c%c%c%c 0x%08" PFMT64x " %02zu:%02zu %-8" PFMT64u "",
(ut64)proc_data.vmareastruct[i], (ut64)proc_data.vmareastruct[i + 1],
proc_data.vmareastruct[i + 2] & VM_READ ? 'r' : '-',
proc_data.vmareastruct[i + 2] & VM_WRITE ? 'w' : '-',
proc_data.vmareastruct[i + 2] & VM_EXEC ? 'x' : '-',
proc_data.vmareastruct[i + 2] & VM_MAYSHARE ? 's' : 'p',
(ut64)proc_data.vmareastruct[i + 3], proc_data.vmareastruct[i + 4],
proc_data.vmareastruct[i + 5], (ut64)proc_data.vmareastruct[i + 6]);
io->cb_printf("\t%s\n", (char *)&(proc_data.vmareastruct[i + 7]));
i = nextstart;
}
io->cb_printf("STACK BASE ADDRESS = 0x%zx\n", proc_data.stack);
}
} break;
default: {
print_help(io, NULL, 1);
}
}
end:
free(databuf);
return 0;
}
int run_new_command(RzIO *io, RzIODesc *iodesc, const char *buf) {
if (rz_str_startswith(buf, "dm")) {
if (buf[2] == ' ') {
// use \p pid
char *cmd = rz_str_newf("p %d", atoi(buf + 2));
run_old_command(io, iodesc, cmd);
free(cmd);
} else if (rzk_struct.beid == 1) {
// use \p pid
char *cmd = rz_str_newf("p %d", rzk_struct.pid);
run_old_command(io, iodesc, cmd);
free(cmd);
} else {
// use \M
run_old_command(io, iodesc, "M");
}
return 1;
}
if (rz_str_startswith(buf, "dr")) {
run_old_command(io, iodesc, "R");
return 1;
}
if (rz_str_startswith(buf, "dR")) {
run_old_command(io, iodesc, "Rp");
return 1;
}
if (rz_str_startswith(buf, "dp")) {
if (buf[2] == ' ') {
rzk_struct.pid = atoi(buf + 3);
} else {
io->cb_printf("%d\n", rzk_struct.pid);
}
return 1;
}
if (rz_str_startswith(buf, "e rzk.io")) {
if (strchr(buf, '?')) {
io->cb_printf("0: Linear memory\n");
io->cb_printf("1: Process memory\n");
io->cb_printf("2: Physical memory\n");
return 1;
}
const char *eq = strchr(buf, '=');
if (eq) {
int v = atoi(eq + 1);
int p = rzk_struct.pid;
char *cmd = rz_str_newf("b %d %d", v, p);
run_old_command(io, iodesc, cmd);
free(cmd);
} else {
run_new_command(io, iodesc, "dp");
}
return 1;
}
if (rz_str_startswith(buf, "e rzk.wp")) {
if (strchr(buf, '?')) {
io->cb_printf("<bool> enable write protection (disabled by default)\n");
return 1;
}
const char *eq = strchr(buf, '=');
if (eq) {
int v = atoi(eq + 1);
rzk_struct.wp = (ut8)v;
} else {
io->cb_printf("%s", rz_str_bool(rzk_struct.wp));
}
return 1;
}
return 0;
}
int run_ioctl_command(RzIO *io, RzIODesc *iodesc, const char *buf) {
buf = rz_str_ichr((char *)buf, ' ');
if (!run_new_command(io, iodesc, buf)) {
return run_old_command(io, iodesc, buf);
}
return 0;
}
#endif

View file

@ -1,131 +0,0 @@
// SPDX-FileCopyrightText: 2016 Rakholiya Jenish
// SPDX-FileCopyrightText: 2016 NighterMan <jpenalbae@gmail.com>
// SPDX-FileCopyrightText: 2017-2020 pancake <pancake@nopcode.org>
// SPDX-License-Identifier: LGPL-3.0-only
#ifndef __IO_RZK_LINUX_H__
#define __IO_RZK_LINUX_H__
#include <rz_io.h>
#include <rz_lib.h>
#include <rz_types.h>
#include <rz_util.h>
#include <rz_util/rz_print.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <errno.h>
#define MAX_PHYS_ADDR 128
/*
* Backend Id (be_id):
* 0: Linear Address
* 1: Process Address
* 2: Physical Address
*/
struct io_rzk_linux {
int beid;
int pid;
ut8 wp;
};
struct rzk_data {
int pid;
size_t addr;
size_t len;
ut8 *buff;
ut8 wp;
};
struct rzk_kernel_map_info {
size_t start_addr;
size_t end_addr;
size_t phys_addr[MAX_PHYS_ADDR];
int n_pages;
int n_phys_addr;
};
struct rzk_kernel_maps {
int n_entries;
int size;
};
struct rzk_control_reg {
#if __x86_64__ || __i386__
size_t cr0;
size_t cr1;
size_t cr2;
size_t cr3;
size_t cr4;
#if __x86_64__
size_t cr8;
#endif
#elif __arm__
size_t ttbr0;
size_t ttbr1;
size_t ttbcr;
size_t c1;
size_t c3;
#elif __arm64__ || __aarch64__
size_t sctlr_el1;
size_t ttbr0_el1;
size_t ttbr1_el1;
size_t tcr_el1;
#endif
};
struct rzk_proc_info {
int pid;
char comm[16];
size_t vmareastruct[4096];
size_t stack;
size_t task;
};
#define RZ_TYPE 0x69
#define READ_KERNEL_MEMORY 0x1
#define WRITE_KERNEL_MEMORY 0x2
#define READ_PROCESS_ADDR 0x3
#define WRITE_PROCESS_ADDR 0X4
#define READ_PHYSICAL_ADDR 0x5
#define WRITE_PHYSICAL_ADDR 0x6
#define GET_KERNEL_MAP 0x7
#define READ_CONTROL_REG 0x8
#define PRINT_PROC_INFO 0x9
#ifdef _IOC_TYPECHECK
#define rzk_data_size struct rzk_data
#define rzk_kernel_maps_size struct rzk_kernel_maps
#define rzk_control_reg_size struct rzk_control_reg
#define rzk_proc_info_size struct rzk_proc_info
#else
#define rzk_data_size sizeof(struct rzk_data)
#define rzk_kernel_maps_size sizeof(struct rzk_kernel_maps)
#define rzk_control_reg_size sizeof(struct rzk_control_reg)
#define rzk_proc_info_size sizeof(struct rzk_proc_info)
#endif
#define IOCTL_READ_KERNEL_MEMORY _IOR(RZ_TYPE, READ_KERNEL_MEMORY, rzk_data_size)
#define IOCTL_WRITE_KERNEL_MEMORY _IOR(RZ_TYPE, WRITE_KERNEL_MEMORY, rzk_data_size)
#define IOCTL_READ_PROCESS_ADDR _IOR(RZ_TYPE, READ_PROCESS_ADDR, rzk_data_size)
#define IOCTL_WRITE_PROCESS_ADDR _IOR(RZ_TYPE, WRITE_PROCESS_ADDR, rzk_data_size)
#define IOCTL_READ_PHYSICAL_ADDR _IOR(RZ_TYPE, READ_PHYSICAL_ADDR, rzk_data_size)
#define IOCTL_WRITE_PHYSICAL_ADDR _IOR(RZ_TYPE, WRITE_PHYSICAL_ADDR, rzk_data_size)
#define IOCTL_GET_KERNEL_MAP _IOR(RZ_TYPE, GET_KERNEL_MAP, rzk_kernel_maps_size)
#define IOCTL_READ_CONTROL_REG _IOR(RZ_TYPE, READ_CONTROL_REG, rzk_control_reg_size)
#define IOCTL_PRINT_PROC_INFO _IOR(RZ_TYPE, PRINT_PROC_INFO, rzk_data_size) // Bad hack. Incorrect size, but since module does not use _IOC_SIZE, it won't matter if size parameter is wrong
#define VM_READ 0x1
#define VM_WRITE 0x2
#define VM_EXEC 0x4
#define VM_MAYSHARE 0x80
extern struct io_rzk_linux rzk_struct;
int ReadMemory(RzIO *io, RzIODesc *iodesc, int ioctl_n, size_t pid, size_t address, ut8 *buf, int len);
int WriteMemory(RzIO *io, RzIODesc *iodesc, int ioctl_n, size_t pid, ut64 address, const ut8 *buf, int len);
int run_ioctl_command(RzIO *io, RzIODesc *iodesc, const char *buf);
#endif

View file

@ -1,194 +0,0 @@
// SPDX-FileCopyrightText: 2016 skuater <skuater@hotmail.com>
// SPDX-FileCopyrightText: 2016 Rakholiya Jenish
// SPDX-FileCopyrightText: 2017 Jose Diaz <josediazplay@gmail.com>
// SPDX-License-Identifier: LGPL-3.0-only
#include "io_rzk_windows.h"
HANDLE gHandleDriver = NULL;
static BOOL InstallService(const char *rutaDriver, LPCTSTR lpServiceName, LPCTSTR lpDisplayName) {
HANDLE hService;
BOOL ret = FALSE;
HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
if (hSCManager) {
LPTSTR rutaDriver_ = rz_sys_conv_utf8_to_win(rutaDriver);
hService = CreateService(hSCManager, lpServiceName, lpDisplayName, SERVICE_START | DELETE | SERVICE_STOP, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, rutaDriver_, NULL, NULL, NULL, NULL, NULL);
if (hService) {
CloseServiceHandle(hService);
ret = TRUE;
}
free(rutaDriver_);
CloseServiceHandle(hSCManager);
}
return ret;
}
static BOOL RemoveService(LPCTSTR lpServiceName) {
HANDLE hService;
BOOL ret = FALSE;
HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
if (hSCManager) {
hService = OpenService(hSCManager, lpServiceName, SERVICE_START | DELETE | SERVICE_STOP);
if (hService) {
DeleteService(hService);
CloseServiceHandle(hService);
ret = TRUE;
}
CloseServiceHandle(hSCManager);
}
return ret;
}
BOOL StartStopService(LPCTSTR lpServiceName, BOOL bStop) {
HANDLE hSCManager;
HANDLE hService;
SERVICE_STATUS ssStatus;
BOOL ret = FALSE;
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
if (hSCManager) {
hService = OpenService(hSCManager, lpServiceName, SERVICE_START | DELETE | SERVICE_STOP);
if (hService) {
if (!bStop) {
if (StartService(hService, 0, NULL)) {
eprintf("Service started [OK]\n");
ret = TRUE;
} else {
eprintf("Service started [FAIL]\n");
}
} else {
if (ControlService(hService, SERVICE_CONTROL_STOP, &ssStatus)) {
eprintf("Service Stopped [OK]\n");
ret = TRUE;
} else {
eprintf("Service Stopped [FAIL]\n");
}
}
CloseServiceHandle(hService);
DeleteService(hService);
}
CloseServiceHandle(hSCManager);
}
return ret;
}
static BOOL InitDriver(VOID) {
const int genericFlags = GENERIC_READ | GENERIC_WRITE;
const int shareFlags = FILE_SHARE_READ | FILE_SHARE_WRITE;
gHandleDriver = CreateFile(TEXT(RZK_DEVICE), genericFlags, shareFlags,
NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_DIRECTORY, 0);
return (gHandleDriver != INVALID_HANDLE_VALUE);
}
static const char *GetFileName(const char *path) {
const char *pfile = path + strlen(path);
for (; pfile > path; pfile--) {
if ((*pfile == '\\') || (*pfile == '/')) {
pfile++;
break;
}
}
return pfile;
}
int GetSystemModules(RzIO *io) {
DWORD bRead = 0;
int i;
LPVOID lpBufMods = NULL;
int bufmodsize = 1024 * 1024;
if (gHandleDriver) {
if (!(lpBufMods = malloc(bufmodsize))) {
eprintf("[rzk] GetSystemModules: Error can't allocate %i bytes of memory.\n", bufmodsize);
return -1;
}
if (DeviceIoControl(gHandleDriver, IOCTL_GET_SYSTEM_MODULES, lpBufMods, bufmodsize, lpBufMods, bufmodsize, &bRead, NULL)) {
PRTL_PROCESS_MODULES pm = (PRTL_PROCESS_MODULES)lpBufMods;
PRTL_PROCESS_MODULE_INFORMATION pMod = pm->Modules;
for (i = 0; i < pm->NumberOfModules; i++) {
const char *fileName = GetFileName((const char *)pMod[i].FullPathName);
io->cb_printf("f nt.%s 0x%x @ 0x%p\n", fileName, pMod[i].ImageSize, pMod[i].ImageBase);
}
}
} else {
eprintf("Driver not initialized.\n");
}
return 1;
}
int ReadKernelMemory(ut64 address, ut8 *buf, int len) {
DWORD ret = -1, bRead = 0;
LPVOID lpBuffer = NULL;
int bufsize;
PPA p;
memset(buf, '\xff', len);
if (gHandleDriver) {
bufsize = sizeof(PA) + len;
if (!(lpBuffer = malloc(bufsize))) {
eprintf("[rzk] ReadKernelMemory: Error can't allocate %i bytes of memory.\n", bufsize);
return -1;
}
p = (PPA)lpBuffer;
p->address.QuadPart = address;
p->len = len;
if (DeviceIoControl(gHandleDriver, IOCTL_READ_KERNEL_MEM, lpBuffer, bufsize, lpBuffer, bufsize, &bRead, NULL)) {
memcpy(buf, lpBuffer, len);
ret = len;
} else {
ret = -1;
// eprintf("[rzk] ReadKernelMemory: Error IOCTL_READ_KERNEL_MEM.\n");
}
free(lpBuffer);
} else {
eprintf("Driver not initialized.\n");
}
return ret;
}
int WriteKernelMemory(ut64 address, const ut8 *buf, int len) {
DWORD ret = -1, bRead = 0;
LPVOID lpBuffer = NULL;
int bufsize;
PPA p;
if (gHandleDriver) {
bufsize = sizeof(PA) + len;
if (!(lpBuffer = malloc(bufsize))) {
eprintf("[rzk] WriteKernelMemory: Error can't allocate %i bytes of memory.\n", bufsize);
return -1;
}
p = (PPA)lpBuffer;
p->address.QuadPart = address;
p->len = len;
memcpy(&p->buffer, buf, len);
if (DeviceIoControl(gHandleDriver, IOCTL_WRITE_KERNEL_MEM, lpBuffer, bufsize, lpBuffer, bufsize, &bRead, NULL)) {
ret = len;
} else {
eprintf("[rzk] WriteKernelMemory: Error IOCTL_WRITE_KERNEL_MEM.\n");
ret = -1;
}
free(lpBuffer);
} else {
eprintf("Driver not initialized.\n");
}
return ret;
}
int Init(const char *driverPath) {
BOOL ret = FALSE;
if (InitDriver() == FALSE) {
if (strlen(driverPath)) {
StartStopService(TEXT("rzk"), TRUE);
RemoveService(TEXT("rzk"));
eprintf("Installing driver: %s\n", driverPath);
if (InstallService(driverPath, TEXT("rzk"), TEXT("rzk"))) {
StartStopService(TEXT("rzk"), FALSE);
ret = InitDriver();
}
} else {
eprintf("Error initalizating driver, try rzk://pathtodriver\nEx: rizin.exe rzk://c:\\rzk.sys");
}
} else {
eprintf("Driver present [OK]\n");
ret = TRUE;
}
return ret;
}

View file

@ -1,68 +0,0 @@
// SPDX-FileCopyrightText: 2016 skuater <skuater@hotmail.com>
// SPDX-FileCopyrightText: 2016 Rakholiya Jenish
// SPDX-FileCopyrightText: 2017 Jose Diaz <josediazplay@gmail.com>
// SPDX-License-Identifier: LGPL-3.0-only
#ifndef __IO_RZK_WINDOWS_H__
#define __IO_RZK_WINDOWS_H__
#include <rz_windows.h>
#include <rz_io.h>
#include <rz_lib.h>
#include <rz_types.h>
#include <rz_util.h>
#include <sys/types.h>
typedef struct {
HANDLE hnd;
} RzIOW32;
typedef struct _PPA {
LARGE_INTEGER address;
DWORD len;
unsigned char buffer;
} PA, *PPA;
typedef struct _RTL_PROCESS_MODULE_INFORMATION {
HANDLE Section;
PVOID MappedBase;
PVOID ImageBase;
ULONG ImageSize;
ULONG Flags;
USHORT LoadOrderIndex;
USHORT InitOrderIndex;
USHORT LoadCount;
USHORT OffsetToFileName;
UCHAR FullPathName[256];
} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;
typedef struct _RTL_PROCESS_MODULES {
ULONG NumberOfModules;
RTL_PROCESS_MODULE_INFORMATION Modules[1];
} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;
#define RZK_DEVICE "\\\\.\\rzk\\"
#define IOCTL_CODE(DeviceType, Function, Method, Access) \
(((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
#if 0
FILE_DEVICE_UNKNOWN 0x22
FILE_READ_ACCESS 1
FILE_WRITE_ACCESS 2
#endif
#define CLOSE_DRIVER IOCTL_CODE(0x22, 0x803, 0, 1 | 2)
#define IOCTL_READ_PHYS_MEM IOCTL_CODE(0x22, 0x807, 0, 1 | 2)
#define IOCTL_READ_KERNEL_MEM IOCTL_CODE(0x22, 0x804, 0, 1 | 2)
#define IOCTL_WRITE_KERNEL_MEM IOCTL_CODE(0x22, 0x805, 0, 1 | 2)
#define IOCTL_GET_PHYSADDR IOCTL_CODE(0x22, 0x809, 0, 1 | 2)
#define IOCTL_WRITE_PHYS_MEM IOCTL_CODE(0x22, 0x808, 0, 1 | 2)
#define IOCTL_GET_SYSTEM_MODULES IOCTL_CODE(0x22, 0x80a, 0, 1 | 2)
extern HANDLE gHandleDriver;
BOOL StartStopService(LPCTSTR lpServiceName, BOOL bStop);
int GetSystemModules(RzIO *io);
int ReadKernelMemory(ut64 address, ut8 *buf, int len);
int WriteKernelMemory(ut64 address, const ut8 *buf, int len);
int Init(const char *driverPath);
#endif

View file

@ -58,7 +58,6 @@ rwd bochs Attach to a BOCHS debugger instance (LGPL3) bochs://
r_d debug Attach to native debugger instance (LGPL3) dbg://,pidof://,waitfor:// v0.2.0 pancake
rw_ default Open local files (LGPL3) file://,nocache://
rwd gdb Attach to gdbserver instance (LGPL3) gdb://
rw_ gprobe Open gprobe connection (LGPL3) gprobe://
rw_ gzip Read/write gzipped files (LGPL3) gzip://
rw_ http Make http get requests (LGPL3) http://
rw_ ihex Open intel HEX file (LGPL) ihex://
@ -68,7 +67,6 @@ rw_ null Null plugin (LGPL3) null://
rw_ procpid Open /proc/[pid]/mem io (LGPL3) procpid://
rwd ptrace Ptrace and /proc/pid/mem (if available) io plugin (LGPL3) ptrace://,attach://
rwd qnx Attach to QNX pdebug instance (LGPL3) qnx://
rw_ rzk Kernel access API io (LGPL3) rzk://
rw_ rzpipe rzpipe io plugin (MIT) rzpipe://
rw_ rzweb rzweb io client plugin (LGPL3) rzweb://
rw_ rap Remote binary protocol plugin (MIT) rap://,raps://
@ -87,7 +85,7 @@ FILE==
BROKEN=1
CMDS=Loj
EXPECT=<<EOF
[{"permissions":"rw_","name":"ar","description":"Open ar/lib files","license":"LGPL3","uris":["ar://","lib://"]},{"permissions":"rw_","name":"fd","description":"Local process filedescriptor IO","license":"MIT","uris":["fd://"]},{"permissions":"rw_","name":"bfdbg","description":"Attach to brainfuck Debugger instance","license":"LGPL3","uris":["bfdbg://"]},{"permissions":"rwd","name":"bochs","description":"Attach to a BOCHS debugger instance","license":"LGPL3","uris":["bochs://"]},{"permissions":"r_d","name":"debug","description":"Attach to native debugger instance","license":"LGPL3","uris":["dbg://","pidof://","waitfor://"],"version":"0.2.0","author":"pancake"},{"permissions":"rw_","name":"default","description":"Open local files","license":"LGPL3","uris":["file://","nocache://"]},{"permissions":"rwd","name":"gdb","description":"Attach to gdbserver instance","license":"LGPL3","uris":["gdb://"]},{"permissions":"rw_","name":"gprobe","description":"Open gprobe connection","license":"LGPL3","uris":["gprobe://"]},{"permissions":"rw_","name":"gzip","description":"Read/write gzipped files","license":"LGPL3","uris":["gzip://"]},{"permissions":"rw_","name":"http","description":"Make http get requests","license":"LGPL3","uris":["http://"]},{"permissions":"rw_","name":"ihex","description":"Open intel HEX file","license":"LGPL","uris":["ihex://"]},{"permissions":"r__","name":"mach","description":"mach debug io (unsupported in this platform)","license":"LGPL"},{"permissions":"rw_","name":"malloc","description":"Memory allocation plugin","license":"LGPL3","uris":["malloc://","hex://"]},{"permissions":"rw_","name":"null","description":"Null plugin","license":"LGPL3","uris":["null://"]},{"permissions":"rw_","name":"procpid","description":"Open /proc/[pid]/mem io","license":"LGPL3","uris":["procpid://"]},{"permissions":"rwd","name":"ptrace","description":"Ptrace and /proc/pid/mem (if available) io plugin","license":"LGPL3","uris":["ptrace://","attach://"]},{"permissions":"rwd","name":"qnx","description":"Attach to QNX pdebug instance","license":"LGPL3","uris":["qnx://"]},{"permissions":"rw_","name":"rzk","description":"Kernel access API io","license":"LGPL3","uris":["rzk://"]},{"permissions":"rw_","name":"rzpipe","description":"rzpipe io plugin","license":"MIT","uris":["rzpipe://"]},{"permissions":"rw_","name":"rzweb","description":"rzweb io client plugin","license":"LGPL3","uris":["rzweb://"]},{"permissions":"rw_","name":"rap","description":"Remote binary protocol plugin","license":"MIT","uris":["rap://","raps://"]},{"permissions":"rw_","name":"self","description":"Read memory from self","license":"LGPL3","uris":["self://"]},{"permissions":"rw_","name":"shm","description":"Shared memory resources plugin","license":"MIT","uris":["shm://"]},{"permissions":"rw_","name":"sparse","description":"Sparse buffer allocation plugin","license":"LGPL3","uris":["sparse://"]},{"permissions":"rw_","name":"tcp","description":"Load files via TCP (listen or connect)","license":"LGPL3","uris":["tcp://"]},{"permissions":"rwd","name":"winkd","description":"Attach to a KD debugger","license":"LGPL3","uris":["winkd://"]},{"permissions":"rwd","name":"winedbg","description":"Wine-dbg io and debug.io plugin","license":"MIT","uris":["winedbg://"]},{"permissions":"rw_","name":"zip","description":"Open zip files","license":"BSD","uris":["zip://","apk://","ipa://","jar://","zipall://","apkall://","ipaall://","jarall://"]}]
[{"permissions":"rw_","name":"ar","description":"Open ar/lib files","license":"LGPL3","uris":["ar://","lib://"]},{"permissions":"rw_","name":"fd","description":"Local process filedescriptor IO","license":"MIT","uris":["fd://"]},{"permissions":"rw_","name":"bfdbg","description":"Attach to brainfuck Debugger instance","license":"LGPL3","uris":["bfdbg://"]},{"permissions":"rwd","name":"bochs","description":"Attach to a BOCHS debugger instance","license":"LGPL3","uris":["bochs://"]},{"permissions":"r_d","name":"debug","description":"Attach to native debugger instance","license":"LGPL3","uris":["dbg://","pidof://","waitfor://"],"version":"0.2.0","author":"pancake"},{"permissions":"rw_","name":"default","description":"Open local files","license":"LGPL3","uris":["file://","nocache://"]},{"permissions":"rwd","name":"gdb","description":"Attach to gdbserver instance","license":"LGPL3","uris":["gdb://"]},{"permissions":"rw_","name":"gzip","description":"Read/write gzipped files","license":"LGPL3","uris":["gzip://"]},{"permissions":"rw_","name":"http","description":"Make http get requests","license":"LGPL3","uris":["http://"]},{"permissions":"rw_","name":"ihex","description":"Open intel HEX file","license":"LGPL","uris":["ihex://"]},{"permissions":"r__","name":"mach","description":"mach debug io (unsupported in this platform)","license":"LGPL"},{"permissions":"rw_","name":"malloc","description":"Memory allocation plugin","license":"LGPL3","uris":["malloc://","hex://"]},{"permissions":"rw_","name":"null","description":"Null plugin","license":"LGPL3","uris":["null://"]},{"permissions":"rw_","name":"procpid","description":"Open /proc/[pid]/mem io","license":"LGPL3","uris":["procpid://"]},{"permissions":"rwd","name":"ptrace","description":"Ptrace and /proc/pid/mem (if available) io plugin","license":"LGPL3","uris":["ptrace://","attach://"]},{"permissions":"rwd","name":"qnx","description":"Attach to QNX pdebug instance","license":"LGPL3","uris":["qnx://"]},{"permissions":"rw_","name":"rzpipe","description":"rzpipe io plugin","license":"MIT","uris":["rzpipe://"]},{"permissions":"rw_","name":"rzweb","description":"rzweb io client plugin","license":"LGPL3","uris":["rzweb://"]},{"permissions":"rw_","name":"rap","description":"Remote binary protocol plugin","license":"MIT","uris":["rap://","raps://"]},{"permissions":"rw_","name":"self","description":"Read memory from self","license":"LGPL3","uris":["self://"]},{"permissions":"rw_","name":"shm","description":"Shared memory resources plugin","license":"MIT","uris":["shm://"]},{"permissions":"rw_","name":"sparse","description":"Sparse buffer allocation plugin","license":"LGPL3","uris":["sparse://"]},{"permissions":"rw_","name":"tcp","description":"Load files via TCP (listen or connect)","license":"LGPL3","uris":["tcp://"]},{"permissions":"rwd","name":"winkd","description":"Attach to a KD debugger","license":"LGPL3","uris":["winkd://"]},{"permissions":"rwd","name":"winedbg","description":"Wine-dbg io and debug.io plugin","license":"MIT","uris":["winedbg://"]},{"permissions":"rw_","name":"zip","description":"Open zip files","license":"BSD","uris":["zip://","apk://","ipa://","jar://","zipall://","apkall://","ipaall://","jarall://"]}]
EOF
RUN