Rizin
unix-like reverse engineering framework and cli tools
debug_winkd.c File Reference
#include <rz_debug.h>
#include <winkd.h>
#include <kd.h>
#include "common_winkd.h"
#include "common_windows.h"
#include "mdmp_windefs.h"
#include "native/reg/windows-x86.h"
#include "native/reg/windows-x64.h"
#include "native/bt/windows-x64.c"
#include "native/bt/generic-all.c"

Go to the source code of this file.

Macros

#define O_(n)   kdctx->windctx.profile->f[n]
 

Functions

static int rz_debug_winkd_reg_read (RZ_BORROW RZ_NONNULL RzDebug *dbg, int type, ut8 *buf, int size)
 
static int rz_debug_winkd_reg_write (RZ_BORROW RZ_NONNULL RzDebug *dbg, int type, const ut8 *buf, int size)
 
static int rz_debug_winkd_continue (RZ_BORROW RZ_NONNULL RzDebug *dbg, int pid, int tid, int sig)
 
static void get_current_process_and_thread (RZ_BORROW RZ_NONNULL RzDebug *dbg, ut64 thread_address)
 
static RzDebugReasonType rz_debug_winkd_wait (RZ_BORROW RZ_NONNULL RzDebug *dbg, int pid)
 
static bool get_module_timestamp (ut64 addr, ut32 *timestamp, ut32 *sizeofimage)
 
static int rz_debug_winkd_attach (RZ_BORROW RZ_NONNULL RzDebug *dbg, int pid)
 
static int rz_debug_winkd_detach (RZ_BORROW RZ_NONNULL RzDebug *dbg, int pid)
 
static char * rz_debug_winkd_reg_profile (RZ_BORROW RZ_NONNULL RzDebug *dbg)
 
static int rz_debug_winkd_breakpoint (RZ_BORROW RZ_NONNULL RzBreakpoint *bp, RZ_BORROW RZ_NULLABLE RzBreakpointItem *b, bool set)
 
static bool rz_debug_winkd_init (RZ_BORROW RZ_NONNULL RzDebug *dbg, void **user)
 
static RzListrz_debug_winkd_pids (RZ_BORROW RZ_NONNULL RzDebug *dbg, int pid)
 
static int rz_debug_winkd_select (RZ_BORROW RZ_NONNULL RzDebug *dbg, int pid, int tid)
 
static RzListrz_debug_winkd_threads (RZ_BORROW RZ_NONNULL RzDebug *dbg, int pid)
 
static RzListrz_debug_winkd_modules (RZ_BORROW RZ_NONNULL RzDebug *dbg)
 
static RzListrz_debug_winkd_frames (RZ_BORROW RZ_NONNULL RzDebug *dbg, ut64 at)
 
static RzListrz_debug_winkd_maps (RZ_BORROW RZ_NONNULL RzDebug *dbg)
 

Variables

static KdCtxkdctx = NULL
 
RzDebugPlugin rz_debug_plugin_winkd
 
RZ_API RzLibStruct rizin_plugin
 

Macro Definition Documentation

◆ O_

#define O_ (   n)    kdctx->windctx.profile->f[n]

Definition at line 11 of file debug_winkd.c.

Function Documentation

◆ get_current_process_and_thread()

static void get_current_process_and_thread ( RZ_BORROW RZ_NONNULL RzDebug dbg,
ut64  thread_address 
)
static

Definition at line 52 of file debug_winkd.c.

52  {
53  if (!O_(ET_ApcProcess)) {
54  return;
55  }
56  WindThread *thread = winkd_get_thread_at(&kdctx->windctx, thread_address);
57  if (!thread) {
58  return;
59  }
60  // Read the process pointer from the current thread
62  if (address_process && address_process != kdctx->windctx.target.eprocess) {
63  // Then read the process
64  WindProc *proc = winkd_get_process_at(&kdctx->windctx, address_process);
65  if (proc) {
68  free(proc);
69  }
70  }
71 
72  kdctx->windctx.target_thread = *thread;
74  free(thread);
75 }
#define O_(n)
Definition: debug_winkd.c:11
static KdCtx * kdctx
Definition: debug_winkd.c:13
RzDebug * dbg
Definition: desil.c:30
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
Definition: winkd.h:11
ut64 eprocess
Definition: winkd.h:12
ut32 uniqueid
Definition: winkd.h:13
ut64 ethread
Definition: winkd.h:24
ut32 uniqueid
Definition: winkd.h:21
WindCtx windctx
Definition: winkd.h:96
WindThread target_thread
Definition: winkd.h:92
WindProc target
Definition: winkd.h:91
WindReadAt * read_at_kernel_virtual
Definition: winkd.h:82
struct Proc * proc
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
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
@ ET_ApcProcess
Definition: winkd.h:60
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

References dbg, WindProc::eprocess, ET_ApcProcess, WindThread::ethread, free(), kdctx, O_, rz_debug_t::pid, proc, _WindCtx::read_at_kernel_virtual, _WindCtx::target, _WindCtx::target_thread, rz_debug_t::tid, WindProc::uniqueid, WindThread::uniqueid, ut64(), _KdCtx::windctx, winkd_get_process_at(), winkd_get_thread_at(), and winkd_read_ptr_at().

Referenced by rz_debug_winkd_attach(), and rz_debug_winkd_wait().

◆ get_module_timestamp()

static bool get_module_timestamp ( ut64  addr,
ut32 timestamp,
ut32 sizeofimage 
)
static

Definition at line 122 of file debug_winkd.c.

122  {
123  ut8 mz[2];
124  if (kdctx->windctx.read_at_kernel_virtual(kdctx->windctx.user, addr, mz, 2) != 2) {
125  return false;
126  }
127  if (memcmp(mz, "MZ", 2)) {
128  return false;
129  }
130  ut8 pe_off_buf[2];
131  if (kdctx->windctx.read_at_kernel_virtual(kdctx->windctx.user, addr + 0x3c, pe_off_buf, 2) != 2) {
132  return false;
133  }
134  const ut16 pe_off = rz_read_le16(pe_off_buf);
135  ut8 pe[2];
136  if (kdctx->windctx.read_at_kernel_virtual(kdctx->windctx.user, addr + pe_off, pe, 2) != 2) {
137  return false;
138  }
139  if (memcmp(pe, "PE", 2)) {
140  return false;
141  }
142  ut8 ts[4];
143  if (kdctx->windctx.read_at_kernel_virtual(kdctx->windctx.user, addr + pe_off + 8, ts, 4) != 4) {
144  return false;
145  }
146  ut8 sz[4];
147  if (kdctx->windctx.read_at_kernel_virtual(kdctx->windctx.user, addr + pe_off + 0x50, sz, 4) != 4) {
148  return false;
149  };
150  *timestamp = rz_read_le32(ts);
151  *sizeofimage = rz_read_le32(sz);
152  return true;
153 }
uint16_t ut16
uint8_t ut8
Definition: lh5801.h:11
static ut16 rz_read_le16(const void *src)
Definition: rz_endian.h:206
static ut32 rz_read_le32(const void *src)
Definition: rz_endian.h:239
void * user
Definition: winkd.h:84
static int addr
Definition: z80asm.c:58

References addr, kdctx, _WindCtx::read_at_kernel_virtual, rz_read_le16(), rz_read_le32(), _WindCtx::user, and _KdCtx::windctx.

Referenced by rz_debug_winkd_attach().

◆ rz_debug_winkd_attach()

static int rz_debug_winkd_attach ( RZ_BORROW RZ_NONNULL RzDebug dbg,
int  pid 
)
static

Definition at line 155 of file debug_winkd.c.

155  {
156  RzIODesc *desc = dbg->iob.io->desc;
157 
158  if (!desc || !desc->plugin || !desc->plugin->name || !desc->data) {
159  return false;
160  }
161  if (strncmp(desc->plugin->name, "winkd", 6)) {
162  return false;
163  }
164  if (dbg->arch && strcmp(dbg->arch, "x86")) {
165  return false;
166  }
167  kdctx = (KdCtx *)desc->data;
168 
169  // Handshake
170  int ret = winkd_sync(kdctx);
171  if (ret < 0) {
172  RZ_LOG_ERROR("Could not connect to winkd\n");
173  return false;
174  } else if (!ret) {
175  RZ_LOG_VERBOSE("Already synced\n");
176  return true;
177  }
178  if (!winkd_read_ver(kdctx)) {
179  return false;
180  }
181 
182  // Load PDB for kernel
184  RzList *modules = NULL;
185  if (!mod->timestamp || !mod->size) {
187  RZ_LOG_ERROR("Could not get timestamp for kernel module\n");
188  return false;
189  }
190  }
191  if (!mod->name) {
192  mod->name = strdup("\\ntoskrnl.exe");
193  }
194  char *exepath, *pdbpath;
196  dbg->corebind.cfgGet(dbg->corebind.core, "pdb.server"),
197  dbg->corebind.cfgGet(dbg->corebind.core, "pdb.symstore"),
198  &exepath, &pdbpath)) {
199  RZ_LOG_ERROR("Failed to download module and pdb\n");
201  return false;
202  }
203  dbg->corebind.cfgSetI(dbg->corebind.core, "bin.baddr", mod->addr);
204  // TODO: Convert to API call
205  dbg->corebind.cmdf(dbg->corebind.core, "idp \"%s\"", pdbpath);
207 
208  if (!kdctx->windctx.profile) {
209  RZ_LOG_INFO("Trying to build profile dinamically by using the ntoskrnl.exe's PDB\n");
211  }
213  // Make rz_debug_is_dead happy
214  dbg->pid = 0;
215  ut8 buf[2];
216  // Get structure offset of current process pointer inside a KTHREAD from the kd debugger data
220  }
221 
222  // Mapping from the vad is unreliable so just tell core that its ok to put breakpoints everywhere
223  dbg->corebind.cfgSetI(dbg->corebind.core, "dbg.bpinmaps", 0);
224  return true;
225 }
const char * desc
Definition: bin_vsf.c:19
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 NULL
Definition: cris-opc.c:27
int mod(int a, int b)
Definition: crypto_rot.c:8
static void get_current_process_and_thread(RZ_BORROW RZ_NONNULL RzDebug *dbg, ut64 thread_address)
Definition: debug_winkd.c:52
static bool get_module_timestamp(ut64 addr, ut32 *timestamp, ut32 *sizeofimage)
Definition: debug_winkd.c:122
voidpf void * buf
Definition: ioapi.h:138
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")
modules
Definition: regress.py:20
#define RZ_LOG_VERBOSE(fmtstr,...)
Definition: rz_log.h:52
#define RZ_LOG_INFO(fmtstr,...)
Definition: rz_log.h:54
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
ut32 size
Definition: winkd.h:31
ut32 timestamp
Definition: winkd.h:32
ut64 addr
Definition: winkd.h:30
Definition: winkd.h:95
WindModule kernel_module
Definition: winkd.h:106
Profile * profile
Definition: winkd.h:80
ut64 KdDebuggerDataBlock
Definition: winkd.h:85
RzTypeDB * typedb
Definition: rz_analysis.h:602
RzCoreConfigSetI cfgSetI
Definition: rz_bind.h:46
RzCoreConfigGet cfgGet
Definition: rz_bind.h:44
void * core
Definition: rz_bind.h:31
RzCoreCmdF cmdf
Definition: rz_bind.h:33
RzCoreBind corebind
Definition: rz_debug.h:314
RzAnalysis * analysis
Definition: rz_debug.h:305
char * arch
Definition: rz_debug.h:242
int bits
Definition: rz_debug.h:243
RzIOBind iob
Definition: rz_debug.h:293
RzIO * io
Definition: rz_io.h:232
struct rz_io_desc_t * desc
Definition: rz_io.h:60
bool winkd_read_ver(RZ_BORROW RZ_NONNULL KdCtx *ctx)
Definition: winkd.c:997
int winkd_read_at(RZ_BORROW RZ_NONNULL KdCtx *ctx, const ut64 offset, RZ_BORROW RZ_NONNULL RZ_OUT ut8 *buf, const int count)
Definition: winkd.c:1377
int winkd_sync(RZ_BORROW RZ_NONNULL KdCtx *ctx)
Definition: winkd.c:1065
int winkd_get_bits(RZ_BORROW RZ_NONNULL WindCtx *ctx)
Definition: winkd.c:80
@ K_OffsetKThreadApcProcess
Definition: winkd.h:46

References WindModule::addr, rz_debug_t::analysis, rz_debug_t::arch, rz_debug_t::bits, rz_core_bind_t::cfgGet, rz_core_bind_t::cfgSetI, rz_core_bind_t::cmdf, rz_core_bind_t::core, rz_debug_t::corebind, dbg, desc, rz_io_t::desc, ET_ApcProcess, WindThread::ethread, get_current_process_and_thread(), get_module_timestamp(), rz_io_bind_t::io, rz_debug_t::iob, K_OffsetKThreadApcProcess, kdctx, _WindCtx::KdDebuggerDataBlock, _KdCtx::kernel_module, mod(), regress::modules, NULL, O_, rz_debug_t::pid, _WindCtx::profile, rz_list_free(), RZ_LOG_ERROR, RZ_LOG_INFO, RZ_LOG_VERBOSE, rz_read_le16(), WindModule::size, strdup(), _WindCtx::target_thread, WindModule::timestamp, rz_analysis_t::typedb, _KdCtx::windctx, winkd_build_profile(), winkd_download_module_and_pdb(), winkd_get_bits(), winkd_read_at(), winkd_read_ver(), and winkd_sync().

Referenced by rz_debug_winkd_reg_profile().

◆ rz_debug_winkd_breakpoint()

static int rz_debug_winkd_breakpoint ( RZ_BORROW RZ_NONNULL RzBreakpoint bp,
RZ_BORROW RZ_NULLABLE RzBreakpointItem b,
bool  set 
)
static

Definition at line 249 of file debug_winkd.c.

249  {
250  int *tag;
251  if (!b) {
252  return false;
253  }
254  // Use a 32 bit word here to keep this compatible with 32 bit hosts
255  if (!b->data) {
256  b->data = RZ_NEWS0(char, 4);
257  if (!b->data) {
258  return 0;
259  }
260  }
261  tag = (int *)b->data;
262  return winkd_bkpt(kdctx, b->addr, set, b->hw, tag);
263 }
#define RZ_NEWS0(x, y)
Definition: rz_types.h:282
#define b(i)
Definition: sha256.c:42
int winkd_bkpt(RZ_BORROW RZ_NONNULL KdCtx *ctx, const ut64 addr, const int set, const int hw, RZ_BORROW RZ_NONNULL int *handle)
Definition: winkd.c:1312

References b, kdctx, RZ_NEWS0, test-lz4-versions::tag, and winkd_bkpt().

◆ rz_debug_winkd_continue()

static int rz_debug_winkd_continue ( RZ_BORROW RZ_NONNULL RzDebug dbg,
int  pid,
int  tid,
int  sig 
)
static

Definition at line 48 of file debug_winkd.c.

48  {
49  return winkd_continue(kdctx, !sig);
50 }
int winkd_continue(RZ_BORROW RZ_NONNULL KdCtx *ctx, bool handled)
Definition: winkd.c:1141

References kdctx, and winkd_continue().

◆ rz_debug_winkd_detach()

static int rz_debug_winkd_detach ( RZ_BORROW RZ_NONNULL RzDebug dbg,
int  pid 
)
static

Definition at line 227 of file debug_winkd.c.

227  {
228  eprintf("Detaching...\n");
229  kdctx->syncd = 0;
230  return true;
231 }
#define eprintf(x, y...)
Definition: rlcc.c:7
int syncd
Definition: winkd.h:100

References eprintf, kdctx, and _KdCtx::syncd.

◆ rz_debug_winkd_frames()

static RzList* rz_debug_winkd_frames ( RZ_BORROW RZ_NONNULL RzDebug dbg,
ut64  at 
)
static

Definition at line 389 of file debug_winkd.c.

389  {
390  if (!kdctx || !kdctx->desc || !kdctx->syncd) {
391  return NULL;
392  }
393  RzList *ret = NULL;
395  struct context_type_amd64 context = { 0 };
397  } else {
398  ret = backtrace_generic(dbg);
399  }
400  return ret;
401 }
static RzList * backtrace_generic(RZ_BORROW RZ_NONNULL RzDebug *dbg)
Definition: generic-all.c:14
io_desc_t * desc
Definition: winkd.h:97
bool is_arm
Definition: winkd.h:90
bool is_64bit
Definition: winkd.h:88
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 backtrace_generic(), backtrace_windows_x64(), dbg, _KdCtx::desc, _WindCtx::is_64bit, _WindCtx::is_arm, kdctx, NULL, _KdCtx::syncd, and _KdCtx::windctx.

◆ rz_debug_winkd_init()

static bool rz_debug_winkd_init ( RZ_BORROW RZ_NONNULL RzDebug dbg,
void **  user 
)
static

Definition at line 265 of file debug_winkd.c.

265  {
266  return true;
267 }

◆ rz_debug_winkd_maps()

static RzList* rz_debug_winkd_maps ( RZ_BORROW RZ_NONNULL RzDebug dbg)
static

Definition at line 403 of file debug_winkd.c.

403  {
405  RzListIter *it;
406  WindMap *m;
408  if (!ret) {
410  return NULL;
411  }
412  rz_list_foreach (maps, it, m) {
414  if (!map) {
416  rz_list_free(ret);
417  return NULL;
418  }
419  if (m->file) {
420  RZ_PTR_MOVE(map->file, m->file);
421  map->name = strdup(rz_file_dos_basename(map->file));
422  }
423  map->size = m->end - m->start;
424  map->addr = m->start;
425  map->addr_end = m->end;
426  map->perm = m->perm;
427  rz_list_append(ret, map);
428  }
430  return ret;
431 }
static RzList * maps(RzBinFile *bf)
Definition: bin_bf.c:116
RZ_API void rz_debug_map_free(RzDebugMap *map)
Definition: dmap.c:77
size_t map(int syms, int left, int len)
Definition: enough.c:237
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 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_NEW0(x)
Definition: rz_types.h:284
#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 kdctx, regress::m, map(), maps(), NULL, rz_debug_map_free(), rz_file_dos_basename(), rz_list_append(), rz_list_free(), rz_list_newf(), RZ_NEW0, RZ_PTR_MOVE, strdup(), _KdCtx::windctx, and winkd_list_maps().

◆ rz_debug_winkd_modules()

static RzList* rz_debug_winkd_modules ( RZ_BORROW RZ_NONNULL RzDebug dbg)
static

Definition at line 358 of file debug_winkd.c.

358  {
359  if (!kdctx || !kdctx->desc || !kdctx->syncd) {
360  return NULL;
361  }
363  if (!ret) {
364  return NULL;
365  }
367  RzListIter *it;
368  WindModule *m;
369  rz_list_foreach (modules, it, m) {
371  if (!mod) {
373  rz_list_free(ret);
374  return NULL;
375  }
376  RZ_PTR_MOVE(mod->file, m->name);
377  mod->size = m->size;
378  mod->addr = m->addr;
379  mod->addr_end = m->addr + m->size;
380  rz_list_append(ret, mod);
381  }
383  return ret;
384 }
RzList * winkd_list_modules(RZ_BORROW RZ_NONNULL WindCtx *ctx)
Definition: winkd.c:625

References _KdCtx::desc, kdctx, regress::m, mod(), regress::modules, NULL, rz_debug_map_free(), rz_list_append(), rz_list_free(), rz_list_newf(), RZ_NEW0, RZ_PTR_MOVE, _KdCtx::syncd, _KdCtx::windctx, and winkd_list_modules().

◆ rz_debug_winkd_pids()

static RzList* rz_debug_winkd_pids ( RZ_BORROW RZ_NONNULL RzDebug dbg,
int  pid 
)
static

Definition at line 269 of file debug_winkd.c.

269  {
270  if (!kdctx || !kdctx->desc || !kdctx->syncd) {
271  return NULL;
272  }
273 
275  if (!ret) {
276  return NULL;
277  }
278 
280  if (!pids) {
281  rz_list_free(ret);
282  return NULL;
283  }
284  RzListIter *it;
285  WindProc *p;
286  rz_list_foreach (pids, it, p) {
287  RzDebugPid *newpid = RZ_NEW0(RzDebugPid);
288  if (!newpid) {
289  rz_list_free(ret);
290  rz_list_free(pids);
291  return NULL;
292  }
293  newpid->path = strdup(p->name);
294  newpid->pid = p->uniqueid;
295  newpid->status = 's';
296  newpid->runnable = true;
297  rz_list_append(ret, newpid);
298  }
299  kdctx->plist_cache = pids;
300  return ret;
301 }
void * p
Definition: libc.cpp:67
RZ_API RzDebugPid * rz_debug_pid_free(RzDebugPid *pid)
Definition: pid.c:20
RzList * plist_cache
Definition: winkd.h:103
char * path
Definition: rz_debug.h:414
RzList * winkd_list_process(RZ_BORROW RZ_NONNULL WindCtx *ctx)
Definition: winkd.c:513

References _KdCtx::desc, kdctx, NULL, p, rz_debug_pid_t::path, rz_debug_pid_t::pid, _KdCtx::plist_cache, rz_debug_pid_t::runnable, rz_debug_pid_free(), rz_list_append(), rz_list_free(), rz_list_newf(), RZ_NEW0, rz_debug_pid_t::status, strdup(), _KdCtx::syncd, _KdCtx::windctx, and winkd_list_process().

◆ rz_debug_winkd_reg_profile()

static char* rz_debug_winkd_reg_profile ( RZ_BORROW RZ_NONNULL RzDebug dbg)
static

Definition at line 233 of file debug_winkd.c.

233  {
234  if (!dbg) {
235  return NULL;
236  }
237  if (dbg->arch && strcmp(dbg->arch, "x86")) {
238  return NULL;
239  }
241  if (dbg->bits == RZ_SYS_BITS_32) {
242 #include "native/reg/windows-x86.h"
243  } else if (dbg->bits == RZ_SYS_BITS_64) {
244 #include "native/reg/windows-x64.h"
245  }
246  return NULL;
247 }
static int rz_debug_winkd_attach(RZ_BORROW RZ_NONNULL RzDebug *dbg, int pid)
Definition: debug_winkd.c:155
@ RZ_SYS_BITS_32
Definition: rz_sys.h:20
@ RZ_SYS_BITS_64
Definition: rz_sys.h:21

References rz_debug_t::arch, rz_debug_t::bits, dbg, NULL, rz_debug_winkd_attach(), RZ_SYS_BITS_32, and RZ_SYS_BITS_64.

◆ rz_debug_winkd_reg_read()

static int rz_debug_winkd_reg_read ( RZ_BORROW RZ_NONNULL RzDebug dbg,
int  type,
ut8 buf,
int  size 
)
static

Definition at line 15 of file debug_winkd.c.

15  {
16  int ret = winkd_read_reg(kdctx, buf, size);
17  if (!ret) {
18  return -1;
19  }
20  return ret;
21 }
voidpf void uLong size
Definition: ioapi.h:138
int winkd_read_reg(RZ_BORROW RZ_NONNULL KdCtx *ctx, RZ_BORROW RZ_NONNULL RZ_OUT ut8 *buf, int size)
Definition: winkd.c:1231

References kdctx, and winkd_read_reg().

◆ rz_debug_winkd_reg_write()

static int rz_debug_winkd_reg_write ( RZ_BORROW RZ_NONNULL RzDebug dbg,
int  type,
const ut8 buf,
int  size 
)
static

Definition at line 23 of file debug_winkd.c.

23  {
24  if (!dbg->reg) {
25  return false;
26  }
27  ut32 flags;
28  if (kdctx->windctx.is_arm) {
29  if (kdctx->windctx.is_64bit) {
30  const struct context_type_arm64 *ctx = (void *)buf;
31  flags = ctx->ContextFlags;
32  } else {
33  const struct context_type_arm *ctx = (void *)buf;
34  flags = ctx->context_flags;
35  }
36  } else {
37  if (kdctx->windctx.is_64bit) {
38  const struct context_type_amd64 *ctx = (void *)buf;
39  flags = ctx->context_flags;
40  } else {
41  const struct context_type_i386 *ctx = (void *)buf;
42  flags = ctx->context_flags;
43  }
44  }
45  return winkd_write_reg(kdctx, flags, buf, size);
46 }
uint32_t ut32
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
RzReg * reg
Definition: rz_debug.h:286
bool winkd_write_reg(RZ_BORROW RZ_NONNULL KdCtx *ctx, ut32 flags, RZ_BORROW RZ_NONNULL RZ_IN const ut8 *buf, int size)
Definition: winkd.c:1179

References dbg, flags, _WindCtx::is_64bit, _WindCtx::is_arm, kdctx, rz_debug_t::reg, _KdCtx::windctx, and winkd_write_reg().

◆ rz_debug_winkd_select()

static int rz_debug_winkd_select ( RZ_BORROW RZ_NONNULL RzDebug dbg,
int  pid,
int  tid 
)
static

Definition at line 303 of file debug_winkd.c.

303  {
306  if (pid != old || tid != old_tid) {
307  kdctx->context_cache_valid = false;
308  if (pid != old) {
311  }
312  }
313  int ret = winkd_set_target(&kdctx->windctx, pid, tid);
314  if (!ret) {
315  return false;
316  }
318  if (!base) {
319  winkd_set_target(&kdctx->windctx, old, tid);
320  return false;
321  }
322  eprintf("Process base is 0x%" PFMT64x "\n", base);
323  return true;
324 }
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
#define PFMT64x
Definition: rz_types.h:393
RzList * tlist_cache
Definition: winkd.h:104
bool context_cache_valid
Definition: winkd.h:109
ut64 winkd_get_target_base(RZ_BORROW RZ_NONNULL WindCtx *ctx)
Definition: winkd.c:166
ut32 winkd_get_target(RZ_BORROW RZ_NONNULL WindCtx *ctx)
Definition: winkd.c:158
ut32 winkd_get_target_thread(RZ_BORROW RZ_NONNULL WindCtx *ctx)
Definition: winkd.c:162
bool winkd_set_target(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut32 pid, ut32 tid)
Definition: winkd.c:106

References _KdCtx::context_cache_valid, eprintf, kdctx, NULL, PFMT64x, pid, rz_list_free(), _KdCtx::tlist_cache, ut64(), _KdCtx::windctx, winkd_get_target(), winkd_get_target_base(), winkd_get_target_thread(), and winkd_set_target().

◆ rz_debug_winkd_threads()

static RzList* rz_debug_winkd_threads ( RZ_BORROW RZ_NONNULL RzDebug dbg,
int  pid 
)
static

Definition at line 326 of file debug_winkd.c.

326  {
327  if (!kdctx || !kdctx->desc || !kdctx->syncd) {
328  return NULL;
329  }
330 
331  RzList *ret = rz_list_newf(free);
332  if (!ret) {
333  return NULL;
334  }
336  if (!threads) {
337  rz_list_free(ret);
338  return NULL;
339  }
340  RzListIter *it;
341  WindThread *t;
342  rz_list_foreach (threads, it, t) {
343  RzDebugPid *newpid = RZ_NEW0(RzDebugPid);
344  if (!newpid) {
345  rz_list_free(ret);
347  return NULL;
348  }
349  newpid->pid = t->uniqueid;
350  newpid->status = t->status;
351  newpid->runnable = t->runnable;
352  rz_list_append(ret, newpid);
353  }
355  return ret;
356 }
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 _KdCtx::desc, free(), kdctx, NULL, rz_debug_pid_t::pid, 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, _KdCtx::syncd, threads, _KdCtx::tlist_cache, WindThread::uniqueid, _KdCtx::windctx, and winkd_list_threads().

◆ rz_debug_winkd_wait()

static RzDebugReasonType rz_debug_winkd_wait ( RZ_BORROW RZ_NONNULL RzDebug dbg,
int  pid 
)
static

Definition at line 77 of file debug_winkd.c.

77  {
79  kd_packet_t *pkt = NULL;
80  kd_stc_64 *stc;
81  if (!winkd_lock_enter(kdctx)) {
83  }
84  for (;;) {
85  void *bed = rz_cons_sleep_begin();
86  int ret;
87  do {
89  } while (ret == KD_E_BREAK || ret == KD_E_MALFORMED);
90  rz_cons_sleep_end(bed);
91  if (ret != KD_E_OK || !pkt) {
92  reason = RZ_DEBUG_REASON_ERROR;
93  break;
94  }
95  stc = (kd_stc_64 *)pkt->data;
96  dbg->reason.addr = stc->pc;
97  dbg->reason.tid = stc->kthread;
98  dbg->reason.signum = stc->state;
99  if (stc->kthread && stc->kthread != kdctx->windctx.target_thread.ethread) {
100  get_current_process_and_thread(dbg, stc->kthread);
101  }
102  winkd_set_cpu(kdctx, stc->cpu);
103  if (stc->state == DbgKdExceptionStateChange) {
104  windows_print_exception_event(kdctx->windctx.target.uniqueid, kdctx->windctx.target_thread.uniqueid, stc->exception.code, stc->exception.flags);
105  dbg->reason.type = windows_exception_to_reason(stc->exception.code);
106  dbg->reason.addr = stc->exception.ex_addr;
107  dbg->reason.signum = stc->exception.code;
108  reason = dbg->reason.type;
109  break;
110  } else if (stc->state == DbgKdLoadSymbolsStateChange) {
112  reason = RZ_DEBUG_REASON_NEW_LIB;
113  break;
114  }
115  RZ_FREE(pkt);
116  }
118  free(pkt);
119  return reason;
120 }
RzDebugReasonType windows_exception_to_reason(ut32 exception_code)
void windows_print_exception_event(ut32 pid, ut32 tid, ut32 exception_code, bool second_chance)
RZ_API void * rz_cons_sleep_begin(void)
Definition: cons.c:443
RZ_API void rz_cons_sleep_end(void *user)
Definition: cons.c:450
@ KD_E_BREAK
Definition: kd.h:15
@ KD_E_OK
Definition: kd.h:10
@ KD_E_MALFORMED
Definition: kd.h:13
@ DbgKdLoadSymbolsStateChange
Definition: kd.h:36
@ DbgKdExceptionStateChange
Definition: kd.h:35
@ KD_PACKET_TYPE_STATE_CHANGE64
Definition: kd.h:26
RzDebugReasonType
Definition: rz_debug.h:89
@ RZ_DEBUG_REASON_UNKNOWN
Definition: rz_debug.h:103
@ RZ_DEBUG_REASON_ERROR
Definition: rz_debug.h:104
@ RZ_DEBUG_REASON_NEW_LIB
Definition: rz_debug.h:107
#define RZ_FREE(x)
Definition: rz_types.h:369
int cpu
Definition: winkd.h:102
RzDebugReason reason
Definition: rz_debug.h:276
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4
bool winkd_lock_leave(RZ_BORROW RZ_NONNULL KdCtx *ctx)
Definition: winkd.c:34
int winkd_wait_packet(RZ_BORROW RZ_NONNULL KdCtx *ctx, const ut32 type, RZ_NULLABLE RZ_OUT kd_packet_t **p)
Definition: winkd.c:258
bool winkd_set_cpu(RZ_BORROW RZ_NONNULL KdCtx *ctx, int cpu)
Definition: winkd.c:91
bool winkd_lock_enter(RZ_BORROW RZ_NONNULL KdCtx *ctx)
Definition: winkd.c:23

References rz_debug_reason_t::addr, _KdCtx::cpu, dbg, DbgKdExceptionStateChange, DbgKdLoadSymbolsStateChange, WindThread::ethread, free(), get_current_process_and_thread(), if(), KD_E_BREAK, KD_E_MALFORMED, KD_E_OK, KD_PACKET_TYPE_STATE_CHANGE64, kdctx, NULL, rz_debug_t::reason, rz_cons_sleep_begin(), rz_cons_sleep_end(), RZ_DEBUG_REASON_ERROR, RZ_DEBUG_REASON_NEW_LIB, RZ_DEBUG_REASON_UNKNOWN, RZ_FREE, rz_debug_reason_t::signum, _WindCtx::target, _WindCtx::target_thread, rz_debug_reason_t::tid, rz_debug_reason_t::type, WindProc::uniqueid, WindThread::uniqueid, _KdCtx::windctx, windows_exception_to_reason(), windows_print_exception_event(), winkd_lock_enter(), winkd_lock_leave(), winkd_set_cpu(), and winkd_wait_packet().

Variable Documentation

◆ kdctx

◆ rizin_plugin

RZ_API RzLibStruct rizin_plugin
Initial value:
= {
.type = RZ_LIB_TYPE_DBG,
}
RzDebugPlugin rz_debug_plugin_winkd
Definition: debug_winkd.c:433
@ 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 457 of file debug_winkd.c.

◆ rz_debug_plugin_winkd

RzDebugPlugin rz_debug_plugin_winkd
Initial value:
= {
.name = "winkd",
.license = "LGPL3",
.arch = "x86",
.reg_write = &rz_debug_winkd_reg_write,
.reg_profile = &rz_debug_winkd_reg_profile,
.modules_get = &rz_debug_winkd_modules,
.map_get = &rz_debug_winkd_maps,
}
static int rz_debug_winkd_select(RZ_BORROW RZ_NONNULL RzDebug *dbg, int pid, int tid)
Definition: debug_winkd.c:303
static int rz_debug_winkd_breakpoint(RZ_BORROW RZ_NONNULL RzBreakpoint *bp, RZ_BORROW RZ_NULLABLE RzBreakpointItem *b, bool set)
Definition: debug_winkd.c:249
static RzList * rz_debug_winkd_frames(RZ_BORROW RZ_NONNULL RzDebug *dbg, ut64 at)
Definition: debug_winkd.c:389
static int rz_debug_winkd_detach(RZ_BORROW RZ_NONNULL RzDebug *dbg, int pid)
Definition: debug_winkd.c:227
static RzList * rz_debug_winkd_maps(RZ_BORROW RZ_NONNULL RzDebug *dbg)
Definition: debug_winkd.c:403
static RzList * rz_debug_winkd_threads(RZ_BORROW RZ_NONNULL RzDebug *dbg, int pid)
Definition: debug_winkd.c:326
static RzList * rz_debug_winkd_pids(RZ_BORROW RZ_NONNULL RzDebug *dbg, int pid)
Definition: debug_winkd.c:269
static int rz_debug_winkd_reg_write(RZ_BORROW RZ_NONNULL RzDebug *dbg, int type, const ut8 *buf, int size)
Definition: debug_winkd.c:23
static int rz_debug_winkd_reg_read(RZ_BORROW RZ_NONNULL RzDebug *dbg, int type, ut8 *buf, int size)
Definition: debug_winkd.c:15
static RzList * rz_debug_winkd_modules(RZ_BORROW RZ_NONNULL RzDebug *dbg)
Definition: debug_winkd.c:358
static char * rz_debug_winkd_reg_profile(RZ_BORROW RZ_NONNULL RzDebug *dbg)
Definition: debug_winkd.c:233
static bool rz_debug_winkd_init(RZ_BORROW RZ_NONNULL RzDebug *dbg, void **user)
Definition: debug_winkd.c:265
static RzDebugReasonType rz_debug_winkd_wait(RZ_BORROW RZ_NONNULL RzDebug *dbg, int pid)
Definition: debug_winkd.c:77
static int rz_debug_winkd_continue(RZ_BORROW RZ_NONNULL RzDebug *dbg, int pid, int tid, int sig)
Definition: debug_winkd.c:48

Definition at line 433 of file debug_winkd.c.