Rizin
unix-like reverse engineering framework and cli tools
io_dmp.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2022 GustavoLCR <gugulcr@gmail.com>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_io.h>
5 #include <winkd.h>
7 
8 static bool dmp_plugin_open(RzIO *io, const char *file, bool many) {
9  return (!strncmp(file, "dmp://", 6));
10 }
11 
12 typedef struct {
13  RzIO *io;
15 } ReadAtCtx;
16 
17 static int op_at_phys(void *user, ut64 address, const ut8 *in, ut8 *out, int len, bool write) {
18  ReadAtCtx *ctx = user;
19  DmpCtx *dmp = ctx->fd->data;
20  const ut64 saved_target = dmp->target;
21  dmp->target = TARGET_BACKEND;
22  int saved_va = ctx->io->va;
23  ctx->io->va = 1;
24  int ret = write ? rz_io_write_at(ctx->io, address, in, len) : rz_io_nread_at(ctx->io, address, out, len);
25  ctx->io->va = saved_va;
26  dmp->target = saved_target;
27  return ret;
28 }
29 
30 static int read_at_phys(void *user, ut64 address, ut8 *buf, int len) {
31  return op_at_phys(user, address, NULL, buf, len, false);
32 }
33 
34 static int write_at_phys(void *user, ut64 address, const ut8 *buf, int len) {
35  return op_at_phys(user, address, buf, NULL, len, true);
36 }
37 
38 static int read_at_kernel_virtual(void *user, ut64 address, ut8 *buf, int len) {
39  ReadAtCtx *ctx = user;
40  DmpCtx *dmp = ctx->fd->data;
41  if (dmp->type == DMP_DUMPTYPE_TRIAGE) {
42  int saved_va = ctx->io->va;
43  ctx->io->va = 1;
44  int ret = rz_io_nread_at(ctx->io, address, buf, len);
45  ctx->io->va = saved_va;
46  return ret;
47  }
48  const ut64 saved_target = dmp->target;
49  dmp->target = TARGET_KERNEL;
50  int ret = rz_io_desc_read_at(ctx->fd, address, buf, len);
51  dmp->target = saved_target;
52  return ret;
53 }
54 
55 static RzIODesc *dmp_open(RzIO *io, const char *file, int rw, int mode) {
56  if (!dmp_plugin_open(io, file, 0)) {
57  return NULL;
58  }
59  RzIOPlugin *p = rz_io_plugin_resolve(io, file + 6, false);
60  if (!p) {
61  return NULL;
62  }
64  if (!ctx) {
65  return NULL;
66  }
67  rz_vector_init(&ctx->KiProcessorBlock, sizeof(ut64), NULL, NULL);
68  ctx->backend = p->open(io, file + 6, rw, mode);
69  if (!ctx->backend) {
70  free(ctx);
71  return NULL;
72  }
73  ctx->target = TARGET_BACKEND;
74  ctx->windctx.read_at_physical = read_at_phys;
75  ctx->windctx.write_at_physical = write_at_phys;
76  ctx->windctx.read_at_kernel_virtual = read_at_kernel_virtual;
78  if (!c) {
79  free(ctx);
80  return NULL;
81  }
82  c->io = io;
83  c->fd = rz_io_desc_new(io, &rz_io_plugin_dmp, file, rw, mode, ctx);
84  if (!c->fd) {
85  free(c);
86  free(ctx);
87  return NULL;
88  }
89  c->fd->name = strdup(file + 6);
90  ctx->windctx.user = c;
91  return c->fd;
92 }
93 
94 static int dmp_write(RzIO *io, RzIODesc *fd, const ut8 *buf, int count) {
95  if (!fd) {
96  return -1;
97  }
98  DmpCtx *ctx = fd->data;
99  if (ctx->target == TARGET_BACKEND) {
100  return rz_io_desc_write_at(ctx->backend, io->off, buf, count);
101  }
102  ut64 address = io->off;
103  if (ctx->target != TARGET_PHYSICAL) {
104  WindProc saved_proc = ctx->windctx.target;
105  WindProc kernel_proc = { .dir_base_table = ctx->kernelDirectoryTable };
106  if (ctx->target == TARGET_KERNEL) {
107  ctx->windctx.target = kernel_proc;
108  }
109  int ret = winkd_write_at_uva(&ctx->windctx, address, buf, count);
110  ctx->windctx.target = saved_proc;
111  return ret;
112  }
113  return write_at_phys(ctx->windctx.user, address, buf, count);
114 }
115 
116 static ut64 dmp_lseek(RzIO *io, RzIODesc *fd, ut64 offset, int whence) {
117  DmpCtx *ctx = fd->data;
118  if (ctx->target == TARGET_BACKEND) {
119  return rz_io_desc_seek(ctx->backend, offset, whence);
120  } else {
121  switch (whence) {
122  case RZ_IO_SEEK_SET: return io->off = offset;
123  case RZ_IO_SEEK_CUR: return io->off += offset;
124  case RZ_IO_SEEK_END: return io->off = UT64_MAX - offset;
125  default: return offset;
126  }
127  }
128 }
129 
130 static int dmp_read(RzIO *io, RzIODesc *fd, ut8 *buf, int count) {
131  if (!fd) {
132  return -1;
133  }
134  DmpCtx *ctx = fd->data;
135  if (ctx->target == TARGET_BACKEND) {
136  return rz_io_desc_read_at(ctx->backend, io->off, buf, count);
137  }
138  ut64 address = io->off;
139  if (ctx->target != TARGET_PHYSICAL) {
140  WindProc saved_proc = ctx->windctx.target;
141  WindProc kernel_proc = { .dir_base_table = ctx->kernelDirectoryTable };
142  if (ctx->target == TARGET_KERNEL) {
143  ctx->windctx.target = kernel_proc;
144  }
145  int ret = winkd_read_at_uva(&ctx->windctx, address, buf, count);
146  ctx->windctx.target = saved_proc;
147  return ret;
148  }
149  return read_at_phys(ctx->windctx.user, address, buf, count);
150 }
151 
152 static int dmp_close(RzIODesc *fd) {
153  DmpCtx *ctx = fd->data;
154  rz_io_desc_close(ctx->backend);
155  winkd_ctx_fini(&ctx->windctx);
156  rz_vector_fini(&ctx->KiProcessorBlock);
157  free(ctx->context);
158  RZ_FREE(fd->data);
159  return true;
160 }
161 
163  .name = "dmp",
164  .desc = "Debug a Windows DMP file",
165  .uris = "dmp://",
166  .license = "LGPL3",
167  .open = dmp_open,
168  .close = dmp_close,
169  .read = dmp_read,
170  .check = dmp_plugin_open,
171  .lseek = dmp_lseek,
172  .write = dmp_write,
173 };
174 
175 #ifndef RZ_PLUGIN_INCORE
177  .type = RZ_LIB_TYPE_IO,
178  .data = &rz_io_plugin_dmp,
180 };
181 #endif
size_t len
Definition: 6502dis.c:15
const lzma_allocator const uint8_t * in
Definition: block.h:527
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
#define RZ_API
#define NULL
Definition: cris-opc.c:27
static static fork write
Definition: sflib.h:33
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 static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
#define DMP_DUMPTYPE_TRIAGE
Definition: dmp_specs.h:20
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
static int read_at_phys(void *user, ut64 address, ut8 *buf, int len)
Definition: io_dmp.c:30
static RzIODesc * dmp_open(RzIO *io, const char *file, int rw, int mode)
Definition: io_dmp.c:55
static int op_at_phys(void *user, ut64 address, const ut8 *in, ut8 *out, int len, bool write)
Definition: io_dmp.c:17
static bool dmp_plugin_open(RzIO *io, const char *file, bool many)
Definition: io_dmp.c:8
static int dmp_close(RzIODesc *fd)
Definition: io_dmp.c:152
static int read_at_kernel_virtual(void *user, ut64 address, ut8 *buf, int len)
Definition: io_dmp.c:38
static ut64 dmp_lseek(RzIO *io, RzIODesc *fd, ut64 offset, int whence)
Definition: io_dmp.c:116
RZ_API RzLibStruct rizin_plugin
Definition: io_dmp.c:176
static int write_at_phys(void *user, ut64 address, const ut8 *buf, int len)
Definition: io_dmp.c:34
RzIOPlugin rz_io_plugin_dmp
Definition: io_dmp.c:162
static int dmp_read(RzIO *io, RzIODesc *fd, ut8 *buf, int count)
Definition: io_dmp.c:130
static int dmp_write(RzIO *io, RzIODesc *fd, const ut8 *buf, int count)
Definition: io_dmp.c:94
@ TARGET_KERNEL
Definition: io_windbg.c:397
voidpf uLong offset
Definition: ioapi.h:144
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
void * p
Definition: libc.cpp:67
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
#define RZ_IO_SEEK_CUR
Definition: rz_io.h:16
RZ_API ut64 rz_io_desc_seek(RzIODesc *desc, ut64 offset, int whence)
Definition: io_desc.c:217
RZ_API RzIODesc * rz_io_desc_new(RzIO *io, RzIOPlugin *plugin, const char *uri, int flags, int mode, void *data)
Definition: io_desc.c:11
RZ_API int rz_io_desc_read_at(RzIODesc *desc, ut64 addr, ut8 *buf, int len)
Definition: io_desc.c:351
RZ_API int rz_io_desc_write_at(RzIODesc *desc, ut64 addr, const ut8 *buf, int len)
Definition: io_desc.c:358
#define RZ_IO_SEEK_SET
Definition: rz_io.h:15
RZ_API bool rz_io_write_at(RzIO *io, ut64 addr, const ut8 *buf, int len)
Definition: io.c:358
RZ_API int rz_io_nread_at(RzIO *io, ut64 addr, ut8 *buf, int len)
Definition: io.c:338
RZ_API RzIOPlugin * rz_io_plugin_resolve(RzIO *io, const char *filename, bool many)
Definition: io_plugin.c:54
#define RZ_IO_SEEK_END
Definition: rz_io.h:17
RZ_API bool rz_io_desc_close(RzIODesc *desc)
Definition: io_desc.c:165
@ RZ_LIB_TYPE_IO
Definition: rz_lib.h:69
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_FREE(x)
Definition: rz_types.h:369
#define UT64_MAX
Definition: rz_types_base.h:86
RZ_API void rz_vector_fini(RzVector *vec)
Definition: vector.c:61
RZ_API void rz_vector_init(RzVector *vec, size_t elem_size, RzVectorFree free, void *free_user)
Definition: vector.c:33
#define RZ_VERSION
Definition: rz_version.h:8
#define c(i)
Definition: sha256.c:43
RzIODesc * fd
Definition: io_dmp.c:14
RzIO * io
Definition: io_dmp.c:13
Definition: winkd.h:11
ut64 dir_base_table
Definition: winkd.h:15
Definition: winkd.h:118
ut32 type
Definition: winkd.h:120
ut64 target
Definition: winkd.h:121
Definition: gzappend.c:170
const char * name
Definition: rz_io.h:115
const char * version
Definition: rz_io.h:117
Definition: rz_io.h:59
ut64 off
Definition: rz_io.h:61
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
int winkd_write_at_uva(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 address, RZ_BORROW RZ_NONNULL RZ_IN const ut8 *buf, int count)
Definition: winkd.c:600
int winkd_read_at_uva(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 address, RZ_BORROW RZ_NONNULL RZ_OUT ut8 *buf, int count)
Definition: winkd.c:596
#define TARGET_BACKEND
Definition: winkd.h:113
static void winkd_ctx_fini(RZ_BORROW RZ_NONNULL WindCtx *ctx)
Definition: winkd.h:141
#define TARGET_PHYSICAL
Definition: winkd.h:114
static const z80_opcode fd[]
Definition: z80_tab.h:997