Rizin
unix-like reverse engineering framework and cli tools
debug_windbg.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2020 GustavoLCR <gugulcr@gmail.com>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_debug.h>
5 #include <DbgEng.h>
6 
7 #ifndef CONTEXT_ARM
8 #define CONTEXT_ARM 0x00200000L
9 #endif
10 #ifndef CONTEXT_ARM64
11 #define CONTEXT_ARM64 0x00400000L
12 #endif
13 #ifndef CONTEXT_AMD64
14 #define CONTEXT_AMD64 0x00100000L
15 #endif
16 #ifndef CONTEXT_i386
17 #define CONTEXT_i386 0x00010000L
18 #endif
19 #ifndef IMAGE_FILE_MACHINE_ARM64
20 #define IMAGE_FILE_MACHINE_ARM64 0xAA64
21 #endif
22 #ifndef DEBUG_DUMP_ACTIVE
23 #define DEBUG_DUMP_ACTIVE 1030
24 #endif
25 
26 #define TIMEOUT 500
27 #define THISCALL(dbginterface, function, ...) dbginterface->lpVtbl->function(dbginterface, __VA_ARGS__)
28 #define ITHISCALL(dbginterface, function, ...) THISCALL(idbg->dbginterface, function, __VA_ARGS__)
29 #define RELEASE(I) \
30  if (I) \
31  THISCALL(I, Release);
32 
33 typedef struct { // Keep in sync with io_windbg.c
35  ULONG64 server;
36  ULONG64 processBase;
38  PDEBUG_CLIENT5 dbgClient;
39  PDEBUG_CONTROL4 dbgCtrl;
40  PDEBUG_DATA_SPACES4 dbgData;
41  PDEBUG_REGISTERS2 dbgReg;
42  PDEBUG_SYSTEM_OBJECTS4 dbgSysObj;
43  PDEBUG_SYMBOLS3 dbgSymbols;
44  PDEBUG_ADVANCED3 dbgAdvanced;
46 
47 static bool is_target_kernel(DbgEngContext *idbg) {
48  ULONG Class, Qualifier;
49  if (SUCCEEDED(ITHISCALL(dbgCtrl, GetDebuggeeType, &Class, &Qualifier))) {
50  if (Class == DEBUG_CLASS_KERNEL) {
51  return true;
52  }
53  }
54  return false;
55 }
56 
57 static inline bool io_desc_is_windbg(RzIO *io) {
58  return io && io->desc && io->desc->plugin && !strcmp(io->desc->plugin->name, "windbg");
59 }
60 
61 static bool windbg_init(RzDebug *dbg, void **user) {
62  DbgEngContext *idbg = dbg->plugin_data;
63  if (!idbg) {
64  if (!io_desc_is_windbg(dbg->iob.io)) {
65  return false;
66  }
67  idbg = dbg->plugin_data = dbg->iob.io->desc->data;
68  }
69  return idbg->initialized;
70 }
71 
72 static int windbg_step(RzDebug *dbg) {
73  DbgEngContext *idbg = dbg->plugin_data;
74  rz_return_val_if_fail(idbg && idbg->initialized, 0);
75  idbg->lastExecutionStatus = DEBUG_STATUS_STEP_INTO;
76  return SUCCEEDED(ITHISCALL(dbgCtrl, SetExecutionStatus, DEBUG_STATUS_STEP_INTO));
77 }
78 
79 static int windbg_select(RzDebug *dbg, int pid, int tid) {
80  DbgEngContext *idbg = dbg->plugin_data;
81  rz_return_val_if_fail(idbg && idbg->initialized, 0);
82  ULONG process_id = pid;
83  ULONG thread_id = tid;
84  if (!is_target_kernel(idbg)) {
85  ITHISCALL(dbgSysObj, GetProcessIdBySystemId, pid, &process_id);
86  ITHISCALL(dbgSysObj, GetThreadIdBySystemId, tid, &thread_id);
87  }
88  if (SUCCEEDED(ITHISCALL(dbgSysObj, SetCurrentProcessId, process_id))) {
89  if (SUCCEEDED(ITHISCALL(dbgSysObj, SetCurrentThreadId, thread_id))) {
90  return 1;
91  }
92  }
93  return 0;
94 }
95 
96 static int windbg_continue(RzDebug *dbg, int pid, int tid, int sig) {
97  DbgEngContext *idbg = dbg->plugin_data;
98  rz_return_val_if_fail(idbg && idbg->initialized, 0);
99  idbg->lastExecutionStatus = DEBUG_STATUS_GO;
100  ITHISCALL(dbgCtrl, SetExecutionStatus, DEBUG_STATUS_GO);
101  return tid;
102 }
103 
104 // nicked from windows_debug.c
106  switch (ExceptionCode) {
119  return RZ_DEBUG_REASON_FPU;
125  return RZ_DEBUG_REASON_STEP;
126  default:
127  return RZ_DEBUG_REASON_TRAP;
128  }
129 }
130 
131 static int windbg_stop(RzDebug *dbg) {
132  DbgEngContext *idbg = dbg->plugin_data;
133  rz_return_val_if_fail(idbg && idbg->initialized, 0);
134  return SUCCEEDED(ITHISCALL(dbgCtrl, SetInterrupt, DEBUG_INTERRUPT_ACTIVE));
135 }
136 
137 static bool do_break = false;
138 
139 static void break_debugger(void *user) {
140  RzDebug *dbg = (RzDebug *)user;
141  DbgEngContext *idbg = dbg->plugin_data;
142  if (is_target_kernel(idbg)) {
143  windbg_stop(dbg);
144  }
145  do_break = true;
146 }
147 
148 static int windbg_wait(RzDebug *dbg, int pid) {
149  DbgEngContext *idbg = dbg->plugin_data;
150  rz_return_val_if_fail(idbg && idbg->initialized, 0);
151  ULONG Type, ProcessId, ThreadId;
153  const ULONG timeout = is_target_kernel(idbg) ? INFINITE : TIMEOUT;
154  HRESULT hr;
155  while ((hr = ITHISCALL(dbgCtrl, WaitForEvent, DEBUG_WAIT_DEFAULT, timeout)) == S_FALSE) {
156  if (do_break) {
157  do_break = false;
161  }
162  }
164  if (FAILED(hr)) {
165  return RZ_DEBUG_REASON_DEAD;
166  }
167  ITHISCALL(dbgCtrl, GetLastEventInformation, &Type, &ProcessId, &ThreadId, NULL, 0, NULL, NULL, 0, NULL);
168  if (!is_target_kernel(idbg)) {
169  ITHISCALL(dbgSysObj, GetCurrentProcessSystemId, (PULONG)&dbg->pid);
170  ITHISCALL(dbgSysObj, GetCurrentThreadSystemId, (PULONG)&dbg->tid);
171  } else {
172  dbg->pid = ProcessId;
173  dbg->tid = ThreadId;
174  }
175  int ret;
176  switch (Type) {
177  case 0:
178  // I dont really get why Type is zero here
179  if (idbg->lastExecutionStatus == DEBUG_STATUS_STEP_INTO || idbg->lastExecutionStatus == DEBUG_STATUS_STEP_OVER) {
180  ret = RZ_DEBUG_REASON_STEP;
181  } else {
182  ret = RZ_DEBUG_REASON_ERROR;
183  }
184  break;
185  case DEBUG_EVENT_BREAKPOINT:
187  break;
188  case DEBUG_EVENT_EXCEPTION: {
189  EXCEPTION_RECORD64 exr;
190  ITHISCALL(dbgCtrl, GetLastEventInformation, &Type, &ProcessId, &ThreadId, &exr, sizeof(exr), NULL, NULL, 0, NULL);
191  dbg->reason.type = exception_to_reason(exr.ExceptionCode);
192  dbg->reason.tid = dbg->tid;
193  dbg->reason.addr = exr.ExceptionAddress;
195  ret = dbg->reason.type;
196  break;
197  }
198  case DEBUG_EVENT_EXIT_PROCESS:
200  break;
201  case DEBUG_EVENT_CREATE_PROCESS:
203  break;
204  default:
205  ret = RZ_DEBUG_REASON_ERROR;
206  break;
207  }
208 
209  return ret;
210 }
211 
213  DbgEngContext *idbg = dbg->plugin_data;
214  rz_return_val_if_fail(idbg && idbg->initialized, 0);
215  idbg->lastExecutionStatus = DEBUG_STATUS_STEP_OVER;
216  if (SUCCEEDED(ITHISCALL(dbgCtrl, SetExecutionStatus, DEBUG_STATUS_STEP_OVER))) {
218  }
219  return 0;
220 }
221 
222 static int windbg_breakpoint(RzBreakpoint *bp, RzBreakpointItem *b, bool set) {
223  static volatile LONG bp_idx = 0;
224  RzDebug *dbg = bp->user;
226  DbgEngContext *idbg = dbg->plugin_data;
227  rz_return_val_if_fail(idbg && idbg->initialized, 0);
228  ULONG type = b->hw ? DEBUG_BREAKPOINT_DATA : DEBUG_BREAKPOINT_CODE;
229  PDEBUG_BREAKPOINT bkpt;
230  if (FAILED(ITHISCALL(dbgCtrl, GetBreakpointById, b->internal, &bkpt))) {
231  HRESULT hr;
232  do {
233  b->internal = InterlockedIncrement(&bp_idx);
234  hr = ITHISCALL(dbgCtrl, AddBreakpoint, type, b->internal, &bkpt);
235  } while (hr == E_INVALIDARG);
236  if (FAILED(hr)) {
237  return 0;
238  }
239  }
240  ULONG flags;
241  THISCALL(bkpt, GetFlags, &flags);
242  flags = set ? flags | DEBUG_BREAKPOINT_ENABLED : flags & ~DEBUG_BREAKPOINT_ENABLED;
243  if (b->hw) {
244  ULONG access_type = 0;
245  if (b->perm & RZ_PERM_X) {
246  access_type |= DEBUG_BREAK_EXECUTE;
247  }
248  if (b->perm & RZ_PERM_R) {
249  access_type |= DEBUG_BREAK_READ;
250  }
251  if (b->perm & RZ_PERM_W) {
252  access_type |= DEBUG_BREAK_WRITE;
253  }
254  if (b->perm & RZ_PERM_RW) {
255  access_type |= DEBUG_BREAK_READ;
256  access_type |= DEBUG_BREAK_WRITE;
257  }
258  THISCALL(bkpt, SetDataParameters, b->size, access_type);
259  }
260  THISCALL(bkpt, SetFlags, flags);
261  THISCALL(bkpt, GetCurrentPassCount, (PULONG)&b->togglehits);
262  THISCALL(bkpt, SetOffset, b->addr);
263  return 1;
264 }
265 
267  DbgEngContext *idbg = dbg->plugin_data;
268  ULONG type;
269  if (!idbg || !idbg->initialized || FAILED(ITHISCALL(dbgCtrl, GetActualProcessorType, &type))) {
270  if (dbg->bits & RZ_SYS_BITS_64) {
271 #include "native/reg/windows-x64.h"
272  } else {
273 #include "native/reg/windows-x86.h"
274  }
275  return NULL;
276  }
277  if (type == IMAGE_FILE_MACHINE_IA64 || type == IMAGE_FILE_MACHINE_AMD64) {
278 #include "native/reg/windows-x64.h"
279  } else if (type == IMAGE_FILE_MACHINE_I386) {
280 #include "native/reg/windows-x86.h"
281  } else if (type == IMAGE_FILE_MACHINE_ARM) {
282 #include "native/reg/windows-arm.h"
283  } else if (type == IMAGE_FILE_MACHINE_ARM64) {
285  }
286  return NULL;
287 }
288 
289 static int windbg_reg_read(RzDebug *dbg, int type, ut8 *buf, int size) {
290  DbgEngContext *idbg = dbg->plugin_data;
291  rz_return_val_if_fail(idbg && idbg->initialized, 0);
292  ULONG ptype;
293  if (!idbg || !idbg->initialized || FAILED(ITHISCALL(dbgCtrl, GetActualProcessorType, &ptype))) {
294  return 0;
295  }
296  if (ptype == IMAGE_FILE_MACHINE_IA64 || ptype == IMAGE_FILE_MACHINE_AMD64) {
297  DWORD *b = (DWORD *)(buf + 0x30);
298  *b |= 0xff | CONTEXT_AMD64;
299  } else if (ptype == IMAGE_FILE_MACHINE_I386) {
300  DWORD *b = (DWORD *)buf;
301  *b |= 0xff | CONTEXT_i386;
302  } else if (ptype == IMAGE_FILE_MACHINE_ARM64) {
303  DWORD *b = (DWORD *)buf;
304  *b |= 0xff | CONTEXT_ARM64;
305  } else if (ptype == IMAGE_FILE_MACHINE_ARM) {
306  DWORD *b = (DWORD *)buf;
307  *b |= 0xff | CONTEXT_ARM;
308  }
309  if (SUCCEEDED(ITHISCALL(dbgAdvanced, GetThreadContext, (PVOID)buf, size))) {
310  return size;
311  }
312  return 0;
313 }
314 static int windbg_reg_write(RzDebug *dbg, int type, const ut8 *buf, int size) {
315  DbgEngContext *idbg = dbg->plugin_data;
316  rz_return_val_if_fail(idbg && idbg->initialized, 0);
317  if (SUCCEEDED(ITHISCALL(dbgAdvanced, SetThreadContext, (PVOID)buf, size))) {
318  return size;
319  }
320  return 0;
321 }
322 
324  DbgEngContext *idbg = dbg->plugin_data;
325  rz_return_val_if_fail(idbg && idbg->initialized, 0);
326  const size_t frame_cnt = 128;
327  PDEBUG_STACK_FRAME dbgframes = RZ_NEWS(DEBUG_STACK_FRAME, frame_cnt);
328  if (!dbgframes) {
329  return NULL;
330  }
331  ULONG frames_filled;
332  if (FAILED(ITHISCALL(dbgCtrl, GetStackTrace, 0, 0, 0, dbgframes, frame_cnt, &frames_filled))) {
333  free(dbgframes);
334  return NULL;
335  }
336  RzList *frames = rz_list_newf(free);
337  size_t i;
338  for (i = 0; i < frames_filled; i++) {
340  if (!f) {
341  break;
342  }
343  f->sp = dbgframes[i].StackOffset;
344  f->bp = dbgframes[i].FrameOffset;
345  f->addr = dbgframes[i].ReturnOffset;
346  f->size = f->bp - f->sp;
347  rz_list_append(frames, f);
348  }
349  return frames;
350 }
351 
353  DbgEngContext *idbg = dbg->plugin_data;
354  rz_return_val_if_fail(idbg && idbg->initialized, 0);
355  ULONG mod_cnt, mod_un_cnt;
356  if (FAILED(ITHISCALL(dbgSymbols, GetNumberModules, &mod_cnt, &mod_un_cnt))) {
357  return NULL;
358  }
359  if (!mod_cnt) {
360  return NULL;
361  }
362  PDEBUG_MODULE_PARAMETERS params = RZ_NEWS(DEBUG_MODULE_PARAMETERS, mod_cnt);
363  if (!params) {
364  return NULL;
365  }
366  if (FAILED(ITHISCALL(dbgSymbols, GetModuleParameters, mod_cnt, 0, 0, params))) {
367  return NULL;
368  }
370  if (!modules_list) {
371  return NULL;
372  }
373  size_t i;
374  for (i = 0; i < mod_cnt; i++) {
375  char *mod_name = malloc(params[i].ModuleNameSize);
376  char *image_name = malloc(params[i].ImageNameSize);
377  if (!mod_name || !image_name) {
378  free(mod_name);
379  free(image_name);
380  break;
381  }
382  if (FAILED(
383  ITHISCALL(dbgSymbols, GetModuleNames,
384  DEBUG_ANY_ID, params[i].Base,
385  image_name, params[i].ImageNameSize, NULL,
386  mod_name, params[i].ModuleNameSize, NULL,
387  NULL, 0, NULL))) {
388  free(mod_name);
389  free(image_name);
390  break;
391  }
392  RzDebugMap *mod = rz_debug_map_new(mod_name, params[i].Base, params[i].Base + params[i].Size, 0, params[i].Size);
393  if (mod) {
394  mod->file = strdup(image_name);
395  rz_list_append(modules_list, mod);
396  }
397  free(mod_name);
398  free(image_name);
399  }
400  return modules_list;
401 }
402 
404  DbgEngContext *idbg = dbg->plugin_data;
405  rz_return_val_if_fail(idbg && idbg->initialized, NULL);
406  int perm;
407  ULONG64 to = 0ULL;
408  MEMORY_BASIC_INFORMATION64 mbi;
409  RzList *mod_list = windbg_modules_get(dbg);
411  const int mod_cnt = mod_list ? rz_list_length(mod_list) : 0;
412  PIMAGE_NT_HEADERS64 h = RZ_NEWS(IMAGE_NT_HEADERS64, mod_cnt);
413  PIMAGE_SECTION_HEADER *s = RZ_NEWS0(PIMAGE_SECTION_HEADER, mod_cnt);
414  RzListIter *it;
415  RzDebugMap *mod = NULL;
416  size_t i = 0;
417  rz_list_foreach (mod_list, it, mod) {
418  if (FAILED(ITHISCALL(dbgData, ReadImageNtHeaders, mod->addr, h + i))) {
419  memset(h + i, 0, sizeof(IMAGE_NT_HEADERS64));
420  } else {
421  IMAGE_DOS_HEADER dos;
422  ITHISCALL(dbgData, ReadVirtual, mod->addr, (PVOID)&dos, sizeof(IMAGE_DOS_HEADER), NULL);
423  const size_t header_size = h[i].OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC
424  ? sizeof(IMAGE_NT_HEADERS32)
425  : sizeof(IMAGE_NT_HEADERS64);
426  ULONG64 offset = mod->addr + dos.e_lfanew + header_size;
427  const ULONG size = sizeof(IMAGE_SECTION_HEADER) * h[i].FileHeader.NumberOfSections;
428  s[i] = malloc(size);
429  ITHISCALL(dbgData, ReadVirtual, offset, (PVOID)s[i], size, NULL);
430  }
431  i++;
432  }
433  ULONG page_size = 1;
434  ITHISCALL(dbgCtrl, GetPageSize, &page_size);
435  ULONG p_mask = page_size - 1;
436  while (SUCCEEDED(ITHISCALL(dbgData, QueryVirtual, to, &mbi))) {
437  to = mbi.BaseAddress + mbi.RegionSize;
438  perm = 0;
439  perm |= mbi.Protect & PAGE_READONLY ? RZ_PERM_R : 0;
440  perm |= mbi.Protect & PAGE_READWRITE ? RZ_PERM_RW : 0;
441  perm |= mbi.Protect & PAGE_EXECUTE ? RZ_PERM_X : 0;
442  perm |= mbi.Protect & PAGE_EXECUTE_READ ? RZ_PERM_RX : 0;
443  perm |= mbi.Protect & PAGE_EXECUTE_READWRITE ? RZ_PERM_RWX : 0;
444  perm = mbi.Protect & PAGE_NOACCESS ? 0 : perm;
445  if (!perm) {
446  continue;
447  }
448  char *name = "";
449  if (mbi.Type == MEM_IMAGE) {
450  i = 0;
451  rz_list_foreach (mod_list, it, mod) {
452  if (mbi.BaseAddress >= mod->addr && mbi.BaseAddress < mod->addr + mod->size) {
453  break;
454  }
455  i++;
456  }
457  if (i < mod_cnt && mod) {
458  size_t j;
459  for (j = 0; j < h[i].FileHeader.NumberOfSections; j++) {
460  ut64 sect_vaddr = mod->addr + s[i][j].VirtualAddress;
461  ut64 sect_vsize = (((ut64)s[i][j].Misc.VirtualSize) + p_mask) & ~p_mask;
462  if (mbi.BaseAddress >= sect_vaddr && mbi.BaseAddress < sect_vaddr + sect_vsize) {
463  name = sdb_fmt("%s | %.8s", mod->name, s[i][j].Name);
464  break;
465  }
466  }
467  if (!*name) {
468  name = mod->name;
469  }
470  }
471  }
472  RzDebugMap *map = rz_debug_map_new(name, mbi.BaseAddress, to, perm, 0);
473  rz_list_append(map_list, map);
474  }
475  for (i = 0; i < mod_cnt; i++) {
476  free(s[i]);
477  }
478  free(s);
479  free(h);
480  rz_list_free(mod_list);
481  return map_list;
482 }
483 
484 static int windbg_attach(RzDebug *dbg, int pid) {
485  ULONG Id = 0;
486  DbgEngContext *idbg = dbg->plugin_data;
487  rz_return_val_if_fail(idbg && idbg->initialized, -1);
488  if (SUCCEEDED(ITHISCALL(dbgSysObj, GetCurrentProcessSystemId, &Id))) {
489  if (Id == pid && SUCCEEDED(ITHISCALL(dbgSysObj, GetCurrentThreadSystemId, &Id))) {
490  return Id;
491  }
492  }
493  if (SUCCEEDED(ITHISCALL(dbgClient, AttachProcess, idbg->server, pid, DEBUG_ATTACH_DEFAULT))) {
494  return windbg_wait(dbg, pid);
495  }
496  return -1;
497 }
498 
499 static int windbg_detach(RzDebug *dbg, int pid) {
500  DbgEngContext *idbg = dbg->plugin_data;
501  rz_return_val_if_fail(idbg && idbg->initialized, 0);
502  return SUCCEEDED(ITHISCALL(dbgClient, DetachProcesses));
503 }
504 
505 static bool windbg_kill(RzDebug *dbg, int pid, int tid, int sig) {
506  DbgEngContext *idbg = dbg->plugin_data;
507  if (!idbg || !idbg->initialized) {
508  return false;
509  }
510  if (!sig) {
511  ULONG exit_code, class, qualifier;
512  if (SUCCEEDED(ITHISCALL(dbgCtrl, GetDebuggeeType, &class, &qualifier))) {
513  if (class == DEBUG_CLASS_UNINITIALIZED) {
514  return false;
515  }
516  if (qualifier >= DEBUG_DUMP_SMALL && qualifier <= DEBUG_DUMP_ACTIVE) {
517  return true;
518  }
519  }
520  if (FAILED(ITHISCALL(dbgClient, GetExitCode, &exit_code))) {
521  return true;
522  }
523  return exit_code == STILL_ACTIVE;
524  }
525  HRESULT hr = ITHISCALL(dbgClient, TerminateProcesses);
526  return SUCCEEDED(hr);
527 }
528 
530  DbgEngContext *idbg = dbg->plugin_data;
531  rz_return_val_if_fail(idbg && idbg->initialized, NULL);
532  ULONG thread_cnt = 0;
533  ITHISCALL(dbgSysObj, GetNumberThreads, &thread_cnt);
534  if (!thread_cnt) {
535  return NULL;
536  }
537  PULONG threads_ids = RZ_NEWS(ULONG, thread_cnt);
538  PULONG threads_sysids = RZ_NEWS(ULONG, thread_cnt);
540  if (!list || !threads_ids || !threads_sysids) {
541  free(list);
542  free(threads_ids);
543  free(threads_sysids);
544  return NULL;
545  }
546  ITHISCALL(dbgSysObj, GetThreadIdsByIndex, 0, thread_cnt, threads_ids, threads_sysids);
547  size_t i;
548  for (i = 0; i < thread_cnt; i++) {
549  ULONG64 pc;
550  ITHISCALL(dbgSysObj, SetCurrentThreadId, threads_ids[i]);
551  ITHISCALL(dbgReg, GetInstructionOffset, &pc);
552  rz_list_append(list, rz_debug_pid_new(NULL, threads_sysids[i], 0, 's', pc));
553  }
555  free(threads_ids);
556  free(threads_sysids);
557  return list;
558 }
559 
560 static RzDebugInfo *windbg_info(RzDebug *dbg, const char *arg) {
561  DbgEngContext *idbg = dbg->plugin_data;
562  rz_return_val_if_fail(idbg && idbg->initialized, NULL);
563  char exeinfo[MAX_PATH];
564  char cmdline[MAX_PATH];
565  if (SUCCEEDED(ITHISCALL(dbgClient, GetRunningProcessDescription, idbg->server, dbg->pid, DEBUG_PROC_DESC_NO_SERVICES | DEBUG_PROC_DESC_NO_MTS_PACKAGES, exeinfo, MAX_PATH, NULL, cmdline, MAX_PATH, NULL))) {
567  if (!info) {
568  return NULL;
569  }
570  info->pid = dbg->pid;
571  info->tid = dbg->tid;
572  info->exe = strdup(exeinfo);
573  info->cmdline = strdup(cmdline);
574  }
575  return NULL;
576 }
577 
578 static bool windbg_gcore(RzDebug *dbg, char *p, RzBuffer *dest) {
579  DbgEngContext *idbg = dbg->plugin_data;
580  rz_return_val_if_fail(idbg && idbg->initialized, false);
581  (void)p;
582  char *path = rz_sys_getenv(RZ_SYS_TMP);
583  if (RZ_STR_ISEMPTY(path)) {
584  free(path);
585  path = rz_sys_getdir();
586  if (RZ_STR_ISEMPTY(path)) {
587  free(path);
588  return false;
589  }
590  }
591  path = rz_str_appendf(path, "\\core.%d", dbg->pid);
592  ITHISCALL(dbgClient, WriteDumpFile, path, DEBUG_DUMP_DEFAULT);
593  free(path);
594  return true;
595 }
596 
598  DbgEngContext *idbg = dbg->plugin_data;
599  rz_return_val_if_fail(idbg && idbg->initialized, NULL);
601  ULONG ids[1000];
602  ULONG ids_cnt;
603  if (SUCCEEDED(ITHISCALL(dbgClient, GetRunningProcessSystemIds,
604  idbg->server, ids, _countof(ids), &ids_cnt))) {
605  size_t i;
606  for (i = 0; i < ids_cnt; i++) {
607  char path[MAX_PATH];
608  if (SUCCEEDED(ITHISCALL(dbgClient, GetRunningProcessDescription,
609  idbg->server, ids[i], DEBUG_PROC_DESC_DEFAULT,
610  path, sizeof(path), NULL, NULL, 0, NULL))) {
611  RzDebugPid *pid = rz_debug_pid_new(path, ids[i], 0, 'r', 0);
613  }
614  }
615  }
616  return list;
617 }
618 
620  .name = "windbg",
621  .license = "LGPL3",
622  .bits = RZ_SYS_BITS_64,
623  .arch = "x86,x64,arm,arm64",
624  .canstep = 1,
625  .init = windbg_init,
626  .attach = windbg_attach,
627  .detach = windbg_detach,
628  .breakpoint = windbg_breakpoint,
629  .frames = windbg_frames,
630  .kill = windbg_kill,
631  .select = windbg_select,
632  .step = windbg_step,
633  .step_over = windbg_step_over,
634  .threads = windbg_threads,
635  .cont = windbg_continue,
636  .wait = windbg_wait,
637  .stop = windbg_stop,
638  .reg_read = windbg_reg_read,
639  .reg_write = windbg_reg_write,
640  .reg_profile = windbg_reg_profile,
641  .map_get = windbg_map_get,
642  .modules_get = windbg_modules_get,
643  .info = windbg_info,
644  .gcore = windbg_gcore,
645  .pids = windbg_pids
646 };
647 
648 #ifndef RZ_PLUGIN_INCORE
651  .data = &rz_debug_plugin_windbg,
653 };
654 #endif // RZ_PLUGIN_INCORE
lzma_index ** i
Definition: index.h:629
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
#define EXCEPTION_SINGLE_STEP
Definition: common_windows.c:9
#define EXCEPTION_GUARD_PAGE
#define EXCEPTION_FLT_STACK_CHECK
#define EXCEPTION_INT_DIVIDE_BY_ZERO
#define EXCEPTION_FLT_UNDERFLOW
#define EXCEPTION_FLT_OVERFLOW
#define EXCEPTION_FLT_DENORMAL_OPERAND
#define EXCEPTION_FLT_INEXACT_RESULT
#define EXCEPTION_ILLEGAL_INSTRUCTION
#define EXCEPTION_ACCESS_VIOLATION
Definition: common_windows.c:6
#define EXCEPTION_BREAKPOINT
Definition: common_windows.c:8
#define EXCEPTION_FLT_INVALID_OPERATION
#define EXCEPTION_FLT_DIVIDE_BY_ZERO
RZ_API void rz_cons_break_pop(void)
Definition: cons.c:361
RZ_API void rz_cons_break_push(RzConsBreak cb, void *user)
Definition: cons.c:357
#define RZ_API
#define NULL
Definition: cris-opc.c:27
int mod(int a, int b)
Definition: crypto_rot.c:8
static static fork const void static count static fd const char const char static newpath const char static path const char path
Definition: sflib.h:35
static char * windbg_reg_profile(RzDebug *dbg)
Definition: debug_windbg.c:266
static bool windbg_gcore(RzDebug *dbg, char *p, RzBuffer *dest)
Definition: debug_windbg.c:578
#define CONTEXT_AMD64
Definition: debug_windbg.c:14
static RzDebugInfo * windbg_info(RzDebug *dbg, const char *arg)
Definition: debug_windbg.c:560
#define DEBUG_DUMP_ACTIVE
Definition: debug_windbg.c:23
static int windbg_attach(RzDebug *dbg, int pid)
Definition: debug_windbg.c:484
RzDebugPlugin rz_debug_plugin_windbg
Definition: debug_windbg.c:619
static void break_debugger(void *user)
Definition: debug_windbg.c:139
static RzList * windbg_map_get(RzDebug *dbg)
Definition: debug_windbg.c:403
#define CONTEXT_ARM64
Definition: debug_windbg.c:11
#define TIMEOUT
Definition: debug_windbg.c:26
#define ITHISCALL(dbginterface, function,...)
Definition: debug_windbg.c:28
static int windbg_detach(RzDebug *dbg, int pid)
Definition: debug_windbg.c:499
static int windbg_breakpoint(RzBreakpoint *bp, RzBreakpointItem *b, bool set)
Definition: debug_windbg.c:222
static bool is_target_kernel(DbgEngContext *idbg)
Definition: debug_windbg.c:47
static RzList * windbg_threads(RzDebug *dbg, int pid)
Definition: debug_windbg.c:529
static bool do_break
Definition: debug_windbg.c:137
#define THISCALL(dbginterface, function,...)
Definition: debug_windbg.c:27
RzList * windbg_pids(RzDebug *dbg, int pid)
Definition: debug_windbg.c:597
RZ_API RzLibStruct rizin_plugin
Definition: debug_windbg.c:649
static int windbg_continue(RzDebug *dbg, int pid, int tid, int sig)
Definition: debug_windbg.c:96
static int windbg_reg_write(RzDebug *dbg, int type, const ut8 *buf, int size)
Definition: debug_windbg.c:314
#define CONTEXT_i386
Definition: debug_windbg.c:17
static RzDebugReasonType exception_to_reason(DWORD ExceptionCode)
Definition: debug_windbg.c:105
static RzList * windbg_frames(RzDebug *dbg, ut64 at)
Definition: debug_windbg.c:323
static int windbg_reg_read(RzDebug *dbg, int type, ut8 *buf, int size)
Definition: debug_windbg.c:289
static int windbg_step(RzDebug *dbg)
Definition: debug_windbg.c:72
static bool io_desc_is_windbg(RzIO *io)
Definition: debug_windbg.c:57
static int windbg_wait(RzDebug *dbg, int pid)
Definition: debug_windbg.c:148
#define IMAGE_FILE_MACHINE_ARM64
Definition: debug_windbg.c:20
static int windbg_select(RzDebug *dbg, int pid, int tid)
Definition: debug_windbg.c:79
static int windbg_step_over(RzDebug *dbg)
Definition: debug_windbg.c:212
static int windbg_stop(RzDebug *dbg)
Definition: debug_windbg.c:131
static bool windbg_init(RzDebug *dbg, void **user)
Definition: debug_windbg.c:61
static bool windbg_kill(RzDebug *dbg, int pid, int tid, int sig)
Definition: debug_windbg.c:505
#define CONTEXT_ARM
Definition: debug_windbg.c:8
static RzList * windbg_modules_get(RzDebug *dbg)
Definition: debug_windbg.c:352
RzDebug * dbg
Definition: desil.c:30
RZ_API void rz_debug_map_free(RzDebugMap *map)
Definition: dmap.c:77
RZ_API RzDebugMap * rz_debug_map_new(char *name, ut64 addr, ut64 addr_end, int perm, int user)
Definition: dmap.c:7
size_t map(int syms, int left, int len)
Definition: enough.c:237
RZ_API char * sdb_fmt(const char *fmt,...)
Definition: fmt.c:26
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
voidpf uLong offset
Definition: ioapi.h:144
voidpf void * buf
Definition: ioapi.h:138
#define LONG
InterlockedIncrement
Definition: kernel.h:56
uint8_t ut8
Definition: lh5801.h:11
return memset(p, 0, total)
void * p
Definition: libc.cpp:67
static void list(RzEgg *egg)
Definition: rz-gg.c:52
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 ut32 rz_list_length(RZ_NONNULL const RzList *list)
Returns the length of the list.
Definition: list.c:109
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")
char * dest
Definition: lz4.h:697
int type
Definition: mipsasm.c:17
RZ_API RzDebugPid * rz_debug_pid_free(RzDebugPid *pid)
Definition: pid.c:20
RZ_API RzDebugPid * rz_debug_pid_new(const char *path, int pid, int uid, char status, ut64 pc)
Definition: pid.c:6
static RzSocket * s
Definition: rtr.c:28
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RzDebugReasonType
Definition: rz_debug.h:89
@ RZ_DEBUG_REASON_DEAD
Definition: rz_debug.h:90
@ RZ_DEBUG_REASON_STEP
Definition: rz_debug.h:98
@ RZ_DEBUG_REASON_ILLEGAL
Definition: rz_debug.h:102
@ RZ_DEBUG_REASON_BREAKPOINT
Definition: rz_debug.h:94
@ RZ_DEBUG_REASON_USERSUSP
Definition: rz_debug.h:115
@ RZ_DEBUG_REASON_TRAP
Definition: rz_debug.h:111
@ RZ_DEBUG_REASON_ERROR
Definition: rz_debug.h:104
@ RZ_DEBUG_REASON_FPU
Definition: rz_debug.h:114
@ RZ_DEBUG_REASON_SEGFAULT
Definition: rz_debug.h:93
@ RZ_DEBUG_REASON_NEW_PID
Definition: rz_debug.h:105
@ RZ_DEBUG_REASON_EXIT_PID
Definition: rz_debug.h:108
@ RZ_DEBUG_REASON_DIVBYZERO
Definition: rz_debug.h:101
@ RZ_LIB_TYPE_DBG
Definition: rz_lib.h:70
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
RZ_API char * rz_str_appendf(char *ptr, const char *fmt,...) RZ_PRINTF_CHECK(2
#define RZ_STR_ISEMPTY(x)
Definition: rz_str.h:67
RZ_API char * rz_sys_getenv(const char *key)
Get the value of an environment variable named key or NULL if none exists.
Definition: sys.c:483
RZ_API char * rz_sys_getdir(void)
Get current working directory.
Definition: sys.c:521
@ RZ_SYS_BITS_64
Definition: rz_sys.h:21
RZ_API ut64 rz_time_now(void)
Returns the current time in microseconds.
Definition: time.c:88
#define RZ_NEWS(x, y)
Definition: rz_types.h:283
#define RZ_PERM_R
Definition: rz_types.h:93
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_PERM_RW
Definition: rz_types.h:96
#define RZ_SYS_TMP
Definition: rz_types.h:221
#define RZ_PERM_W
Definition: rz_types.h:94
#define RZ_PERM_X
Definition: rz_types.h:95
#define RZ_PERM_RX
Definition: rz_types.h:97
#define RZ_NEWS0(x, y)
Definition: rz_types.h:282
#define RZ_PERM_RWX
Definition: rz_types.h:98
#define RZ_VERSION
Definition: rz_version.h:8
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr socklen_t static fromlen const void const struct sockaddr to
Definition: sfsocketcall.h:125
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
#define b(i)
Definition: sha256.c:42
#define f(i)
Definition: sha256.c:46
#define h(i)
Definition: sha256.c:48
DWORD lastExecutionStatus
Definition: debug_windbg.c:37
PDEBUG_SYSTEM_OBJECTS4 dbgSysObj
Definition: debug_windbg.c:42
PDEBUG_REGISTERS2 dbgReg
Definition: debug_windbg.c:41
PDEBUG_CONTROL4 dbgCtrl
Definition: debug_windbg.c:39
ULONG64 server
Definition: debug_windbg.c:35
ULONG64 processBase
Definition: debug_windbg.c:36
PDEBUG_CLIENT5 dbgClient
Definition: debug_windbg.c:38
PDEBUG_SYMBOLS3 dbgSymbols
Definition: debug_windbg.c:43
PDEBUG_DATA_SPACES4 dbgData
Definition: debug_windbg.c:40
PDEBUG_ADVANCED3 dbgAdvanced
Definition: debug_windbg.c:44
Definition: swift.c:7
Definition: z80asm.h:102
Definition: rz_bp.h:78
void * user
Definition: rz_bp.h:79
const char * version
Definition: rz_debug.h:362
const char * name
Definition: rz_debug.h:359
RzDebugReason reason
Definition: rz_debug.h:276
int bits
Definition: rz_debug.h:243
void * plugin_data
Definition: rz_debug.h:296
RzIOBind iob
Definition: rz_debug.h:293
RzIO * io
Definition: rz_io.h:232
void * data
Definition: rz_io.h:102
struct rz_io_plugin_t * plugin
Definition: rz_io.h:103
const char * name
Definition: rz_io.h:115
Definition: rz_io.h:59
struct rz_io_desc_t * desc
Definition: rz_io.h:60
uv_timer_t timeout
Definition: main.c:9
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
ULONG
PVOID
DWORD
PULONG