diff --git a/doc/gprobe.md b/doc/gprobe.md deleted file mode 100644 index 77419b39aa..0000000000 --- a/doc/gprobe.md +++ /dev/null @@ -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 diff --git a/librz/include/rz_io.h b/librz/include/rz_io.h index b763e323bd..74c359154f 100644 --- a/librz/include/rz_io.h +++ b/librz/include/rz_io.h @@ -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 diff --git a/librz/io/meson.build b/librz/io/meson.build index 3549e4056b..d89880842d 100644 --- a/librz/io/meson.build +++ b/librz/io/meson.build @@ -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 diff --git a/librz/io/p/io_gprobe.c b/librz/io/p/io_gprobe.c deleted file mode 100644 index 182073fec7..0000000000 --- a/librz/io/p/io_gprobe.c +++ /dev/null @@ -1,1248 +0,0 @@ -// SPDX-FileCopyrightText: 2018 Dirk Eibach -// SPDX-FileCopyrightText: 2018 Guntermann -// SPDX-FileCopyrightText: 2018 Drunck GmbH -// SPDX-License-Identifier: LGPL-3.0-only - -#include -#include -#include -#include - -#if __UNIX__ -#include -#include -#endif - -#define USE_OWNTIMER 1 -#if USE_OWNTIMER -#include "io_gprobe.h" -#else -#define Timersub timersub -#define Timeradd timeradd -#define Timercmp timercmp -#endif - -#if __WINDOWS__ -#include -#include -#else - -#if __linux__ || __APPLE__ || __OpenBSD__ || __FreeBSD__ || __NetBSD__ || __DragonFly__ || __HAIKU__ -#include -#include -#else -#include -#endif - -#endif - -#define GPROBE_SIZE (1LL << 32) -#define GPROBE_I2C_ADDR 0x6e - -#define I2C_SLAVE 0x0703 - -/* serial port code adapted from git://sigrok.org/libserialport */ -struct gport { - const char *name; -#if __WINDOWS__ - HANDLE hdl; - COMMTIMEOUTS timeouts; - OVERLAPPED write_ovl; - OVERLAPPED read_ovl; - OVERLAPPED wait_ovl; - DWORD events; - BYTE pending_byte; - BOOL writing; - BOOL wait_running; -#else - int fd; -#endif - int (*send_request)(struct gport *port, RzBuffer *request); - int (*get_reply)(struct gport *port, ut8 cmd, RzBuffer *reply); - void (*frame)(RzBuffer *frame); - - ut32 max_rx_size; - ut32 max_tx_size; -}; - -typedef struct { - struct gport gport; - ut64 offset; -} RzIOGprobe; - -enum { - GPROBE_DEBUGON = 0x09, - GPROBE_DEBUGOFF = 0x0a, - GPROBE_ACK = 0x0c, - GPROBE_RESET = 0x20, - GPROBE_GET_DEVICE_ID = 0x30, - GPROBE_GET_INFORMATION = 0x40, - GPROBE_RAM_READ_2 = 0x52, - GPROBE_RAM_WRITE_2 = 0x53, - GPROBE_RUN_CODE_2 = 0x54, -}; - -#if __UNIX__ -static ut8 gprobe_checksum_i2c(const ut8 *p, unsigned int size, ut8 initial) { - ut8 res = initial; - unsigned int k; - - for (k = 0; k < size; k++) { - res ^= p[k]; - } - - return res; -} - -static void gprobe_frame_i2c(RzBuffer *frame) { - ut8 size = rz_buf_size(frame) + 1; - ut8 header[] = { 0x51, 0x80 + size + 3, 0xc2, 0x00, 0x00 }; - - rz_buf_prepend_bytes(frame, &size, 1); - rz_buf_prepend_bytes(frame, header, sizeof(header)); - - ut64 tmpsz; - const ut8 *tmp = rz_buf_data(frame, &tmpsz); - ut8 checksum = gprobe_checksum_i2c(tmp, tmpsz, GPROBE_I2C_ADDR); - - rz_buf_append_bytes(frame, &checksum, 1); -} - -static int gprobe_get_reply_i2c(struct gport *port, ut8 cmd, RzBuffer *reply) { - ut8 buf[131]; - int count; - int ddc2bi3_len; - ut8 addr = 0x50; - ut8 checksum; - - rz_sys_usleep(40000); - - count = read(port->fd, buf, sizeof(buf)); - - if (count != sizeof(buf)) { - return -1; - } - - ddc2bi3_len = buf[1] & ~0x80; - - if (((buf[0] & 0xfe) != GPROBE_I2C_ADDR) || !(buf[1] & 0x80) || (buf[2] != 0xc2) || (buf[3] != 0x00) || (buf[4] != 0x00) || (cmd != buf[6]) || !(buf[5] - 2) || (buf[5] != ddc2bi3_len - 2)) { - return -1; - } - - checksum = gprobe_checksum_i2c(&addr, 1, 0); - - if (gprobe_checksum_i2c(buf, ddc2bi3_len + 2, checksum) != buf[ddc2bi3_len + 2]) { - eprintf("gprobe rx checksum error\n"); - } - - rz_buf_append_bytes(reply, buf + 7, buf[5] - 3); - - return 0; -} - -static int gprobe_send_request_i2c(struct gport *port, RzBuffer *request) { - ut64 tmpsz; - const ut8 *tmp = rz_buf_data(request, &tmpsz); - if (write(port->fd, tmp, tmpsz) != rz_buf_size(request)) { - return -1; - } - return 0; -} - -static int i2c_open(struct gport *port) { - char *end, filename[32]; - int i2cbus = strtol(port->name + 4, &end, 0); - - if (*end) { - return -1; - } - - snprintf(filename, sizeof(filename), "/dev/i2c/%d", i2cbus); - filename[sizeof(filename) - 1] = '\0'; - int file = rz_sys_open(filename, O_RDWR, 0); - - if (file < 0 && (errno == ENOENT || errno == ENOTDIR)) { - sprintf(filename, "/dev/i2c-%d", i2cbus); - file = rz_sys_open(filename, O_RDWR, 0); - } - if (file < 0) { - return -1; - } - if (ioctl(file, I2C_SLAVE, GPROBE_I2C_ADDR >> 1) < 0) { - close(file); - port->fd = -1; - return -1; - } - port->fd = file; - return 0; -} -#endif - -static int sp_close(struct gport *port) { -#if __WINDOWS__ - /* Returns non-zero upon success, 0 upon failure. */ - if (CloseHandle(port->hdl) == 0) { - return -1; - } - port->hdl = INVALID_HANDLE_VALUE; - - /* Close event handles for overlapped structures. */ -#define CLOSE_OVERLAPPED(ovl) \ - do { \ - if (port->ovl.hEvent != INVALID_HANDLE_VALUE && \ - CloseHandle(port->ovl.hEvent) == 0) \ - return -1; \ - } while (0) - CLOSE_OVERLAPPED(read_ovl); - CLOSE_OVERLAPPED(write_ovl); - CLOSE_OVERLAPPED(wait_ovl); -#else - if (close(port->fd) == -1) { - return -1; - } - - port->fd = -1; -#endif - return 0; -} - -#if __WINDOWS__ -/* To be called after port receive buffer is emptied. */ -static int restart_wait(struct gport *port) { - DWORD wait_result; - - if (port->wait_running) { - /* Check status of running wait operation. */ - if (GetOverlappedResult(port->hdl, &port->wait_ovl, - &wait_result, FALSE)) { - port->wait_running = FALSE; - } else if (GetLastError() == ERROR_IO_INCOMPLETE) { - return 0; - } - return -1; - } - if (!port->wait_running) { - /* Start new wait operation. */ - if (WaitCommEvent(port->hdl, &port->events, - &port->wait_ovl)) { - } else if (GetLastError() == ERROR_IO_PENDING) { - port->wait_running = TRUE; - } - return -1; - } - return 0; -} -#endif - -static int sp_open(struct gport *port) { -#if __WINDOWS__ - int ret; - DWORD errors; - char *escaped_port_name; - COMSTAT status; - DCB dcb; - LPTSTR filename_; - - /* Prefix port name with '\\.\' to work with ports above COM9. */ - if (!(escaped_port_name = malloc(strlen(port->name) + 5))) { - return -1; - } - sprintf(escaped_port_name, "\\\\.\\%s", port->name); - - filename_ = rz_sys_conv_utf8_to_win(escaped_port_name); - - port->hdl = CreateFile(filename_, GENERIC_READ | GENERIC_WRITE, 0, 0, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 0); - - free(escaped_port_name); - - if (port->hdl == INVALID_HANDLE_VALUE) { - return -1; - } - - /* All timeouts initially disabled. */ - port->timeouts.ReadIntervalTimeout = 0; - port->timeouts.ReadTotalTimeoutMultiplier = 0; - port->timeouts.ReadTotalTimeoutConstant = 0; - port->timeouts.WriteTotalTimeoutMultiplier = 0; - port->timeouts.WriteTotalTimeoutConstant = 0; - - if (SetCommTimeouts(port->hdl, &port->timeouts) == 0) { - sp_close(port); - return -1; - } - - /* Prepare OVERLAPPED structures. */ -#define INIT_OVERLAPPED(ovl) \ - do { \ - memset(&port->ovl, 0, sizeof(port->ovl)); \ - port->ovl.hEvent = INVALID_HANDLE_VALUE; \ - if ((port->ovl.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL)) == INVALID_HANDLE_VALUE) { \ - sp_close(port); \ - return -1; \ - } \ - } while (0) - - INIT_OVERLAPPED(read_ovl); - INIT_OVERLAPPED(write_ovl); - INIT_OVERLAPPED(wait_ovl); - - /* Set event mask for RX and error events. */ - if (SetCommMask(port->hdl, EV_RXCHAR | EV_ERR) == 0) { - sp_close(port); - return -1; - } - - port->writing = FALSE; - port->wait_running = FALSE; - - ret = restart_wait(port); - - if (ret < 0) { - sp_close(port); - return -1; - } - - dcb.fBinary = TRUE; - dcb.fDsrSensitivity = FALSE; - dcb.fErrorChar = FALSE; - dcb.fNull = FALSE; - dcb.fAbortOnError = FALSE; - - if (ClearCommError(port->hdl, &errors, &status) == 0) { - return -1; - } - - dcb.BaudRate = CBR_115200; - - dcb.ByteSize = 8; - dcb.Parity = NOPARITY; - dcb.StopBits = ONESTOPBIT; - dcb.fRtsControl = RTS_CONTROL_DISABLE; - dcb.fOutxCtsFlow = FALSE; - dcb.fDtrControl = DTR_CONTROL_DISABLE; - dcb.fOutxDsrFlow = FALSE; - dcb.fInX = FALSE; - dcb.fOutX = FALSE; - - if (!SetCommState(port->hdl, &dcb)) { - return -1; - } - - return 0; -#else - struct termios tty = { 0 }; - - if ((port->fd = rz_sys_open(port->name, O_NONBLOCK | O_NOCTTY | O_RDWR, 0)) < 0) { - return -1; - } - - if (tcgetattr(port->fd, &tty) != 0) { - sp_close(port); - return -1; - } - - cfsetospeed(&tty, B115200); - cfsetispeed(&tty, B115200); - - tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; - tty.c_iflag &= ~IGNBRK; - tty.c_lflag = 0; - tty.c_oflag = 0; - tty.c_cc[VMIN] = 0; - tty.c_cc[VTIME] = 0; - tty.c_iflag &= ~(IXON | IXOFF | IXANY); - - tty.c_cflag |= (CLOCAL | CREAD); - tty.c_cflag &= ~(PARENB | PARODD); - tty.c_cflag &= ~CSTOPB; -#ifdef CRTSCTS - tty.c_cflag &= ~CRTSCTS; -#else - tty.c_cflag &= ~020000000000; -#endif - - if (tcsetattr(port->fd, TCSANOW, &tty) != 0) { - return -1; - } - - return 0; -#endif -} - -#if __WINDOWS__ -/* Restart wait operation if buffer was emptied. */ -static int restart_wait_if_needed(struct gport *port, unsigned int bytes_read) { - DWORD errors; - COMSTAT comstat; - - if (bytes_read == 0) { - return 0; - } - - if (ClearCommError(port->hdl, &errors, &comstat) == 0) { - return -1; - } - - if (comstat.cbInQue == 0) { - if (restart_wait(port)) { - return -1; - } - } - - return 0; -} -#endif - -static int sp_blocking_read(struct gport *port, void *buf, - size_t count, unsigned int timeout_ms) { -#if __WINDOWS__ - DWORD bytes_read = 0; - - /* Set timeout. */ - if (port->timeouts.ReadIntervalTimeout != 0 || - port->timeouts.ReadTotalTimeoutMultiplier != 0 || - port->timeouts.ReadTotalTimeoutConstant != timeout_ms) { - port->timeouts.ReadIntervalTimeout = 0; - port->timeouts.ReadTotalTimeoutMultiplier = 0; - port->timeouts.ReadTotalTimeoutConstant = timeout_ms; - if (SetCommTimeouts(port->hdl, &port->timeouts) == 0) { - return -1; - } - } - - /* Start read. */ - if (ReadFile(port->hdl, buf, count, NULL, &port->read_ovl)) { - bytes_read = count; - } else if (GetLastError() == ERROR_IO_PENDING) { - if (GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read, TRUE) == 0) - return -1; - } else { - return -1; - } - - if (restart_wait_if_needed(port, bytes_read)) { - return -1; - } - - return bytes_read; -#else - size_t bytes_read = 0; - unsigned char *ptr = (unsigned char *)buf; - struct timeval start, delta, now, end = { 0, 0 }; - int started = 0; - fd_set fds; - int result; - - if (timeout_ms) { - /* Get time at start of operation. */ - gettimeofday(&start, NULL); - /* Define duration of timeout. */ - delta.tv_sec = timeout_ms / 1000; - delta.tv_usec = (timeout_ms % 1000) * 1000; - /* Calculate time at which we should give up. */ - Timeradd(&start, &delta, &end); - } - - FD_ZERO(&fds); - FD_SET(port->fd, &fds); - - /* Loop until we have the requested number of bytes. */ - while (bytes_read < count) { - /* - * Check timeout only if we have run select() at least once, - * to avoid any issues if a short timeout is reached before - * select() is even run. - */ - if (timeout_ms && started) { - gettimeofday(&now, NULL); - if (Timercmp(&now, &end, >)) { - /* Timeout has expired. */ - break; - } - Timersub(&end, &now, &delta); - } - result = select(port->fd + 1, &fds, NULL, NULL, timeout_ms ? &delta : NULL); - started = 1; - if (result < 0) { - if (errno == EINTR) { - continue; - } else { - return -1; - } - } else if (result == 0) { - /* Timeout has expired. */ - break; - } - - /* Do read. */ - result = read(port->fd, ptr, count - bytes_read); - - if (result < 0) { - if (errno == EAGAIN) { - /* - * This shouldn't happen because we did a - * select() first, but handle anyway. - */ - continue; - } else { - /* This is an actual failure. */ - return -1; - } - } - - bytes_read += result; - ptr += result; - } - - return bytes_read; -#endif -} - -static int sp_flush(struct gport *port) { -#if __WINDOWS__ - /* Returns non-zero upon success, 0 upon failure. */ - if (PurgeComm(port->hdl, PURGE_RXCLEAR) == 0) { - return -1; - } - - if (restart_wait(port)) { - return -1; - } -#else - if (tcflush(port->fd, TCIFLUSH) < 0) { - return -1; - } -#endif - - return 0; -} - -#if __WINDOWS__ -static int await_write_completion(struct gport *port) { - DWORD bytes_written; - BOOL result; - - /* Wait for previous non-blocking write to complete, if any. */ - if (port->writing) { - result = GetOverlappedResult(port->hdl, &port->write_ovl, &bytes_written, TRUE); - port->writing = 0; - if (!result) { - return -1; - } - } - - return 0; -} -#endif - -static int sp_blocking_write(struct gport *port, const void *buf, - size_t count, unsigned int timeout_ms) { -#if __WINDOWS__ - DWORD bytes_written = 0; - - if (await_write_completion(port)) { - return -1; - } - - /* Set timeout. */ - if (port->timeouts.WriteTotalTimeoutConstant != timeout_ms) { - port->timeouts.WriteTotalTimeoutConstant = timeout_ms; - if (SetCommTimeouts(port->hdl, &port->timeouts) == 0) { - return -1; - } - } - - /* Start write. */ - if (WriteFile(port->hdl, buf, count, NULL, &port->write_ovl)) { - return count; - } else if (GetLastError() == ERROR_IO_PENDING) { - if (GetOverlappedResult(port->hdl, &port->write_ovl, &bytes_written, TRUE) == 0) { - if (GetLastError() == ERROR_SEM_TIMEOUT) - return 0; - else - return -1; - } - return bytes_written; - } else { - return -1; - } -#else - size_t bytes_written = 0; - unsigned char *ptr = (unsigned char *)buf; - struct timeval start, delta, now, end = { 0, 0 }; - int started = 0; - fd_set fds; - int result; - - if (timeout_ms) { - /* Get time at start of operation. */ - gettimeofday(&start, NULL); - /* Define duration of timeout. */ - delta.tv_sec = timeout_ms / 1000; - delta.tv_usec = (timeout_ms % 1000) * 1000; - /* Calculate time at which we should give up. */ - Timeradd(&start, &delta, &end); - } - - FD_ZERO(&fds); - FD_SET(port->fd, &fds); - - /* Loop until we have written the requested number of bytes. */ - while (bytes_written < count) { - /* - * Check timeout only if we have run select() at least once, - * to avoid any issues if a short timeout is reached before - * select() is even run. - */ - if (timeout_ms && started) { - gettimeofday(&now, NULL); - if (Timercmp(&now, &end, >)) { - /* Timeout has expired. */ - break; - } - Timersub(&end, &now, &delta); - } - result = select(port->fd + 1, NULL, &fds, NULL, timeout_ms ? &delta : NULL); - started = 1; - if (result < 0) { - if (errno == EINTR) { - continue; - } else { - return -1; - } - } else if (result == 0) { - /* Timeout has expired. */ - break; - } - - /* Do write. */ - result = write(port->fd, ptr, count - bytes_written); - - if (result < 0) { - if (errno == EAGAIN) { - /* This shouldn't happen because we did a select() first, but handle anyway. */ - continue; - } else { - /* This is an actual failure. */ - return -1; - } - } - - bytes_written += result; - ptr += result; - } - - return bytes_written; -#endif -} - -static ut8 gprobe_checksum(const ut8 *p, unsigned int size) { - ut8 res = 0; - unsigned int k; - - for (k = 0; k < size; k++) { - res += p[k]; - } - - res = ~res + 1; - - return res; -} - -static void gprobe_frame_sp(RzBuffer *frame) { - ut64 size; - const ut8 *tmp = rz_buf_data(frame, &size); - size += 2; - ut8 checksum; - - rz_buf_prepend_bytes(frame, (const ut8 *)&size, 1); - checksum = gprobe_checksum(tmp, size - 1); - - rz_buf_append_bytes(frame, &checksum, 1); -} - -static int gprobe_get_reply_sp(struct gport *port, ut8 cmd, RzBuffer *reply) { - ut8 buf[256]; - int count = sp_blocking_read(port, buf, 2, 50); - - if (count < 2) { - return -1; - } - - if (cmd != buf[1]) { - return -1; - } - - if (!(buf[0] - 2)) { - return 0; - } - - count = sp_blocking_read(port, buf + 2, buf[0] - 2, 50) + 2; - - if (count != buf[0]) { - return -1; - } - -/* checksumming answers does not work reliably */ -#if 0 - if (gprobe_checksum(buf, count - 1) != buf[count - 1]) { - printf("### CHECKSUM FAILED\n"); - } -#endif - - rz_buf_append_bytes(reply, buf + 2, count - 3); - - return 0; -} - -static int gprobe_send_request_sp(struct gport *port, RzBuffer *request) { - sp_flush(port); - - ut64 tmpsz; - const ut8 *tmp = rz_buf_data(request, &tmpsz); - if (sp_blocking_write(port, tmp, tmpsz, 100) != tmpsz) { - return -1; - } - - return 0; -} - -static int gprobe_read(struct gport *port, ut32 addr, ut8 *buf, ut32 count) { - RzBuffer *request = rz_buf_new_with_bytes(NULL, 0); - RzBuffer *reply = rz_buf_new_with_bytes(NULL, 0); - const ut8 cmd = GPROBE_RAM_READ_2; - ut8 addr_be[4]; - ut8 count_be[4]; - int res; - - if (!request || !reply) { - rz_buf_free(request); - rz_buf_free(reply); - return -1; - } - - count = RZ_MIN(port->max_rx_size, count); - - rz_write_be32(addr_be, addr); - rz_write_be32(count_be, count); - - rz_buf_append_bytes(request, &cmd, 1); - rz_buf_append_bytes(request, addr_be, 4); - rz_buf_append_bytes(request, count_be, 4); - - port->frame(request); - - if (port->send_request(port, request)) { - goto fail; - } - - if (port->get_reply(port, cmd, reply)) { - goto fail; - } - - res = rz_buf_read_at(reply, 0, buf, rz_buf_size(reply)); - - rz_buf_free(request); - rz_buf_free(reply); - - return res; - -fail: - rz_buf_free(request); - rz_buf_free(reply); - return -1; -} - -static int gprobe_write(struct gport *port, ut32 addr, const ut8 *buf, ut32 count) { - RzBuffer *request = rz_buf_new_with_bytes(NULL, 0); - RzBuffer *reply = rz_buf_new_with_bytes(NULL, 0); - const ut8 cmd = GPROBE_RAM_WRITE_2; - ut8 addr_be[4]; - ut8 count_be[4]; - - if (!request || !reply) { - rz_buf_free(request); - rz_buf_free(reply); - return -1; - } - - count = RZ_MIN(port->max_tx_size, count); - - rz_write_be32(addr_be, addr); - rz_write_be32(count_be, count); - - rz_buf_append_bytes(request, &cmd, 1); - rz_buf_append_bytes(request, addr_be, 4); - rz_buf_append_bytes(request, buf, count); - - port->frame(request); - - if (port->send_request(port, request)) { - goto fail; - } - - if (port->get_reply(port, GPROBE_ACK, reply)) { - goto fail; - } - - rz_buf_free(request); - rz_buf_free(reply); - - return count; - -fail: - rz_buf_free(request); - rz_buf_free(reply); - return -1; -} - -static int gprobe_reset(struct gport *port, ut8 code) { - if (!port) { - return -1; - } - RzBuffer *request = rz_buf_new_with_bytes(NULL, 0); - RzBuffer *reply = rz_buf_new_with_bytes(NULL, 0); - const ut8 cmd = GPROBE_RESET; - - if (!request || !reply) { - goto fail; - } - - rz_buf_append_bytes(request, &cmd, 1); - rz_buf_append_bytes(request, &code, 1); - - port->frame(request); - - sp_flush(port); - - if (port->send_request(port, request)) { - goto fail; - } - - if (port->get_reply(port, GPROBE_ACK, reply)) { - goto fail; - } - - rz_buf_free(request); - rz_buf_free(reply); - - return 0; - -fail: - rz_buf_free(request); - rz_buf_free(reply); - return -1; -} - -static int gprobe_debugon(struct gport *port) { - if (!port) { - return -1; - } - RzBuffer *request = rz_buf_new_with_bytes(NULL, 0); - RzBuffer *reply = rz_buf_new_with_bytes(NULL, 0); - const ut8 cmd = GPROBE_DEBUGON; - - if (!request || !reply) { - goto fail; - } - rz_buf_append_bytes(request, &cmd, 1); - - port->frame(request); - - if (port->send_request(port, request)) { - goto fail; - } - - if (port->get_reply(port, GPROBE_ACK, reply)) { - goto fail; - } - - rz_buf_free(request); - rz_buf_free(reply); - - return 0; - -fail: - rz_buf_free(request); - rz_buf_free(reply); - return -1; -} - -static int gprobe_debugoff(struct gport *port) { - RzBuffer *request = rz_buf_new_with_bytes(NULL, 0); - RzBuffer *reply = rz_buf_new_with_bytes(NULL, 0); - const ut8 cmd = GPROBE_DEBUGOFF; - - if (!request || !reply) { - goto fail; - } - rz_buf_append_bytes(request, &cmd, 1); - port->frame(request); - if (port->send_request(port, request)) { - goto fail; - } - if (port->get_reply(port, GPROBE_ACK, reply)) { - goto fail; - } - rz_buf_free(request); - rz_buf_free(reply); - return 0; -fail: - rz_buf_free(request); - rz_buf_free(reply); - return -1; -} - -static int gprobe_runcode(struct gport *port, ut32 addr) { - if (!port) { - return -1; - } - RzBuffer *request = rz_buf_new_with_bytes(NULL, 0); - RzBuffer *reply = rz_buf_new_with_bytes(NULL, 0); - const ut8 cmd = GPROBE_RUN_CODE_2; - ut8 addr_be[4]; - - if (!request || !reply) { - goto fail; - } - - rz_write_be32(addr_be, addr); - - rz_buf_append_bytes(request, &cmd, 1); - rz_buf_append_bytes(request, addr_be, 4); - - port->frame(request); - - if (port->send_request(port, request)) { - goto fail; - } - - if (port->get_reply(port, GPROBE_ACK, reply)) { - goto fail; - } - - rz_buf_free(request); - rz_buf_free(reply); - - return 0; - -fail: - rz_buf_free(request); - rz_buf_free(reply); - return -1; -} - -static int gprobe_getdeviceid(struct gport *port, ut8 index) { - if (!port) { - return -1; - } - RzBuffer *request = rz_buf_new_with_bytes(NULL, 0); - RzBuffer *reply = rz_buf_new_with_bytes(NULL, 0); - const ut8 cmd = GPROBE_GET_DEVICE_ID; - - if (!request || !reply) { - goto fail; - } - - rz_buf_append_bytes(request, &cmd, 1); - rz_buf_append_bytes(request, &index, 1); - - port->frame(request); - - if (port->send_request(port, request)) { - goto fail; - } - - if (port->get_reply(port, cmd, reply)) { - goto fail; - } - - char *s = rz_buf_to_string(reply); - if (s) { - printf("%s\n", s); - free(s); - } - - rz_buf_free(request); - rz_buf_free(reply); - - return 0; - -fail: - rz_buf_free(request); - rz_buf_free(reply); - return -1; -} - -static int gprobe_getinformation(struct gport *port) { - if (!port) { - return -1; - } - RzBuffer *request = rz_buf_new_with_bytes(NULL, 0); - RzBuffer *reply = rz_buf_new_with_bytes(NULL, 0); - const ut8 cmd = GPROBE_GET_INFORMATION; - const ut8 index = 0; - - if (!request || !reply) { - goto fail; - } - - rz_buf_append_bytes(request, &cmd, 1); - rz_buf_append_bytes(request, &index, 1); - - port->frame(request); - - if (port->send_request(port, request)) { - goto fail; - } - - if (port->get_reply(port, cmd, reply)) { - goto fail; - } - - ut64 tmpsz; - const ut8 *tmp = rz_buf_data(reply, &tmpsz); - RzPrint *print = rz_print_new(); - char *dump = rz_print_hexdump_str(print, 0, tmp, tmpsz, 16, 1, 1); - rz_cons_print(dump); - free(dump); - rz_print_free(print); - - rz_buf_free(request); - rz_buf_free(reply); - - return 0; - -fail: - rz_buf_free(request); - rz_buf_free(reply); - return -1; -} - -static int __write(RzIO *io, RzIODesc *fd, const ut8 *buf, int count) { - RzIOGprobe *gprobe; - int res; - int has_written = 0; - - if (!fd || !fd->data || !buf) { - return -1; - } - - gprobe = (RzIOGprobe *)fd->data; - - if ((gprobe->offset + count) > GPROBE_SIZE) { - count = GPROBE_SIZE - gprobe->offset; - } - - while (has_written < count) { - res = gprobe_write(&gprobe->gport, gprobe->offset, buf + has_written, count - has_written); - if (res <= 0) { - return -1; - } - gprobe->offset += res; - has_written += res; - } - - return count; -} - -static int __read(RzIO *io, RzIODesc *fd, ut8 *buf, int count) { - int res; - RzIOGprobe *gprobe; - int has_read = 0; - - if (!fd || !fd->data || !buf) { - return -1; - } - - gprobe = (RzIOGprobe *)fd->data; - - if ((gprobe->offset + count) > GPROBE_SIZE) { - count = GPROBE_SIZE - gprobe->offset; - } - - while (has_read < count) { - res = gprobe_read(&gprobe->gport, gprobe->offset, buf + has_read, count - has_read); - if (res <= 0) { - return -1; - } - gprobe->offset += res; - has_read += res; - } - - return has_read; -} - -static int __close(RzIODesc *fd) { - RzIOGprobe *gprobe; - - if (!fd || !fd->data) { - return -1; - } - gprobe = (RzIOGprobe *)fd->data; - - sp_close(&gprobe->gport); - RZ_FREE(fd->data); - - return 0; -} - -static ut64 __lseek(RzIO *io, RzIODesc *fd, ut64 offset, int whence) { - RzIOGprobe *gprobe; - if (!fd || !fd->data) { - return offset; - } - gprobe = (RzIOGprobe *)fd->data; - switch (whence) { - case SEEK_SET: - if (offset >= GPROBE_SIZE) { - return gprobe->offset = GPROBE_SIZE - 1; - } - return gprobe->offset = offset; - case SEEK_CUR: - if ((gprobe->offset + offset) >= GPROBE_SIZE) { - return gprobe->offset = GPROBE_SIZE - 1; - } - return gprobe->offset += offset; - case SEEK_END: - return gprobe->offset = GPROBE_SIZE - 1; - } - return offset; -} - -static bool __plugin_open(RzIO *io, const char *pathname, bool many) { - return pathname && rz_str_startswith(pathname, "gprobe://") && strlen(pathname + strlen("gprobe://")); -} - -static RzIODesc *__open(RzIO *io, const char *pathname, int rw, int mode) { - if (__plugin_open(io, pathname, 0)) { - RzIOGprobe *gprobe = RZ_NEW0(RzIOGprobe); - - gprobe->offset = 0LL; - gprobe->gport.name = pathname + strlen("gprobe://"); - - if (rz_str_startswith(gprobe->gport.name, "i2c-")) { -#if __UNIX__ - gprobe->gport.send_request = gprobe_send_request_i2c; - gprobe->gport.get_reply = gprobe_get_reply_i2c; - gprobe->gport.frame = gprobe_frame_i2c; - gprobe->gport.max_tx_size = 117; - gprobe->gport.max_rx_size = 121; - - if (i2c_open(&gprobe->gport)) { - RZ_FREE(gprobe); - return NULL; - } -#else - RZ_FREE(gprobe); - return NULL; -#endif - } else { - gprobe->gport.send_request = gprobe_send_request_sp; - gprobe->gport.get_reply = gprobe_get_reply_sp; - gprobe->gport.frame = gprobe_frame_sp; - gprobe->gport.max_tx_size = 248; - gprobe->gport.max_rx_size = 252; - - if (sp_open(&gprobe->gport)) { - RZ_FREE(gprobe); - return NULL; - } - } - - return rz_io_desc_new(io, &rz_io_plugin_gprobe, pathname, rw, mode, gprobe); - } - - return NULL; -} - -static char *__system(RzIO *io, RzIODesc *fd, const char *cmd) { - RzIOGprobe *gprobe; - - if (!fd || !fd->data) { - return NULL; - } - gprobe = (RzIOGprobe *)fd->data; - - if (!cmd[0] || cmd[0] == '?' || !strcmp(cmd, "help")) { - printf("Usage: R!cmd args\n" - " R!reset code\n" - " R!debugon\n" - " R!debugoff\n" - " R!runcode address\n" - " R!getdeviceid\n" - " R!getinformation\n"); - return NULL; - } - - if (rz_str_startswith(cmd, "reset") && (strlen(cmd) > 6)) { - ut32 code = (ut32)strtoul(cmd + 6, NULL, 10); - - gprobe_reset(&gprobe->gport, code); - - return NULL; - } - - if (rz_str_startswith(cmd, "debugon")) { - gprobe_debugon(&gprobe->gport); - - return NULL; - } - - if (rz_str_startswith(cmd, "debugoff")) { - gprobe_debugoff(&gprobe->gport); - - return NULL; - } - - if (rz_str_startswith(cmd, "runcode") && (strlen(cmd) > 8)) { - ut32 address = (ut32)strtoul(cmd + 8, NULL, 0); - - gprobe_runcode(&gprobe->gport, address); - - return NULL; - } - - if (rz_str_startswith(cmd, "getdeviceid")) { - ut8 index = 0; - - while (!gprobe_getdeviceid(&gprobe->gport, index++)) { - }; - - return NULL; - } - - if (rz_str_startswith(cmd, "getinformation")) { - gprobe_getinformation(&gprobe->gport); - - return NULL; - } - - printf("Try: 'R!?'\n"); - - return NULL; -} - -RzIOPlugin rz_io_plugin_gprobe = { - .name = "gprobe", - .desc = "Open gprobe connection", - .license = "LGPL3", - .uris = "gprobe://", - .open = __open, - .close = __close, - .read = __read, - .check = __plugin_open, - .lseek = __lseek, - .write = __write, - .system = __system, -}; - -#ifndef RZ_PLUGIN_INCORE -RZ_API RzLibStruct rizin_plugin = { - .type = RZ_LIB_TYPE_IO, - .data = &rz_io_plugin_gprobe, - .version = RZ_VERSION -}; -#endif diff --git a/librz/io/p/io_gprobe.h b/librz/io/p/io_gprobe.h deleted file mode 100644 index b1925e2f85..0000000000 --- a/librz/io/p/io_gprobe.h +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-FileCopyrightText: 2018-2020 pancake -// 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) diff --git a/librz/io/p/io_rzk.c b/librz/io/p/io_rzk.c deleted file mode 100644 index 9321cef607..0000000000 --- a/librz/io/p/io_rzk.c +++ /dev/null @@ -1,157 +0,0 @@ -// SPDX-FileCopyrightText: 2016-2018 SkUaTeR -// SPDX-FileCopyrightText: 2016-2018 panda -// SPDX-License-Identifier: LGPL-3.0-only - -#include -#include -#include -#include -#include - -#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 diff --git a/librz/io/p/io_rzk_linux.c b/librz/io/p/io_rzk_linux.c deleted file mode 100644 index 49c3521715..0000000000 --- a/librz/io/p/io_rzk_linux.c +++ /dev/null @@ -1,851 +0,0 @@ -// SPDX-FileCopyrightText: 2016 Rakholiya Jenish -// SPDX-FileCopyrightText: 2016 NighterMan -// SPDX-FileCopyrightText: 2017-2020 pancake -// 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(" 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 diff --git a/librz/io/p/io_rzk_linux.h b/librz/io/p/io_rzk_linux.h deleted file mode 100644 index 77c620fc5e..0000000000 --- a/librz/io/p/io_rzk_linux.h +++ /dev/null @@ -1,131 +0,0 @@ -// SPDX-FileCopyrightText: 2016 Rakholiya Jenish -// SPDX-FileCopyrightText: 2016 NighterMan -// SPDX-FileCopyrightText: 2017-2020 pancake -// SPDX-License-Identifier: LGPL-3.0-only - -#ifndef __IO_RZK_LINUX_H__ -#define __IO_RZK_LINUX_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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 diff --git a/librz/io/p/io_rzk_windows.c b/librz/io/p/io_rzk_windows.c deleted file mode 100644 index e4530bfc03..0000000000 --- a/librz/io/p/io_rzk_windows.c +++ /dev/null @@ -1,194 +0,0 @@ -// SPDX-FileCopyrightText: 2016 skuater -// SPDX-FileCopyrightText: 2016 Rakholiya Jenish -// SPDX-FileCopyrightText: 2017 Jose Diaz -// 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; -} diff --git a/librz/io/p/io_rzk_windows.h b/librz/io/p/io_rzk_windows.h deleted file mode 100644 index eec7ab05db..0000000000 --- a/librz/io/p/io_rzk_windows.h +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-FileCopyrightText: 2016 skuater -// SPDX-FileCopyrightText: 2016 Rakholiya Jenish -// SPDX-FileCopyrightText: 2017 Jose Diaz -// SPDX-License-Identifier: LGPL-3.0-only - -#ifndef __IO_RZK_WINDOWS_H__ -#define __IO_RZK_WINDOWS_H__ -#include - -#include -#include -#include -#include -#include - -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 diff --git a/test/db/cmd/cmd_list b/test/db/cmd/cmd_list index 17440ea560..feb1f042d1 100644 --- a/test/db/cmd/cmd_list +++ b/test/db/cmd/cmd_list @@ -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=<