Remove rzk and gprobe IO plugins (#3654)
This commit is contained in:
parent
8e41d975bf
commit
f29171ceb1
11 changed files with 1 additions and 2749 deletions
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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, ®_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
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue