Rizin
unix-like reverse engineering framework and cli tools
winkd.h File Reference
#include <rz_util.h>
#include <stdint.h>
#include "kd.h"

Go to the source code of this file.

Classes

struct  WindProc
 
struct  WindThread
 
struct  WindModule
 
struct  WindMap
 
struct  Profile
 
struct  _WindCtx
 
struct  _KdCtx
 
struct  _DmpCtx
 

Macros

#define TARGET_BACKEND   0
 
#define TARGET_PHYSICAL   1
 
#define TARGET_KERNEL   2
 
#define TARGET_VIRTUAL   3
 

Typedefs

typedef struct WindProc WindProc
 
typedef struct WindThread WindThread
 
typedef struct WindModule WindModule
 
typedef struct WindMap WindMap
 
typedef int WindReadAt(RZ_NONNULL void *user, ut64 address, RZ_BORROW RZ_NONNULL RZ_OUT ut8 *buf, int count)
 
typedef int WindWriteAt(RZ_NONNULL void *user, ut64 address, RZ_BORROW RZ_NONNULL RZ_IN const ut8 *buf, int count)
 
typedef struct _WindCtx WindCtx
 
typedef struct _KdCtx KdCtx
 
typedef struct _DmpCtx DmpCtx
 

Enumerations

enum  { K_PaeEnabled = 0x036 , K_PsActiveProcessHead = 0x050 , K_CmNtCSDVersion = 0x268 , K_OffsetKThreadApcProcess = 0x2a0 }
 
enum  {
  E_ActiveProcessLinks , E_UniqueProcessId , E_Peb , E_ImageFileName ,
  E_VadRoot , E_ThreadListHead , K_DirectoryTableBase , P_ImageBaseAddress ,
  P_ProcessParameters , RZ_ImagePathName , ET_ApcProcess , ET_ThreadListEntry ,
  ET_Win32StartAddress , ET_Cid , C_UniqueThread , O_Max
}
 

Functions

static ut64 winkd_read_ptr_at (RZ_BORROW RZ_NONNULL WindCtx *ctx, RZ_BORROW RZ_NONNULL WindReadAt *read_at_func, ut64 at)
 
static void winkd_ctx_fini (RZ_BORROW RZ_NONNULL WindCtx *ctx)
 
int winkd_get_bits (RZ_BORROW RZ_NONNULL WindCtx *ctx)
 
int winkd_get_sp (RZ_BORROW RZ_NONNULL WindCtx *ctx)
 
Profilewinkd_get_profile (int bits, int build, int sp)
 
bool winkd_va_to_pa (RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 directory_table, ut64 va, RZ_BORROW RZ_NONNULL RZ_OUT ut64 *pa)
 
ut64 winkd_get_target_base (RZ_BORROW RZ_NONNULL WindCtx *ctx)
 
ut32 winkd_get_target (RZ_BORROW RZ_NONNULL WindCtx *ctx)
 
ut32 winkd_get_target_thread (RZ_BORROW RZ_NONNULL WindCtx *ctx)
 
bool winkd_set_target (RZ_BORROW RZ_NONNULL WindCtx *ctx, ut32 pid, ut32 tid)
 
WindProcwinkd_get_process_at (RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 address)
 
WindThreadwinkd_get_thread_at (RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 address)
 
RzListwinkd_list_process (RZ_BORROW RZ_NONNULL WindCtx *ctx)
 
RzListwinkd_list_threads (RZ_BORROW RZ_NONNULL WindCtx *ctx)
 
void winkd_windmodule_free (void *ptr)
 
RzListwinkd_list_modules (RZ_BORROW RZ_NONNULL WindCtx *ctx)
 
RzListwinkd_list_maps (RZ_BORROW RZ_NONNULL WindCtx *ctx)
 
int winkd_read_at_uva (RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 offset, RZ_BORROW RZ_NONNULL RZ_OUT ut8 *buf, int count)
 
int winkd_write_at_uva (RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 offset, RZ_BORROW RZ_NONNULL RZ_IN const ut8 *buf, int count)
 
KdCtxwinkd_kdctx_new (RZ_BORROW RZ_NONNULL io_desc_t *desc)
 
void winkd_kdctx_free (RZ_OWN KdCtx **ctx)
 
int winkd_get_cpus (RZ_BORROW RZ_NONNULL KdCtx *ctx)
 
bool winkd_set_cpu (RZ_BORROW RZ_NONNULL KdCtx *ctx, int cpu)
 
int winkd_get_cpu (RZ_BORROW RZ_NONNULL KdCtx *ctx)
 
int winkd_wait_packet (RZ_BORROW RZ_NONNULL KdCtx *ctx, const ut32 type, RZ_NULLABLE RZ_OUT kd_packet_t **p)
 
int winkd_sync (RZ_BORROW RZ_NONNULL KdCtx *ctx)
 
bool winkd_read_ver (RZ_BORROW RZ_NONNULL KdCtx *ctx)
 
int winkd_continue (RZ_BORROW RZ_NONNULL KdCtx *ctx, bool handled)
 
bool winkd_write_reg (RZ_BORROW RZ_NONNULL KdCtx *ctx, ut32 flags, RZ_BORROW RZ_NONNULL RZ_IN const ut8 *buf, int size)
 
int winkd_read_reg (RZ_BORROW RZ_NONNULL KdCtx *ctx, RZ_BORROW RZ_NONNULL RZ_OUT ut8 *buf, int size)
 
int winkd_query_mem (RZ_BORROW RZ_NONNULL KdCtx *ctx, const ut64 addr, int *address_space, int *flags)
 
int winkd_bkpt (RZ_BORROW RZ_NONNULL KdCtx *ctx, const ut64 addr, const int set, const int hw, RZ_BORROW RZ_NONNULL int *handle)
 
int winkd_read_at (RZ_BORROW RZ_NONNULL KdCtx *ctx, const ut64 offset, RZ_BORROW RZ_NONNULL RZ_OUT ut8 *buf, const int count)
 
int winkd_read_at_phys (RZ_BORROW RZ_NONNULL KdCtx *ctx, const ut64 offset, RZ_BORROW RZ_NONNULL RZ_OUT ut8 *buf, const int count)
 
int winkd_write_at (RZ_BORROW RZ_NONNULL KdCtx *ctx, const ut64 offset, RZ_BORROW RZ_NONNULL RZ_IN const ut8 *buf, const int count)
 
int winkd_write_at_phys (RZ_BORROW RZ_NONNULL KdCtx *ctx, const ut64 offset, RZ_BORROW RZ_NONNULL RZ_IN const ut8 *buf, const int count)
 
void winkd_break (void *ctx)
 
bool winkd_lock_enter (RZ_BORROW RZ_NONNULL KdCtx *ctx)
 
bool winkd_lock_leave (RZ_BORROW RZ_NONNULL KdCtx *ctx)
 

Macro Definition Documentation

◆ TARGET_BACKEND

#define TARGET_BACKEND   0

Definition at line 113 of file winkd.h.

◆ TARGET_KERNEL

#define TARGET_KERNEL   2

Definition at line 115 of file winkd.h.

◆ TARGET_PHYSICAL

#define TARGET_PHYSICAL   1

Definition at line 114 of file winkd.h.

◆ TARGET_VIRTUAL

#define TARGET_VIRTUAL   3

Definition at line 116 of file winkd.h.

Typedef Documentation

◆ DmpCtx

typedef struct _DmpCtx DmpCtx

◆ KdCtx

typedef struct _KdCtx KdCtx

◆ WindCtx

typedef struct _WindCtx WindCtx

◆ WindMap

typedef struct WindMap WindMap

◆ WindModule

typedef struct WindModule WindModule

◆ WindProc

typedef struct WindProc WindProc

◆ WindReadAt

typedef int WindReadAt(RZ_NONNULL void *user, ut64 address, RZ_BORROW RZ_NONNULL RZ_OUT ut8 *buf, int count)

Definition at line 76 of file winkd.h.

◆ WindThread

typedef struct WindThread WindThread

◆ WindWriteAt

typedef int WindWriteAt(RZ_NONNULL void *user, ut64 address, RZ_BORROW RZ_NONNULL RZ_IN const ut8 *buf, int count)

Definition at line 77 of file winkd.h.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
K_PaeEnabled 
K_PsActiveProcessHead 
K_CmNtCSDVersion 
K_OffsetKThreadApcProcess 

Definition at line 42 of file winkd.h.

42  {
43  K_PaeEnabled = 0x036,
44  K_PsActiveProcessHead = 0x050,
45  K_CmNtCSDVersion = 0x268,
47 };
@ K_OffsetKThreadApcProcess
Definition: winkd.h:46
@ K_CmNtCSDVersion
Definition: winkd.h:45
@ K_PsActiveProcessHead
Definition: winkd.h:44
@ K_PaeEnabled
Definition: winkd.h:43

◆ anonymous enum

anonymous enum
Enumerator
E_ActiveProcessLinks 
E_UniqueProcessId 
E_Peb 
E_ImageFileName 
E_VadRoot 
E_ThreadListHead 
K_DirectoryTableBase 
P_ImageBaseAddress 
P_ProcessParameters 
RZ_ImagePathName 
ET_ApcProcess 
ET_ThreadListEntry 
ET_Win32StartAddress 
ET_Cid 
C_UniqueThread 
O_Max 

Definition at line 49 of file winkd.h.

49  {
50  E_ActiveProcessLinks, // EPROCESS
51  E_UniqueProcessId, // EPROCESS
52  E_Peb, // EPROCESS
53  E_ImageFileName, // EPROCESS
54  E_VadRoot, // EPROCESS
55  E_ThreadListHead, // EPROCESS
56  K_DirectoryTableBase, // KPROCESS
57  P_ImageBaseAddress, // PEB
58  P_ProcessParameters, // PEB
59  RZ_ImagePathName, // RTL_USER_PROCESS_PARAMETERS
60  ET_ApcProcess, // ETHREAD
61  ET_ThreadListEntry, // ETHREAD
62  ET_Win32StartAddress, // ETHREAD
63  ET_Cid, // ETHREAD
64  C_UniqueThread, // CLIENT_ID
65  O_Max,
66 };
@ P_ProcessParameters
Definition: winkd.h:58
@ C_UniqueThread
Definition: winkd.h:64
@ E_Peb
Definition: winkd.h:52
@ E_UniqueProcessId
Definition: winkd.h:51
@ ET_Win32StartAddress
Definition: winkd.h:62
@ ET_ApcProcess
Definition: winkd.h:60
@ E_ActiveProcessLinks
Definition: winkd.h:50
@ K_DirectoryTableBase
Definition: winkd.h:56
@ ET_Cid
Definition: winkd.h:63
@ E_VadRoot
Definition: winkd.h:54
@ O_Max
Definition: winkd.h:65
@ RZ_ImagePathName
Definition: winkd.h:59
@ E_ImageFileName
Definition: winkd.h:53
@ ET_ThreadListEntry
Definition: winkd.h:61
@ E_ThreadListHead
Definition: winkd.h:55
@ P_ImageBaseAddress
Definition: winkd.h:57

Function Documentation

◆ winkd_bkpt()

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 at line 1312 of file winkd.c.

1312  {
1313  kd_req_t req = { 0 };
1314  kd_packet_t *pkt;
1315 
1316  if (!ctx || !ctx->desc || !ctx->syncd) {
1317  return 0;
1318  }
1319 
1321  req.cpu = ctx->cpu;
1322 
1323  if (set) {
1324  req.rz_set_bp.addr = addr;
1325  } else {
1326  req.rz_del_bp.handle = *handle;
1327  }
1328 
1329  if (!winkd_send_state_manipulate_req(ctx, &req, NULL, 0, &pkt)) {
1330  return 0;
1331  }
1332 
1333  kd_req_t *rr = PKT_REQ(pkt);
1334 
1335  if (rr->ret) {
1336  free(pkt);
1337  return 0;
1338  }
1339  *handle = rr->rz_set_bp.handle;
1340  free(pkt);
1341  return 1;
1342 }
static mcore_handle handle
Definition: asm_mcore.c:8
#define NULL
Definition: cris-opc.c:27
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec req
Definition: sflib.h:128
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
@ DbgKdWriteBreakPointApi
Definition: kd.h:47
@ DbgKdRestoreBreakPointApi
Definition: kd.h:48
#define PKT_REQ(p)
Definition: winkd.c:202
static bool winkd_send_state_manipulate_req(RZ_BORROW RZ_NONNULL KdCtx *ctx, kd_req_t *req, RZ_BORROW RZ_NULLABLE RZ_IN const ut8 *buf, const ut32 buf_len, RZ_BORROW RZ_NULLABLE RZ_OUT kd_packet_t **pkt)
Definition: winkd.c:940
static int addr
Definition: z80asm.c:58

References addr, DbgKdRestoreBreakPointApi, DbgKdWriteBreakPointApi, free(), handle, NULL, PKT_REQ, req, and winkd_send_state_manipulate_req().

Referenced by rz_debug_winkd_breakpoint().

◆ winkd_break()

void winkd_break ( void *  ctx)

Definition at line 1442 of file winkd.c.

1442  {
1443  // This command shouldn't be wrapped by locks since it can always be sent and we don't
1444  // want break queued up after another background task
1445  KdCtx *ctx = (KdCtx *)arg;
1446  ctx->breaked = true;
1447  (void)iob_write(ctx->desc, (const ut8 *)"b", 1);
1448 }
uint8_t ut8
Definition: lh5801.h:11
Definition: winkd.h:95
int iob_write(io_desc_t *desc, const uint8_t *buf, const uint32_t buf_len)
Definition: transport.c:16

References iob_write().

Referenced by winkd_lock_enter().

◆ winkd_continue()

int winkd_continue ( RZ_BORROW RZ_NONNULL KdCtx ctx,
bool  handled 
)

Definition at line 1141 of file winkd.c.

1141  {
1142  kd_req_t req = { 0 };
1143 
1144  if (!ctx || !ctx->desc || !ctx->syncd) {
1145  return 0;
1146  }
1147  req.req = DbgKdContinueApi;
1148  req.cpu = ctx->cpu;
1149  req.rz_cont.reason = handled ? 0x10001 : 0x80010001;
1150  // The meaning of 0x400 is unknown, but Windows doesn't
1151  // behave like suggested by ReactOS source
1152  req.rz_cont.tf = 0x400;
1153 
1154  if (!winkd_lock_enter(ctx)) {
1155  return KD_E_TIMEOUT;
1156  }
1157  int ret;
1158  do {
1160  ctx->seq_id, (ut8 *)&req, sizeof(kd_req_t), NULL, 0);
1161  if (ret != KD_E_OK) {
1162  break;
1163  }
1165  if (ret == KD_E_OK) {
1166  break;
1167  }
1168  } while (ret == KD_E_MALFORMED);
1169 
1170  rz_list_free(ctx->plist_cache);
1171  ctx->plist_cache = NULL;
1172  rz_list_free(ctx->tlist_cache);
1173  ctx->tlist_cache = NULL;
1174  ctx->context_cache_valid = false;
1176  return ret == KD_E_OK;
1177 }
int kd_send_data_packet(io_desc_t *desc, const ut32 type, const ut32 id, const ut8 *req, const int req_len, const ut8 *buf, const ut32 buf_len)
Definition: kd.c:41
@ KD_E_OK
Definition: kd.h:10
@ KD_E_MALFORMED
Definition: kd.h:13
@ KD_E_TIMEOUT
Definition: kd.h:12
@ DbgKdContinueApi
Definition: kd.h:49
@ KD_PACKET_TYPE_STATE_MANIPULATE
Definition: kd.h:21
@ KD_PACKET_TYPE_ACKNOWLEDGE
Definition: kd.h:23
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
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_lock_enter(RZ_BORROW RZ_NONNULL KdCtx *ctx)
Definition: winkd.c:23

References DbgKdContinueApi, KD_E_MALFORMED, KD_E_OK, KD_E_TIMEOUT, KD_PACKET_TYPE_ACKNOWLEDGE, KD_PACKET_TYPE_STATE_MANIPULATE, kd_send_data_packet(), NULL, req, rz_list_free(), winkd_lock_enter(), winkd_lock_leave(), and winkd_wait_packet().

Referenced by rz_debug_winkd_continue().

◆ winkd_ctx_fini()

static void winkd_ctx_fini ( RZ_BORROW RZ_NONNULL WindCtx ctx)
inlinestatic

Definition at line 141 of file winkd.h.

141  {
142  free(ctx->user);
143  free(ctx->profile);
144 }

References free().

Referenced by dmp_close(), and winkd_kdctx_free().

◆ winkd_get_bits()

int winkd_get_bits ( RZ_BORROW RZ_NONNULL WindCtx ctx)

Definition at line 80 of file winkd.c.

80  {
81  return ctx->is_64bit ? RZ_SYS_BITS_64 : RZ_SYS_BITS_32;
82 }
@ RZ_SYS_BITS_32
Definition: rz_sys.h:20
@ RZ_SYS_BITS_64
Definition: rz_sys.h:21

References RZ_SYS_BITS_32, and RZ_SYS_BITS_64.

Referenced by rz_debug_winkd_attach().

◆ winkd_get_cpu()

int winkd_get_cpu ( RZ_BORROW RZ_NONNULL KdCtx ctx)

Definition at line 99 of file winkd.c.

99  {
100  if (!ctx) {
101  return -1;
102  }
103  return ctx->cpu;
104 }

◆ winkd_get_cpus()

int winkd_get_cpus ( RZ_BORROW RZ_NONNULL KdCtx ctx)

Definition at line 84 of file winkd.c.

84  {
85  if (!ctx) {
86  return -1;
87  }
88  return ctx->cpu_count;
89 }

◆ winkd_get_process_at()

WindProc* winkd_get_process_at ( RZ_BORROW RZ_NONNULL WindCtx ctx,
ut64  address 
)

Definition at line 488 of file winkd.c.

488  {
489  ut8 type;
490  if (!ctx->read_at_kernel_virtual(ctx->user, address, &type, 1)) {
491  RZ_LOG_WARN("Failed to read DISPACHER_HEAD.Type at: 0x%" PFMT64x "\n", address);
492  return NULL;
493  }
494  if ((type & 0x7f) != KOBJECT_PROCESS) {
495  RZ_LOG_WARN("KOBJECT at 0x%" PFMT64x " is not a process.\n", address);
496  return NULL;
497  }
499  if (!proc) {
500  return NULL;
501  }
502  // Read the short name
503  ctx->read_at_kernel_virtual(ctx->user, address + O_(E_ImageFileName), (ut8 *)proc->name, sizeof(proc->name));
504  proc->name[sizeof(proc->name) - 1] = '\0';
505  proc->eprocess = address;
506  proc->vadroot = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, address + O_(E_VadRoot));
507  proc->uniqueid = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, address + O_(E_UniqueProcessId));
508  proc->peb = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, address + O_(E_Peb));
509  proc->dir_base_table = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, address + O_(K_DirectoryTableBase));
510  return proc;
511 }
int type
Definition: mipsasm.c:17
#define RZ_LOG_WARN(fmtstr,...)
Definition: rz_log.h:56
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define PFMT64x
Definition: rz_types.h:393
const char * name
Definition: spp.h:129
Definition: winkd.h:11
struct Proc * proc
#define KOBJECT_PROCESS
Definition: winkd.c:20
#define O_(n)
Definition: winkd.c:17
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 E_ImageFileName, E_Peb, E_UniqueProcessId, E_VadRoot, K_DirectoryTableBase, KOBJECT_PROCESS, Proc::name, NULL, O_, PFMT64x, proc, RZ_LOG_WARN, RZ_NEW0, type, and winkd_read_ptr_at().

Referenced by get_current_process_and_thread(), rz_debug_dmp_attach(), rz_debug_dmp_init(), and winkd_list_process().

◆ winkd_get_profile()

Profile* winkd_get_profile ( int  bits,
int  build,
int  sp 
)

Definition at line 58 of file winkd.c.

58  {
59  int i;
60  for (i = 0; p_table[i]; i++) {
61  if (p_table[i]->build != build) {
62  continue;
63  }
64  if (p_table[i]->sp != sp) {
65  continue;
66  }
67  if (p_table[i]->bits != bits) {
68  continue;
69  }
71  if (!p) {
72  return NULL;
73  }
74  *p = *p_table[i];
75  return p;
76  }
77  return NULL;
78 }
lzma_index ** i
Definition: index.h:629
int bits(struct state *s, int need)
Definition: blast.c:72
static RzBuffer * build(RzEgg *egg)
Definition: egg_bind.c:144
void * p
Definition: libc.cpp:67
static Profile * p_table[]
Definition: profiles.h:201
Definition: winkd.h:68
static int sp
Definition: z80asm.c:91

References bits(), build(), i, NULL, p, p_table, RZ_NEW0, and sp.

Referenced by rz_debug_dmp_init(), and winkd_read_ver().

◆ winkd_get_sp()

int winkd_get_sp ( RZ_BORROW RZ_NONNULL WindCtx ctx)

Definition at line 40 of file winkd.c.

40  {
41  ut64 ptr = 0;
42  // Grab the CmNtCSDVersion field to extract the Service Pack number
43  if (!ctx->read_at_kernel_virtual(ctx->user, ctx->KdDebuggerDataBlock + K_CmNtCSDVersion, (ut8 *)&ptr, 8)) {
44  RZ_LOG_DEBUG("Failed to read at %" PFMT64x "\n", ctx->KdDebuggerDataBlock + K_CmNtCSDVersion);
45  return 0;
46  }
47  ut64 res;
48  if (!ctx->read_at_kernel_virtual(ctx->user, ptr, (ut8 *)&res, 8)) {
49  RZ_LOG_DEBUG("Failed to read at %" PFMT64x "\n", ptr);
50  return 0;
51  }
52  if (res == UT64_MAX) {
53  return 0;
54  }
55  return (res >> 8) & 0xff;
56 }
#define RZ_LOG_DEBUG(fmtstr,...)
Definition: rz_log.h:49
#define UT64_MAX
Definition: rz_types_base.h:86
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References K_CmNtCSDVersion, PFMT64x, RZ_LOG_DEBUG, ut64(), and UT64_MAX.

Referenced by rz_debug_dmp_init(), and winkd_read_ver().

◆ winkd_get_target()

ut32 winkd_get_target ( RZ_BORROW RZ_NONNULL WindCtx ctx)

Definition at line 158 of file winkd.c.

158  {
159  return ctx->target.uniqueid;
160 }

Referenced by __read(), __write(), and rz_debug_winkd_select().

◆ winkd_get_target_base()

ut64 winkd_get_target_base ( RZ_BORROW RZ_NONNULL WindCtx ctx)

Definition at line 166 of file winkd.c.

166  {
167  ut64 base = 0;
168 
169  if (!winkd_read_at_uva(ctx, ctx->target.peb + O_(P_ImageBaseAddress),
170  (ut8 *)&base, 4 << ctx->is_64bit)) {
171  return 0;
172  }
173 
174  return base;
175 }
int winkd_read_at_uva(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 address, RZ_BORROW RZ_NONNULL RZ_OUT ut8 *buf, int count)
Definition: winkd.c:596

References O_, P_ImageBaseAddress, ut64(), and winkd_read_at_uva().

Referenced by rz_debug_winkd_select().

◆ winkd_get_target_thread()

ut32 winkd_get_target_thread ( RZ_BORROW RZ_NONNULL WindCtx ctx)

Definition at line 162 of file winkd.c.

162  {
163  return ctx->target_thread.uniqueid;
164 }

Referenced by rz_debug_winkd_select().

◆ winkd_get_thread_at()

WindThread* winkd_get_thread_at ( RZ_BORROW RZ_NONNULL WindCtx ctx,
ut64  address 
)

Definition at line 739 of file winkd.c.

739  {
740  int running_offset;
741  if (ctx->profile->build < 9200) {
742  running_offset = ctx->is_64bit ? 0x49 : 0x39;
743  } else {
744  running_offset = ctx->is_64bit ? 0x71 : 0x55;
745  }
746  ut8 type = 0;
747  if (!ctx->read_at_kernel_virtual(ctx->user, address, &type, 1)) {
748  RZ_LOG_WARN("Failed to read DISPACHER_HEAD.Type at: 0x%" PFMT64x "\n", address);
749  return NULL;
750  }
751  if ((type & 0x7f) != KOBJECT_THREAD) {
752  RZ_LOG_WARN("KOBJECT at 0x%" PFMT64x " is not a thread.\n", address);
753  return NULL;
754  }
755  ut64 entrypoint = 0;
756  if (!ctx->read_at_kernel_virtual(ctx->user, address + O_(ET_Win32StartAddress), (ut8 *)&entrypoint, 4 << ctx->is_64bit)) {
757  RZ_LOG_WARN("Failed to read Win32StartAddress at: 0x%" PFMT64x "\n", address + O_(ET_Win32StartAddress));
758  return NULL;
759  }
760  ut64 uniqueid = 0;
761  if (!ctx->read_at_kernel_virtual(ctx->user, address + O_(ET_Cid) + O_(C_UniqueThread), (ut8 *)&uniqueid, 4 << ctx->is_64bit)) {
762  RZ_LOG_WARN("Failed to read UniqueThread at: 0x%" PFMT64x "\n", address + O_(ET_Cid) + O_(C_UniqueThread));
763  return NULL;
764  }
765  bool running = false;
766  if (!ctx->read_at_kernel_virtual(ctx->user, address + running_offset, (ut8 *)&running, 1)) {
767  RZ_LOG_WARN("Failed to read KTHREAD.Running at: 0x%" PFMT64x "\n", address + running_offset);
768  return NULL;
769  }
770  WindThread *thread = calloc(1, sizeof(WindThread));
771  if (!thread) {
772  return NULL;
773  }
774  thread->uniqueid = uniqueid;
775  thread->status = running ? 'r' : 's';
776  thread->runnable = true;
777  thread->ethread = address;
778  thread->entrypoint = entrypoint;
779  return thread;
780 }
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
ut64 entrypoint
Definition: winkd.h:25
ut64 ethread
Definition: winkd.h:24
bool runnable
Definition: winkd.h:22
char status
Definition: winkd.h:23
ut32 uniqueid
Definition: winkd.h:21
#define KOBJECT_THREAD
Definition: winkd.c:21

References C_UniqueThread, calloc(), WindThread::entrypoint, ET_Cid, ET_Win32StartAddress, WindThread::ethread, KOBJECT_THREAD, NULL, O_, PFMT64x, WindThread::runnable, RZ_LOG_WARN, WindThread::status, type, WindThread::uniqueid, and ut64().

Referenced by get_current_process_and_thread(), rz_debug_dmp_attach(), rz_debug_dmp_init(), and winkd_list_threads().

◆ winkd_kdctx_free()

void winkd_kdctx_free ( RZ_OWN KdCtx **  ctx)

Definition at line 187 of file winkd.c.

187  {
188  if (!ctx || !*ctx) {
189  return;
190  }
191  rz_list_free((*ctx)->plist_cache);
192  rz_list_free((*ctx)->tlist_cache);
193  io_desc_t *desc = (*ctx)->desc;
194  desc->iob->close(desc->fp);
195  RZ_FREE(desc);
196  rz_th_lock_free((*ctx)->dontmix);
197  winkd_ctx_fini(&(*ctx)->windctx);
198  free((*ctx)->kernel_module.name);
199  RZ_FREE(*ctx);
200 }
const char * desc
Definition: bin_vsf.c:19
#define RZ_FREE(x)
Definition: rz_types.h:369
RZ_API void rz_th_lock_free(RZ_NULLABLE RzThreadLock *thl)
Frees a RzThreadLock structure.
Definition: thread_lock.c:89
static void winkd_ctx_fini(RZ_BORROW RZ_NONNULL WindCtx *ctx)
Definition: winkd.h:141

References desc, free(), RZ_FREE, rz_list_free(), rz_th_lock_free(), and winkd_ctx_fini().

Referenced by __close().

◆ winkd_kdctx_new()

KdCtx* winkd_kdctx_new ( RZ_BORROW RZ_NONNULL io_desc_t desc)

Definition at line 177 of file winkd.c.

177  {
178  KdCtx *ctx = RZ_NEW0(KdCtx);
179  if (!ctx) {
180  return NULL;
181  }
182  ctx->dontmix = rz_th_lock_new(true);
183  ctx->desc = desc;
184  return ctx;
185 }
RZ_API RZ_OWN RzThreadLock * rz_th_lock_new(bool recursive)
Allocates and initialize a RzThreadLock structure.
Definition: thread_lock.c:14

References desc, NULL, RZ_NEW0, and rz_th_lock_new().

Referenced by __open().

◆ winkd_list_maps()

RzList* winkd_list_maps ( RZ_BORROW RZ_NONNULL WindCtx ctx)

Definition at line 476 of file winkd.c.

476  {
477  if (!ctx->target.vadroot) {
478  return NULL;
479  }
481  if (!maps) {
482  return NULL;
483  }
484  winkd_walk_vadtree(ctx, ctx->target.vadroot, UT64_MAX, maps);
485  return maps;
486 }
static RzList * maps(RzBinFile *bf)
Definition: bin_bf.c:116
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
void winkd_walk_vadtree(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 address, ut64 parent, RzList *out)
Definition: winkd.c:390

References free(), maps(), NULL, rz_list_newf(), UT64_MAX, and winkd_walk_vadtree().

Referenced by rz_debug_dmp_maps(), and rz_debug_winkd_maps().

◆ winkd_list_modules()

RzList* winkd_list_modules ( RZ_BORROW RZ_NONNULL WindCtx ctx)

Definition at line 625 of file winkd.c.

625  {
627  if (!ret) {
628  return NULL;
629  }
630  ut64 ptr, base;
631  int list_entry_off = 0;
632  const bool is_target_kernel = ctx->target.uniqueid <= 4;
633  if (is_target_kernel) {
634  if (!ctx->PsLoadedModuleList) {
635  RZ_LOG_ERROR("No PsLoadedModuleList\n");
636  return ret;
637  }
638  ptr = ctx->PsLoadedModuleList;
639  base = ptr;
640  if (!ctx->read_at_kernel_virtual(ctx->user, ptr, (ut8 *)&ptr, 4 << ctx->is_64bit)) {
641  RZ_LOG_ERROR("PsLoadedModuleList not present in mappings\n");
642  }
643  if (ptr == base) {
644  return ret;
645  }
646  } else {
647  // Get kernel modules
648  const ut32 saved_target = ctx->target.uniqueid;
649  ctx->target.uniqueid = 0;
650  RzList *kernel_modules = winkd_list_modules(ctx);
651  ctx->target.uniqueid = saved_target;
652 
653  if (kernel_modules) {
654  rz_list_join(ret, kernel_modules);
655  rz_list_free(kernel_modules);
656  }
657 
658  if (!ctx->target.peb) {
659  RZ_LOG_ERROR("No PEB for target\n");
660  return ret;
661  }
662 
663  // Grab the _PEB_LDR_DATA from PEB
664  ut64 ldroff = ctx->is_64bit ? 0x18 : 0xC;
665  if (!winkd_read_at_uva(ctx, ctx->target.peb + ldroff, (ut8 *)&ptr, 4 << ctx->is_64bit)) {
666  RZ_LOG_ERROR("PEB not present in target mappings\n");
667  return ret;
668  }
669 
670  RZ_LOG_DEBUG("_PEB_LDR_DATA : 0x%016" PFMT64x "\n", ptr);
671 
672  // LIST_ENTRY InMemoryOrderModuleList
673  ut64 mlistoff = ctx->is_64bit ? 0x20 : 0x14;
674 
675  base = ptr + mlistoff;
676 
677  winkd_read_at_uva(ctx, base, (ut8 *)&ptr, 4 << ctx->is_64bit);
678 
679  // Offset of InMemoryOrderLinks inside _LDR_DATA_TABLE_ENTRY
680  list_entry_off = (4 << ctx->is_64bit) * 2;
681  }
682 
683  RZ_LOG_DEBUG("InMemoryOrderModuleList : 0x%016" PFMT64x "\n", ptr);
684 
685  const ut64 baseoff = ctx->is_64bit ? 0x30 : 0x18;
686  const ut64 sizeoff = ctx->is_64bit ? 0x40 : 0x20;
687  const ut64 nameoff = ctx->is_64bit ? 0x48 : 0x24;
688  const ut64 timestampoff = is_target_kernel
689  ? ctx->is_64bit ? 0x9c : 0x58
690  : ctx->is_64bit ? 0x80
691  : 0x44;
692  do {
693 
694  ut64 next = 0;
695  read_at_uva_or_kernel(ctx, ptr, (ut8 *)&next, 4 << ctx->is_64bit);
696 
697  RZ_LOG_DEBUG("_%sLDR_DATA_TABLE_ENTRY : 0x%016" PFMT64x "\n", is_target_kernel ? "K" : "", next);
698  if (!next || next == UT64_MAX) {
699  RZ_LOG_WARN("Corrupted InMemoryOrderModuleList found at: 0x%" PFMT64x "\n", ptr);
700  break;
701  }
702 
703  ptr -= list_entry_off;
704 
706  if (!mod) {
707  break;
708  }
709  read_at_uva_or_kernel(ctx, ptr + baseoff, (ut8 *)&mod->addr, 4 << ctx->is_64bit);
710  read_at_uva_or_kernel(ctx, ptr + sizeoff, (ut8 *)&mod->size, 4);
711  read_at_uva_or_kernel(ctx, ptr + timestampoff, (ut8 *)&mod->timestamp, 4);
712 
713  ut16 length;
714  read_at_uva_or_kernel(ctx, ptr + nameoff, (ut8 *)&length, sizeof(ut16));
715 
716  ut64 bufferaddr = 0;
717  int align = ctx->is_64bit ? sizeof(ut64) : sizeof(ut32);
718  read_at_uva_or_kernel(ctx, ptr + nameoff + align, (ut8 *)&bufferaddr, 4 << ctx->is_64bit);
719 
720  ut8 *unname = calloc((ut64)length + 2, 1);
721  if (!unname) {
722  break;
723  }
724  read_at_uva_or_kernel(ctx, bufferaddr, unname, length);
725 
726  mod->name = calloc((ut64)length + 1, 1);
727  if (!mod->name) {
728  break;
729  }
730  rz_str_utf16_to_utf8((ut8 *)mod->name, length + 1, unname, length + 2, true);
731  free(unname);
733 
734  ptr = next;
735  } while (ptr != base);
736  return ret;
737 }
int mod(int a, int b)
Definition: crypto_rot.c:8
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
Definition: sflib.h:133
static bool is_target_kernel(DbgEngContext *idbg)
Definition: debug_windbg.c:47
uint16_t ut16
uint32_t ut32
RZ_API bool rz_list_join(RZ_NONNULL RzList *list1, RZ_NONNULL RzList *list2)
Joins 2 list into one (list2 pointer needs to be freed by the user)
Definition: list.c:209
RZ_API RZ_BORROW RzListIter * rz_list_add_sorted(RZ_NONNULL RzList *list, void *data, RZ_NONNULL RzListComparator cmp)
Adds an element to a sorted list via the RzListComparator.
Definition: list.c:518
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API int rz_str_utf16_to_utf8(ut8 *dst, int len_dst, const ut8 *src, int len_src, bool little_endian)
Definition: str.c:2884
int map_comparator(const void *m1, const void *m2)
Definition: winkd.c:604
void winkd_windmodule_free(void *ptr)
Definition: winkd.c:611
RzList * winkd_list_modules(RZ_BORROW RZ_NONNULL WindCtx *ctx)
Definition: winkd.c:625
static int read_at_uva_or_kernel(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 address, ut8 *buf, int count)
Definition: winkd.c:617

References calloc(), free(), is_target_kernel(), length, map_comparator(), mod(), NULL, PFMT64x, read_at_uva_or_kernel(), rz_list_add_sorted(), rz_list_free(), rz_list_join(), rz_list_newf(), RZ_LOG_DEBUG, RZ_LOG_ERROR, RZ_LOG_WARN, RZ_NEW0, rz_str_utf16_to_utf8(), ut64(), UT64_MAX, winkd_read_at_uva(), and winkd_windmodule_free().

Referenced by dmp_get_modules(), rz_debug_dmp_init(), and rz_debug_winkd_modules().

◆ winkd_list_process()

RzList* winkd_list_process ( RZ_BORROW RZ_NONNULL WindCtx ctx)

Definition at line 513 of file winkd.c.

513  {
514  RzList *ret = NULL;
515  bool current_process_found = false;
516  // Grab the PsActiveProcessHead from _KDDEBUGGER_DATA64
517  ctx->PsActiveProcessHead = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->KdDebuggerDataBlock + K_PsActiveProcessHead);
518 
519  // Walk the LIST_ENTRY
520  ut64 ptr = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ctx->PsActiveProcessHead);
521 
522  // Check for empty list
523  if (ptr == 0 || ptr == UT64_MAX) {
524  RZ_LOG_ERROR("NULL value at PsActiveProcessHead\n");
525  if (ctx->target.eprocess) {
526  ret = rz_list_newf(free);
527  goto get_cur_process;
528  }
529  return NULL;
530  }
531  ret = rz_list_newf(free);
532 
533  do {
534  ut64 next;
535 
536  // Read the ActiveProcessLinks entry
537  next = winkd_read_ptr_at(ctx, ctx->read_at_kernel_virtual, ptr);
538 
539  if (!next || next == UT64_MAX) {
540  RZ_LOG_WARN("Corrupted ActiveProcessLinks entry found at: 0x%" PFMT64x "\n", ptr);
541  break;
542  }
543 
544  // This points to the 'ActiveProcessLinks' list, adjust the ptr so that it point to the
545  // EPROCESS base
546  ptr -= O_(E_ActiveProcessLinks);
547 
549  if (proc) {
550  if (proc->eprocess == ctx->target.eprocess) {
551  current_process_found = true;
552  }
553  rz_list_append(ret, proc);
554  }
555  ptr = next;
556  } while (ptr != ctx->PsActiveProcessHead);
557 get_cur_process:
558  if (!current_process_found && ctx->target.eprocess) {
559  WindProc *proc = winkd_get_process_at(ctx, ctx->target.eprocess);
560  if (proc) {
561  rz_list_append(ret, proc);
562  }
563  }
564  return ret;
565 }
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
WindProc * winkd_get_process_at(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 address)
Definition: winkd.c:488

References E_ActiveProcessLinks, free(), K_PsActiveProcessHead, NULL, O_, PFMT64x, proc, rz_list_append(), rz_list_newf(), RZ_LOG_ERROR, RZ_LOG_WARN, ut64(), UT64_MAX, winkd_get_process_at(), and winkd_read_ptr_at().

Referenced by rz_debug_dmp_pids(), rz_debug_winkd_pids(), and winkd_set_target().

◆ winkd_list_threads()

RzList* winkd_list_threads ( RZ_BORROW RZ_NONNULL WindCtx ctx)

Definition at line 782 of file winkd.c.

782  {
783  RzList *ret;
784  ut64 ptr, base;
785  bool current_thread_found = false;
786  ptr = ctx->target.eprocess;
787  if (!ptr) {
788  RZ_LOG_ERROR("No _EPROCESS for target\n");
789  if (ctx->target_thread.ethread) {
790  ret = rz_list_newf(free);
791  goto get_cur_thread;
792  }
793  return NULL;
794  }
795 
796  // Grab the ThreadListHead from _EPROCESS
797  ctx->read_at_kernel_virtual(ctx->user, ptr + O_(E_ThreadListHead), (ut8 *)&ptr, 4 << ctx->is_64bit);
798  if (!ptr) {
799  RZ_LOG_ERROR("No ThreadListHead for target\n");
800  if (ctx->target_thread.ethread) {
801  ret = rz_list_newf(free);
802  goto get_cur_thread;
803  }
804  return NULL;
805  }
806 
807  base = ptr;
808 
809  ret = rz_list_newf(free);
810 
811  do {
812  ut64 next = 0;
813 
814  ctx->read_at_kernel_virtual(ctx->user, ptr, (ut8 *)&next, 4 << ctx->is_64bit);
815  if (!next || next == UT64_MAX) {
816  RZ_LOG_WARN("Corrupted ThreadListEntry found at: 0x%" PFMT64x "\n", ptr);
817  break;
818  }
819  if (next == base) {
820  break;
821  }
822 
823  // Adjust the ptr so that it points to the ETHREAD base
824  ptr -= O_(ET_ThreadListEntry);
825 
826  WindThread *thread = winkd_get_thread_at(ctx, ptr);
827  if (thread) {
828  if (thread->ethread == ctx->target_thread.ethread) {
829  current_thread_found = true;
830  }
831  rz_list_append(ret, thread);
832  }
833  ptr = next;
834  } while (true);
835 get_cur_thread:
836  if (!current_thread_found && ctx->target_thread.ethread) {
837  WindThread *thread = winkd_get_thread_at(ctx, ctx->target_thread.ethread);
838  if (thread) {
839  rz_list_append(ret, thread);
840  }
841  }
842  return ret;
843 }
WindThread * winkd_get_thread_at(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 address)
Definition: winkd.c:739

References E_ThreadListHead, ET_ThreadListEntry, WindThread::ethread, free(), NULL, O_, PFMT64x, rz_list_append(), rz_list_newf(), RZ_LOG_ERROR, RZ_LOG_WARN, ut64(), UT64_MAX, and winkd_get_thread_at().

Referenced by rz_debug_dmp_threads(), rz_debug_winkd_threads(), and winkd_set_target().

◆ winkd_lock_enter()

bool winkd_lock_enter ( RZ_BORROW RZ_NONNULL KdCtx ctx)

Definition at line 23 of file winkd.c.

23  {
25  while (!rz_th_lock_tryenter(ctx->dontmix)) {
26  if (rz_cons_is_breaked()) {
28  return false;
29  }
30  }
31  return true;
32 }
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
RZ_API bool rz_cons_is_breaked(void)
Definition: cons.c:373
RZ_API bool rz_th_lock_tryenter(RZ_NONNULL RzThreadLock *thl)
Tries to acquire a RzThreadLock structure.
Definition: thread_lock.c:61
void winkd_break(void *arg)
Definition: winkd.c:1442

References rz_cons_break_pop(), rz_cons_break_push(), rz_cons_is_breaked(), rz_th_lock_tryenter(), and winkd_break().

Referenced by do_io_reply(), rz_debug_winkd_wait(), winkd_continue(), winkd_send_state_manipulate_req(), and winkd_sync().

◆ winkd_lock_leave()

bool winkd_lock_leave ( RZ_BORROW RZ_NONNULL KdCtx ctx)

Definition at line 34 of file winkd.c.

34  {
36  rz_th_lock_leave(ctx->dontmix);
37  return true;
38 }
RZ_API void rz_th_lock_leave(RZ_NONNULL RzThreadLock *thl)
Releases a RzThreadLock structure.
Definition: thread_lock.c:75

References rz_cons_break_pop(), and rz_th_lock_leave().

Referenced by do_io_reply(), rz_debug_winkd_wait(), winkd_continue(), winkd_send_state_manipulate_req(), and winkd_sync().

◆ winkd_query_mem()

int winkd_query_mem ( RZ_BORROW RZ_NONNULL KdCtx ctx,
const ut64  addr,
int address_space,
int flags 
)

Definition at line 1276 of file winkd.c.

1276  {
1277  kd_req_t req = { 0 };
1278  kd_packet_t *pkt;
1279 
1280  if (!ctx || !ctx->desc || !ctx->syncd) {
1281  return 0;
1282  }
1283 
1284  req.req = DbgKdQueryMemoryApi;
1285  req.cpu = ctx->cpu;
1286 
1287  req.rz_query_mem.addr = addr;
1288  req.rz_query_mem.address_space = 0; // Tells the kernel that 'addr' is a virtual address
1289 
1290  if (!winkd_send_state_manipulate_req(ctx, &req, NULL, 0, &pkt)) {
1291  return 0;
1292  }
1293 
1294  kd_req_t *rr = PKT_REQ(pkt);
1295 
1296  if (rr->ret) {
1297  free(pkt);
1298  return 0;
1299  }
1300 
1301  if (address_space) {
1302  *address_space = rr->rz_query_mem.address_space;
1303  }
1304  if (flags) {
1305  *flags = rr->rz_query_mem.flags;
1306  }
1307 
1308  free(pkt);
1309  return 1;
1310 }
@ DbgKdQueryMemoryApi
Definition: kd.h:81
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123

References addr, DbgKdQueryMemoryApi, flags, free(), NULL, PKT_REQ, req, and winkd_send_state_manipulate_req().

◆ winkd_read_at()

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 at line 1377 of file winkd.c.

1377  {
1378  if (!ctx || !ctx->desc || !ctx->syncd || count < 0) {
1379  return 0;
1380  }
1382 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
voidpf uLong offset
Definition: ioapi.h:144
voidpf void * buf
Definition: ioapi.h:138
@ DbgKdReadVirtualMemoryApi
Definition: kd.h:43
static int read_at(RZ_BORROW RZ_NONNULL KdCtx *ctx, enum KD_PACKET_MANIPULATE_TYPE type, ut8 *buf, const ut64 offset, const int count)
Definition: winkd.c:1344

References count, DbgKdReadVirtualMemoryApi, and read_at().

Referenced by __read(), read_at_kernel_virtual(), rz_debug_winkd_attach(), and winkd_read_ver().

◆ winkd_read_at_phys()

int winkd_read_at_phys ( RZ_BORROW RZ_NONNULL KdCtx ctx,
const ut64  offset,
RZ_BORROW RZ_NONNULL RZ_OUT ut8 buf,
const int  count 
)

Definition at line 1370 of file winkd.c.

1370  {
1371  if (!ctx || !ctx->desc || !ctx->syncd) {
1372  return 0;
1373  }
1375 }
@ DbgKdReadPhysicalMemoryApi
Definition: kd.h:56

References count, DbgKdReadPhysicalMemoryApi, and read_at().

Referenced by op_at_phys().

◆ winkd_read_at_uva()

int winkd_read_at_uva ( RZ_BORROW RZ_NONNULL WindCtx ctx,
ut64  offset,
RZ_BORROW RZ_NONNULL RZ_OUT ut8 buf,
int  count 
)

Definition at line 596 of file winkd.c.

596  {
597  return winkd_op_at_uva(ctx, address, buf, count, false);
598 }
int winkd_op_at_uva(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 address, ut8 *buf, int count, bool write)
Definition: winkd.c:567

References count, and winkd_op_at_uva().

Referenced by __read(), dmp_read(), read_at_uva_or_kernel(), winkd_get_target_base(), and winkd_list_modules().

◆ winkd_read_ptr_at()

static ut64 winkd_read_ptr_at ( RZ_BORROW RZ_NONNULL WindCtx ctx,
RZ_BORROW RZ_NONNULL WindReadAt read_at_func,
ut64  at 
)
inlinestatic

Definition at line 133 of file winkd.h.

133  {
134  ut8 ptr_buf[8];
135  if (!read_at_func(ctx->user, at, ptr_buf, ctx->is_64bit ? 8 : 4)) {
136  return 0;
137  }
138  return ctx->is_64bit ? rz_read_le64(ptr_buf) : rz_read_le32(ptr_buf);
139 }
static ut32 rz_read_le32(const void *src)
Definition: rz_endian.h:239
static ut64 rz_read_le64(const void *src)
Definition: rz_endian.h:266

References rz_read_le32(), and rz_read_le64().

Referenced by get_current_process_and_thread(), rz_debug_dmp_attach(), rz_debug_dmp_init(), rz_debug_dmp_pids(), rz_debug_dmp_reg_read(), winkd_get_process_at(), winkd_list_process(), and winkd_walk_vadtree().

◆ winkd_read_reg()

int winkd_read_reg ( RZ_BORROW RZ_NONNULL KdCtx ctx,
RZ_BORROW RZ_NONNULL RZ_OUT ut8 buf,
int  size 
)

Definition at line 1231 of file winkd.c.

1231  {
1232  kd_req_t req = { 0 };
1233  kd_packet_t *pkt = NULL;
1234 
1235  if (!ctx || !ctx->desc || !ctx->syncd) {
1236  return 0;
1237  }
1238 
1239  if (ctx->context_cache_size >= size && ctx->context_cache_valid) {
1240  memcpy(buf, ctx->context_cache, size);
1241  return size;
1242  }
1243 
1244  req.req = DbgKdGetContextApi;
1245  req.cpu = ctx->cpu;
1246 
1247  req.rz_ctx.flags = 0x1003F;
1248 
1249  if (!winkd_send_state_manipulate_req(ctx, &req, NULL, 0, &pkt)) {
1250  return 0;
1251  }
1252 
1253  kd_req_t *rr = PKT_REQ(pkt);
1254  const size_t context_rq_sz = pkt->length - sizeof(kd_req_t);
1255  memcpy(buf, rr->data, RZ_MIN(size, context_rq_sz));
1256  free(pkt);
1257 
1258  if (context_rq_sz > ctx->context_cache_size || !ctx->context_cache) {
1259  void *tmp = realloc(ctx->context_cache, context_rq_sz);
1260  if (!tmp) {
1261  free(ctx->context_cache);
1262  ctx->context_cache = NULL;
1263  ctx->context_cache_size = 0;
1264  ctx->context_cache_valid = false;
1265  return 0;
1266  }
1267  ctx->context_cache = tmp;
1268  ctx->context_cache_size = context_rq_sz;
1269  }
1270  memcpy(ctx->context_cache, rr->data, context_rq_sz);
1271  ctx->context_cache_valid = true;
1272  ctx->context_cache_valid = context_rq_sz;
1273  return context_rq_sz;
1274 }
voidpf void uLong size
Definition: ioapi.h:138
@ DbgKdGetContextApi
Definition: kd.h:45
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
#define RZ_MIN(x, y)

References DbgKdGetContextApi, free(), memcpy(), NULL, PKT_REQ, realloc(), req, RZ_MIN, autogen_x86imm::tmp, and winkd_send_state_manipulate_req().

Referenced by rz_debug_winkd_reg_read().

◆ winkd_read_ver()

bool winkd_read_ver ( RZ_BORROW RZ_NONNULL KdCtx ctx)

Definition at line 997 of file winkd.c.

997  {
998  kd_req_t req = { 0 };
999  kd_packet_t *pkt;
1000 
1001  if (!ctx || !ctx->desc || !ctx->syncd) {
1002  return false;
1003  }
1004 
1005  req.req = 0x3146;
1006  req.cpu = ctx->cpu;
1007 
1008  if (!winkd_send_state_manipulate_req(ctx, &req, NULL, 0, &pkt)) {
1009  return false;
1010  }
1011 
1012  kd_req_t *rr = PKT_REQ(pkt);
1013 
1014  RZ_LOG_DEBUG("Major : %i Minor %i\n", rr->rz_ver.major, rr->rz_ver.minor);
1015  RZ_LOG_DEBUG("Protocol version : %i.%i\n", rr->rz_ver.proto_major, rr->rz_ver.proto_minor);
1016  RZ_LOG_DEBUG("Flags : %08x\n", rr->rz_ver.flags);
1017  RZ_LOG_DEBUG("Machine : %08x\n", rr->rz_ver.machine);
1018  RZ_LOG_DEBUG("Kernel Base : %016" PFMT64x "\n", rr->rz_ver.kernel_base);
1019  RZ_LOG_DEBUG("Module list : %016" PFMT64x "\n", rr->rz_ver.mod_addr);
1020  RZ_LOG_DEBUG("Debug block : %016" PFMT64x "\n", rr->rz_ver.dbg_addr);
1021 
1022  if (rr->rz_ver.machine != KD_MACH_I386 && rr->rz_ver.machine != KD_MACH_AMD64) {
1023  RZ_LOG_ERROR("Unsupported target host\n");
1024  free(pkt);
1025  return false;
1026  }
1027 
1028  if (!(rr->rz_ver.flags & DBGKD_VERS_FLAG_DATA)) {
1029  RZ_LOG_ERROR("No _KDDEBUGGER_DATA64 pointer has been supplied by the debugee!\n");
1030  free(pkt);
1031  return false;
1032  }
1033 
1034  ctx->kernel_module.addr = rr->rz_ver.kernel_base;
1035  ctx->windctx.is_64bit = rr->rz_ver.flags & DBGKD_VERS_FLAG_PTR64;
1036 
1037  ut64 ptr = 0;
1038  if (!winkd_read_at(ctx, rr->rz_ver.dbg_addr, (ut8 *)&ptr, 4 << ctx->windctx.is_64bit)) {
1039  free(pkt);
1040  return false;
1041  }
1042 
1043  ctx->windctx.PsLoadedModuleList = rr->rz_ver.mod_addr;
1044  ctx->windctx.KdDebuggerDataBlock = ptr;
1045 
1046  RZ_LOG_DEBUG("PsLoadedModuleList at 0x%016" PFMT64x "\n", ctx->windctx.PsLoadedModuleList);
1047  RZ_LOG_DEBUG("_KDDEBUGGER_DATA64 at 0x%016" PFMT64x "\n", ctx->windctx.KdDebuggerDataBlock);
1048 
1049  // Thanks to this we don't have to find a way to read the cr4
1050  ut16 pae_enabled;
1051  if (!winkd_read_at(ctx, ctx->windctx.KdDebuggerDataBlock + K_PaeEnabled, (ut8 *)&pae_enabled, sizeof(ut16))) {
1052  free(pkt);
1053  return false;
1054  }
1055 
1056  ctx->windctx.is_pae = pae_enabled & 1;
1057  ctx->windctx.profile = winkd_get_profile(32 << ctx->windctx.is_64bit, rr->rz_ver.minor, winkd_get_sp(&ctx->windctx));
1058  if (!ctx->windctx.profile) {
1059  RZ_LOG_WARN("Could not find a suitable profile for the target OS\n");
1060  }
1061  free(pkt);
1062  return true;
1063 }
#define KD_MACH_I386
Definition: kd.h:110
#define KD_MACH_AMD64
Definition: kd.h:112
#define DBGKD_VERS_FLAG_PTR64
Definition: kd.h:117
#define DBGKD_VERS_FLAG_DATA
Definition: kd.h:116
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
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

References DBGKD_VERS_FLAG_DATA, DBGKD_VERS_FLAG_PTR64, free(), K_PaeEnabled, KD_MACH_AMD64, KD_MACH_I386, NULL, PFMT64x, PKT_REQ, req, RZ_LOG_DEBUG, RZ_LOG_ERROR, RZ_LOG_WARN, ut64(), winkd_get_profile(), winkd_get_sp(), winkd_read_at(), and winkd_send_state_manipulate_req().

Referenced by rz_debug_winkd_attach().

◆ winkd_set_cpu()

bool winkd_set_cpu ( RZ_BORROW RZ_NONNULL KdCtx ctx,
int  cpu 
)

Definition at line 91 of file winkd.c.

91  {
92  if (!ctx || cpu > ctx->cpu_count) {
93  return false;
94  }
95  ctx->cpu = cpu;
96  return true;
97 }
static ut32 cpu[32]
Definition: analysis_or1k.c:21

References cpu.

Referenced by rz_debug_winkd_wait().

◆ winkd_set_target()

bool winkd_set_target ( RZ_BORROW RZ_NONNULL WindCtx ctx,
ut32  pid,
ut32  tid 
)

Definition at line 106 of file winkd.c.

106  {
107  WindProc *p;
108  WindThread *t;
109  RzList *l;
110  RzListIter *it;
111  const bool is_cur_process = ctx->target.eprocess && (ctx->target.uniqueid == pid);
112  bool found = false;
113  if (!is_cur_process) {
114  l = winkd_list_process(ctx);
115  rz_list_foreach (l, it, p) {
116  if (p->uniqueid == pid) {
117  found = true;
118  ctx->target = *p;
119  break;
120  }
121  }
122  rz_list_free(l);
123  if (!found) {
124  ctx->target.eprocess = 0;
125  ctx->target.uniqueid = 0;
126  return false;
127  }
128  }
129  const bool is_cur_thread = ctx->target_thread.ethread && (ctx->target_thread.uniqueid == tid);
130  found = false;
131  if (!is_cur_thread || !is_cur_process) {
132  l = winkd_list_threads(ctx);
133  if (is_cur_process) {
134  rz_list_foreach (l, it, t) {
135  if (t->uniqueid == tid) {
136  ctx->target_thread = *t;
137  found = true;
138  break;
139  }
140  }
141  } else {
142  t = rz_list_first(l);
143  if (t) {
144  ctx->target_thread = *t;
145  found = true;
146  }
147  }
148  rz_list_free(l);
149  if (!found) {
150  ctx->target_thread.ethread = 0;
151  ctx->target_thread.uniqueid = 0;
152  return false;
153  }
154  }
155  return true;
156 }
RZ_API const KEY_TYPE bool * found
Definition: ht_inc.h:130
RZ_API RZ_BORROW void * rz_list_first(RZ_NONNULL const RzList *list)
Returns the first element of the list.
Definition: list.c:77
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
RzList * winkd_list_threads(RZ_BORROW RZ_NONNULL WindCtx *ctx)
Definition: winkd.c:782
RzList * winkd_list_process(RZ_BORROW RZ_NONNULL WindCtx *ctx)
Definition: winkd.c:513

References found, p, pid, rz_list_first(), rz_list_free(), WindThread::uniqueid, winkd_list_process(), and winkd_list_threads().

Referenced by rz_debug_dmp_select(), and rz_debug_winkd_select().

◆ winkd_sync()

int winkd_sync ( RZ_BORROW RZ_NONNULL KdCtx ctx)

Definition at line 1065 of file winkd.c.

1065  {
1066  int ret = -1;
1067  kd_packet_t *s;
1068 
1069  if (!ctx || !ctx->desc) {
1070  return -1;
1071  }
1072 
1073  if (ctx->syncd) {
1074  return 0;
1075  }
1076 
1077  while (!winkd_lock_enter(ctx)) {
1078  };
1079 
1080  if (ctx->desc->iob->type == KD_IO_NET) {
1081  // Read a KD packet to initialize KDNet interface
1082  // The first packet will always be type of KD_PACKET_TYPE_UNUSED
1083  ret = kd_read_packet(ctx->desc, &s);
1084  if (ret != KD_E_OK) {
1085  goto end;
1086  }
1087  }
1088 
1089  // Send the breakin packet
1090  if (iob_write(ctx->desc, (const ut8 *)"b", 1) != 1) {
1091  ret = KD_E_IOERR;
1092  goto end;
1093  }
1094 
1095  if (ctx->desc->iob->type == KD_IO_PIPE) {
1096  // Reset the host
1097  ret = kd_send_ctrl_packet(ctx->desc, KD_PACKET_TYPE_RESET, 0);
1098  if (ret != KD_E_OK) {
1099  goto end;
1100  }
1101 
1102  // Wait for the response
1104  if (ret != KD_E_OK) {
1105  goto end;
1106  }
1107  }
1108  ctx->last_received_id = KD_INITIAL_PACKET_ID;
1109 
1110  // Syncronize with the first KD_PACKET_TYPE_STATE_CHANGE64 packet
1112  if (ret != KD_E_OK) {
1113  goto end;
1114  }
1115 
1116  // Reset the sequence id
1117  ctx->seq_id = KD_INITIAL_PACKET_ID;
1118 
1119  kd_stc_64 *stc64 = PKT_STC(s);
1120  ctx->cpu = stc64->cpu;
1121  ctx->cpu_count = stc64->cpu_count;
1122  ctx->windctx.target.eprocess = 0;
1123  rz_list_free(ctx->plist_cache);
1124  ctx->plist_cache = NULL;
1125  rz_list_free(ctx->tlist_cache);
1126  ctx->tlist_cache = NULL;
1127  ctx->windctx.is_pae = 0;
1128  ctx->windctx.target_thread.ethread = stc64->kthread;
1129  // We're ready to go
1130  ctx->syncd = 1;
1131 
1132  free(s);
1133  RZ_LOG_INFO("Sync done! (%i cpus found)\n", ctx->cpu_count);
1134  ret = 1;
1135 
1136 end:
1138  return ret;
1139 }
int kd_send_ctrl_packet(io_desc_t *desc, const ut32 type, const ut32 id)
Definition: kd.c:25
int kd_read_packet(io_desc_t *desc, kd_packet_t **p)
Definition: kd.c:80
@ KD_E_IOERR
Definition: kd.h:14
@ KD_PACKET_TYPE_STATE_CHANGE64
Definition: kd.h:26
@ KD_PACKET_TYPE_RESET
Definition: kd.h:25
#define KD_INITIAL_PACKET_ID
Definition: kd.h:100
static RzSocket * s
Definition: rtr.c:28
#define RZ_LOG_INFO(fmtstr,...)
Definition: rz_log.h:54
#define KD_IO_PIPE
Definition: transport.h:17
#define KD_IO_NET
Definition: transport.h:18
#define PKT_STC(p)
Definition: winkd.c:203

References test_evm::end, free(), iob_write(), KD_E_IOERR, KD_E_OK, KD_INITIAL_PACKET_ID, KD_IO_NET, KD_IO_PIPE, KD_PACKET_TYPE_RESET, KD_PACKET_TYPE_STATE_CHANGE64, kd_read_packet(), kd_send_ctrl_packet(), NULL, PKT_STC, rz_list_free(), RZ_LOG_INFO, s, winkd_lock_enter(), winkd_lock_leave(), and winkd_wait_packet().

Referenced by rz_debug_winkd_attach().

◆ winkd_va_to_pa()

bool winkd_va_to_pa ( RZ_BORROW RZ_NONNULL WindCtx ctx,
ut64  directory_table,
ut64  va,
RZ_BORROW RZ_NONNULL RZ_OUT ut64 pa 
)

Definition at line 860 of file winkd.c.

860  {
861  ut64 pml4i, pdpi, pdi, pti;
862  ut64 tmp, mask;
863 
864  if (ctx->is_64bit) {
865  pti = (va >> 12) & 0x1ff;
866  pdi = (va >> 21) & 0x1ff;
867  pdpi = (va >> 30) & 0x1ff;
868  pml4i = (va >> 39) & 0x1ff;
869  // Grab the PageFrameNumber field off the _HARDWARE_PTE entry
870  mask = 0x000000fffffff000;
871  } else {
872  if (ctx->is_pae) {
873  pti = (va >> 12) & 0x1ff;
874  pdi = (va >> 21) & 0x1ff;
875  pdpi = (va >> 30) & 0x3;
876  pml4i = 0;
877  } else {
878  pti = (va >> 12) & 0x3ff;
879  pdi = (va >> 22) & 0x3ff;
880  pdpi = 0;
881  pml4i = 0;
882  }
883  // Grab the PageFrameNumber field off the _HARDWARE_PTE entry
884  mask = 0xfffff000;
885  }
886 
887  tmp = directory_table;
888  tmp &= ~0x1f;
889 
890  if (ctx->is_64bit) {
891  // PML4 lookup
892  if (!ctx->read_at_physical(ctx->user, tmp + pml4i * 8, (ut8 *)&tmp, 8)) {
893  return false;
894  }
895  tmp &= mask;
896  }
897 
898  if (ctx->is_pae) {
899  // PDPT lookup
900  if (!ctx->read_at_physical(ctx->user, tmp + pdpi * 8, (ut8 *)&tmp, 8)) {
901  return false;
902  }
903  tmp &= mask;
904  }
905 
906  const int read_size = ctx->is_pae ? 8 : 4;
907 
908  // PDT lookup
909  if (!ctx->read_at_physical(ctx->user, tmp + pdi * read_size, (ut8 *)&tmp, read_size)) {
910  return false;
911  }
912 
913  // Large page entry
914  // The page size differs between pae and non-pae systems, the former points to 2MB pages while
915  // the latter points to 4MB pages
916  if (is_page_large(ctx, tmp)) {
917  tmp = (tmp << 16) >> 16;
918  *pa = ctx->is_pae ? (tmp & (~0x1fffff)) | (va & 0x1fffff) : (tmp & (~0x3fffff)) | (va & 0x3fffff);
919  return true;
920  }
921 
922  // PT lookup
923  if (!ctx->read_at_physical(ctx->user, (tmp & mask) + pti * read_size, (ut8 *)&tmp, read_size)) {
924  return false;
925  }
926 
927  if (tmp & PTE_VALID) {
928  *pa = (tmp & mask) | (va & 0xfff);
929  return true;
930  }
931 
932  if (tmp & PTE_PROTOTYPE) {
933  // TODO : prototype PTE support
934  RZ_LOG_ERROR("Prototype PTE lookup is currently missing!\n");
935  }
936 
937  return false;
938 }
#define mask()
#define PTE_PROTOTYPE
Definition: winkd.c:847
#define PTE_VALID
Definition: winkd.c:845
static bool is_page_large(RZ_BORROW RZ_NONNULL WindCtx *ctx, ut64 page_descriptor)
Definition: winkd.c:850

References is_page_large(), mask, PTE_PROTOTYPE, PTE_VALID, RZ_LOG_ERROR, autogen_x86imm::tmp, and ut64().

Referenced by winkd_op_at_uva().

◆ winkd_wait_packet()

int winkd_wait_packet ( RZ_BORROW RZ_NONNULL KdCtx ctx,
const ut32  type,
RZ_NULLABLE RZ_OUT kd_packet_t **  p 
)

Definition at line 258 of file winkd.c.

258  {
259  kd_packet_t *pkt = NULL;
260  int ret;
261  if (p) {
262  *p = NULL;
263  }
264 
265  bool is_repeated_packet;
266  do {
267  free(pkt);
268  // Try to read a whole packet
269  ret = kd_read_packet(ctx->desc, &pkt);
270  if (ret != KD_E_OK) {
271  return ret;
272  }
273  RZ_LOG_DEBUG("=== Received Packet ===\n");
274  RZ_LOG_DEBUG("PACKET ID : 0x%x\n", pkt->id);
275  is_repeated_packet = ctx->last_received_id == pkt->id;
276  if (is_repeated_packet) {
277  RZ_LOG_DEBUG("Repeated packet, skipping\n");
278  } else if (pkt->leader == KD_PACKET_DATA) {
279  ctx->last_received_id = pkt->id;
280  }
281  if (pkt->type == KD_PACKET_TYPE_UNUSED) {
282  is_repeated_packet = true;
283  continue;
284  }
285  } while (is_repeated_packet);
286 
287  if (pkt->type != type) {
288  RZ_LOG_DEBUG("We were not waiting for this: %02x Expected: %02x\n", pkt->type, type);
289  }
290  if (pkt->leader == KD_PACKET_DATA && pkt->type == KD_PACKET_TYPE_STATE_CHANGE64) {
291  RZ_LOG_VERBOSE("Got STATE_CHANGE64 packet\n");
292  kd_stc_64 *stc = PKT_STC(pkt);
293  if (stc->state == DbgKdExceptionStateChange) {
294  RZ_LOG_VERBOSE(" Exception\n");
295  RZ_LOG_VERBOSE(" Code : %08" PFMT32x "\n", stc->exception.code);
296  RZ_LOG_VERBOSE(" Flags : %08" PFMT32x "\n", stc->exception.flags);
297  RZ_LOG_VERBOSE(" Record : %016" PFMT64x "\n", stc->exception.ex_record);
298  RZ_LOG_VERBOSE(" Addr : %016" PFMT64x "\n", stc->exception.ex_addr);
299  if (ctx->breaked) {
300  RZ_LOG_VERBOSE(" BREAKED\n");
301  }
302  } else if (stc->state == DbgKdLoadSymbolsStateChange) {
303  RZ_LOG_VERBOSE(stc->load_symbols.unload ? " Unload Symbols\n" : " Load Symbols\n");
304  RZ_LOG_VERBOSE(" Path Size : %016" PFMT64x "\n", stc->load_symbols.pathsize);
305  RZ_LOG_VERBOSE(" Base : %016" PFMT64x "\n", stc->load_symbols.base);
306  RZ_LOG_VERBOSE(" Checksum : %08" PFMT32x "\n", stc->load_symbols.checksum);
307  RZ_LOG_VERBOSE(" ImageSize : %08" PFMT32x "\n", stc->load_symbols.size);
308  if (load_symbol_path_is_valid(pkt)) {
309  char *path = (char *)pkt->data + pkt->length - stc->load_symbols.pathsize;
310  path[stc->load_symbols.pathsize - 1] = 0;
311  RZ_LOG_VERBOSE(" Image : %s\n", path);
312  if (rz_str_endswith(path, "\\ntoskrnl.exe")) {
313  ctx->kernel_module.addr = stc->load_symbols.base;
314  ctx->kernel_module.size = stc->load_symbols.size;
315  ctx->kernel_module.name = strdup(path);
316  }
317  }
318  } else if (stc->state == DbgKdCommandStringStateChange) {
319  RZ_LOG_VERBOSE("CommandString\n");
320  } else {
321  RZ_LOG_WARN("Unknown state change packet type: 0x%" PFMT32x "\n", (ut32)pkt->type);
322  }
323  } else if (pkt->leader == KD_PACKET_DATA && pkt->type == KD_PACKET_TYPE_FILE_IO) {
324  RZ_LOG_DEBUG("File IO\n");
325  RZ_LOG_DEBUG(" req: %08" PFMT32x "\n", PKT_IO(pkt)->req);
326  RZ_LOG_DEBUG(" ret: %08" PFMT32x "\n", PKT_IO(pkt)->ret);
327  RZ_LOG_DEBUG("Replying IO\n");
328  do_io_reply(ctx, pkt);
329  } else if (pkt->leader == KD_PACKET_DATA && pkt->type == KD_PACKET_TYPE_STATE_MANIPULATE) {
330  RZ_LOG_DEBUG("State_manipulate\n");
331  RZ_LOG_DEBUG(" req: %08" PFMT32x "\n", PKT_REQ(pkt)->req);
332  RZ_LOG_DEBUG(" cpu_level: %08x\n", PKT_REQ(pkt)->cpu_level);
333  RZ_LOG_DEBUG(" cpu: %i\n", PKT_REQ(pkt)->cpu);
334  RZ_LOG_DEBUG(" ret: %08" PFMT32x "\n", PKT_REQ(pkt)->ret);
335  }
336 
337  if (pkt->leader == KD_PACKET_CTRL) {
338  switch (pkt->type) {
340  RZ_LOG_DEBUG("ACK received\n");
341  if (pkt->id == ctx->seq_id) {
342  ctx->seq_id ^= 1;
343  }
345  free(pkt);
346  return KD_E_OK;
347  }
348  break;
350  RZ_LOG_DEBUG("Reset received\n");
351  ctx->seq_id = KD_INITIAL_PACKET_ID;
352  ctx->last_received_id = KD_INITIAL_PACKET_ID;
353  free(pkt);
354  if (type == KD_PACKET_TYPE_RESET) {
355  return KD_E_OK;
356  }
357  return KD_E_MALFORMED;
359  // The host didn't like our request
361  RZ_LOG_DEBUG("Waoh. You probably sent a malformed packet!\n");
362  free(pkt);
363  return KD_E_MALFORMED;
364  }
365  }
366  if (pkt->type != type) {
367  free(pkt);
368  if (ctx->breaked) {
369  ctx->breaked = false;
370  return KD_E_BREAK;
371  } else {
372  return KD_E_MALFORMED;
373  }
374  }
375  ctx->breaked = false;
376  if (ret != KD_E_OK) {
377  free(pkt);
378  return ret;
379  }
380 
381  if (p) {
382  *p = pkt;
383  } else {
384  free(pkt);
385  }
386 
387  return KD_E_OK;
388 }
#define PFMT32x
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
@ KD_E_BREAK
Definition: kd.h:15
#define KD_PACKET_DATA
Definition: kd.h:97
@ DbgKdCommandStringStateChange
Definition: kd.h:37
@ DbgKdLoadSymbolsStateChange
Definition: kd.h:36
@ DbgKdExceptionStateChange
Definition: kd.h:35
@ KD_PACKET_TYPE_RESEND
Definition: kd.h:24
@ KD_PACKET_TYPE_UNUSED
Definition: kd.h:19
@ KD_PACKET_TYPE_FILE_IO
Definition: kd.h:30
#define KD_PACKET_CTRL
Definition: kd.h:98
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_LOG_VERBOSE(fmtstr,...)
Definition: rz_log.h:52
RZ_API bool rz_str_endswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string ends with a specifc sequence of characters (case sensitive)
Definition: str.c:3329
RZ_API char RZ_API void rz_sys_backtrace(void)
Print the backtrace at the point this function is called from.
Definition: sys.c:265
static int do_io_reply(RZ_BORROW RZ_NONNULL KdCtx *ctx, kd_packet_t *pkt)
Definition: winkd.c:225
static bool load_symbol_path_is_valid(kd_packet_t *pkt)
Definition: winkd.c:252
#define PKT_IO(p)
Definition: winkd.c:204

References cpu, DbgKdCommandStringStateChange, DbgKdExceptionStateChange, DbgKdLoadSymbolsStateChange, do_io_reply(), free(), KD_E_BREAK, KD_E_MALFORMED, KD_E_OK, KD_INITIAL_PACKET_ID, KD_PACKET_CTRL, KD_PACKET_DATA, KD_PACKET_TYPE_ACKNOWLEDGE, KD_PACKET_TYPE_FILE_IO, KD_PACKET_TYPE_RESEND, KD_PACKET_TYPE_RESET, KD_PACKET_TYPE_STATE_CHANGE64, KD_PACKET_TYPE_STATE_MANIPULATE, KD_PACKET_TYPE_UNUSED, kd_read_packet(), load_symbol_path_is_valid(), NULL, p, path, PFMT32x, PFMT64x, PKT_IO, PKT_REQ, PKT_STC, req, RZ_LOG_DEBUG, RZ_LOG_VERBOSE, RZ_LOG_WARN, rz_str_endswith(), rz_sys_backtrace(), strdup(), and type.

Referenced by do_io_reply(), rz_debug_winkd_wait(), winkd_continue(), winkd_send_state_manipulate_req(), and winkd_sync().

◆ winkd_windmodule_free()

void winkd_windmodule_free ( void *  ptr)

Definition at line 611 of file winkd.c.

611  {
612  WindModule *mod = ptr;
613  free(mod->name);
614  free(mod);
615 }

References free(), and mod().

Referenced by dmp_get_modules(), and winkd_list_modules().

◆ winkd_write_at()

int winkd_write_at ( RZ_BORROW RZ_NONNULL KdCtx ctx,
const ut64  offset,
RZ_BORROW RZ_NONNULL RZ_IN const ut8 buf,
const int  count 
)

Definition at line 1384 of file winkd.c.

1384  {
1385  kd_packet_t *pkt = NULL;
1386  kd_req_t req = { 0 };
1387 
1388  if (!ctx || !ctx->desc || !ctx->syncd) {
1389  return 0;
1390  }
1391 
1392  int payload = RZ_MIN(count, KD_MAX_PAYLOAD - sizeof(kd_req_t));
1394  req.cpu = ctx->cpu;
1395  req.rz_mem.addr = offset;
1396  req.rz_mem.length = payload;
1397 
1398  if (!winkd_send_state_manipulate_req(ctx, &req, buf, payload, &pkt)) {
1399  return 0;
1400  }
1401 
1402  kd_req_t *rr = PKT_REQ(pkt);
1403  int ret = rr->rz_mem.read;
1404  free(pkt);
1405  return ret;
1406 }
#define KD_MAX_PAYLOAD
Definition: kd.h:102
@ DbgKdWriteVirtualMemoryApi
Definition: kd.h:44

References count, DbgKdWriteVirtualMemoryApi, free(), KD_MAX_PAYLOAD, NULL, PKT_REQ, req, RZ_MIN, and winkd_send_state_manipulate_req().

Referenced by __write().

◆ winkd_write_at_phys()

int winkd_write_at_phys ( RZ_BORROW RZ_NONNULL KdCtx ctx,
const ut64  offset,
RZ_BORROW RZ_NONNULL RZ_IN const ut8 buf,
const int  count 
)

Definition at line 1408 of file winkd.c.

1408  {
1409  kd_packet_t *pkt;
1410  kd_req_t req = { 0 };
1411 
1412  if (!ctx || !ctx->desc || !ctx->syncd) {
1413  return 0;
1414  }
1415 
1416  int payload = RZ_MIN(count, KD_MAX_PAYLOAD - sizeof(kd_req_t));
1417 
1418  memset(&req, 0, sizeof(kd_req_t));
1419 
1421  req.cpu = ctx->cpu;
1422 
1423  req.rz_mem.addr = offset;
1424  req.rz_mem.length = payload;
1425  req.rz_mem.read = 0; // Default caching option
1426 
1427  if (!winkd_send_state_manipulate_req(ctx, &req, buf, payload, &pkt)) {
1428  return 0;
1429  }
1430 
1431  kd_req_t *rr = PKT_REQ(pkt);
1432 
1433  if (rr->ret) {
1434  free(pkt);
1435  return 0;
1436  }
1437  int ret = rr->rz_mem.read;
1438  free(pkt);
1439  return ret;
1440 }
@ DbgKdWritePhysicalMemoryApi
Definition: kd.h:57
return memset(p, 0, total)

References count, DbgKdWritePhysicalMemoryApi, free(), KD_MAX_PAYLOAD, memset(), PKT_REQ, req, RZ_MIN, and winkd_send_state_manipulate_req().

Referenced by op_at_phys().

◆ winkd_write_at_uva()

int winkd_write_at_uva ( RZ_BORROW RZ_NONNULL WindCtx ctx,
ut64  offset,
RZ_BORROW RZ_NONNULL RZ_IN const ut8 buf,
int  count 
)

Definition at line 600 of file winkd.c.

600  {
601  return winkd_op_at_uva(ctx, address, (ut8 *)buf, count, true);
602 }

References count, and winkd_op_at_uva().

Referenced by __write(), and dmp_write().

◆ winkd_write_reg()

bool winkd_write_reg ( RZ_BORROW RZ_NONNULL KdCtx ctx,
ut32  flags,
RZ_BORROW RZ_NONNULL RZ_IN const ut8 buf,
int  size 
)

Definition at line 1179 of file winkd.c.

1179  {
1180  kd_packet_t *pkt = NULL;
1181  kd_req_t req = { 0 };
1182 
1183  if (!ctx || !ctx->desc || !ctx->syncd) {
1184  return false;
1185  }
1186  const ut64 max_ctx_size = KD_MAX_PAYLOAD - sizeof(kd_req_t);
1187  RZ_LOG_DEBUG("Regwrite() size: %x\n", size);
1188  if (size > max_ctx_size) {
1189  ut32 offset = 0;
1190  ut32 left = size;
1191  req.req = DbgKdSetContextEx;
1192  req.cpu = ctx->cpu;
1193  req.rz_ctx_ex.copied = size;
1194  do {
1195  const ut64 rest = RZ_MIN(left, max_ctx_size);
1196  req.rz_ctx_ex.count = rest;
1197  req.rz_ctx_ex.offset = offset;
1198  RZ_FREE(pkt);
1199  if (!winkd_send_state_manipulate_req(ctx, &req, buf + offset, rest, &pkt)) {
1200  break;
1201  }
1202  if (PKT_REQ(pkt)->rz_ctx_ex.count > left) {
1203  offset = size;
1204  break;
1205  }
1206  left -= PKT_REQ(pkt)->rz_ctx_ex.count;
1207  offset += PKT_REQ(pkt)->rz_ctx_ex.count;
1208  } while (left);
1209  size = offset;
1210  } else {
1211  req.req = DbgKdSetContextApi;
1212  req.cpu = ctx->cpu;
1213  req.rz_ctx.flags = flags;
1214  if (!winkd_send_state_manipulate_req(ctx, &req, buf, size, &pkt)) {
1215  return false;
1216  }
1217  }
1218 
1219  if (size > ctx->context_cache_size) {
1220  free(ctx->context_cache);
1221  ctx->context_cache = malloc(size);
1222  ctx->context_cache_size = size;
1223  }
1224 
1225  memcpy(ctx->context_cache, buf, size);
1226 
1227  free(pkt);
1228  return size;
1229 }
@ DbgKdSetContextEx
Definition: kd.h:85
@ DbgKdSetContextApi
Definition: kd.h:46
void * malloc(size_t size)
Definition: malloc.c:123

References DbgKdSetContextApi, DbgKdSetContextEx, flags, free(), KD_MAX_PAYLOAD, malloc(), memcpy(), NULL, PKT_REQ, req, RZ_FREE, RZ_LOG_DEBUG, RZ_MIN, ut64(), and winkd_send_state_manipulate_req().

Referenced by rz_debug_winkd_reg_write().