Rizin
unix-like reverse engineering framework and cli tools
windows-all.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2021 GustavoLCR <gugulcr@gmail.com>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_windows.h>
5 #include <DbgHelp.h>
6 #include <w32dbg_wrap.h>
7 
8 #define DEF_PROC(proc) static proc##_t *w32_##proc
9 #define GET_PROC(proc) \
10  w32_##proc = (proc##_t *)GetProcAddress(dbghelp, #proc); \
11  if (!w32_##proc) { \
12  return false; \
13  }
14 
15 typedef BOOL __stdcall SymInitialize_t(
16  _In_ HANDLE hProcess,
17  _In_opt_ PCSTR UserSearchPath,
18  _In_ BOOL fInvadeProcess);
19 
20 typedef BOOL __stdcall SymCleanup_t(
21  _In_ HANDLE hProcess);
22 
24  _In_ HANDLE hProcess,
25  _In_ DWORD64 AddrBase);
26 
27 typedef DWORD64 __stdcall SymGetModuleBase64_t(
28  _In_ HANDLE hProcess,
29  _In_ DWORD64 qwAddr);
30 
31 typedef BOOL __stdcall StackWalk64_t(
32  _In_ DWORD MachineType,
33  _In_ HANDLE hProcess,
34  _In_ HANDLE hThread,
35  _Inout_ LPSTACKFRAME64 StackFrame,
36  _Inout_ PVOID ContextRecord,
37  _In_opt_ PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
38  _In_opt_ PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
39  _In_opt_ PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
40  _In_opt_ PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress);
41 
42 DEF_PROC(SymInitialize);
43 DEF_PROC(SymCleanup);
44 DEF_PROC(SymFunctionTableAccess64);
45 DEF_PROC(SymGetModuleBase64);
46 DEF_PROC(StackWalk64);
47 
48 static inline bool initialize_sym_api(void) {
49  static bool initialized = false;
50  if (initialized) {
51  return true;
52  }
53  HMODULE dbghelp = LoadLibrary(TEXT("DbgHelp"));
54  if (!dbghelp) {
55  return false;
56  }
57  GET_PROC(SymInitialize);
58  GET_PROC(SymCleanup);
59  GET_PROC(SymFunctionTableAccess64);
60  GET_PROC(SymGetModuleBase64);
61  GET_PROC(StackWalk64);
62  initialized = true;
63  return true;
64 }
65 
68  static RzThreadLock *lock = NULL;
69  if (!lock) {
70  lock = rz_th_lock_new(false);
71  if (!lock) {
72  return NULL;
73  }
74  }
75  W32DbgWInst *wrap = dbg->plugin_data;
76 #if __arm64__
77  DWORD machine_type = IMAGE_FILE_MACHINE_ARM64;
78 #elif __arm__
79  DWORD machine_type = IMAGE_FILE_MACHINE_ARMNT;
80 #elif __x86_64__
81  DWORD machine_type = IMAGE_FILE_MACHINE_AMD64;
82 #else
83  DWORD machine_type = IMAGE_FILE_MACHINE_I386;
84 #endif
85  STACKFRAME64 stack = { 0 };
86  stack.AddrFrame.Mode = AddrModeFlat;
87  stack.AddrFrame.Offset = rz_reg_getv(dbg->reg, rz_reg_get_name(dbg->reg, RZ_REG_NAME_BP));
88  stack.AddrStack.Mode = AddrModeFlat;
89  stack.AddrStack.Offset = rz_reg_getv(dbg->reg, rz_reg_get_name(dbg->reg, RZ_REG_NAME_SP));
90  stack.AddrPC.Mode = AddrModeFlat;
92 
94  if (!list) {
95  return NULL;
96  }
97  CONTEXT *ctx = (CONTEXT *)rz_reg_arena_peek(dbg->reg);
99  w32_SymInitialize(wrap->pi.hProcess, NULL, TRUE);
100  while (w32_StackWalk64(machine_type, wrap->pi.hProcess, wrap->pi.hThread, &stack, ctx, NULL, w32_SymFunctionTableAccess64, w32_SymGetModuleBase64, NULL)) {
102  if (!frame) {
103  break;
104  }
105  frame->addr = stack.AddrPC.Offset;
106  frame->bp = stack.AddrFrame.Offset;
107  frame->sp = stack.AddrStack.Offset;
108  frame->size = frame->bp - frame->sp;
109  if (!rz_list_append(list, frame)) {
110  free(frame);
111  break;
112  }
113  }
114  w32_SymCleanup(wrap->pi.hProcess);
116  free(ctx);
117  return list;
118 }
119 
120 #undef DEF_PROC
121 #undef GET_PROC
RZ_API ut8 * rz_reg_arena_peek(RzReg *reg)
Definition: arena.c:280
#define NULL
Definition: cris-opc.c:27
#define IMAGE_FILE_MACHINE_ARM64
Definition: debug_windbg.c:20
RzDebug * dbg
Definition: desil.c:30
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
static void list(RzEgg *egg)
Definition: rz-gg.c:52
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API 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
#define TRUE
Definition: mybfd.h:103
RZ_API ut64 rz_reg_getv(RzReg *reg, const char *name)
Definition: reg.c:332
RZ_API const char * rz_reg_get_name(RzReg *reg, int role)
Definition: reg.c:147
@ RZ_REG_NAME_SP
Definition: rz_reg.h:44
@ RZ_REG_NAME_BP
Definition: rz_reg.h:46
@ RZ_REG_NAME_PC
Definition: rz_reg.h:43
#define RZ_NEW0(x)
Definition: rz_types.h:284
PROCESS_INFORMATION pi
Definition: w32dbg_wrap.h:40
RzReg * reg
Definition: rz_debug.h:286
void * plugin_data
Definition: rz_debug.h:296
Definition: z80asm.h:140
RZ_API void rz_th_lock_leave(RZ_NONNULL RzThreadLock *thl)
Releases a RzThreadLock structure.
Definition: thread_lock.c:75
RZ_API RZ_OWN RzThreadLock * rz_th_lock_new(bool recursive)
Allocates and initialize a RzThreadLock structure.
Definition: thread_lock.c:14
RZ_API void rz_th_lock_enter(RZ_NONNULL RzThreadLock *thl)
Acquires a RzThreadLock structure.
Definition: thread_lock.c:45
static void lock(volatile int *lk)
Definition: malloc.c:61
static int initialized
Definition: tricore-dis.c:96
static bool initialize_sym_api(void)
Definition: windows-all.c:48
BOOL __stdcall SymCleanup_t(_In_ HANDLE hProcess)
Definition: windows-all.c:20
BOOL __stdcall StackWalk64_t(_In_ DWORD MachineType, _In_ HANDLE hProcess, _In_ HANDLE hThread, _Inout_ LPSTACKFRAME64 StackFrame, _Inout_ PVOID ContextRecord, _In_opt_ PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, _In_opt_ PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, _In_opt_ PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, _In_opt_ PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress)
Definition: windows-all.c:31
static RzList * backtrace_windows(RzDebug *dbg, ut64 at)
Definition: windows-all.c:66
BOOL __stdcall SymInitialize_t(_In_ HANDLE hProcess, _In_opt_ PCSTR UserSearchPath, _In_ BOOL fInvadeProcess)
Definition: windows-all.c:15
DWORD64 __stdcall SymGetModuleBase64_t(_In_ HANDLE hProcess, _In_ DWORD64 qwAddr)
Definition: windows-all.c:27
#define DEF_PROC(proc)
Definition: windows-all.c:8
#define GET_PROC(proc)
Definition: windows-all.c:9
PVOID __stdcall SymFunctionTableAccess64_t(_In_ HANDLE hProcess, _In_ DWORD64 AddrBase)
Definition: windows-all.c:23
DWORD * HANDLE
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
PVOID
PCONTEXT DWORD64
DWORD