Rizin
unix-like reverse engineering framework and cli tools
io_rzk_linux.c File Reference
#include "io_rzk_linux.h"

Go to the source code of this file.

Macros

#define fset(num, shift)   ((((num) & (((ut64)1) << (shift))) == 0) ? 0 : 1)
 

Functions

static const char * getargpos (const char *buf, int pos)
 
static size_t getvalue (const char *buf, int pos)
 
static void print_help (RzIO *io, char *cmd, int p_usage)
 
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_old_command (RzIO *io, RzIODesc *iodesc, const char *buf)
 
int run_new_command (RzIO *io, RzIODesc *iodesc, const char *buf)
 
int run_ioctl_command (RzIO *io, RzIODesc *iodesc, const char *buf)
 

Macro Definition Documentation

◆ fset

#define fset (   num,
  shift 
)    ((((num) & (((ut64)1) << (shift))) == 0) ? 0 : 1)

Definition at line 10 of file io_rzk_linux.c.

Function Documentation

◆ getargpos()

static const char* getargpos ( const char *  buf,
int  pos 
)
static

Definition at line 208 of file io_rzk_linux.c.

208  {
209  int i;
210  for (i = 0; buf && i < pos; i++) {
211  buf = strchr(buf, ' ');
212  if (!buf) {
213  break;
214  }
215  buf = rz_str_ichr((char *)buf, ' ');
216  }
217  return buf;
218 }
lzma_index ** i
Definition: index.h:629
voidpf void * buf
Definition: ioapi.h:138
RZ_API char * rz_str_ichr(char *str, char chr)
Definition: str.c:660
int pos
Definition: main.c:11

References i, pos, and rz_str_ichr().

Referenced by getvalue(), and run_old_command().

◆ getvalue()

static size_t getvalue ( const char *  buf,
int  pos 
)
static

Definition at line 220 of file io_rzk_linux.c.

220  {
221  size_t ret;
222  buf = getargpos(buf, pos);
223  if (buf) {
224  ret = strtoul(buf, 0, 0);
225  } else {
226  ret = -1;
227  }
228  return ret;
229 }
static const char * getargpos(const char *buf, int pos)
Definition: io_rzk_linux.c:208

References getargpos(), and pos.

Referenced by run_old_command().

◆ print_help()

static void print_help ( RzIO io,
char *  cmd,
int  p_usage 
)
static

Definition at line 231 of file io_rzk_linux.c.

231  {
232  int i = 0;
233  int cmd_len = cmd ? strlen(cmd) : 0;
234  const char *usage = "Usage: \\[MprRw][lpP] [args...]";
235  const char *help_msg[] = {
236  "\\dm Print kernel memory map (or process if rzk.io==1)",
237  "\\dr Print control registers",
238  "\\dR Print control registers in detailed mode",
239  "\\dp [pid] Print current selected pid or change it",
240  "\\e rzk.io=[012] Read/Write from 0: Linear, 1: Process, 2: Physical addresses"
241  };
242  const char *help_msg_old[] = {
243  "\\M Print kernel memory map",
244  "\\b beid [pid] Change rzk backend. pid is required when beid is 1.",
245  " 0: linear address; 1: process address; 2: physical address",
246  "\\p pid Print process information",
247  "\\rl addr len Read from linear address",
248  "\\rp pid addr len Read from process address",
249  "\\rP addr len Read physical address",
250  "\\R[p] Print control registers. Use R!Rp for detailed description",
251  "\\wl[x] addr input Write at linear address. Use R!wlx for input in hex",
252  "\\wp[x] pid addr input Write at process address. Use R!wpx for input in hex",
253  "\\wP[x] addr input Write at physical address. Use R!wPx for input in hex",
254  "\\W 1|0 Honor arch write protect (1 enable WP, 0 disable WP)"
255  };
256  if (p_usage) {
257  io->cb_printf("%s\n", usage);
258  }
259  for (i = 0; i < (sizeof(help_msg) / sizeof(char *)); i++) {
260  if (!cmd || !strncmp(cmd, help_msg[i] + 1, cmd_len)) {
261  io->cb_printf("%s\n", help_msg[i]);
262  }
263  }
264  io->cb_printf("\nOld Commands: (deprecated)\n");
265  for (i = 0; i < (sizeof(help_msg_old) / sizeof(char *)); i++) {
266  if (!cmd || !strncmp(cmd, help_msg_old[i] + 1, cmd_len)) {
267  io->cb_printf("%s\n", help_msg_old[i]);
268  }
269  }
270 }
void usage(const char *message)
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags cmd
Definition: sflib.h:79
PrintfCallback cb_printf
Definition: rz_io.h:91

References rz_io_t::cb_printf, cmd, i, and usage().

Referenced by run_old_command().

◆ ReadMemory()

int ReadMemory ( RzIO io,
RzIODesc iodesc,
int  ioctl_n,
size_t  pid,
size_t  address,
ut8 buf,
int  len 
)

Definition at line 272 of file io_rzk_linux.c.

272  {
273  int ret = -1;
274  int pagesize, newlen;
275  ut64 pageaddr, offset;
276  bool flag = 0;
277  ut8 garbage;
278 
279  if (iodesc && iodesc->data > 0 && buf) {
280  struct rzk_data data;
281 
282  data.pid = pid;
283  data.addr = address;
284  data.len = len;
285  data.buff = (ut8 *)calloc(len + 1, 1);
286  if (!data.buff) {
287  return -1;
288  }
289 
290  ret = ioctl((int)(size_t)iodesc->data, ioctl_n, &data);
291  if (!ret) {
292  memcpy(buf, data.buff, len);
293  ret = len;
294  } else {
295  garbage = 0xff;
296  flag = 0;
297  offset = 0;
298  pagesize = getpagesize();
299  pageaddr = address + pagesize;
300  pageaddr -= (pageaddr % pagesize);
301  if ((len - (int)(pageaddr - address)) > 0) {
302  data.len = pageaddr - address;
303  ret = ioctl((int)(size_t)iodesc->data, ioctl_n, &data);
304  if (!ret) {
305  memcpy(buf + offset, data.buff, pageaddr - address);
306  flag = 1;
307  } else {
308  memset(buf + offset, garbage, pageaddr - address);
309  }
310 
311  offset = pageaddr - address;
312  newlen = len - offset;
313  while (newlen >= pagesize) {
314  data.addr = pageaddr;
315  data.len = pagesize;
316 
317  ret = ioctl((int)(size_t)iodesc->data, ioctl_n, &data);
318  if (!ret) {
319  memcpy(buf + offset, data.buff, pagesize);
320  flag = 1;
321  } else {
322  memset(buf + offset, garbage, pagesize);
323  }
324  pageaddr += pagesize;
325  offset += pagesize;
326  newlen -= pagesize;
327  }
328 
329  data.addr = pageaddr;
330  data.len = newlen;
331  ret = ioctl((int)(size_t)iodesc->data, ioctl_n, &data);
332  if (!ret) {
333  memcpy(buf + offset, data.buff, newlen);
334  flag = 1;
335  } else {
336  memset(buf + offset, garbage, newlen);
337  }
338  }
339  ret = flag ? len : -1;
340  }
341 
342  free(data.buff);
343  } else if (!buf) {
344  io->cb_printf("Invalid input buffer.\n");
345  } else {
346  io->cb_printf("IOCTL device not initialized.\n");
347  }
348  return ret;
349 }
size_t len
Definition: 6502dis.c:15
static static sync static getppid static getegid const char static filename ioctl
Definition: sflib.h:62
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf uLong offset
Definition: ioapi.h:144
uint8_t ut8
Definition: lh5801.h:11
return memset(p, 0, total)
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc pid
Definition: sflib.h:64
void * data
Definition: rz_io.h:102
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References rzk_data::addr, rzk_data::buff, calloc(), rz_io_t::cb_printf, rz_io_desc_t::data, free(), ioctl, len, rzk_data::len, memcpy(), memset(), pid, rzk_data::pid, and ut64().

Referenced by run_old_command(), and rzk__read().

◆ run_ioctl_command()

int run_ioctl_command ( RzIO io,
RzIODesc iodesc,
const char *  buf 
)

Definition at line 842 of file io_rzk_linux.c.

842  {
843  buf = rz_str_ichr((char *)buf, ' ');
844 
845  if (!run_new_command(io, iodesc, buf)) {
846  return run_old_command(io, iodesc, buf);
847  }
848  return 0;
849 }
int run_new_command(RzIO *io, RzIODesc *iodesc, const char *buf)
Definition: io_rzk_linux.c:772
int run_old_command(RzIO *io, RzIODesc *iodesc, const char *buf)
Definition: io_rzk_linux.c:385

References run_new_command(), run_old_command(), and rz_str_ichr().

Referenced by rzk__system().

◆ run_new_command()

int run_new_command ( RzIO io,
RzIODesc iodesc,
const char *  buf 
)

Definition at line 772 of file io_rzk_linux.c.

772  {
773  if (rz_str_startswith(buf, "dm")) {
774  if (buf[2] == ' ') {
775  // use \p pid
776  char *cmd = rz_str_newf("p %d", atoi(buf + 2));
777  run_old_command(io, iodesc, cmd);
778  free(cmd);
779  } else if (rzk_struct.beid == 1) {
780  // use \p pid
781  char *cmd = rz_str_newf("p %d", rzk_struct.pid);
782  run_old_command(io, iodesc, cmd);
783  free(cmd);
784  } else {
785  // use \M
786  run_old_command(io, iodesc, "M");
787  }
788  return 1;
789  }
790  if (rz_str_startswith(buf, "dr")) {
791  run_old_command(io, iodesc, "R");
792  return 1;
793  }
794  if (rz_str_startswith(buf, "dR")) {
795  run_old_command(io, iodesc, "Rp");
796  return 1;
797  }
798  if (rz_str_startswith(buf, "dp")) {
799  if (buf[2] == ' ') {
800  rzk_struct.pid = atoi(buf + 3);
801  } else {
802  io->cb_printf("%d\n", rzk_struct.pid);
803  }
804  return 1;
805  }
806  if (rz_str_startswith(buf, "e rzk.io")) {
807  if (strchr(buf, '?')) {
808  io->cb_printf("0: Linear memory\n");
809  io->cb_printf("1: Process memory\n");
810  io->cb_printf("2: Physical memory\n");
811  return 1;
812  }
813  const char *eq = strchr(buf, '=');
814  if (eq) {
815  int v = atoi(eq + 1);
816  int p = rzk_struct.pid;
817  char *cmd = rz_str_newf("b %d %d", v, p);
818  run_old_command(io, iodesc, cmd);
819  free(cmd);
820  } else {
821  run_new_command(io, iodesc, "dp");
822  }
823  return 1;
824  }
825  if (rz_str_startswith(buf, "e rzk.wp")) {
826  if (strchr(buf, '?')) {
827  io->cb_printf("<bool> enable write protection (disabled by default)\n");
828  return 1;
829  }
830  const char *eq = strchr(buf, '=');
831  if (eq) {
832  int v = atoi(eq + 1);
833  rzk_struct.wp = (ut8)v;
834  } else {
835  io->cb_printf("%s", rz_str_bool(rzk_struct.wp));
836  }
837  return 1;
838  }
839  return 0;
840 }
#define ut8
Definition: dcpu16.h:8
const char * v
Definition: dsignal.c:12
struct io_rzk_linux rzk_struct
void * p
Definition: libc.cpp:67
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API const char * rz_str_bool(int b)
Definition: str.c:3896
RZ_API bool rz_str_startswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string starts with a specifc sequence of characters (case sensitive)
Definition: str.c:3286

References io_rzk_linux::beid, rz_io_t::cb_printf, cmd, eq, free(), p, io_rzk_linux::pid, run_old_command(), rz_str_bool(), rz_str_newf(), rz_str_startswith(), rzk_struct, ut8, v, and io_rzk_linux::wp.

Referenced by run_ioctl_command().

◆ run_old_command()

int run_old_command ( RzIO io,
RzIODesc iodesc,
const char *  buf 
)

Definition at line 385 of file io_rzk_linux.c.

385  {
386  int ret, inphex, ioctl_n;
387  size_t pid, addr, len;
388  ut8 *databuf = NULL;
389  switch (*buf) {
390  case 'W': {
391  if (buf[1] != ' ') {
392  io->cb_printf("Write Protect: %d\n", rzk_struct.wp);
393  io->cb_printf("Usage:\n");
394  print_help(io, "W", 0);
395  break;
396  }
397 
398  int wp = getvalue(buf, 1);
399  if (wp < 0 || wp > 1) {
400  io->cb_printf("Invalid usage of W\n");
401  print_help(io, "W", 0);
402  break;
403  }
404  rzk_struct.wp = (ut8)wp;
405  } break;
406  case 'b': {
407  char *cmd = NULL;
408  if (buf[1] != ' ') {
409  io->cb_printf("beid: %d\n", rzk_struct.beid);
410  io->cb_printf("pid: %d\n", rzk_struct.pid);
411  io->cb_printf("Usage:\n");
412  print_help(io, "b", 0);
413  goto end;
414  }
415  int beid = getvalue(buf, 1);
416  int pid = getvalue(buf, 2);
417  if (beid < 0 || beid > 2) {
418  io->cb_printf("Invalid usage of b\n");
419  print_help(io, "b", 0);
420  break;
421  }
422  if (beid == 1 && pid < 0) {
423  io->cb_printf("Invalid pid read.\n");
424  print_help(io, "b", 0);
425  break;
426  }
427  rzk_struct.beid = beid;
428  rzk_struct.pid = (beid == 1) ? pid : 0;
429 
430  cmd = (char *)malloc(27);
431  if (!cmd) {
432  io->cb_printf("io_rzk_linux : Malloc failed. Seeking to 0x0\n");
433  io->corebind.cmd(io->corebind.core, "s 0");
434  } else {
435  sprintf(cmd, "s 0x%" PFMT64x, io->off);
436  io->corebind.cmd(io->corebind.core, cmd);
437  free(cmd);
438  }
439  } break;
440  case 'r': {
441  RzPrint *print = rz_print_new();
442  switch (buf[1]) {
443  case 'l':
444  // read linear address
445  // R! rl addr len
446  if (buf[2] != ' ') {
447  print_help(io, "rl", 0);
448  goto end;
449  }
450  pid = 0;
451  addr = getvalue(buf, 1);
452  len = getvalue(buf, 2);
453  if (addr == -1 || len == -1) {
454  io->cb_printf("Invalid number of arguments.\n");
455  print_help(io, "rl", 0);
456  goto end;
457  }
458  ioctl_n = IOCTL_READ_KERNEL_MEMORY;
459  break;
460  case 'p':
461  // read process address
462  // R! rp pid address len
463  if (buf[2] != ' ') {
464  print_help(io, "rp", 0);
465  goto end;
466  }
467  pid = getvalue(buf, 1);
468  addr = getvalue(buf, 2);
469  len = getvalue(buf, 3);
470  if (pid == -1 || addr == -1 || len == -1) {
471  io->cb_printf("Invalid number of arguments.\n");
472  print_help(io, "rp", 0);
473  goto end;
474  ;
475  }
476  ioctl_n = IOCTL_READ_PROCESS_ADDR;
477  break;
478  case 'P':
479  // read physical address
480  // R! rP address len
481  if (buf[2] != ' ') {
482  print_help(io, "rP", 0);
483  goto end;
484  }
485  pid = 0;
486  addr = getvalue(buf, 1);
487  len = getvalue(buf, 2);
488  if (addr == -1 || len == -1) {
489  io->cb_printf("Invalid number of arguments.\n");
490  print_help(io, "rP", 0);
491  goto end;
492  }
493  ioctl_n = IOCTL_READ_PHYSICAL_ADDR;
494  break;
495  default:
496  print_help(io, "r", 0);
497  rz_print_free(print);
498  goto end;
499  }
500  databuf = (ut8 *)calloc(len + 1, 1);
501  if (databuf) {
502  ret = ReadMemory(io, iodesc, ioctl_n, pid, addr, databuf, len);
503  if (ret > 0) {
504  char *dump = rz_print_hexdump_str(print, addr, (const ut8 *)databuf, ret, 16, 1, 1);
505  rz_cons_print(dump);
506  free(dump);
507  }
508  } else {
509  io->cb_printf("Failed to allocate buffer\n");
510  }
511  rz_print_free(print);
512  } break;
513  case 'w':
514  inphex = (buf[2] == 'x') ? 1 : 0;
515  switch (buf[1]) {
516  case 'l':
517  // write linear address
518  // R! wl addr str
519  if ((inphex && buf[3] != ' ') || (!inphex && buf[2] != ' ')) {
520  print_help(io, "wl", 0);
521  goto end;
522  }
523  pid = 0;
524  addr = getvalue(buf, 1);
525  buf = getargpos(buf, 2);
526  if (addr == -1 || !buf) {
527  io->cb_printf("Invalid number of arguments.\n");
528  print_help(io, "wl", 0);
529  goto end;
530  }
531  ioctl_n = IOCTL_WRITE_KERNEL_MEMORY;
532  break;
533  case 'p':
534  // write process address
535  // R! wp pid address str
536  if ((inphex && buf[3] != ' ') || (!inphex && buf[2] != ' ')) {
537  print_help(io, "wp", 0);
538  goto end;
539  }
540  pid = getvalue(buf, 1);
541  addr = getvalue(buf, 2);
542  buf = getargpos(buf, 3);
543  if (pid == -1 || addr == -1 || !buf) {
544  io->cb_printf("Invalid number of arguments.\n");
545  print_help(io, "wp", 0);
546  goto end;
547  }
548  ioctl_n = IOCTL_WRITE_PROCESS_ADDR;
549  break;
550  case 'P':
551  // write physical address
552  // R! wP address str
553  if ((inphex && buf[3] != ' ') || (!inphex && buf[2] != ' ')) {
554  print_help(io, "wP", 0);
555  goto end;
556  }
557  pid = 0;
558  addr = getvalue(buf, 1);
559  buf = getargpos(buf, 2);
560  if (addr == -1 || !buf) {
561  io->cb_printf("Invalid number of arguments.\n");
562  print_help(io, "wP", 0);
563  goto end;
564  }
565  ioctl_n = IOCTL_WRITE_PHYSICAL_ADDR;
566  break;
567  default:
568  print_help(io, "w", 0);
569  goto end;
570  }
571  // coverity says this cant happen, but it doesnt hurts to add a check
572  if (!buf) {
573  break;
574  }
575  len = strlen(buf);
576  databuf = (ut8 *)calloc(len + 1, 1);
577  if (databuf) {
578  if (inphex) {
579  len = rz_hex_str2bin(buf, databuf);
580  } else {
581  memcpy(databuf, buf, strlen(buf) + 1);
582  len = rz_str_unescape((char *)databuf);
583  }
584  WriteMemory(io, iodesc, ioctl_n, pid, addr, (const ut8 *)databuf, len);
585  } else {
586  eprintf("Failed to allocate buffer.\n");
587  }
588  break;
589  case 'M': {
590  // Print kernel memory map.
591  // R! M
592  int i, j;
593  struct rzk_kernel_maps map_data;
594  struct rzk_kernel_map_info *info;
595  long page_size = sysconf(_SC_PAGESIZE);
596 
597  ioctl_n = IOCTL_GET_KERNEL_MAP;
598  ret = ioctl((int)(size_t)iodesc->data, ioctl_n, &map_data);
599 
600  if (ret < 0) {
601  io->cb_printf("ioctl err: %s\n", strerror(errno));
602  break;
603  }
604 
605  io->cb_printf("map_data.size: %d, map_data.n_entries: %d\n", map_data.size, map_data.n_entries);
606  info = mmap(0, map_data.size, PROT_READ, MAP_SHARED, (int)(size_t)iodesc->data, 0);
607  if (info == MAP_FAILED) {
608  io->cb_printf("mmap err: %s\n", strerror(errno));
609  break;
610  }
611 
612  for (i = 0; i < map_data.n_entries; i++) {
613  struct rzk_kernel_map_info *in = &info[i];
614  io->cb_printf("start_addr: 0x%" PFMT64x "\n", (ut64)in->start_addr);
615  io->cb_printf("end_addr: 0x%" PFMT64x "\n", (ut64)in->end_addr);
616  io->cb_printf("n_pages: %d (%ld Kbytes)\n", in->n_pages, (in->n_pages * page_size) / 1024);
617  io->cb_printf("n_phys_addr: %d\n", in->n_phys_addr);
618  for (j = 0; j < in->n_phys_addr; j++) {
619  io->cb_printf("\tphys_addr: 0x%" PFMT64x "\n", (ut64)in->phys_addr[j]);
620  }
621  io->cb_printf("\n");
622  }
623 
624  if (munmap(info, map_data.size) == -1) {
625  io->cb_printf("munmap failed.\n");
626  }
627  } break;
628  case 'R': {
629  // Read control registers
630  // R! R[p]
631  struct rzk_control_reg reg_data;
632  ioctl_n = IOCTL_READ_CONTROL_REG;
633  ret = ioctl((int)(size_t)iodesc->data, ioctl_n, &reg_data);
634 
635  if (ret) {
636  io->cb_printf("ioctl err: %s\n", strerror(errno));
637  break;
638  }
639 
640 #if __i386__ || __x86_64__
641  // Print cr1 as null instead of random value from kernel land.
642  reg_data.cr1 = 0;
643  if (buf[1] != 0 && buf[1] == 'p') {
644  x86_ctrl_reg_pretty_print(io, reg_data);
645  } else {
646  io->cb_printf("cr0 = 0x%" PFMT64x "\n", (ut64)reg_data.cr0);
647  io->cb_printf("cr1 = 0x%" PFMT64x "\n", (ut64)reg_data.cr1);
648  io->cb_printf("cr2 = 0x%" PFMT64x "\n", (ut64)reg_data.cr2);
649  io->cb_printf("cr3 = 0x%" PFMT64x "\n", (ut64)reg_data.cr3);
650  io->cb_printf("cr4 = 0x%" PFMT64x "\n", (ut64)reg_data.cr4);
651 #if __x86_64__
652  io->cb_printf("cr8 = 0x%" PFMT64x "\n", (ut64)reg_data.cr8);
653 #endif
654  }
655 #elif __arm__
656  if (buf[1] != 0 && buf[1] == 'p') {
657  arm_ctrl_reg_pretty_print(io, reg_data);
658  } else {
659  io->cb_printf("ttbr0 = 0x%" PFMT64x "\n", (ut64)reg_data.ttbr0);
660  io->cb_printf("ttbr1 = 0x%" PFMT64x "\n", (ut64)reg_data.ttbr1);
661  io->cb_printf("ttbcr = 0x%" PFMT64x "\n", (ut64)reg_data.ttbcr);
662  io->cb_printf("c1 = 0x%" PFMT64x "\n", (ut64)reg_data.c1);
663  io->cb_printf("c3 = 0x%" PFMT64x "\n", (ut64)reg_data.c3);
664  }
665 #elif __arm64__ || __aarch64__
666  if (buf[1] != 0 && buf[1] == 'p') {
667  arm64_ctrl_reg_pretty_print(io, reg_data);
668  } else {
669  io->cb_printf("sctlr_el1 = 0x%" PFMT64x "\n", (ut64)reg_data.sctlr_el1);
670  io->cb_printf("ttbr0_el1 = 0x%" PFMT64x "\n", (ut64)reg_data.ttbr0_el1);
671  io->cb_printf("ttbr1_el1 = 0x%" PFMT64x "\n", (ut64)reg_data.ttbr1_el1);
672  io->cb_printf("tcr_el1 = 0x%" PFMT64x "\n", (ut64)reg_data.tcr_el1);
673  }
674 #endif
675  } break;
676  case 'p': {
677  // Print process info
678  // R! p pid
679  ut64 i;
680  ut64 nextstart;
681  ut64 buffsize;
682  bool fflag = 0;
683  struct rzk_proc_info proc_data;
684 
685  if (*(buf + 1) == '*') {
686  fflag = 1;
687  }
688  switch (*(buf + 1)) {
689  case '*':
690  fflag = 1;
691  if (*(buf + 2) != ' ') {
692  print_help(io, "p*", 0);
693  goto end;
694  }
695  break;
696  case ' ':
697  break;
698  default:
699  print_help(io, "p", 0);
700  goto end;
701  }
702 
703  pid = getvalue(buf, 1);
704  if (pid == -1) {
705  io->cb_printf("Invalid number of arguments.\n");
706  print_help(io, "p", 0);
707  break;
708  }
709  proc_data.pid = pid;
710  ioctl_n = IOCTL_PRINT_PROC_INFO;
711 
712  ret = ioctl((int)(size_t)iodesc->data, ioctl_n, &proc_data);
713  if (ret) {
714  io->cb_printf("ioctl err: %s\n", strerror(errno));
715  break;
716  }
717 
718  buffsize = (ut64)(sizeof(proc_data.vmareastruct) / sizeof(proc_data.vmareastruct[0]));
719  if (fflag) {
720  int j = 0;
721  for (i = 0; i + 1 < buffsize;) {
722  nextstart = 0;
723  if (i + 7 < buffsize) {
724  nextstart = i + 7 + (strlen((const char *)&(proc_data.vmareastruct[i + 7])) - 1 + sizeof(size_t)) / sizeof(size_t);
725  }
726  if (!proc_data.vmareastruct[i] && (i + 1 < buffsize) &&
727  !proc_data.vmareastruct[i + 1] &&
728  nextstart > 0 && nextstart - 1 < buffsize) {
729  break;
730  }
731  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]);
732  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]);
733  j += 1;
734  i = nextstart;
735  }
736  io->cb_printf("f pid.%d.task_struct @ 0x%08zu\n", proc_data.pid, proc_data.task);
737  } else {
738  io->cb_printf("pid = %d\nprocess name = %s\n", proc_data.pid, proc_data.comm);
739  io->cb_printf("task_struct = 0x%08zu\n", proc_data.task);
740  for (i = 0; i < buffsize;) {
741  nextstart = 0;
742  if (i + 7 < buffsize) {
743  nextstart = i + 7 + (strlen((const char *)&(proc_data.vmareastruct[i + 7])) - 1 + sizeof(size_t)) / sizeof(size_t);
744  }
745  if (!proc_data.vmareastruct[i] && !proc_data.vmareastruct[i + 1] &&
746  nextstart > 0 && nextstart - 1 < buffsize) {
747  break;
748  }
749  io->cb_printf("0x%08" PFMT64x " - 0x%08" PFMT64x " %c%c%c%c 0x%08" PFMT64x " %02zu:%02zu %-8" PFMT64u "",
750  (ut64)proc_data.vmareastruct[i], (ut64)proc_data.vmareastruct[i + 1],
751  proc_data.vmareastruct[i + 2] & VM_READ ? 'r' : '-',
752  proc_data.vmareastruct[i + 2] & VM_WRITE ? 'w' : '-',
753  proc_data.vmareastruct[i + 2] & VM_EXEC ? 'x' : '-',
754  proc_data.vmareastruct[i + 2] & VM_MAYSHARE ? 's' : 'p',
755  (ut64)proc_data.vmareastruct[i + 3], proc_data.vmareastruct[i + 4],
756  proc_data.vmareastruct[i + 5], (ut64)proc_data.vmareastruct[i + 6]);
757  io->cb_printf("\t%s\n", (char *)&(proc_data.vmareastruct[i + 7]));
758  i = nextstart;
759  }
760  io->cb_printf("STACK BASE ADDRESS = 0x%zx\n", proc_data.stack);
761  }
762  } break;
763  default: {
764  print_help(io, NULL, 1);
765  }
766  }
767 end:
768  free(databuf);
769  return 0;
770 }
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
const lzma_allocator const uint8_t * in
Definition: block.h:527
#define NULL
Definition: cris-opc.c:27
static void print_help(RzIO *io, char *cmd, int p_usage)
Definition: io_rzk_linux.c:231
static size_t getvalue(const char *buf, int pos)
Definition: io_rzk_linux.c:220
int WriteMemory(RzIO *io, RzIODesc *iodesc, int ioctl_n, size_t pid, ut64 address, const ut8 *buf, int len)
Definition: io_rzk_linux.c:351
int ReadMemory(RzIO *io, RzIODesc *iodesc, int ioctl_n, size_t pid, size_t address, ut8 *buf, int len)
Definition: io_rzk_linux.c:272
#define IOCTL_READ_KERNEL_MEMORY
Definition: io_rzk_linux.h:110
#define IOCTL_GET_KERNEL_MAP
Definition: io_rzk_linux.h:116
#define VM_EXEC
Definition: io_rzk_linux.h:122
#define IOCTL_READ_PHYSICAL_ADDR
Definition: io_rzk_linux.h:114
#define IOCTL_WRITE_PHYSICAL_ADDR
Definition: io_rzk_linux.h:115
#define VM_MAYSHARE
Definition: io_rzk_linux.h:123
#define IOCTL_WRITE_PROCESS_ADDR
Definition: io_rzk_linux.h:113
#define IOCTL_WRITE_KERNEL_MEMORY
Definition: io_rzk_linux.h:111
#define IOCTL_READ_CONTROL_REG
Definition: io_rzk_linux.h:117
#define IOCTL_PRINT_PROC_INFO
Definition: io_rzk_linux.h:118
#define IOCTL_READ_PROCESS_ADDR
Definition: io_rzk_linux.h:112
#define VM_WRITE
Definition: io_rzk_linux.h:121
#define VM_READ
Definition: io_rzk_linux.h:120
sprintf
Definition: kernel.h:365
void * malloc(size_t size)
Definition: malloc.c:123
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz fd_set fd_set fd_set struct timeval static timeout const char char static bufsiz const char static swapflags mmap
Definition: sflib.h:115
static const void static count static fd struct stat static buf struct pollfd unsigned static timeout void static offset munmap
Definition: sflib.h:43
RZ_API RzPrint * rz_print_new(void)
Definition: print.c:56
RZ_API RzPrint * rz_print_free(RzPrint *p)
Definition: print.c:101
RZ_API RZ_OWN char * rz_print_hexdump_str(RZ_NONNULL RzPrint *p, ut64 addr, RZ_NONNULL const ut8 *buf, int len, int base, int step, size_t zoomsz)
Prints a hexdump of buf at addr.
Definition: print.c:573
#define eprintf(x, y...)
Definition: rlcc.c:7
RZ_API int rz_hex_str2bin(const char *in, ut8 *out)
Convert an input string in into the binary form in out.
Definition: hex.c:444
RZ_API int rz_str_unescape(char *buf)
Definition: str.c:1300
#define PFMT64u
Definition: rz_types.h:395
#define PFMT64x
Definition: rz_types.h:393
#define PROT_READ
Definition: sftypes.h:95
int size_t
Definition: sftypes.h:40
#define MAP_SHARED
Definition: sftypes.h:101
RzCoreCmd cmd
Definition: rz_bind.h:32
void * core
Definition: rz_bind.h:31
RzCoreBind corebind
Definition: rz_io.h:92
ut64 off
Definition: rz_io.h:61
static int addr
Definition: z80asm.c:58

References addr, io_rzk_linux::beid, calloc(), rz_io_t::cb_printf, rz_core_bind_t::cmd, cmd, rzk_proc_info::comm, rz_core_bind_t::core, rz_io_t::corebind, rz_io_desc_t::data, test_evm::end, eprintf, free(), getargpos(), getvalue(), i, in, info(), ioctl, IOCTL_GET_KERNEL_MAP, IOCTL_PRINT_PROC_INFO, IOCTL_READ_CONTROL_REG, IOCTL_READ_KERNEL_MEMORY, IOCTL_READ_PHYSICAL_ADDR, IOCTL_READ_PROCESS_ADDR, IOCTL_WRITE_KERNEL_MEMORY, IOCTL_WRITE_PHYSICAL_ADDR, IOCTL_WRITE_PROCESS_ADDR, len, malloc(), MAP_SHARED, memcpy(), mmap, munmap, rzk_kernel_maps::n_entries, NULL, rz_io_t::off, PFMT64u, PFMT64x, pid, io_rzk_linux::pid, rzk_proc_info::pid, print_help(), PROT_READ, ReadMemory(), rz_hex_str2bin(), rz_print_free(), rz_print_hexdump_str(), rz_print_new(), rz_str_unescape(), rzk_struct, rzk_kernel_maps::size, sprintf, rzk_proc_info::stack, rzk_proc_info::task, ut64(), ut8, VM_EXEC, VM_MAYSHARE, VM_READ, VM_WRITE, rzk_proc_info::vmareastruct, io_rzk_linux::wp, rzk_data::wp, and WriteMemory().

Referenced by run_ioctl_command(), and run_new_command().

◆ WriteMemory()

int WriteMemory ( RzIO io,
RzIODesc iodesc,
int  ioctl_n,
size_t  pid,
ut64  address,
const ut8 buf,
int  len 
)

Definition at line 351 of file io_rzk_linux.c.

351  {
352  int ret = -1;
353 
354  if (iodesc && iodesc->data > 0 && buf) {
355  struct rzk_data data;
356 
357  data.pid = pid;
358  data.addr = address;
359  data.len = len;
360  data.buff = (ut8 *)calloc(len + 1, 1);
361  data.wp = rzk_struct.wp;
362 
363  if (!data.buff) {
364  return -1;
365  }
366 
367  memcpy(data.buff, buf, len);
368  ret = ioctl((int)(size_t)iodesc->data, ioctl_n, &data);
369  if (!ret) {
370  ret = len;
371  } else {
372  io->cb_printf("Write failed. ioctl err: %s\n", strerror(errno));
373  ret = -1;
374  }
375 
376  free(data.buff);
377  } else if (!buf) {
378  io->cb_printf("Invalid input buffer.\n");
379  } else {
380  io->cb_printf("IOCTL device not initialized.\n");
381  }
382  return ret;
383 }

References rzk_data::addr, rzk_data::buff, calloc(), rz_io_t::cb_printf, rz_io_desc_t::data, free(), ioctl, len, rzk_data::len, memcpy(), pid, rzk_data::pid, rzk_struct, io_rzk_linux::wp, and rzk_data::wp.

Referenced by run_old_command(), and rzk__write().