From 4db5cded34dac275bf069ccbf204fabbc03beee4 Mon Sep 17 00:00:00 2001 From: pancake Date: Wed, 17 Nov 2010 00:56:48 +0100 Subject: [PATCH] * Fix w32dist find command * Display TODO message in r2 -L * Implement rax2 -s - and rax2 - * Honor dbg->tid in many places * Implement basic stuff for dbg->reason - Only w32 and *nix atm - Not yet displayed or used - Added many new reason types in enum * Fix w32 register map * Handle attach:// in io_w32dbg plugin * Implement w32 process and thread list - You can now select the thread > dp # list pids > dp=1424 # attach to pid > dpt # list threads > dpt=580 # select thread * Added dummy code to list windows --- Makefile | 2 +- binr/radare2/radare2.c | 5 +- binr/rax2/rax2.c | 8 ++- doc/windows | 4 +- libr/core/cmd.c | 8 +-- libr/core/config.c | 5 +- libr/debug/debug.c | 10 ++- libr/debug/p/debug_native.c | 95 ++++++++++++++++++------- libr/debug/p/native/w32.c | 135 +++++++++++++++++++++++++++++++++--- libr/debug/reg.c | 2 +- libr/include/r_debug.h | 18 +++-- libr/include/r_types_base.h | 3 + libr/io/p/io_w32dbg.c | 2 + libr/util/t/argv.c | 3 +- libr/util/t/ralloc.c | 16 ++--- 15 files changed, 249 insertions(+), 67 deletions(-) diff --git a/Makefile b/Makefile index 9787f59589..748ab8002e 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ w32: w32dist: rm -rf radare2-w32-${VERSION} w32dist mkdir w32dist - for a in `find * | grep -e exe$$ -e dll$$`; do cp $$a w32dist ; done + for a in `find binr libr | grep -e exe$$ -e dll$$`; do cp $$a w32dist ; done rm w32dist/plugin.dll mv w32dist radare2-w32-${VERSION} zip -r radare2-w32-${VERSION}.zip radare2-w32-${VERSION} diff --git a/binr/radare2/radare2.c b/binr/radare2/radare2.c index 83b924d10d..dc56ac67b3 100644 --- a/binr/radare2/radare2.c +++ b/binr/radare2/radare2.c @@ -119,8 +119,9 @@ int main(int argc, char **argv) { seek = r_num_math (r.num, optarg); break; case 'L': + eprintf ("TODO: list IO plugins and handler only, not lib list\n"); r_lib_list (r.lib); - //r_io_plugin_list (&r.io); + //r_io_plugin_list (r.io); return 0; case 'u': eprintf ("TODO\n"); @@ -255,7 +256,7 @@ int main(int argc, char **argv) { if (debug) { if (r_cons_yesno ('y', "Do you want to quit? (Y/n)")) { if (r_cons_yesno ('y', "Do you want to kill the process? (Y/n)")) - r_debug_kill (r.dbg, 9); // KILL + r_debug_kill (r.dbg, R_FALSE, 9); // KILL } else continue; } const char *prj = r_config_get (r.config, "file.project"); diff --git a/binr/rax2/rax2.c b/binr/rax2/rax2.c index 19ff271d96..974e09a377 100644 --- a/binr/rax2/rax2.c +++ b/binr/rax2/rax2.c @@ -101,12 +101,16 @@ static int rax (char *str) { int use_stdin () { char buf[1024]; - while (!feof (stdin)) { fgets (buf, sizeof (buf)-1, stdin); if (feof (stdin)) break; buf[strlen (buf)-1] = '\0'; - if (!rax (buf)) break; + if (!flags) { + int i; + for (i=0; buf[i]; i++) + printf ("%02x", buf[i]); + printf ("\n"); + } else if (!rax (buf)) break; } return 0; } diff --git a/doc/windows b/doc/windows index 9efcbd0ffb..7c3cc67af2 100644 --- a/doc/windows +++ b/doc/windows @@ -9,7 +9,7 @@ Crosscompilation ArchLinux --------- - ./configure --without-gmp --without-openssl --with-compiler=i486-mingw32-gcc --with-ostype=windows --host=i486-unknown-windows + ./configure --without-gmp --with-compiler=i486-mingw32-gcc --with-ostype=windows --host=i486-unknown-windows make make w32dist @@ -26,7 +26,7 @@ Crosscompilation Ubuntu ------ sudo apt-get install mingw32 - ./configure --without-gmp --without-openssl --with-compiler=i586-mingw32msvc-gcc --with-ostype=windows --host=i586-unknown-windows + ./configure --without-gmp --with-compiler=i586-mingw32msvc-gcc --with-ostype=windows --host=i586-unknown-windows make make w32dist diff --git a/libr/core/cmd.c b/libr/core/cmd.c index dd71484625..5de0bde7dc 100644 --- a/libr/core/cmd.c +++ b/libr/core/cmd.c @@ -3742,13 +3742,12 @@ static void cmd_debug_pid(RCore *core, const char *input) { if (pid > 0) { eprintf ("Sending signal '%d' to pid '%d'\n", sig, pid); - r_debug_kill (core->dbg, sig); + r_debug_kill (core->dbg, R_FALSE, sig); } else eprintf ("Invalid arguments\n"); break; case 't': if (input[2]=='=' || input[2]==' ') - r_debug_select (core->dbg, - (int) r_num_math (core->num, input+3), + r_debug_select (core->dbg, core->dbg->pid, (int) r_num_math (core->num, input+3)); else r_debug_thread_list (core->dbg, core->dbg->pid); break; @@ -3776,8 +3775,7 @@ static void cmd_debug_pid(RCore *core, const char *input) { break; case '=': r_debug_select (core->dbg, - (int) r_num_math (core->num, input+2), - (int) r_num_math (core->num, input+2)); + (int) r_num_math (core->num, input+2), core->dbg->tid); break; case '*': r_debug_pid_list (core->dbg, 0); diff --git a/libr/core/config.c b/libr/core/config.c index f18e0ceab5..e02ab4f029 100644 --- a/libr/core/config.c +++ b/libr/core/config.c @@ -54,8 +54,9 @@ static int config_iocache_callback(void *user, void *data) { static int config_cfgdebug_callback(void *user, void *data) { RCore *core = (RCore*) user; RConfigNode *node = (RConfigNode*) data; - core->io->debug = node->i_value; - if (node->i_value) { + if (core && core->io) + core->io->debug = node->i_value; + if (core->dbg && node->i_value) { r_debug_use (core->dbg, r_config_get (core->config, "dbg.backend")); if (core->file) r_debug_select (core->dbg, core->file->fd, core->file->fd); diff --git a/libr/debug/debug.c b/libr/debug/debug.c index 7d5795a7da..41688339d6 100644 --- a/libr/debug/debug.c +++ b/libr/debug/debug.c @@ -15,6 +15,7 @@ static int r_debug_recoil(RDebug *dbg) { recoil = r_bp_recoil (dbg->bp, addr); eprintf ("Recoil at 0x%"PFMT64x" = %d\n", addr, recoil); if (recoil) { + dbg->reason = R_DBG_REASON_BP; r_reg_set_value (dbg->reg, ri, addr-recoil); r_debug_reg_sync (dbg, R_REG_TYPE_GPR, R_TRUE); ret = R_TRUE; @@ -31,6 +32,7 @@ R_API RDebug *r_debug_new(int hard) { dbg->tid = -1; dbg->swstep = 0; dbg->newstate = 0; + dbg->reason = R_DBG_REASON_UNKNOWN; dbg->stop_all_threads = R_FALSE; dbg->trace = r_debug_trace_new (); dbg->printf = (void *)printf; @@ -156,14 +158,16 @@ R_API int r_debug_stop_reason(RDebug *dbg) { // - illegal instruction // - fpu exception // return dbg->reason - return R_DBG_REASON_UNKNOWN; + return dbg->reason; } /* Returns PID */ R_API int r_debug_wait(RDebug *dbg) { int ret = 0; if (dbg && dbg->h && dbg->h->wait) { + dbg->reason = R_DBG_REASON_UNKNOWN; ret = dbg->h->wait (dbg->pid); + dbg->reason = ret; dbg->newstate = 1; eprintf ("wait = %d\n", ret); if (dbg->trace->enabled) @@ -345,10 +349,10 @@ R_API int r_debug_syscall(struct r_debug_t *dbg, int num) { return ret; } -R_API int r_debug_kill(struct r_debug_t *dbg, int sig) { +R_API int r_debug_kill(struct r_debug_t *dbg, boolt thread, int sig) { int ret = R_FALSE; if (dbg->h && dbg->h->kill) - ret = dbg->h->kill (dbg, sig); + ret = dbg->h->kill (dbg, thread, sig); else eprintf ("Backend does not implements kill()\n"); return ret; } diff --git a/libr/debug/p/debug_native.c b/libr/debug/p/debug_native.c index f61bc1acda..9aee9680d7 100644 --- a/libr/debug/p/debug_native.c +++ b/libr/debug/p/debug_native.c @@ -9,7 +9,7 @@ static int r_debug_native_continue(int pid, int sig); static int r_debug_native_reg_read(RDebug *dbg, int type, ut8 *buf, int size); -static int r_debug_native_reg_write(int pid, int type, const ut8* buf, int size); +static int r_debug_native_reg_write(int pid, int tid, int type, const ut8* buf, int size); #define DEBUGGER 1 #define MAXBT 128 @@ -143,7 +143,7 @@ static inline void debug_arch_x86_trap_set(RDebug *dbg, int foo) { eprintf ("trap flag: %d\n", (regs.__eflags&0x100)); if (foo) regs.__eflags |= EFLAGS_TRAP_FLAG; else regs.__eflags &= ~EFLAGS_TRAP_FLAG; - r_debug_native_reg_write (dbg, R_REG_TYPE_GPR, ®s, sizeof (regs)); + r_debug_native_reg_write (dbg->pid, dbg->tid, R_REG_TYPE_GPR, ®s, sizeof (regs)); #endif } #endif // __APPLE__ @@ -160,7 +160,7 @@ static int r_debug_native_step(RDebug *dbg, int pid) { /* up TRAP flag */ r_debug_native_reg_read (dbg, R_REG_TYPE_GPR, ®s, sizeof (regs)); regs.EFlags |= 0x100; - r_debug_native_reg_write (dbg, R_REG_TYPE_GPR, ®s, sizeof (regs)); + r_debug_native_reg_write (dbg->pid, dbg->tid, R_REG_TYPE_GPR, ®s, sizeof (regs)); //single_step = pid; r_debug_native_continue (pid, -1); #elif __APPLE__ @@ -270,6 +270,8 @@ static int r_debug_native_wait(int pid) { //printf ("prewait\n"); ret = waitpid (pid, &status, 0); //printf ("status=%d (return=%d)\n", status, ret); + // TODO: switch status and handle reasons here + status = R_DBG_REASON_UNKNOWN; return status; #endif } @@ -296,18 +298,21 @@ static const char *r_debug_native_reg_profile() { "seg fs .32 136 0\n" "seg es .32 140 0\n" "seg ds .32 144 0\n" - "gpr edi .32 148 0\n" - "gpr esi .32 152 0\n" - "gpr ebx .32 156 0\n" - "gpr edx .32 160 0\n" - "gpr ecx .32 164 0\n" - "gpr eax .32 168 0\n" - "gpr ebp .32 172 0\n" - "gpr eip .32 176 0\n" + "gpr edi .32 156 0\n" + "gpr esi .32 160 0\n" + "gpr ebx .32 164 0\n" + "gpr edx .32 168 0\n" + "gpr ecx .32 172 0\n" + "gpr eax .32 176 0\n" + "gpr ebp .32 180 0\n" + "gpr esp .32 196 0\n" + "gpr eip .32 184 0\n" "seg cs .32 184 0\n" - "gpr eflags .32 188 0 c1p.a.zstido.n.rv\n" // XXX must be flg - "seg esp .32 192 0\n" - "seg ss .32 196 0\n" + "seg ds .32 152 0\n" + "seg gs .32 140 0\n" + "seg fs .32 144 0\n" + "gpr eflags .32 192 0 c1p.a.zstido.n.rv\n" // XXX must be flg + "seg ss .32 200 0\n" /* +512 bytes for maximum supoprted extension extended registers */ ); #elif __POWERPC__ && __APPLE__ @@ -633,7 +638,7 @@ static RDebugPid *darwin_get_pid(int pid) { static RList *r_debug_native_pids(int pid) { RList *list = r_list_new (); #if __WINDOWS__ - eprintf ("pids: TODO\n"); + return w32_pids (pid, list); #elif __APPLE__ if (pid) { RDebugPid *p = darwin_get_pid (pid); @@ -708,7 +713,7 @@ static RList *r_debug_native_threads(int pid) { RList *list = r_list_new (); /* TODO */ #if __WINDOWS__ - eprintf ("pids: TODO\n"); + return w32_thread_list (pid, list); #elif __APPLE__ #if __arm__ #define OSX_PC state.r15 @@ -794,14 +799,33 @@ static RList *r_debug_native_threads(int pid) { static int r_debug_native_reg_read(RDebug *dbg, int type, ut8 *buf, int size) { int pid = dbg->pid; #if __WINDOWS__ - CONTEXT ctx; + CONTEXT ctx __attribute__ ((aligned (16))); ctx.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; - if (!GetThreadContext (tid2handler (pid), &ctx)) { + if (!GetThreadContext (tid2handler (dbg->pid, dbg->tid), &ctx)) { eprintf ("GetThreadContext: %x\n", (int)GetLastError()); return R_FALSE; } if (sizeof (CONTEXT) < size) size = sizeof (CONTEXT); +#if 0 +// TODO: fix missing regs deltas in profile (DRX+..) +#include +eprintf ("++ EAX = 0x%08x %d\n", ctx.Eax, r_offsetof (CONTEXT, Eax)); +eprintf ("++ EBX = 0x%08x %d\n", ctx.Ebx, r_offsetof (CONTEXT, Ebx)); +eprintf ("++ ECX = 0x%08x %d\n", ctx.Ecx, r_offsetof (CONTEXT, Ecx)); +eprintf ("++ EDX = 0x%08x %d\n", ctx.Edx, r_offsetof (CONTEXT, Edx)); +eprintf ("++ EIP = 0x%08x %d\n", ctx.Eip, r_offsetof (CONTEXT, Eip)); +eprintf ("++ EDI = 0x%08x %d\n", ctx.Edi, r_offsetof (CONTEXT, Edi)); +eprintf ("++ ESI = 0x%08x %d\n", ctx.Esi, r_offsetof (CONTEXT, Esi)); +eprintf ("++ ESP = 0x%08x %d\n", ctx.Esp, r_offsetof (CONTEXT, Esp)); +eprintf ("++ EBP = 0x%08x %d\n", ctx.Ebp, r_offsetof (CONTEXT, Ebp)); +eprintf ("++ CS = 0x%08x %d\n", ctx.SegCs, r_offsetof (CONTEXT, SegCs)); +eprintf ("++ DS = 0x%08x %d\n", ctx.SegDs, r_offsetof (CONTEXT, SegDs)); +eprintf ("++ GS = 0x%08x %d\n", ctx.SegGs, r_offsetof (CONTEXT, SegGs)); +eprintf ("++ FS = 0x%08x %d\n", ctx.SegFs, r_offsetof (CONTEXT, SegFs)); +eprintf ("++ SS = 0x%08x %d\n", ctx.SegSs, r_offsetof (CONTEXT, SegSs)); +eprintf ("++ EFL = 0x%08x %d\n", ctx.EFlags, r_offsetof (CONTEXT, EFlags)); +#endif memcpy (buf, &ctx, size); return size; // XXX this must be defined somewhere else @@ -893,11 +917,11 @@ static int r_debug_native_reg_read(RDebug *dbg, int type, ut8 *buf, int size) { #endif } -static int r_debug_native_reg_write(int pid, int type, const ut8* buf, int size) { +static int r_debug_native_reg_write(int pid, int tid, int type, const ut8* buf, int size) { // XXX use switch or so if (type == R_REG_TYPE_DRX) { #ifdef __FreeBSD__ - return (0 == ptrace (PTRACE_SETDBREGS, pid, buf, sizeof (struct dbreg))); + return (0 == ptrace (PTRACE_SETDBREGS, dbg->pid, buf, sizeof (struct dbreg))); #elif __linux__ { int i; @@ -918,7 +942,7 @@ static int r_debug_native_reg_write(int pid, int type, const ut8* buf, int size) #if __WINDOWS__ CONTEXT ctx; ctx.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; - return SetThreadContext (tid2handler (pid), &ctx)? 0: -1; + return SetThreadContext (tid2handler (pid, tid), &ctx)? 0: -1; #elif __linux__ || __sun || __NetBSD__ || __FreeBSD__ || __OpenBSD__ int ret = ptrace (PTRACE_SETREGS, pid, 0, buf); if (sizeof (R_DEBUG_REG_T) < size) @@ -1306,16 +1330,37 @@ static RList *r_debug_native_frames(RDebug *dbg) { } #endif -static int r_debug_native_kill(RDebug *dbg, int sig) { +// TODO: implement own-defined signals +static int r_debug_native_kill(RDebug *dbg, boolt thread, int sig) { #if __WINDOWS__ + // TODO: implement thread support signaling here HANDLE hProcess; // XXX +#if 0 + static uint WM_CLOSE = 0x10; + static bool CloseWindow(IntPtr hWnd) { + hWnd = FindWindowByCaption (0, "explorer"); + SendMessage(hWnd, WM_CLOSE, NULL, NULL); + CloseWindow(hWnd); + return true; + } +#endif TerminateProcess (hProcess, 1); return R_FALSE; #else int ret = R_FALSE; - if (dbg->pid>0 && (ret = kill (dbg->pid, sig))) { - if (ret != -1) - ret = R_TRUE; + if (thread) { +#if 0 +// XXX this is linux>2.5 specific..ugly + if (dbg->tid>0 && (ret = tgkill (dbg->pid, dbg->tid, sig))) { + if (ret != -1) + ret = R_TRUE; + } +#endif + } else { + if (dbg->pid>0 && (ret = kill (dbg->pid, sig))) { + if (ret != -1) + ret = R_TRUE; + } } return ret; #endif diff --git a/libr/debug/p/native/w32.c b/libr/debug/p/native/w32.c index 96ef545357..296d139abd 100644 --- a/libr/debug/p/native/w32.c +++ b/libr/debug/p/native/w32.c @@ -4,10 +4,47 @@ #include #include -static HANDLE tid2handler(int tid); +static HANDLE tid2handler(int pid, int tid); // XXX remove #define WIN32_PI(x) x +#if 0 +// list windows.. required to get list of windows for current pid and send kill signals +BOOL CALLBACK enumWindowsProc (HWND hwnd, LPARAM lParam) { + +DWORD procid; + +GetWindowThreadProcessId (hwnd, &procid); + +if ((HANDLE)procid == g_hProc) { staticchar module[1024]; +module[0] = 0; + +if (g_softPhoneTitle.Size() > 0) { int rc = GetWindowText (hwnd, module, 1023); +module[rc] = 0; + +} + +if (IsWindow(hwnd) && ((g_appTitle.Size() == 0) || (g_appTitle.EqualsNoCase(module)))) { +g_hWnd = hwnd; + +return (false); +} + +} + +return (true); +} + +int + +findApplicationWindow (void) { +g_hWnd = NULL; + +EnumWindows (enumWindowsProc, 0); + +return (0); +} +#endif #if 0 @@ -226,6 +263,7 @@ static int w32_dbg_wait(int pid) { DEBUG_EVENT de; int tid, next_event = 0; unsigned int code; + int ret = R_DBG_REASON_UNKNOWN; do { /* handle debug events */ @@ -254,33 +292,39 @@ static int w32_dbg_wait(int pid) { de.u.CreateProcessInfo.lpStartAddress); r_debug_native_continue (pid, -1); next_event = 1; + ret = R_DBG_REASON_NEW_PID; break; case EXIT_PROCESS_DEBUG_EVENT: eprintf ("\n\n______________[ process finished ]_______________\n\n"); //debug_load(); next_event = 0; + ret = R_DBG_REASON_EXIT_PID; break; case CREATE_THREAD_DEBUG_EVENT: eprintf ("(%d) created thread (0x%x)\n", pid, de.u.CreateThread.lpStartAddress); r_debug_native_continue (pid, -1); + ret = R_DBG_REASON_NEW_TID; next_event = 1; break; case EXIT_THREAD_DEBUG_EVENT: eprintf("EXIT_THREAD\n"); r_debug_native_continue (pid, -1); next_event = 1; + ret = R_DBG_REASON_EXIT_TID; break; case LOAD_DLL_DEBUG_EVENT: eprintf("(%d) Loading %s library at 0x%x\n", pid, "", de.u.LoadDll.lpBaseOfDll); r_debug_native_continue (pid, -1); next_event = 1; + ret = R_DBG_REASON_NEW_LIB; break; case UNLOAD_DLL_DEBUG_EVENT: eprintf ("UNLOAD_DLL\n"); r_debug_native_continue (pid, -1); next_event = 1; + ret = R_DBG_REASON_EXIT_LIB; break; case OUTPUT_DEBUG_STRING_EVENT: eprintf("OUTPUT_DBUG_STING\n"); @@ -291,10 +335,12 @@ static int w32_dbg_wait(int pid) { eprintf("RIP_EVENT\n"); r_debug_native_continue (pid, -1); next_event = 1; + // XXX unknown ret = R_DBG_REASON_TRAP; break; case EXCEPTION_DEBUG_EVENT: next_event = debug_exception_event ( de.u.Exception.ExceptionRecord.ExceptionCode); + ret = R_DBG_REASON_TRAP; break; default: eprintf ("Unknown event: %d\n", code); @@ -302,7 +348,7 @@ static int w32_dbg_wait(int pid) { } } while (next_event); - return 0; + return ret; } static inline int CheckValidPE(unsigned char * PeHeader) { @@ -428,8 +474,8 @@ static RList *w32_dbg_maps() { return list; } -static HANDLE tid2handler(int tid) { - HANDLE th = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD, tid); +static HANDLE tid2handler(int pid, int tid) { + HANDLE th = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD, pid); THREADENTRY32 te32 = { .dwSize = sizeof (THREADENTRY32) }; int ret = -1; if (th == INVALID_HANDLE_VALUE) @@ -439,12 +485,11 @@ static HANDLE tid2handler(int tid) { return NULL; } do { - if (te32.th32OwnerProcessID == tid) { - // if (te32.th32ThreadID == tid) { + if (te32.th32OwnerProcessID == pid && te32.th32ThreadID == tid) { + CloseHandle (th); return w32_openthread (THREAD_ALL_ACCESS, 0, te32.th32ThreadID); - // }{ - } + } ret++; } while (Thread32Next (th, &te32)); if (ret == -1) @@ -453,3 +498,77 @@ static HANDLE tid2handler(int tid) { return NULL; } +RList *w32_thread_list (int pid, RList *list) { + HANDLE th; + HANDLE thid; + THREADENTRY32 te32; + int ret; + + ret = -1; + te32.dwSize = sizeof(THREADENTRY32); + + if (w32_openthread == NULL) { + eprintf("w32_thread_list: no w32_openthread?\n"); + return list; + } + th = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, pid); + if(th == INVALID_HANDLE_VALUE || !Thread32First (th, &te32)) + goto err_load_th; + do { + /* get all threads of process */ + if (te32.th32OwnerProcessID == pid) { + //te32.dwFlags); + /* open a new handler */ + // XXX: fd leak? +#if 0 + 75 typedef struct tagTHREADENTRY32 { + 76 DWORD dwSize; + 77 DWORD cntUsage; + 78 DWORD th32ThreadID; + 79 DWORD th32OwnerProcessID; + 80 LONG tpBasePri; + 81 LONG tpDeltaPri; + 82 DWORD dwFlags; +#endif + thid = w32_openthread (THREAD_ALL_ACCESS, 0, te32.th32ThreadID); + if (thid == NULL) + goto err_load_th; + ret = te32.th32ThreadID; + //eprintf("Thread: %x %x\n", thid, te32.th32ThreadID); + r_list_append (list, r_debug_pid_new ("???", te32.th32ThreadID, 's', 0)); + } + } while (Thread32Next (th, &te32)); +err_load_th: + if(ret == -1) + print_lasterr ((char *)__FUNCTION__); + if(th != INVALID_HANDLE_VALUE) + CloseHandle (th); + return list; +} + +// XXX hacky +RList *w32_pids (int pid, RList *list) { + HANDLE th; + HANDLE thid; + THREADENTRY32 te32; + int ret = -1; + te32.dwSize = sizeof (THREADENTRY32); + if (w32_openthread == NULL) { + eprintf ("w32_thread_list: no w32_openthread?\n"); + return list; + } + th = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD, pid); + if(th == INVALID_HANDLE_VALUE || !Thread32First (th, &te32)) + goto err_load_th; + do { + if (ret != te32.th32OwnerProcessID) + r_list_append (list, r_debug_pid_new ("???", te32.th32OwnerProcessID, 's', 0)); + ret = te32.th32OwnerProcessID; + } while (Thread32Next (th, &te32)); +err_load_th: + if(ret == -1) + print_lasterr ((char *)__FUNCTION__); + if(th != INVALID_HANDLE_VALUE) + CloseHandle (th); + return list; +} diff --git a/libr/debug/reg.c b/libr/debug/reg.c index b60ce87840..478c590b83 100644 --- a/libr/debug/reg.c +++ b/libr/debug/reg.c @@ -11,7 +11,7 @@ R_API int r_debug_reg_sync(struct r_debug_t *dbg, int type, int write) { if (write) { if (dbg && dbg->h && dbg->h->reg_write) { ut8 *buf = r_reg_get_bytes (dbg->reg, type, &size); - if (!dbg->h->reg_write (dbg->pid, type, buf, sizeof (buf))) + if (!dbg->h->reg_write (dbg->pid, dbg->tid, type, buf, sizeof (buf))) eprintf ("r_debug_reg: error writing registers\n"); } else eprintf ("r_debug_reg: cannot set registers\n"); } else { diff --git a/libr/include/r_debug.h b/libr/include/r_debug.h index 4943d85e04..198464e997 100644 --- a/libr/include/r_debug.h +++ b/libr/include/r_debug.h @@ -29,14 +29,20 @@ enum { }; enum { // TODO: not yet used by r_debug - R_DBG_REASON_NEWPROC, + R_DBG_REASON_UNKNOWN, + R_DBG_REASON_NEW_PID, + R_DBG_REASON_NEW_TID, + R_DBG_REASON_NEW_LIB, + R_DBG_REASON_EXIT_PID, + R_DBG_REASON_EXIT_TID, + R_DBG_REASON_EXIT_LIB, R_DBG_REASON_TRAP, R_DBG_REASON_ILL, R_DBG_REASON_INT, R_DBG_REASON_SIGNAL, R_DBG_REASON_FPU, R_DBG_REASON_BP, - R_DBG_REASON_UNKNOWN, + R_DBG_REASON_DEAD }; /* TODO: move to r_anal */ @@ -82,6 +88,7 @@ typedef struct r_debug_t { int swstep; /* steps with software traps */ int steps; /* counter of steps done */ int newstate; + int reason; /* stop reason */ RDebugTrace *trace; int stop_all_threads; char *reg_profile; @@ -131,13 +138,14 @@ typedef struct r_debug_plugin_t { int (*step)(RDebug *dbg, int pid); // if step() is NULL; reimplement it with traps int (*cont)(int pid, int sig); int (*wait)(int pid); - int (*kill)(RDebug *dbg, int sig); + int (*kill)(RDebug *dbg, boolt thread, int sig); int (*contsc)(int pid, int sc); RList* (*frames)(RDebug *dbg); RBreakpointCallback breakpoint; +// XXX: specify, pid, tid, or RDebug ? int (*reg_read)(struct r_debug_t *dbg, int type, ut8 *buf, int size); + int (*reg_write)(int pid, int tid, int type, const ut8 *buf, int size); //XXX struct r_regset_t regs); char* (*reg_profile)(); - int (*reg_write)(int pid, int type, const ut8 *buf, int size); //XXX struct r_regset_t regs); /* memory */ RList *(*map_get)(RDebug *dbg); ut64 (*map_alloc)(RDebug *dbg, RDebugMap *map); @@ -186,7 +194,7 @@ R_API struct r_debug_t *r_debug_new(int hard); R_API struct r_debug_t *r_debug_free(struct r_debug_t *dbg); /* send signals */ -R_API int r_debug_kill(struct r_debug_t *dbg, int sig); +R_API int r_debug_kill(struct r_debug_t *dbg, boolt thread, int sig); // XXX: must be uint64 action R_API int r_debug_kill_setup(struct r_debug_t *dbg, int sig, int action); R_API int r_debug_step(struct r_debug_t *dbg, int steps); diff --git a/libr/include/r_types_base.h b/libr/include/r_types_base.h index 7088e73774..87732aa6dd 100644 --- a/libr/include/r_types_base.h +++ b/libr/include/r_types_base.h @@ -8,8 +8,11 @@ #define ut16 unsigned short #define ut8 unsigned char #define st8 char +typedef int boolt; +/* #undef boolt #define boolt int +*/ #define R_FAIL -1 #define R_FALSE 0 diff --git a/libr/io/p/io_w32dbg.c b/libr/io/p/io_w32dbg.c index fb1e8c9fec..53b97ddd8a 100644 --- a/libr/io/p/io_w32dbg.c +++ b/libr/io/p/io_w32dbg.c @@ -43,6 +43,8 @@ static int __write(struct r_io_t *io, int pid, const ut8 *buf, int len) { } static int __plugin_open(struct r_io_t *io, const char *file) { + if (!memcmp (file, "attach://", 9)) + return R_TRUE; return (!memcmp (file, "w32dbg://", 9))? R_TRUE: R_FALSE; } diff --git a/libr/util/t/argv.c b/libr/util/t/argv.c index 655ae7e547..8348e7aa48 100644 --- a/libr/util/t/argv.c +++ b/libr/util/t/argv.c @@ -9,11 +9,12 @@ static void test(const char *str) { r_str_argv_free (argv); } -main () { +int main () { test (" hello world "); test ("hello world"); test ("hello \"world\""); test ("'hello world'"); test ("/bin/ls -l 'food is pure bar' \"barra cow is low\""); test ("'hello' \"world\""); + return 0; } diff --git a/libr/util/t/ralloc.c b/libr/util/t/ralloc.c index 8c60097bdb..ace2aa02f5 100644 --- a/libr/util/t/ralloc.c +++ b/libr/util/t/ralloc.c @@ -1,4 +1,4 @@ -/* radare - LGPL - Copyright 2007-2009 pancake */ +/* radare - LGPL - Copyright 2007-2010 pancake */ /* simple example testing the r_alloca api */ #include @@ -6,8 +6,7 @@ #define TIMES 299999 -int afun(const char *str, int iters) -{ +int afun(const char *str, int iters) { int ret; char *ptr; if (iters == 0) return 0; @@ -17,8 +16,7 @@ int afun(const char *str, int iters) return afun(str, iters-1); } -int fun(const char *str, int iters) -{ +int fun(const char *str, int iters) { int ret; char *ptr; if (iters == 0) return 0; @@ -28,8 +26,7 @@ int fun(const char *str, int iters) } /* malloc */ -int mfun(const char *str, int iters) -{ +int mfun(const char *str, int iters) { int ret; char *ptr; if (iters == 0) return 0; @@ -39,10 +36,8 @@ int mfun(const char *str, int iters) return ret; } - /* main */ -int main() -{ +int main() { int i; printf("Running r_alloca performance test...\n"); fflush(stdout); @@ -68,4 +63,5 @@ int main() system("date"); fflush(stdout); + return 0; }