Rizin
unix-like reverse engineering framework and cli tools
windows_message.c File Reference
#include <rz_windows.h>
#include "windows_message.h"

Go to the source code of this file.

Classes

struct  _window
 

Typedefs

typedef struct _window window
 

Functions

void free_window (void *ptr)
 
static windowwindow_from_handle (HANDLE hwnd)
 
static RzTablecreate_window_table (void)
 
static void add_window_to_table (RzTable *tbl, window *win)
 
RZ_API void rz_w32_identify_window (void)
 
static BOOL CALLBACK enum_childs (_In_ HWND hwnd, _In_ LPARAM lParam)
 
static RzListget_windows (RzDebug *dbg)
 
static ut64 get_dispatchmessage_offset (RzDebug *dbg)
 
static void init_msg_types (Sdb **msg_types)
 
static DWORD get_msg_type (char *name)
 
static void print_windows (RzDebug *dbg, RzList *windows)
 
RZ_API void rz_w32_print_windows (RzDebug *dbg)
 
RZ_API bool rz_w32_add_winmsg_breakpoint (RzDebug *dbg, const char *msg_name, const char *window_id)
 

Variables

static char * msg_types_arr []
 

Typedef Documentation

◆ window

typedef struct _window window

Function Documentation

◆ add_window_to_table()

static void add_window_to_table ( RzTable tbl,
window win 
)
static

Definition at line 301 of file windows_message.c.

301  {
302  rz_return_if_fail(tbl && win);
303  char *handle = rz_str_newf("0x%08" PFMT64x "", (ut64)win->h);
304  char *pid = rz_str_newf("%lu", win->pid);
305  char *tid = rz_str_newf("%lu", win->tid);
306  rz_table_add_row(tbl, handle, pid, tid, win->name, NULL);
307  free(handle);
308  free(tid);
309  free(pid);
310 }
static mcore_handle handle
Definition: asm_mcore.c:8
#define NULL
Definition: cris-opc.c:27
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
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 rz_return_if_fail(expr)
Definition: rz_assert.h:100
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API void rz_table_add_row(RZ_NONNULL RzTable *t, const char *name,...)
Definition: table.c:329
#define PFMT64x
Definition: rz_types.h:393
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References free(), handle, NULL, PFMT64x, pid, rz_return_if_fail, rz_str_newf(), rz_table_add_row(), and ut64().

Referenced by print_windows(), and rz_w32_identify_window().

◆ create_window_table()

static RzTable* create_window_table ( void  )
static

Definition at line 289 of file windows_message.c.

289  {
290  RzTable *tbl = rz_table_new();
291  if (!tbl) {
292  return NULL;
293  }
294  rz_table_add_column(tbl, rz_table_type("number"), "Handle", ST32_MAX);
295  rz_table_add_column(tbl, rz_table_type("number"), "PID", ST32_MAX);
296  rz_table_add_column(tbl, rz_table_type("number"), "TID", ST32_MAX);
297  rz_table_add_column(tbl, rz_table_type("string"), "Class Name", ST32_MAX);
298  return tbl;
299 }
RZ_API void rz_table_add_column(RzTable *t, RzTableColumnType *type, const char *name, int maxWidth)
Definition: table.c:134
RZ_API RzTable * rz_table_new(void)
Definition: table.c:103
RZ_API RzTableColumnType * rz_table_type(const char *name)
Definition: table.c:24
#define ST32_MAX
Definition: rz_types_base.h:97

References NULL, rz_table_add_column(), rz_table_new(), rz_table_type(), and ST32_MAX.

Referenced by print_windows(), and rz_w32_identify_window().

◆ enum_childs()

static BOOL CALLBACK enum_childs ( _In_ HWND  hwnd,
_In_ LPARAM  lParam 
)
static

Definition at line 346 of file windows_message.c.

348  {
349  RzList *windows = (RzList *)lParam;
350  window *win = window_from_handle(hwnd);
351  if (!win) {
352  return false;
353  }
354  rz_list_push(windows, win);
355  return true;
356 }
RZ_API RZ_BORROW RzListIter * rz_list_push(RZ_NONNULL RzList *list, void *item)
Alias for rz_list_append.
Definition: list.c:60
static window * window_from_handle(HANDLE hwnd)

References rz_list_push(), and window_from_handle().

Referenced by get_windows().

◆ free_window()

void free_window ( void *  ptr)

Definition at line 259 of file windows_message.c.

259  {
260  window *win = ptr;
261  free(win->name);
262  free(win);
263 }

References free().

Referenced by get_windows().

◆ get_dispatchmessage_offset()

static ut64 get_dispatchmessage_offset ( RzDebug dbg)
static

Definition at line 378 of file windows_message.c.

378  {
379  RzList *modlist = rz_debug_modules_list(dbg);
380  RzListIter *it;
381  RzDebugMap *mod;
382  bool found = false;
383  rz_list_foreach (modlist, it, mod) {
384  if (!strnicmp(mod->name, "user32.dll", sizeof("user32.dll"))) {
385  found = true;
386  break;
387  }
388  }
389  if (!found) {
390  return 0;
391  }
392  char *res = dbg->corebind.cmdstr(dbg->corebind.core, "f~DispatchMessageW");
393  if (!*res) {
394  free(res);
395  return 0;
396  }
397  char *line = strtok(res, "\n");
398  ut64 offset = 0;
399  do {
400  char *sym = strrchr(line, ' ');
401  if (sym && rz_str_startswith(sym + 1, "sym.imp")) {
403  dbg->iob.read_at(dbg->iob.io, offset, (ut8 *)&offset, sizeof(offset));
404  break;
405  }
406  } while ((line = strtok(NULL, "\n")));
407  free(res);
408  return offset;
409 }
int mod(int a, int b)
Definition: crypto_rot.c:8
RzDebug * dbg
Definition: desil.c:30
RZ_API RzList * rz_debug_modules_list(RzDebug *dbg)
Definition: dmap.c:29
RZ_API const KEY_TYPE bool * found
Definition: ht_inc.h:130
voidpf uLong offset
Definition: ioapi.h:144
uint8_t ut8
Definition: lh5801.h:11
line
Definition: setup.py:34
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
Definition: unum.c:456
RZ_API bool rz_str_startswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string starts with a specifc sequence of characters (case sensitive)
Definition: str.c:3286
RzCoreCmdStr cmdstr
Definition: rz_bind.h:34
void * core
Definition: rz_bind.h:31
RzCoreBind corebind
Definition: rz_debug.h:314
RzIOBind iob
Definition: rz_debug.h:293
RzIOReadAt read_at
Definition: rz_io.h:240
RzIO * io
Definition: rz_io.h:232

References rz_core_bind_t::cmdstr, rz_core_bind_t::core, rz_debug_t::corebind, dbg, found, free(), rz_io_bind_t::io, rz_debug_t::iob, setup::line, mod(), NULL, rz_io_bind_t::read_at, rz_debug_modules_list(), rz_num_math(), rz_str_startswith(), and ut64().

Referenced by rz_w32_add_winmsg_breakpoint().

◆ get_msg_type()

static DWORD get_msg_type ( char *  name)
static

Definition at line 420 of file windows_message.c.

420  {
421  static Sdb *msg_types = NULL;
422  if (!msg_types) {
423  init_msg_types(&msg_types);
424  }
425  ut32 found;
426  const char *type_str = sdb_const_get(msg_types, name, &found);
427  if (found) {
428  int type = rz_num_get(NULL, type_str);
429  return type;
430  }
431  return 0;
432 }
uint32_t ut32
int type
Definition: mipsasm.c:17
RZ_API ut64 rz_num_get(RzNum *num, const char *str)
Definition: unum.c:172
RZ_API const char * sdb_const_get(Sdb *s, const char *key, ut32 *cas)
Definition: sdb.c:279
Definition: z80asm.h:102
Definition: sdb.h:63
static void init_msg_types(Sdb **msg_types)

References found, init_msg_types(), NULL, rz_num_get(), sdb_const_get(), and type.

Referenced by rz_w32_add_winmsg_breakpoint().

◆ get_windows()

static RzList* get_windows ( RzDebug dbg)
static

Definition at line 358 of file windows_message.c.

358  {
360  HWND hCurWnd = NULL;
361  do {
362  hCurWnd = FindWindowEx(NULL, hCurWnd, NULL, NULL);
363  DWORD dwProcessID = 0;
364  GetWindowThreadProcessId(hCurWnd, &dwProcessID);
365  if (dbg->pid == dwProcessID) {
366  EnumChildWindows(hCurWnd, enum_childs, (LPARAM)windows);
367  window *win = window_from_handle(hCurWnd);
368  if (!win) {
369  rz_list_free(windows);
370  return NULL;
371  }
372  rz_list_push(windows, win);
373  }
374  } while (hCurWnd != NULL);
375  return windows;
376 }
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
DWORD
static BOOL CALLBACK enum_childs(_In_ HWND hwnd, _In_ LPARAM lParam)
void free_window(void *ptr)

References dbg, DWORD, enum_childs(), free_window(), NULL, rz_debug_t::pid, rz_list_free(), rz_list_newf(), rz_list_push(), and window_from_handle().

Referenced by rz_w32_add_winmsg_breakpoint(), and rz_w32_print_windows().

◆ init_msg_types()

static void init_msg_types ( Sdb **  msg_types)
static

Definition at line 411 of file windows_message.c.

411  {
412  *msg_types = sdb_new0();
413  int i;
414  char *cur_type;
415  for (i = 0; (cur_type = msg_types_arr[i]); i++) {
416  sdb_query(*msg_types, cur_type);
417  }
418 }
lzma_index ** i
Definition: index.h:629
RZ_API int sdb_query(Sdb *s, const char *cmd)
Definition: query.c:785
RZ_API Sdb * sdb_new0(void)
Definition: sdb.c:43
static char * msg_types_arr[]

References i, msg_types_arr, sdb_new0(), and sdb_query().

Referenced by get_msg_type().

◆ print_windows()

static void print_windows ( RzDebug dbg,
RzList windows 
)
static

Definition at line 434 of file windows_message.c.

434  {
435  RzTable *tbl = create_window_table();
436  if (!tbl) {
437  return;
438  }
439  RzListIter *it;
440  window *win;
441  rz_list_foreach (windows, it, win) {
442  add_window_to_table(tbl, win);
443  }
444  char *t = rz_table_tostring(tbl);
445  dbg->cb_printf(t);
446  free(t);
447  rz_table_free(tbl);
448 }
RZ_API void rz_table_free(RzTable *t)
Definition: table.c:114
RZ_API char * rz_table_tostring(RzTable *t)
Definition: table.c:510
PrintfCallback cb_printf
Definition: rz_debug.h:292
static void add_window_to_table(RzTable *tbl, window *win)
static RzTable * create_window_table(void)

References add_window_to_table(), rz_debug_t::cb_printf, create_window_table(), dbg, free(), rz_table_free(), and rz_table_tostring().

Referenced by rz_w32_add_winmsg_breakpoint(), and rz_w32_print_windows().

◆ rz_w32_add_winmsg_breakpoint()

RZ_API bool rz_w32_add_winmsg_breakpoint ( RzDebug dbg,
const char *  msg_name,
const char *  window_id 
)

Definition at line 462 of file windows_message.c.

462  {
463  rz_return_val_if_fail(dbg && msg_name, false);
464  char *name = strdup(msg_name);
465  rz_str_trim(name);
466 
468  if (!type) {
469  free(name);
470  return false;
471  }
472  ut64 offset = 0;
473  if (window_id) {
474  RzList *windows = get_windows(dbg);
475  if (windows && !windows->length) {
476  dbg->cb_printf("No windows for this process.\n");
477  }
478  ut64 win_h = rz_num_math(NULL, window_id);
479  RzListIter *it;
480  window *win;
481  rz_list_foreach (windows, it, win) {
482  if ((ut64)win->h == win_h || !strnicmp(win->name, window_id, strlen(window_id))) {
483  offset = win->proc;
484  break;
485  }
486  }
487  if (!offset) {
488  dbg->cb_printf("Window not found, try these:\n");
489  print_windows(dbg, windows);
490  }
491  rz_list_free(windows);
492  } else {
494  }
495  if (!offset) {
496  free(name);
497  return false;
498  }
499  RzBreakpointItem *b = rz_debug_bp_add(dbg, offset, 0, 0, 0, NULL, 0);
500  if (!b) {
501  free(name);
502  return false;
503  }
504  char *cond;
505  if (window_id) {
506  char *reg;
507  if (!strcmp(dbg->arch, "arm")) {
508  if (dbg->bits == RZ_SYS_BITS_64) {
509  reg = "x1";
510  } else {
511  reg = "r1";
512  }
513  } else {
514  reg = "edx";
515  }
516  b->cond = rz_str_newf("?q `ae %s,%d,-`", reg, type);
517  } else {
518  char *reg;
519  if (!strcmp(dbg->arch, "arm")) {
520  if (dbg->bits == RZ_SYS_BITS_64) {
521  reg = "x0";
522  } else {
523  reg = "r0";
524  }
525  } else {
526  if (dbg->bits == RZ_SYS_BITS_64) {
527  reg = "rcx";
528  } else {
529  reg = "ecx";
530  }
531  }
532  b->cond = rz_str_newf("?q `ae %lu,%s,%d,+,[4],-`", type, reg, dbg->bits);
533  }
534  free(name);
535  return true;
536 }
#define reg(n)
RZ_API RZ_BORROW RzBreakpointItem * rz_debug_bp_add(RZ_NONNULL RzDebug *dbg, ut64 addr, int hw, bool watch, int rw, RZ_NULLABLE const char *module, st64 m_delta)
Definition: debug.c:270
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_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API void rz_str_trim(RZ_NONNULL RZ_INOUT char *str)
Removes whitespace characters (space, tab, newline etc.) from the beginning and end of a string.
Definition: str_trim.c:190
@ RZ_SYS_BITS_64
Definition: rz_sys.h:21
#define b(i)
Definition: sha256.c:42
#define cond(bop, top, mask, flags)
char * arch
Definition: rz_debug.h:242
int bits
Definition: rz_debug.h:243
ut32 length
Definition: rz_list.h:22
static DWORD get_msg_type(char *name)
static RzList * get_windows(RzDebug *dbg)
static void print_windows(RzDebug *dbg, RzList *windows)
static ut64 get_dispatchmessage_offset(RzDebug *dbg)

References rz_debug_t::arch, b, rz_debug_t::bits, rz_debug_t::cb_printf, cond, dbg, DWORD, free(), get_dispatchmessage_offset(), get_msg_type(), get_windows(), rz_list_t::length, NULL, print_windows(), reg, rz_debug_bp_add(), rz_list_free(), rz_num_math(), rz_return_val_if_fail, rz_str_newf(), rz_str_trim(), RZ_SYS_BITS_64, strdup(), type, and ut64().

Referenced by rz_cmd_debug_set_cond_bp_win_handler().

◆ rz_w32_identify_window()

RZ_API void rz_w32_identify_window ( void  )

Definition at line 312 of file windows_message.c.

312  {
313  while (!rz_cons_yesno('y', "Move cursor to the window to be identified. Ready? (Y/n)"))
314  ;
315  POINT p;
316  if (!GetCursorPos(&p)) {
317  rz_sys_perror("GetCursorPos");
318  }
319  HWND hwnd = WindowFromPoint(p);
320  window *win = NULL;
321  if (hwnd) {
322  if (rz_cons_yesno('y', "Try to get the child? (Y/n)")) {
323  HWND child = ChildWindowFromPoint(hwnd, p);
324  hwnd = child ? child : hwnd;
325  }
326  win = window_from_handle(hwnd);
327  } else {
328  eprintf("No window found\n");
329  return;
330  }
331  if (!win) {
332  eprintf("Error trying to get information from 0x%08" PFMT64x "\n", (ut64)hwnd);
333  return;
334  }
335  RzTable *tbl = create_window_table();
336  if (!tbl) {
337  return;
338  }
339  add_window_to_table(tbl, win);
340  char *tbl_str = rz_table_tofancystring(tbl);
341  rz_cons_print(tbl_str);
342  free(tbl_str);
343  rz_table_free(tbl);
344 }
RZ_API bool rz_cons_yesno(int def, const char *fmt,...)
Definition: input.c:666
void * p
Definition: libc.cpp:67
#define eprintf(x, y...)
Definition: rlcc.c:7
RZ_API RZ_OWN char * rz_table_tofancystring(RZ_NONNULL RzTable *t)
Convert the content of RzTable to string.
Definition: table.c:404
#define rz_sys_perror(x)
Definition: rz_types.h:336

References add_window_to_table(), create_window_table(), eprintf, free(), NULL, p, PFMT64x, rz_cons_yesno(), rz_sys_perror, rz_table_free(), rz_table_tofancystring(), ut64(), and window_from_handle().

Referenced by rz_cmd_debug().

◆ rz_w32_print_windows()

RZ_API void rz_w32_print_windows ( RzDebug dbg)

Definition at line 450 of file windows_message.c.

450  {
451  RzList *windows = get_windows(dbg);
452  if (windows) {
453  if (!windows->length) {
454  dbg->cb_printf("No windows for this process.\n");
455  return;
456  }
457  print_windows(dbg, windows);
458  }
459  rz_list_free(windows);
460 }

References rz_debug_t::cb_printf, dbg, get_windows(), rz_list_t::length, print_windows(), and rz_list_free().

Referenced by rz_cmd_debug().

◆ window_from_handle()

static window* window_from_handle ( HANDLE  hwnd)
static

Definition at line 265 of file windows_message.c.

265  {
267  window *win = RZ_NEW0(window);
268  if (!win) {
269  return NULL;
270  }
271  win->h = hwnd;
272  win->tid = GetWindowThreadProcessId(hwnd, &win->pid);
273  win->proc = GetClassLongPtrW(hwnd, GCLP_WNDPROC);
274  const size_t sz = MAX_CLASS_NAME * sizeof(WCHAR);
275  wchar_t *tmp = malloc(sz);
276  if (!tmp) {
277  free(win);
278  return NULL;
279  }
280  GetClassNameW(hwnd, tmp, MAX_CLASS_NAME);
281  win->name = rz_utf16_to_utf8(tmp);
282  free(tmp);
283  if (!win->name) {
284  win->name = strdup("");
285  }
286  return win;
287 }
void * malloc(size_t size)
Definition: malloc.c:123
#define RZ_NEW0(x)
Definition: rz_types.h:284

References free(), malloc(), NULL, RZ_NEW0, rz_return_val_if_fail, strdup(), and autogen_x86imm::tmp.

Referenced by enum_childs(), get_windows(), and rz_w32_identify_window().

Variable Documentation

◆ msg_types_arr

char* msg_types_arr[]
static

Definition at line 7 of file windows_message.c.

Referenced by init_msg_types().