Rizin
unix-like reverse engineering framework and cli tools
debug_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_core.h>
5 #include <rz_debug.h>
6 #include <dmp_specs.h>
7 #include <dmp64.h>
8 #include <pe_specs.h>
9 #include <winkd.h>
10 #include "common_winkd.h"
11 
12 #include "native/bt/windows-x64.c"
13 #include "native/bt/generic-all.c"
14 
15 static bool rz_debug_dmp_init(RzDebug *dbg, void **user) {
16  RzCore *core = dbg->corebind.core;
17  RzIODesc *desc = core->io->desc;
18  if (!desc) {
19  return false;
20  }
21  if (strcmp(desc->plugin->name, "dmp")) {
22  RZ_LOG_ERROR("Open a file with dmp:// to use the 'dmp' debug plugin\n");
23  return false;
24  }
25  RzBinInfo *info = core->bin->cur->o->info;
26  if (!info || !info->rclass || strcmp(info->rclass, "dmp64")) {
27  RZ_LOG_ERROR("Open a Windows kernel dump file with dmp:// to use the 'dmp' debug plugin\n");
28  return false;
29  }
30 
31  dbg->plugin_data = core->io->desc->data;
33  ctx->bf = core->bin->cur;
34 
35  int ret = rz_hex_str2bin(core->bin->cur->o->regstate, NULL);
36  ctx->context = malloc(ret);
37  if (!ctx->context) {
38  return false;
39  }
40  ctx->context_sz = ret;
41  rz_hex_str2bin(core->bin->cur->o->regstate, ctx->context);
42 
43  ut32 MachineImageType = 0; // Windows Architecture (IMAGE_FILE_MACHINE)
44  ut32 MinorVersion = 0; // Windows Version
45  ut32 ServicePackBuild = 0;
46  ut32 ProcessOffset = 0;
47  ut32 ThreadOffset = 0;
48  ut32 CallStackOffset = 0;
49  ut32 SizeOfCallStack = 0;
50  ut64 TopOfStack = 0;
51  ut32 NumberProcessors = 0;
52  ctx->target = TARGET_BACKEND;
53  dbg->corebind.cmd(dbg->corebind.core, "e io.va=0");
55  rz_buf_read_le64_at(b, rz_offsetof(dmp64_header, DirectoryTableBase), &ctx->kernelDirectoryTable);
56  rz_buf_read_le64_at(b, rz_offsetof(dmp64_header, PsActiveProcessHead), &ctx->windctx.PsActiveProcessHead);
57  rz_buf_read_le64_at(b, rz_offsetof(dmp64_header, PsLoadedModuleList), &ctx->windctx.PsLoadedModuleList);
58  rz_buf_read_le64_at(b, rz_offsetof(dmp64_header, KdDebuggerDataBlock), &ctx->windctx.KdDebuggerDataBlock);
59  rz_buf_read_le32_at(b, rz_offsetof(dmp64_header, NumberProcessors), &NumberProcessors);
60  rz_buf_read_le32_at(b, rz_offsetof(dmp64_header, DumpType), &ctx->type);
61  rz_buf_read_le32_at(b, rz_offsetof(dmp64_header, MachineImageType), &MachineImageType);
62  rz_buf_read_le32_at(b, rz_offsetof(dmp64_header, MinorVersion), &MinorVersion);
63  rz_buf_read_le32_at(b, sizeof(dmp64_header) + rz_offsetof(dmp64_triage, ServicePackBuild), &ServicePackBuild);
64  rz_buf_read_le32_at(b, sizeof(dmp64_header) + rz_offsetof(dmp64_triage, ProcessOffset), &ProcessOffset);
65  rz_buf_read_le32_at(b, sizeof(dmp64_header) + rz_offsetof(dmp64_triage, ThreadOffset), &ThreadOffset);
66  rz_buf_read_le32_at(b, sizeof(dmp64_header) + rz_offsetof(dmp64_triage, CallStackOffset), &CallStackOffset);
67  rz_buf_read_le32_at(b, sizeof(dmp64_header) + rz_offsetof(dmp64_triage, SizeOfCallStack), &SizeOfCallStack);
68  rz_buf_read_le64_at(b, sizeof(dmp64_header) + rz_offsetof(dmp64_triage, TopOfStack), &TopOfStack);
69  rz_buf_free(b);
70 
71  RzIOMap *map = rz_io_map_get(core->io, 0);
72  if (map) {
73  // Remove file mapping
74  rz_io_map_del(core->io, map->id);
75  }
76  if (ctx->type == DMP_DUMPTYPE_TRIAGE) {
77  dbg->corebind.cfgSetI(dbg->corebind.core, "io.va", 1);
78  ctx->target = TARGET_BACKEND;
79  ctx->kernelDirectoryTable = TARGET_BACKEND;
80  } else {
81  ctx->target = TARGET_KERNEL;
82  ServicePackBuild = winkd_get_sp(&ctx->windctx);
83  }
84 
85  switch (MachineImageType) {
87  ctx->windctx.is_arm = true;
88  ctx->windctx.is_64bit = true;
89  ctx->windctx.is_pae = true;
90  break;
92  ctx->windctx.is_arm = true;
93  ctx->windctx.is_pae = true;
94  break;
96  ctx->windctx.is_64bit = true;
97  ctx->windctx.is_pae = true;
98  break;
99  default:
100  return false;
101  }
102 
103  ctx->windctx.profile = winkd_get_profile(dbg->bits * 8, MinorVersion, ServicePackBuild);
104 
105  // Find ntoskrnl.exe module
106  RzListIter *it;
107  WindModule mod = { 0 };
108  if (ctx->type == DMP_DUMPTYPE_TRIAGE) {
109  struct rz_bin_dmp64_obj_t *obj = core->bin->cur->o->bin_obj;
110  dmp_driver_desc *driver;
111  rz_list_foreach (obj->drivers, it, driver) {
112  if (rz_str_endswith(driver->file, "\\ntoskrnl.exe")) {
113  mod.name = driver->file;
114  mod.addr = driver->base;
115  mod.size = driver->size;
116  mod.timestamp = driver->timestamp;
117  break;
118  }
119  }
120  } else {
121  WindProc kernel = { .dir_base_table = ctx->kernelDirectoryTable, .uniqueid = 4 };
122  ctx->windctx.target = kernel;
123  RzList *modules = winkd_list_modules(&ctx->windctx);
124  WindModule *m;
125  rz_list_foreach (modules, it, m) {
126  if (rz_str_endswith(m->name, "\\ntoskrnl.exe")) {
127  mod = *m;
128  break;
129  }
130  }
131  ctx->windctx.target.uniqueid = 0;
132  }
133  char *kernel_pdb = NULL;
134  if (mod.name) {
135  core->bin->cur->o->opts.baseaddr = mod.addr;
136  const char *server = dbg->corebind.cfgGet(dbg->corebind.core, "pdb.server");
137  const char *symstore = dbg->corebind.cfgGet(dbg->corebind.core, "pdb.symstore");
138  char *pdbpath, *exepath;
139  if (winkd_download_module_and_pdb(&mod, server, symstore, &exepath, &pdbpath)) {
140  // TODO: Convert to API call
141  dbg->corebind.cmdf(dbg->corebind.core, "idp \"%s\"", pdbpath);
142  free(exepath);
143  kernel_pdb = strdup(rz_file_basename(pdbpath));
144  free(pdbpath);
145  if (!ctx->windctx.profile) {
146  winkd_build_profile(&ctx->windctx, dbg->analysis->typedb);
147  if (ctx->windctx.profile) {
148  ctx->windctx.profile->build = MinorVersion;
149  ctx->windctx.profile->sp = ServicePackBuild;
150  }
151  }
152  } else {
153  RZ_LOG_WARN("Failed to download ntoskrnl.pdb, many things won't work.\n");
154  }
155  }
156 
157  if (!ctx->windctx.profile) {
158  RZ_LOG_ERROR("Could not find a profile for this Windows: %s %" PFMT32d "-bit %" PFMT32u " SP %" PFMT32u "\n",
159  ctx->windctx.is_arm ? "ARM" : "x86", dbg->bits * 8, MinorVersion, ServicePackBuild);
160  return false;
161  }
162 
163  ctx->kthread_process_offset = rz_type_db_struct_member_offset(dbg->analysis->typedb, "_KTHREAD", "Process");
164  ctx->kprcb_context_offset = rz_type_db_struct_member_offset(dbg->analysis->typedb, "_KPRCB", "Context");
165  if (ctx->windctx.is_arm) {
166  const ut64 switch_frame_offset = rz_type_db_struct_member_offset(dbg->analysis->typedb, "_KTHREAD", "SwitchFrame");
167  ctx->kthread_switch_frame_offset = switch_frame_offset + rz_type_db_struct_member_offset(dbg->analysis->typedb, "_KSWITCH_FRAME", "Fp");
168  }
169  char *kpb_flag_name;
170  if (kernel_pdb) {
171  rz_str_replace(kernel_pdb, ".pdb", "", 0);
172  kpb_flag_name = rz_str_newf("pdb.%s.KiProcessorBlock", kernel_pdb);
173  free(kernel_pdb);
174  } else {
175  kpb_flag_name = strdup("0");
176  }
177  const ut64 KiProcessorBlock = dbg->corebind.numGet(dbg->corebind.core, kpb_flag_name);
178  free(kpb_flag_name);
179  ut64 i;
180  for (i = 0; i < NumberProcessors; i++) {
181  ut64 address = KiProcessorBlock + i * (ctx->windctx.is_64bit ? 8 : 4);
182  ut64 kprcb = winkd_read_ptr_at(&ctx->windctx, ctx->windctx.read_at_kernel_virtual, address);
183  rz_vector_push(&ctx->KiProcessorBlock, &kprcb);
184  }
185 
186  if (ctx->type == DMP_DUMPTYPE_TRIAGE) {
187  // Map Call stack into address space
188  map = rz_io_map_new(core->io, desc->fd, RZ_PERM_R, CallStackOffset, TopOfStack, SizeOfCallStack);
189 
190  // Map ETHREAD into address space
191  const ut64 address = 0x1000;
192  map = rz_io_map_new(core->io, desc->fd, RZ_PERM_R, ThreadOffset, address, CallStackOffset - ThreadOffset);
193  map->name = strdup("kernel.target.ethread");
194  WindThread *target_thread = winkd_get_thread_at(&ctx->windctx, address);
195 
196  ctx->windctx.target_thread.ethread = address;
197  const ut64 current_thread_offset = ctx->windctx.is_64bit ? 8 : 4;
198  ut64 *kprcb;
199  rz_vector_foreach(&ctx->KiProcessorBlock, kprcb) {
200  const ut64 current_thread = winkd_read_ptr_at(&ctx->windctx, ctx->windctx.read_at_kernel_virtual, *kprcb + current_thread_offset);
201  WindThread *thread = winkd_get_thread_at(&ctx->windctx, current_thread);
202  if (thread && thread->uniqueid == target_thread->uniqueid) {
203  // Map EPROCESS into address space
204  const ut64 current_process = winkd_read_ptr_at(&ctx->windctx, ctx->windctx.read_at_kernel_virtual, thread->ethread + ctx->kthread_process_offset);
205  RzIOMap *map = rz_io_map_new(core->io, desc->fd, RZ_PERM_R, ProcessOffset, current_process, ThreadOffset - ProcessOffset);
206  map->name = strdup("kernel.target.eprocess");
207  WindProc *process = winkd_get_process_at(&ctx->windctx, current_process);
208  ctx->windctx.target = *process;
209  ctx->windctx.target_thread = *thread;
210  free(process);
211  free(thread);
212  break;
213  }
214  free(thread);
215  }
216  rz_io_map_remap(core->io, map->id, ctx->windctx.target_thread.ethread);
217  free(target_thread);
218  }
219 
220  return true;
221 }
222 
223 static int rz_debug_dmp_attach(RzDebug *dbg, int pid) {
225  if (ctx->type == DMP_DUMPTYPE_TRIAGE) {
226  dbg->pid = ctx->windctx.target.uniqueid;
227  dbg->tid = ctx->windctx.target_thread.uniqueid;
228  return dbg->pid;
229  }
230  const ut64 current_thread_offset = ctx->windctx.is_64bit ? 8 : 4;
231  ut64 *kprcb;
232  rz_vector_foreach_prev(&ctx->KiProcessorBlock, kprcb) {
233  const ut64 current_thread = winkd_read_ptr_at(&ctx->windctx, ctx->windctx.read_at_kernel_virtual, *kprcb + current_thread_offset);
234  WindThread *thread = winkd_get_thread_at(&ctx->windctx, current_thread);
235  if (!thread) {
236  continue;
237  }
238  const ut64 current_process = winkd_read_ptr_at(&ctx->windctx, ctx->windctx.read_at_kernel_virtual, thread->ethread + ctx->kthread_process_offset);
239  WindProc *process = winkd_get_process_at(&ctx->windctx, current_process);
240  if (!process || (!process->uniqueid && !strncmp(process->name, "Idle", sizeof(process->name)))) {
241  free(thread);
242  free(process);
243  continue;
244  }
245  ctx->windctx.target = *process;
246  ctx->windctx.target_thread = *thread;
247  free(thread);
248  free(process);
249  break;
250  }
251 
252  dbg->pid = ctx->windctx.target.uniqueid;
253  dbg->tid = ctx->windctx.target_thread.uniqueid;
254  return ctx->windctx.target.uniqueid;
255 }
256 
260  if (!ret) {
261  return NULL;
262  }
263  RzVector procs;
264  rz_vector_init(&procs, sizeof(ut64), NULL, NULL);
265  const ut64 current_thread_offset = ctx->windctx.is_64bit ? 8 : 4;
266  ut64 *kprcb;
267  // Get currently running processes
268  rz_vector_foreach_prev(&ctx->KiProcessorBlock, kprcb) {
269  const ut64 current_thread = winkd_read_ptr_at(&ctx->windctx, ctx->windctx.read_at_kernel_virtual, *kprcb + current_thread_offset);
270  ut64 current_process = winkd_read_ptr_at(&ctx->windctx, ctx->windctx.read_at_kernel_virtual, current_thread + ctx->kthread_process_offset);
271  rz_vector_push(&procs, &current_process);
272  }
273 
274  RzList *pids = winkd_list_process(&ctx->windctx);
275  RzListIter *it;
276  WindProc *p;
277  rz_list_foreach (pids, it, p) {
278  RzDebugPid *newpid = RZ_NEW0(RzDebugPid);
279  if (!newpid) {
281  rz_list_free(ret);
282  rz_list_free(pids);
283  return NULL;
284  }
285  newpid->path = strdup(p->name);
286  newpid->pid = p->uniqueid;
287  newpid->status = 's';
288  newpid->runnable = true;
289  ut64 *process;
291  if (*process == p->eprocess) {
292  newpid->status = 'r';
293  }
294  }
295  rz_list_append(ret, newpid);
296  }
298  rz_list_free(pids);
299  return ret;
300 }
301 
302 static int rz_debug_dmp_select(RzDebug *dbg, int pid, int tid) {
304  if (ctx->type == DMP_DUMPTYPE_TRIAGE) {
305  if (pid != ctx->windctx.target.uniqueid || tid != ctx->windctx.target_thread.uniqueid) {
306  RZ_LOG_ERROR("Cannot select other targets on a triage dump\n");
307  }
308  dbg->pid = ctx->windctx.target.uniqueid;
309  dbg->tid = ctx->windctx.target_thread.uniqueid;
310  return ctx->windctx.target_thread.uniqueid;
311  }
312 
313  if (winkd_set_target(&ctx->windctx, pid, tid)) {
314  ctx->target = TARGET_VIRTUAL;
315  } else {
316  ctx->target = TARGET_PHYSICAL;
317  }
318  dbg->pid = ctx->windctx.target.uniqueid;
319  dbg->tid = ctx->windctx.target_thread.uniqueid;
320  return ctx->windctx.target_thread.uniqueid;
321 }
322 
323 static inline bool is_kernel_address_present(WindCtx *ctx, ut64 at) {
324  ut8 ptr_buf[8];
325  if (!ctx->read_at_kernel_virtual(ctx->user, at, ptr_buf, ctx->is_64bit ? 8 : 4)) {
326  return false;
327  }
328  return true;
329 }
330 
331 static int rz_debug_dmp_reg_read(RzDebug *dbg, int type, ut8 *buf, int size) {
332  DmpCtx *dmp = dbg->plugin_data;
333  WindCtx *ctx = &dmp->windctx;
334  if (!is_kernel_address_present(ctx, ctx->target_thread.ethread)) {
335  return 0;
336  }
337  const ut64 current_thread_offset = ctx->is_64bit ? 8 : 4;
338  ut64 *kprcb;
339  rz_vector_foreach(&dmp->KiProcessorBlock, kprcb) {
340  const ut64 current_thread = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, *kprcb + current_thread_offset);
341  if (current_thread == ctx->target_thread.ethread) {
342  const ut64 current_context = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, *kprcb + dmp->kprcb_context_offset);
343  if (current_context) {
344  return ctx->read_at_kernel_virtual(ctx->user, current_context, buf, size);
345  }
346  RZ_LOG_WARN("Failed to get KPRCB Context pointer at 0x%" PFMT64x "\n", current_context);
347  }
348  }
349  if (dmp->type == DMP_DUMPTYPE_TRIAGE || !ctx->target_thread.uniqueid) {
350  memcpy(buf, dmp->context, RZ_MIN(size, dmp->context_sz));
351  return size;
352  }
353  const int kernel_stack_offset = ctx->is_64bit ? 0x58 : 0x48;
354  if (ctx->is_arm) {
355  if (ctx->is_64bit) {
356  struct context_type_arm64 *regs = (struct context_type_arm64 *)buf;
357  regs->Sp = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->target_thread.ethread + kernel_stack_offset);
358  regs->Fp = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->target_thread.ethread + dmp->kthread_switch_frame_offset);
359  regs->Pc = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->target_thread.ethread + dmp->kthread_switch_frame_offset + 8);
360  } else {
361  struct context_type_arm *regs = (struct context_type_arm *)buf;
362  regs->sp = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->target_thread.ethread + kernel_stack_offset);
363  regs->pc = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->target_thread.ethread + dmp->kthread_switch_frame_offset + 4);
364  }
365  } else {
366  if (ctx->is_64bit) {
367  struct context_type_amd64 *regs = (struct context_type_amd64 *)buf;
368  regs->rsp = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->target_thread.ethread + kernel_stack_offset);
369  } else {
370  struct context_type_i386 *regs = (struct context_type_i386 *)buf;
371  regs->esp = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->target_thread.ethread + kernel_stack_offset);
372  }
373  }
374  return size;
375 }
376 
379  if (!ctx) {
380 #include "native/reg/windows-x64.h"
381  }
382  if (ctx->windctx.is_arm) {
383  if (ctx->windctx.is_64bit) {
385  }
386 #include "native/reg/windows-arm.h"
387  }
388  if (ctx->windctx.is_64bit) {
389 #include "native/reg/windows-x64.h"
390  }
391 #include "native/reg/windows-x86.h"
392  return NULL;
393 }
394 
397  RzList *ret = rz_list_newf(free);
398  if (!ret) {
399  return NULL;
400  }
401  RzList *threads = winkd_list_threads(&ctx->windctx);
402  RzListIter *it;
403  WindThread *t;
404  rz_list_foreach (threads, it, t) {
405  RzDebugPid *newpid = RZ_NEW0(RzDebugPid);
406  if (!newpid) {
408  rz_list_free(ret);
409  return NULL;
410  }
411  newpid->pid = t->uniqueid;
412  newpid->status = t->status;
413  newpid->runnable = t->runnable;
414  rz_list_append(ret, newpid);
415  }
417  return ret;
418 }
419 
421  if (ctx->type != DMP_DUMPTYPE_TRIAGE) {
422  return winkd_list_modules(&ctx->windctx);
423  }
425  if (!ret) {
426  return NULL;
427  }
428  struct rz_bin_dmp64_obj_t *obj = (struct rz_bin_dmp64_obj_t *)((RzBinFile *)ctx->bf)->o->bin_obj;
429  RzListIter *it;
430  dmp_driver_desc *driver;
431  rz_list_foreach (obj->drivers, it, driver) {
433  if (!mod) {
434  rz_list_free(ret);
435  return NULL;
436  }
437  mod->name = strdup(driver->file);
438  mod->size = driver->size;
439  mod->addr = driver->base;
440  mod->timestamp = driver->timestamp;
441  rz_list_append(ret, mod);
442  }
443  return ret;
444 }
445 
449  if (!ret) {
450  return NULL;
451  }
453  RzListIter *it;
454  WindModule *m;
455  rz_list_foreach (modules, it, m) {
457  if (!mod) {
459  rz_list_free(ret);
460  return NULL;
461  }
462  RZ_PTR_MOVE(mod->file, m->name);
463  mod->name = strdup(rz_file_dos_basename(mod->file));
464  mod->size = m->size;
465  mod->addr = m->addr;
466  mod->addr_end = m->addr + m->size;
467  rz_list_append(ret, mod);
468  }
470  return ret;
471 }
472 
475  RzList *maps = winkd_list_maps(&ctx->windctx);
476  RzListIter *it;
477  WindMap *m;
479  if (!ret) {
481  return NULL;
482  }
483  rz_list_foreach (maps, it, m) {
485  if (!map) {
487  rz_list_free(ret);
488  return NULL;
489  }
490  if (m->file) {
491  RZ_PTR_MOVE(map->file, m->file);
492  map->name = strdup(rz_file_dos_basename(map->file));
493  }
494  map->size = m->end - m->start;
495  map->addr = m->start;
496  map->addr_end = m->end;
497  map->perm = m->perm;
498  rz_list_append(ret, map);
499  }
501  return ret;
502 }
503 
504 static bool rz_debug_dmp_kill(RzDebug *dbg, int pid, int tid, int sig) {
505  return true;
506 }
507 
508 static int is_pc_inside_windmodule(const void *value, const void *list_data) {
509  const ut64 pc = *(const ut64 *)value;
510  const WindModule *module = list_data;
511  return !(pc >= module->addr && pc < (module->addr + module->size));
512 }
513 
514 typedef RzList *(*RzDebugFrameCallback)(RzDebug *dbg, ut64 at);
515 
517  RzCore *core = dbg->corebind.core;
519  RzList *ret = NULL;
520  if (!ctx->windctx.is_arm && ctx->windctx.is_64bit) {
521  RzList *modules = NULL;
522  struct context_type_amd64 context = { 0 };
523  const char *server = dbg->corebind.cfgGet(dbg->corebind.core, "pdb.server");
524  const char *symstore = dbg->corebind.cfgGet(dbg->corebind.core, "pdb.symstore");
525  ut64 last_rsp = 0;
526  while (!backtrace_windows_x64(dbg, &ret, &context)) {
527  if (last_rsp == context.rsp) {
528  break;
529  }
530  last_rsp = context.rsp;
531  if (!modules) {
533  }
535  if (!it) {
536  break;
537  }
539  char *exepath, *pdbpath;
540  if (!winkd_download_module_and_pdb(module, server, symstore, &exepath, &pdbpath)) {
541  break;
542  }
543  RzBinOptions opts = { 0 };
544  opts.obj_opts.baseaddr = module->addr;
545  RzBinFile *file = rz_bin_open(core->bin, exepath, &opts);
546  if (!file) {
547  free(exepath);
548  free(pdbpath);
549  break;
550  }
551  dbg->corebind.applyBinInfo(core, file, RZ_CORE_BIN_ACC_MAPS | RZ_CORE_BIN_ACC_SYMBOLS);
552  dbg->corebind.cmdf(dbg->corebind.core, "idp %s", pdbpath);
553  dbg->corebind.cmdf(dbg->corebind.core, "ompb %d", ((RzBinFile *)ctx->bf)->id);
554  free(exepath);
555  free(pdbpath);
556  }
558  } else {
559  ret = backtrace_generic(dbg);
560  }
561  return ret;
562 }
563 
565  .name = "dmp",
566  .license = "LGPL3",
567  .arch = "x86,arm",
568  .bits = RZ_SYS_BITS_32 | RZ_SYS_BITS_64,
569  .init = &rz_debug_dmp_init,
570  .attach = &rz_debug_dmp_attach,
571  .pids = &rz_debug_dmp_pids,
572  .select = &rz_debug_dmp_select,
573  .reg_read = &rz_debug_dmp_reg_read,
574  .reg_profile = &rz_debug_dmp_reg_profile,
575  .threads = &rz_debug_dmp_threads,
576  .modules_get = &rz_debug_dmp_modules,
577  .map_get = &rz_debug_dmp_maps,
578  .kill = &rz_debug_dmp_kill,
579  .frames = &rz_debug_dmp_frames,
580 };
581 
582 #ifndef RZ_PLUGIN_INCORE
585  .data = &rz_debug_plugin_dmp,
587 };
588 #endif
static char * regs[]
Definition: analysis_sh.c:203
lzma_index ** i
Definition: index.h:629
RZ_API RzBinFile * rz_bin_open(RzBin *bin, const char *file, RzBinOptions *opt)
Definition: bin.c:200
static RzList * maps(RzBinFile *bf)
Definition: bin_bf.c:116
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
const char * desc
Definition: bin_vsf.c:19
struct Proc * procs[]
Definition: config.h:24
static int value
Definition: cmd_api.c:93
void winkd_build_profile(WindCtx *ctx, RzTypeDB *db)
Definition: common_winkd.c:7
bool winkd_download_module_and_pdb(WindModule *module, const char *symserver, const char *symstore, char **exepath, char **pdbpath)
Definition: common_winkd.c:75
#define RZ_API
#define NULL
Definition: cris-opc.c:27
int mod(int a, int b)
Definition: crypto_rot.c:8
static RzList * dmp_get_modules(DmpCtx *ctx)
Definition: debug_dmp.c:420
static bool is_kernel_address_present(WindCtx *ctx, ut64 at)
Definition: debug_dmp.c:323
RzDebugPlugin rz_debug_plugin_dmp
Definition: debug_dmp.c:564
static int rz_debug_dmp_reg_read(RzDebug *dbg, int type, ut8 *buf, int size)
Definition: debug_dmp.c:331
static bool rz_debug_dmp_kill(RzDebug *dbg, int pid, int tid, int sig)
Definition: debug_dmp.c:504
static int rz_debug_dmp_select(RzDebug *dbg, int pid, int tid)
Definition: debug_dmp.c:302
static RzList * rz_debug_dmp_maps(RzDebug *dbg)
Definition: debug_dmp.c:473
RzList * rz_debug_dmp_frames(RzDebug *dbg, ut64 at)
Definition: debug_dmp.c:516
static bool rz_debug_dmp_init(RzDebug *dbg, void **user)
Definition: debug_dmp.c:15
static RzList * rz_debug_dmp_modules(RzDebug *dbg)
Definition: debug_dmp.c:446
RZ_API RzLibStruct rizin_plugin
Definition: debug_dmp.c:583
static int is_pc_inside_windmodule(const void *value, const void *list_data)
Definition: debug_dmp.c:508
static char * rz_debug_dmp_reg_profile(RzDebug *dbg)
Definition: debug_dmp.c:377
static RzList * rz_debug_dmp_pids(RzDebug *dbg, int pid)
Definition: debug_dmp.c:257
static int rz_debug_dmp_attach(RzDebug *dbg, int pid)
Definition: debug_dmp.c:223
static RzList * rz_debug_dmp_threads(RzDebug *dbg, int pid)
Definition: debug_dmp.c:395
uint32_t ut32
RzDebug * dbg
Definition: desil.c:30
RZ_API void rz_debug_map_free(RzDebugMap *map)
Definition: dmap.c:77
#define DMP_DUMPTYPE_TRIAGE
Definition: dmp_specs.h:20
size_t map(int syms, int left, int len)
Definition: enough.c:237
static RzList * backtrace_generic(RZ_BORROW RZ_NONNULL RzDebug *dbg)
Definition: generic-all.c:14
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
@ TARGET_KERNEL
Definition: io_windbg.c:397
voidpf void uLong size
Definition: ioapi.h:138
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
RZ_API RZ_BORROW RzListIter * rz_list_find(RZ_NONNULL const RzList *list, const void *p, RZ_NONNULL RzListComparator cmp)
Returns RzListIter element which matches via the RzListComparator.
Definition: list.c:620
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API void * rz_list_iter_get_data(RzListIter *list)
returns the value stored in the list element
Definition: list.c:42
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
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 pid
Definition: sflib.h:64
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")
int type
Definition: mipsasm.c:17
modules
Definition: regress.py:20
#define PE_IMAGE_FILE_MACHINE_ARMNT
Definition: pe_specs.h:70
#define PE_IMAGE_FILE_MACHINE_AMD64
Definition: pe_specs.h:68
#define PE_IMAGE_FILE_MACHINE_ARM64
Definition: pe_specs.h:71
RZ_API RzDebugPid * rz_debug_pid_free(RzDebugPid *pid)
Definition: pid.c:20
#define rz_buf_read_le32_at(b, addr, result)
Definition: rz_buf.h:271
RZ_API void rz_buf_free(RzBuffer *b)
Free all internal data hold by the buffer and the buffer.
Definition: buf.c:1253
RZ_API RZ_OWN RzBuffer * rz_buf_new_with_io(RZ_NONNULL void *iob)
Creates a new buffer wrapping the memory map exposed by RzIOBind.
Definition: buf.c:509
#define rz_buf_read_le64_at(b, addr, result)
Definition: rz_buf.h:272
RZ_API const char * rz_file_basename(const char *path)
Definition: file.c:83
RZ_API const char * rz_file_dos_basename(RZ_BORROW RZ_NONNULL const char *path)
Definition: file.c:102
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 bool rz_io_map_del(RzIO *io, ut32 id)
Definition: io_map.c:192
RZ_API RzIOMap * rz_io_map_get(RzIO *io, ut64 addr)
Definition: io_map.c:176
RZ_API bool rz_io_map_remap(RzIO *io, ut32 id, ut64 addr)
Definition: io_map.c:54
RZ_API RzIOMap * rz_io_map_new(RzIO *io, int fd, int flags, ut64 delta, ut64 addr, ut64 size)
Definition: io_map.c:50
@ RZ_LIB_TYPE_DBG
Definition: rz_lib.h:70
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
#define RZ_LOG_WARN(fmtstr,...)
Definition: rz_log.h:56
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_str_replace(char *str, const char *key, const char *val, int g)
Definition: str.c:1110
RZ_API bool rz_str_endswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string ends with a specifc sequence of characters (case sensitive)
Definition: str.c:3329
@ RZ_SYS_BITS_32
Definition: rz_sys.h:20
@ RZ_SYS_BITS_64
Definition: rz_sys.h:21
#define RZ_PERM_R
Definition: rz_types.h:93
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define PFMT32u
Definition: rz_types.h:409
#define RZ_PTR_MOVE(d, s)
Definition: rz_types.h:301
#define rz_offsetof(type, member)
Definition: rz_types.h:360
#define PFMT64x
Definition: rz_types.h:393
#define PFMT32d
Definition: rz_types.h:408
#define RZ_MIN(x, y)
RZ_API void * rz_vector_push(RzVector *vec, void *x)
Definition: vector.c:197
#define rz_vector_foreach(vec, it)
Definition: rz_vector.h:169
RZ_API void rz_vector_fini(RzVector *vec)
Definition: vector.c:61
#define rz_vector_foreach_prev(vec, it)
Definition: rz_vector.h:173
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 b(i)
Definition: sha256.c:42
Definition: winkd.h:35
Definition: winkd.h:11
ut64 dir_base_table
Definition: winkd.h:15
ut64 ethread
Definition: winkd.h:24
bool runnable
Definition: winkd.h:22
char status
Definition: winkd.h:23
ut32 uniqueid
Definition: winkd.h:21
Definition: winkd.h:118
RzVector KiProcessorBlock
Definition: winkd.h:124
size_t context_sz
Definition: winkd.h:129
ut32 kprcb_context_offset
Definition: winkd.h:125
ut32 type
Definition: winkd.h:120
ut32 kthread_switch_frame_offset
Definition: winkd.h:126
WindCtx windctx
Definition: winkd.h:119
ut8 * context
Definition: winkd.h:128
Definition: winkd.h:79
ut32 size
Definition: dmp64.h:19
ut64 base
Definition: dmp64.h:21
ut32 timestamp
Definition: dmp64.h:20
char * file
Definition: dmp64.h:18
Definition: gzappend.c:170
Definition: sftypes.h:77
RzTypeDB * typedb
Definition: rz_analysis.h:602
RzList * drivers
Definition: dmp64.h:34
ut64 baseaddr
where the linker maps the binary in memory
Definition: rz_bin.h:248
XX curplugin == o->plugin.
Definition: rz_bin.h:298
RzBinObject * o
Definition: rz_bin.h:305
char * rclass
Definition: rz_bin.h:213
RzBinObjectLoadOptions opts
Definition: rz_bin.h:260
RzBinInfo * info
Definition: rz_bin.h:287
void * bin_obj
Definition: rz_bin.h:293
char * regstate
Definition: rz_bin.h:286
RZ_DEPRECATE RzBinFile * cur
never use this in new code! Get a file from the binfiles list or track it yourself.
Definition: rz_bin.h:330
RzCoreBinApplyInfo applyBinInfo
Definition: rz_bind.h:49
RzCoreCmd cmd
Definition: rz_bind.h:32
RzCoreConfigSetI cfgSetI
Definition: rz_bind.h:46
RzCoreConfigGet cfgGet
Definition: rz_bind.h:44
RzCoreNumGet numGet
Definition: rz_bind.h:47
void * core
Definition: rz_bind.h:31
RzCoreCmdF cmdf
Definition: rz_bind.h:33
RzBin * bin
Definition: rz_core.h:298
RzIO * io
Definition: rz_core.h:313
char * path
Definition: rz_debug.h:414
const char * version
Definition: rz_debug.h:362
const char * name
Definition: rz_debug.h:359
RzCoreBind corebind
Definition: rz_debug.h:314
RzAnalysis * analysis
Definition: rz_debug.h:305
int bits
Definition: rz_debug.h:243
void * plugin_data
Definition: rz_debug.h:296
RzIOBind iob
Definition: rz_debug.h:293
void * data
Definition: rz_io.h:102
struct rz_io_desc_t * desc
Definition: rz_io.h:60
static uv_thread_t * threads
Definition: threadpool.c:38
RZ_API ut64 rz_type_db_struct_member_offset(RZ_NONNULL const RzTypeDB *typedb, RZ_NONNULL const char *name, RZ_NONNULL const char *member)
Returns the offset in bytes of the structure member if there is a match.
Definition: path.c:269
static bool backtrace_windows_x64(RZ_IN RzDebug *dbg, RZ_INOUT RzList **out_frames, RZ_INOUT struct context_type_amd64 *context)
Definition: windows-x64.c:273
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
WindThread * winkd_get_thread_at(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 address)
Definition: winkd.c:739
Profile * winkd_get_profile(int bits, int build, int sp)
Definition: winkd.c:58
RzList * winkd_list_threads(RZ_BORROW RZ_NONNULL WindCtx *ctx)
Definition: winkd.c:782
RzList * winkd_list_maps(RZ_BORROW RZ_NONNULL WindCtx *ctx)
Definition: winkd.c:476
int winkd_get_sp(RZ_BORROW RZ_NONNULL WindCtx *ctx)
Definition: winkd.c:40
void winkd_windmodule_free(void *ptr)
Definition: winkd.c:611
RzList * winkd_list_modules(RZ_BORROW RZ_NONNULL WindCtx *ctx)
Definition: winkd.c:625
bool winkd_set_target(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut32 pid, ut32 tid)
Definition: winkd.c:106
WindProc * winkd_get_process_at(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 address)
Definition: winkd.c:488
RzList * winkd_list_process(RZ_BORROW RZ_NONNULL WindCtx *ctx)
Definition: winkd.c:513
#define TARGET_BACKEND
Definition: winkd.h:113
#define TARGET_VIRTUAL
Definition: winkd.h:116
#define TARGET_PHYSICAL
Definition: winkd.h:114
static ut64 winkd_read_ptr_at(RZ_BORROW RZ_NONNULL WindCtx *ctx, RZ_BORROW RZ_NONNULL WindReadAt *read_at_func, ut64 at)
Definition: winkd.h:133
static zip_compression_status_t process(void *ud, zip_uint8_t *data, zip_uint64_t *length)