Rizin
unix-like reverse engineering framework and cli tools
debug_dmp.c File Reference
#include <rz_core.h>
#include <rz_debug.h>
#include <dmp_specs.h>
#include <dmp64.h>
#include <pe_specs.h>
#include <winkd.h>
#include "common_winkd.h"
#include "native/bt/windows-x64.c"
#include "native/bt/generic-all.c"
#include "native/reg/windows-x64.h"
#include "native/reg/windows-arm64.h"
#include "native/reg/windows-arm.h"
#include "native/reg/windows-x86.h"

Go to the source code of this file.

Typedefs

typedef RzList *(* RzDebugFrameCallback) (RzDebug *dbg, ut64 at)
 

Functions

static bool rz_debug_dmp_init (RzDebug *dbg, void **user)
 
static int rz_debug_dmp_attach (RzDebug *dbg, int pid)
 
static RzListrz_debug_dmp_pids (RzDebug *dbg, int pid)
 
static int rz_debug_dmp_select (RzDebug *dbg, int pid, int tid)
 
static bool is_kernel_address_present (WindCtx *ctx, ut64 at)
 
static int rz_debug_dmp_reg_read (RzDebug *dbg, int type, ut8 *buf, int size)
 
static char * rz_debug_dmp_reg_profile (RzDebug *dbg)
 
static RzListrz_debug_dmp_threads (RzDebug *dbg, int pid)
 
static RzListdmp_get_modules (DmpCtx *ctx)
 
static RzListrz_debug_dmp_modules (RzDebug *dbg)
 
static RzListrz_debug_dmp_maps (RzDebug *dbg)
 
static bool rz_debug_dmp_kill (RzDebug *dbg, int pid, int tid, int sig)
 
static int is_pc_inside_windmodule (const void *value, const void *list_data)
 
RzListrz_debug_dmp_frames (RzDebug *dbg, ut64 at)
 

Variables

RzDebugPlugin rz_debug_plugin_dmp
 
RZ_API RzLibStruct rizin_plugin
 

Typedef Documentation

◆ RzDebugFrameCallback

typedef RzList*(* RzDebugFrameCallback) (RzDebug *dbg, ut64 at)

Definition at line 514 of file debug_dmp.c.

Function Documentation

◆ dmp_get_modules()

static RzList* dmp_get_modules ( DmpCtx ctx)
static

Definition at line 420 of file debug_dmp.c.

420  {
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 }
#define NULL
Definition: cris-opc.c:27
int mod(int a, int b)
Definition: crypto_rot.c:8
#define DMP_DUMPTYPE_TRIAGE
Definition: dmp_specs.h:20
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 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
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_NEW0(x)
Definition: rz_types.h:284
RzList * drivers
Definition: dmp64.h:34
XX curplugin == o->plugin.
Definition: rz_bin.h:298
void winkd_windmodule_free(void *ptr)
Definition: winkd.c:611
RzList * winkd_list_modules(RZ_BORROW RZ_NONNULL WindCtx *ctx)
Definition: winkd.c:625

References DMP_DUMPTYPE_TRIAGE, rz_bin_dmp64_obj_t::drivers, mod(), NULL, rz_list_append(), rz_list_free(), rz_list_newf(), RZ_NEW0, strdup(), winkd_list_modules(), and winkd_windmodule_free().

Referenced by rz_debug_dmp_frames(), and rz_debug_dmp_modules().

◆ is_kernel_address_present()

static bool is_kernel_address_present ( WindCtx ctx,
ut64  at 
)
inlinestatic

Definition at line 323 of file debug_dmp.c.

323  {
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 }
uint8_t ut8
Definition: lh5801.h:11

Referenced by rz_debug_dmp_reg_read().

◆ is_pc_inside_windmodule()

static int is_pc_inside_windmodule ( const void *  value,
const void *  list_data 
)
static

Definition at line 508 of file debug_dmp.c.

508  {
509  const ut64 pc = *(const ut64 *)value;
510  const WindModule *module = list_data;
511  return !(pc >= module->addr && pc < (module->addr + module->size));
512 }
static int value
Definition: cmd_api.c:93
Definition: sftypes.h:77
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References pc, ut64(), and value.

Referenced by rz_debug_dmp_frames().

◆ rz_debug_dmp_attach()

static int rz_debug_dmp_attach ( RzDebug dbg,
int  pid 
)
static

Definition at line 223 of file debug_dmp.c.

223  {
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 }
RzDebug * dbg
Definition: desil.c:30
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
#define rz_vector_foreach_prev(vec, it)
Definition: rz_vector.h:173
Definition: winkd.h:11
ut64 ethread
Definition: winkd.h:24
Definition: winkd.h:118
void * plugin_data
Definition: rz_debug.h:296
WindThread * winkd_get_thread_at(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 address)
Definition: winkd.c:739
WindProc * winkd_get_process_at(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 address)
Definition: winkd.c:488
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)

References dbg, DMP_DUMPTYPE_TRIAGE, WindThread::ethread, free(), rz_debug_t::pid, rz_debug_t::plugin_data, process(), rz_vector_foreach_prev, rz_debug_t::tid, ut64(), winkd_get_process_at(), winkd_get_thread_at(), and winkd_read_ptr_at().

◆ rz_debug_dmp_frames()

RzList* rz_debug_dmp_frames ( RzDebug dbg,
ut64  at 
)

Definition at line 516 of file debug_dmp.c.

516  {
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 }
RZ_API RzBinFile * rz_bin_open(RzBin *bin, const char *file, RzBinOptions *opt)
Definition: bin.c:200
bool winkd_download_module_and_pdb(WindModule *module, const char *symserver, const char *symstore, char **exepath, char **pdbpath)
Definition: common_winkd.c:75
static RzList * dmp_get_modules(DmpCtx *ctx)
Definition: debug_dmp.c:420
static int is_pc_inside_windmodule(const void *value, const void *list_data)
Definition: debug_dmp.c:508
static RzList * backtrace_generic(RZ_BORROW RZ_NONNULL RzDebug *dbg)
Definition: generic-all.c:14
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 void * rz_list_iter_get_data(RzListIter *list)
returns the value stored in the list element
Definition: list.c:42
modules
Definition: regress.py:20
Definition: gzappend.c:170
RzCoreBinApplyInfo applyBinInfo
Definition: rz_bind.h:49
RzCoreConfigGet cfgGet
Definition: rz_bind.h:44
void * core
Definition: rz_bind.h:31
RzCoreCmdF cmdf
Definition: rz_bind.h:33
RzBin * bin
Definition: rz_core.h:298
RzCoreBind corebind
Definition: rz_debug.h:314
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

References rz_core_bind_t::applyBinInfo, backtrace_generic(), backtrace_windows_x64(), rz_core_t::bin, rz_core_bind_t::cfgGet, rz_core_bind_t::cmdf, rz_core_bind_t::core, rz_debug_t::corebind, dbg, dmp_get_modules(), free(), is_pc_inside_windmodule(), regress::modules, NULL, rz_debug_t::plugin_data, rz_bin_open(), rz_list_find(), rz_list_free(), rz_list_iter_get_data(), ut64(), and winkd_download_module_and_pdb().

◆ rz_debug_dmp_init()

static bool rz_debug_dmp_init ( RzDebug dbg,
void **  user 
)
static

Definition at line 15 of file debug_dmp.c.

15  {
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 }
lzma_index ** i
Definition: index.h:629
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
const char * desc
Definition: bin_vsf.c:19
void winkd_build_profile(WindCtx *ctx, RzTypeDB *db)
Definition: common_winkd.c:7
uint32_t ut32
size_t map(int syms, int left, int len)
Definition: enough.c:237
@ TARGET_KERNEL
Definition: io_windbg.c:397
void * malloc(size_t size)
Definition: malloc.c:123
#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
#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 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
#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
#define RZ_PERM_R
Definition: rz_types.h:93
#define PFMT32u
Definition: rz_types.h:409
#define rz_offsetof(type, member)
Definition: rz_types.h:360
#define PFMT32d
Definition: rz_types.h:408
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
#define b(i)
Definition: sha256.c:42
ut64 dir_base_table
Definition: winkd.h:15
ut32 uniqueid
Definition: winkd.h:21
ut32 size
Definition: dmp64.h:19
ut64 base
Definition: dmp64.h:21
ut32 timestamp
Definition: dmp64.h:20
char * file
Definition: dmp64.h:18
RzTypeDB * typedb
Definition: rz_analysis.h:602
ut64 baseaddr
where the linker maps the binary in memory
Definition: rz_bin.h:248
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
RzCoreCmd cmd
Definition: rz_bind.h:32
RzCoreConfigSetI cfgSetI
Definition: rz_bind.h:46
RzCoreNumGet numGet
Definition: rz_bind.h:47
RzIO * io
Definition: rz_core.h:313
RzAnalysis * analysis
Definition: rz_debug.h:305
int bits
Definition: rz_debug.h:243
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
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
Profile * winkd_get_profile(int bits, int build, int sp)
Definition: winkd.c:58
int winkd_get_sp(RZ_BORROW RZ_NONNULL WindCtx *ctx)
Definition: winkd.c:40
#define TARGET_BACKEND
Definition: winkd.h:113

References rz_debug_t::analysis, b, dmp_driver_desc::base, rz_bin_file_load_options_t::baseaddr, rz_core_t::bin, rz_bin_object_t::bin_obj, rz_debug_t::bits, rz_core_bind_t::cfgGet, rz_core_bind_t::cfgSetI, rz_core_bind_t::cmd, rz_core_bind_t::cmdf, rz_core_bind_t::core, rz_debug_t::corebind, rz_bin_t::cur, rz_io_desc_t::data, dbg, desc, rz_io_t::desc, WindProc::dir_base_table, DMP_DUMPTYPE_TRIAGE, rz_bin_dmp64_obj_t::drivers, WindThread::ethread, dmp_driver_desc::file, free(), i, info(), rz_bin_object_t::info, rz_core_t::io, rz_debug_t::iob, regress::m, malloc(), map(), mod(), regress::modules, NULL, rz_core_bind_t::numGet, rz_bin_file_t::o, rz_bin_object_t::opts, PE_IMAGE_FILE_MACHINE_AMD64, PE_IMAGE_FILE_MACHINE_ARM64, PE_IMAGE_FILE_MACHINE_ARMNT, PFMT32d, PFMT32u, rz_debug_t::plugin_data, process(), rz_bin_info_t::rclass, rz_bin_object_t::regstate, rz_buf_free(), rz_buf_new_with_io(), rz_buf_read_le32_at, rz_buf_read_le64_at, rz_file_basename(), rz_hex_str2bin(), rz_io_map_del(), rz_io_map_get(), rz_io_map_new(), rz_io_map_remap(), RZ_LOG_ERROR, RZ_LOG_WARN, rz_offsetof, RZ_PERM_R, rz_str_endswith(), rz_str_newf(), rz_str_replace(), rz_type_db_struct_member_offset(), rz_vector_foreach, rz_vector_push(), dmp_driver_desc::size, strdup(), TARGET_BACKEND, TARGET_KERNEL, dmp_driver_desc::timestamp, rz_analysis_t::typedb, WindThread::uniqueid, ut64(), winkd_build_profile(), winkd_download_module_and_pdb(), winkd_get_process_at(), winkd_get_profile(), winkd_get_sp(), winkd_get_thread_at(), winkd_list_modules(), and winkd_read_ptr_at().

◆ rz_debug_dmp_kill()

static bool rz_debug_dmp_kill ( RzDebug dbg,
int  pid,
int  tid,
int  sig 
)
static

Definition at line 504 of file debug_dmp.c.

504  {
505  return true;
506 }

◆ rz_debug_dmp_maps()

static RzList* rz_debug_dmp_maps ( RzDebug dbg)
static

Definition at line 473 of file debug_dmp.c.

473  {
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 }
static RzList * maps(RzBinFile *bf)
Definition: bin_bf.c:116
RZ_API void rz_debug_map_free(RzDebugMap *map)
Definition: dmap.c:77
RZ_API const char * rz_file_dos_basename(RZ_BORROW RZ_NONNULL const char *path)
Definition: file.c:102
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
#define RZ_PTR_MOVE(d, s)
Definition: rz_types.h:301
Definition: winkd.h:35
RzList * winkd_list_maps(RZ_BORROW RZ_NONNULL WindCtx *ctx)
Definition: winkd.c:476

References dbg, regress::m, map(), maps(), NULL, rz_debug_t::plugin_data, rz_debug_map_free(), rz_file_dos_basename(), rz_list_append(), rz_list_free(), rz_list_newf(), RZ_NEW0, RZ_PTR_MOVE, strdup(), and winkd_list_maps().

◆ rz_debug_dmp_modules()

static RzList* rz_debug_dmp_modules ( RzDebug dbg)
static

Definition at line 446 of file debug_dmp.c.

446  {
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 }

References dbg, dmp_get_modules(), regress::m, mod(), regress::modules, NULL, rz_debug_t::plugin_data, rz_debug_map_free(), rz_file_dos_basename(), rz_list_append(), rz_list_free(), rz_list_newf(), RZ_NEW0, RZ_PTR_MOVE, and strdup().

◆ rz_debug_dmp_pids()

static RzList* rz_debug_dmp_pids ( RzDebug dbg,
int  pid 
)
static

Definition at line 257 of file debug_dmp.c.

257  {
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 }
struct Proc * procs[]
Definition: config.h:24
void * p
Definition: libc.cpp:67
RZ_API RzDebugPid * rz_debug_pid_free(RzDebugPid *pid)
Definition: pid.c:20
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
char * path
Definition: rz_debug.h:414
RzList * winkd_list_process(RZ_BORROW RZ_NONNULL WindCtx *ctx)
Definition: winkd.c:513

References dbg, NULL, p, rz_debug_pid_t::path, rz_debug_pid_t::pid, rz_debug_t::plugin_data, process(), procs, rz_debug_pid_t::runnable, rz_debug_pid_free(), rz_list_append(), rz_list_free(), rz_list_newf(), RZ_NEW0, rz_vector_fini(), rz_vector_foreach, rz_vector_foreach_prev, rz_vector_init(), rz_vector_push(), rz_debug_pid_t::status, strdup(), ut64(), winkd_list_process(), and winkd_read_ptr_at().

◆ rz_debug_dmp_reg_profile()

static char* rz_debug_dmp_reg_profile ( RzDebug dbg)
static

Definition at line 377 of file debug_dmp.c.

377  {
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 }

References dbg, NULL, and rz_debug_t::plugin_data.

◆ rz_debug_dmp_reg_read()

static int rz_debug_dmp_reg_read ( RzDebug dbg,
int  type,
ut8 buf,
int  size 
)
static

Definition at line 331 of file debug_dmp.c.

331  {
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 }
static char * regs[]
Definition: analysis_sh.c:203
static bool is_kernel_address_present(WindCtx *ctx, ut64 at)
Definition: debug_dmp.c:323
voidpf void uLong size
Definition: ioapi.h:138
voidpf void * buf
Definition: ioapi.h:138
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
#define PFMT64x
Definition: rz_types.h:393
#define RZ_MIN(x, y)
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

References _DmpCtx::context, _DmpCtx::context_sz, dbg, DMP_DUMPTYPE_TRIAGE, is_kernel_address_present(), _DmpCtx::KiProcessorBlock, _DmpCtx::kprcb_context_offset, _DmpCtx::kthread_switch_frame_offset, memcpy(), PFMT64x, rz_debug_t::plugin_data, regs, RZ_LOG_WARN, RZ_MIN, rz_vector_foreach, _DmpCtx::type, ut64(), _DmpCtx::windctx, and winkd_read_ptr_at().

◆ rz_debug_dmp_select()

static int rz_debug_dmp_select ( RzDebug dbg,
int  pid,
int  tid 
)
static

Definition at line 302 of file debug_dmp.c.

302  {
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 }
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
bool winkd_set_target(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut32 pid, ut32 tid)
Definition: winkd.c:106
#define TARGET_VIRTUAL
Definition: winkd.h:116
#define TARGET_PHYSICAL
Definition: winkd.h:114

References dbg, DMP_DUMPTYPE_TRIAGE, rz_debug_t::pid, pid, rz_debug_t::plugin_data, RZ_LOG_ERROR, TARGET_PHYSICAL, TARGET_VIRTUAL, rz_debug_t::tid, and winkd_set_target().

◆ rz_debug_dmp_threads()

static RzList* rz_debug_dmp_threads ( RzDebug dbg,
int  pid 
)
static

Definition at line 395 of file debug_dmp.c.

395  {
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 }
bool runnable
Definition: winkd.h:22
char status
Definition: winkd.h:23
static uv_thread_t * threads
Definition: threadpool.c:38
RzList * winkd_list_threads(RZ_BORROW RZ_NONNULL WindCtx *ctx)
Definition: winkd.c:782

References dbg, free(), NULL, rz_debug_pid_t::pid, rz_debug_t::plugin_data, rz_debug_pid_t::runnable, WindThread::runnable, rz_list_append(), rz_list_free(), rz_list_newf(), RZ_NEW0, rz_debug_pid_t::status, WindThread::status, threads, WindThread::uniqueid, and winkd_list_threads().

Variable Documentation

◆ rizin_plugin

RZ_API RzLibStruct rizin_plugin
Initial value:
= {
.type = RZ_LIB_TYPE_DBG,
}
RzDebugPlugin rz_debug_plugin_dmp
Definition: debug_dmp.c:564
@ RZ_LIB_TYPE_DBG
Definition: rz_lib.h:70
#define RZ_VERSION
Definition: rz_version.h:8
const char * version
Definition: rz_debug.h:362

Definition at line 583 of file debug_dmp.c.

◆ rz_debug_plugin_dmp

RzDebugPlugin rz_debug_plugin_dmp
Initial value:
= {
.name = "dmp",
.license = "LGPL3",
.arch = "x86,arm",
.attach = &rz_debug_dmp_attach,
.select = &rz_debug_dmp_select,
.reg_read = &rz_debug_dmp_reg_read,
.reg_profile = &rz_debug_dmp_reg_profile,
.threads = &rz_debug_dmp_threads,
.modules_get = &rz_debug_dmp_modules,
.map_get = &rz_debug_dmp_maps,
.frames = &rz_debug_dmp_frames,
}
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
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
@ RZ_SYS_BITS_32
Definition: rz_sys.h:20
@ RZ_SYS_BITS_64
Definition: rz_sys.h:21

Definition at line 564 of file debug_dmp.c.