mirror of
https://github.com/radareorg/radare2.git
synced 2025-03-03 19:59:09 +00:00
* Merge
This commit is contained in:
commit
e4edce88e1
8
configure
vendored
8
configure
vendored
@ -99,12 +99,12 @@ done
|
||||
: ${INSTALL_PROGRAM:=${INSTALL} -m 755 -s}
|
||||
: ${INSTALL_MAN:=${INSTALL} -m 444}
|
||||
: ${INSTALL_LIB:=${INSTALL} -c}
|
||||
PKGNAME='radare2' ; VERSION='0.4a' ; CONTACT_MAIL="pancake@nopcode.org" ; CONTACT_NAME="pancake" ; CONTACT="pancake <pancake@nopcode.org>" ;
|
||||
PKGNAME='radare2' ; VERSION='0.4b' ; CONTACT_MAIL="pancake@nopcode.org" ; CONTACT_NAME="pancake" ; CONTACT="pancake <pancake@nopcode.org>" ;
|
||||
}
|
||||
|
||||
show_usage() {
|
||||
cat <<EOF2
|
||||
'configure' configures radare2-0.4a to adapt to many kinds of systems.
|
||||
'configure' configures radare2-0.4b to adapt to many kinds of systems.
|
||||
|
||||
Usage: ./configure [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@ -171,7 +171,7 @@ take_environ() {
|
||||
}
|
||||
|
||||
show_version() {
|
||||
echo "radare2-0.4a configuration script done with acr v0.8.1.
|
||||
echo "radare2-0.4b configuration script done with acr v0.8.1.
|
||||
The 'Free Software Foundation' message is only for autodetection.
|
||||
Originally written by pancake <youterm.com>."
|
||||
exit 0
|
||||
@ -189,7 +189,7 @@ case $flag in
|
||||
show_version ; ;;
|
||||
"-r"|"--r"|"--report")
|
||||
echo "PKGNAME: radare2"
|
||||
echo "VERSION: 0.4a"
|
||||
echo "VERSION: 0.4b"
|
||||
echo "LANGS: c"
|
||||
echo "REQUIRED: libdl lib>=vala-1.0 libvala-1.0>=0.5.0"
|
||||
echo "OPTIONAL: libewf"
|
||||
|
@ -1,5 +1,5 @@
|
||||
PKGNAME radare2
|
||||
VERSION 0.4a
|
||||
VERSION 0.4b
|
||||
CONTACT pancake ; pancake@nopcode.org
|
||||
|
||||
LANG_C!
|
||||
|
@ -50,6 +50,13 @@ R_API RCons *r_cons_free (RCons *foo) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if __WINDOWS__
|
||||
static BOOL __w32_control(DWORD type) {
|
||||
if (type == CTRL_C_EVENT)
|
||||
break_signal (2); // SIGINT
|
||||
}
|
||||
#endif
|
||||
|
||||
R_API int r_cons_init() {
|
||||
I.is_interactive = R_TRUE;
|
||||
I.breaked = R_FALSE;
|
||||
@ -73,6 +80,8 @@ R_API int r_cons_init() {
|
||||
#elif __WINDOWS__
|
||||
GetConsoleMode (h, &I.term_buf);
|
||||
I.term_raw = 0;
|
||||
if (!SetConsoleCtrlHandler ((PHANDLER_ROUTINE)__w32_control, TRUE))
|
||||
eprintf ("r_cons: Cannot set control console handler\n");
|
||||
#endif
|
||||
//r_cons_palette_init(NULL);
|
||||
r_cons_reset ();
|
||||
|
@ -940,7 +940,7 @@ static void cmd_syscall_do(RCore *core, int num) {
|
||||
break;
|
||||
case 'z':
|
||||
{ char str[64];
|
||||
r_io_read_at (&core->io, arg, str, sizeof (str));
|
||||
r_io_read_at (&core->io, arg, (ut8*)str, sizeof (str));
|
||||
// TODO: filter zero terminated string
|
||||
str[63] = '\0';
|
||||
r_str_filter (str, strlen (str));
|
||||
@ -2142,6 +2142,7 @@ static void cmd_dm(RCore *core, const char *input) {
|
||||
" dm* Same as above but in radare commands\n"
|
||||
" dm 4096 Allocate 4096 bytes in child process\n"
|
||||
" dm-0x8048 Deallocate memory map of address 0x8048\n"
|
||||
//" dm rw- esp 9K set 9KB of the stack as read+write (no exec)\n"
|
||||
"TODO: map files in process memory.\n");
|
||||
break;
|
||||
case '*':
|
||||
@ -2208,6 +2209,7 @@ static int cmd_debug(void *data, const char *input) {
|
||||
pid = atoi (input);
|
||||
ptr = strchr (input, ' ');
|
||||
if (ptr) sig = atoi (ptr+1);
|
||||
else sig = 0;
|
||||
if (pid > 0) {
|
||||
eprintf ("Sending signal '%d' to pid '%d'\n",
|
||||
sig, pid);
|
||||
@ -2327,11 +2329,16 @@ static int cmd_debug(void *data, const char *input) {
|
||||
//r_core_cmd(core, "|reg", 0);
|
||||
break;
|
||||
case 'p':
|
||||
// TODO: Support PID and Thread
|
||||
if (input[1]=='?')
|
||||
r_cons_printf ("Usage: dp[=][pid]\n");
|
||||
else
|
||||
if (input[1]=='=')
|
||||
r_debug_select (&core->dbg, atoi (input+2), atoi (input+2));
|
||||
else
|
||||
if (input[1]==' ')
|
||||
r_debug_pid_list (&core->dbg, atoi (input+2));
|
||||
//r_debug_select(&core->dbg, core->dbg.pid, atoi(input+2));
|
||||
r_debug_select (&core->dbg, atoi(input+2), atoi(input+2));
|
||||
else eprintf ("TODO: List processes..\n");
|
||||
else r_debug_pid_list (&core->dbg, core->dbg.pid);
|
||||
break;
|
||||
case 'h':
|
||||
if (input[1]==' ')
|
||||
@ -2348,15 +2355,13 @@ static int cmd_debug(void *data, const char *input) {
|
||||
" do 3 perform 3 steps overs\n"
|
||||
" dsl step to next source line\n"
|
||||
" df show frames (backtrace)\n"
|
||||
" dp [pid] list or set pid\n"
|
||||
" dp[=?][pid] list, attach to process id\n"
|
||||
" dt [tid] select thread id\n"
|
||||
" dc[?] continue execution. dc? for more\n"
|
||||
" dr[?] cpu registers, dr? for extended help\n"
|
||||
" db[?] breakpoints\n"
|
||||
" dm show memory maps\n"
|
||||
" dm 4096 allocate 4KB in child process\n"
|
||||
" dm rw- esp 9K set 9KB of the stack as read+write (no exec)\n"
|
||||
" dk pid sig send signal to a process ID\n");
|
||||
" dk pid sig send signal to a process ID\n"
|
||||
" dm show memory maps\n");
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
@ -147,7 +147,7 @@ int main(int argc, char **argv) {
|
||||
if (debug) {
|
||||
r_core_cmd (&r, "e io.ffio=true", 0);
|
||||
r_core_cmd (&r, "dh native", 0);
|
||||
r_core_cmdf (&r, "dp %d", r.file->fd);
|
||||
r_core_cmdf (&r, "dp=%d", r.file->fd);
|
||||
r_core_cmd (&r, ".dr*", 0);
|
||||
r_core_cmd (&r, "s eip", 0);
|
||||
r_config_set (&r.config, "cmd.prompt", ".dr*");
|
||||
|
@ -7,12 +7,15 @@
|
||||
#include <r_lib.h>
|
||||
#include <signal.h>
|
||||
|
||||
static int r_debug_native_continue(int pid, int sig);
|
||||
|
||||
#define DEBUGGER 1
|
||||
#define MAXBT 128
|
||||
|
||||
#if __WINDOWS__
|
||||
#include <windows.h>
|
||||
#define R_DEBUG_REG_T CONTEXT
|
||||
#include "native/w32.c"
|
||||
|
||||
#elif __OpenBSD__ || __NetBSD__ || __FreeBSD__
|
||||
#define R_DEBUG_REG_T struct reg
|
||||
@ -127,9 +130,21 @@ static void debug_arch_x86_trap_set(int pid, int foo) {
|
||||
|
||||
static int r_debug_native_step(int pid) {
|
||||
int ret = R_FALSE;
|
||||
//R_DEBUG_REG_T regs;
|
||||
#if __WINDOWS__
|
||||
CONTEXT regs;
|
||||
|
||||
#if __APPLE__
|
||||
regs.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
|
||||
GetTheadContext (tid2hnd
|
||||
// XXX TODO CONTINUE h
|
||||
/* up TRAP flag */
|
||||
debug_getregs (ps.tid, ®s);
|
||||
GetThreadContext (tid2handler
|
||||
regs.EFlags |= 0x100;
|
||||
debug_setregs (ps.tid, ®s);
|
||||
single_step = ps.tid;
|
||||
r_deubg_native_continue (pid, -1);
|
||||
|
||||
#elif __APPLE__
|
||||
debug_arch_x86_trap_set (pid, 1);
|
||||
//eprintf ("stepping from pc = %08x\n", (ut32)get_offset("eip"));
|
||||
//ret = ptrace (PT_STEP, ps.tid, (caddr_t)get_offset("eip"), SIGSTOP);
|
||||
@ -154,23 +169,28 @@ static int r_debug_native_step(int pid) {
|
||||
}
|
||||
|
||||
static int r_debug_native_attach(int pid) {
|
||||
void *addr = 0;
|
||||
void *data = 0;
|
||||
#if __APPLE__
|
||||
int ret = ptrace (PT_ATTACH, pid, addr, data);
|
||||
int ret = -1;
|
||||
#if __WINDOWS__
|
||||
WIN32_PI (hProcess) = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
|
||||
if (WIN32_PI (hProcess) != (HANDLE)NULL && DebugActiveProcess (pid)) {
|
||||
w32_dbg_threads (pid);
|
||||
ret = 0;
|
||||
} else ret = -1;
|
||||
#elif __APPLE__
|
||||
ret = ptrace (PT_ATTACH, pid, 0, 0);
|
||||
#else
|
||||
int ret = ptrace (PTRACE_ATTACH, pid, addr, data);
|
||||
ret = ptrace (PTRACE_ATTACH, pid, 0, 0);
|
||||
#endif
|
||||
return (ret != -1)?R_TRUE:R_FALSE;
|
||||
}
|
||||
|
||||
static int r_debug_native_detach(int pid) {
|
||||
void *addr = 0;
|
||||
void *data = 0;
|
||||
#if __APPLE__
|
||||
return ptrace (PT_DETACH, pid, addr, data);
|
||||
#if __WINDOWS__
|
||||
return win32_detach (pid)? 0 : -1;
|
||||
#elif __APPLE__
|
||||
return ptrace (PT_DETACH, pid, NULL, NULL);
|
||||
#else
|
||||
return ptrace (PTRACE_DETACH, pid, addr, data);
|
||||
return ptrace (PTRACE_DETACH, pid, NULL, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -181,15 +201,23 @@ static int r_debug_native_continue_syscall(int pid, int num) {
|
||||
ut64 pc = 0LL; // XXX
|
||||
return ptrace (PTRACE_SYSCALL, pid, pc, 0);
|
||||
#else
|
||||
eprintf ("TODO: continue syscall not implemented yet\n");
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int r_debug_native_continue(int pid, int sig) {
|
||||
int tid = pid;
|
||||
void *data = NULL;
|
||||
if (sig != -1)
|
||||
data = (void*)(size_t)sig;
|
||||
#if __APPLE__
|
||||
#if __WINDOWS__
|
||||
if (ContinueDebugEvent (pid, tid, DBG_CONTINUE) == 0) {
|
||||
eprintf ("debug_contp: error\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
#elif __APPLE__
|
||||
eprintf ("debug_contp: program is now running...\n");
|
||||
|
||||
/* XXX */
|
||||
@ -208,17 +236,55 @@ static int r_debug_native_continue(int pid, int sig) {
|
||||
}
|
||||
|
||||
static int r_debug_native_wait(int pid) {
|
||||
#if __WINDOWS__
|
||||
return w32_dbg_wait (pid);
|
||||
#else
|
||||
int ret, status = -1;
|
||||
//printf ("prewait\n");
|
||||
ret = waitpid (pid, &status, 0);
|
||||
//printf ("status=%d (return=%d)\n", status, ret);
|
||||
return status;
|
||||
#endif
|
||||
}
|
||||
|
||||
// TODO: why strdup here?
|
||||
static const char *r_debug_native_reg_profile() {
|
||||
#if __POWERPC__ && __APPLE__
|
||||
return strdup(
|
||||
#if __WINDOWS__
|
||||
return strdup (
|
||||
"=pc eip\n"
|
||||
"=sp esp\n"
|
||||
"=bp ebp\n"
|
||||
"=a0 eax\n"
|
||||
"=a1 ebx\n"
|
||||
"=a2 ecx\n"
|
||||
"=a3 edi\n"
|
||||
"drx dr0 .32 4 0\n"
|
||||
"drx dr1 .32 8 0\n"
|
||||
"drx dr2 .32 12 0\n"
|
||||
"drx dr3 .32 16 0\n"
|
||||
"drx dr6 .32 20 0\n"
|
||||
"drx dr7 .32 24 0\n"
|
||||
/* floating save area 4+4+4+4+4+4+4+80+4 = 112 */
|
||||
"seg gs .32 136 0\n"
|
||||
"seg fs .32 140 0\n"
|
||||
"seg es .32 144 0\n"
|
||||
"seg ds .32 148 0\n"
|
||||
"gpr edi .32 152 0\n"
|
||||
"gpr esi .32 156 0\n"
|
||||
"gpr ebx .32 160 0\n"
|
||||
"gpr edx .32 164 0\n"
|
||||
"gpr ecx .32 168 0\n"
|
||||
"gpr eax .32 172 0\n"
|
||||
"gpr ebp .32 176 0\n"
|
||||
"gpr eip .32 180 0\n"
|
||||
"seg cs .32 184 0\n"
|
||||
"flg eflags .32 188 0\n"
|
||||
"seg esp .32 192 0\n"
|
||||
"seg ss .32 196 0\n"
|
||||
/* +512 bytes for maximum supoprted extension extended registers */
|
||||
);
|
||||
#elif __POWERPC__ && __APPLE__
|
||||
return strdup (
|
||||
"=pc srr0\n"
|
||||
"=sr srr1\n" // status register
|
||||
"=a0 r0\n"
|
||||
@ -274,7 +340,7 @@ static const char *r_debug_native_reg_profile() {
|
||||
"gpr vrsave .32 156 0\n"
|
||||
);
|
||||
#elif __i386__
|
||||
return strdup(
|
||||
return strdup (
|
||||
"=pc eip\n"
|
||||
"=sp esp\n"
|
||||
"=bp ebp\n"
|
||||
@ -395,17 +461,71 @@ static const char *r_debug_native_reg_profile() {
|
||||
"gpr r16 .32 64 0\n"
|
||||
"gpr r17 .32 68 0\n"
|
||||
);
|
||||
#endif
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static RList *r_debug_native_pids(int pid) {
|
||||
int i, j, fd;
|
||||
RDebugPid *p;
|
||||
char cmdline[1024];
|
||||
// TODO: new syntax: R_LIST (r_debug_pid_free)
|
||||
RList *list = r_list_new ();
|
||||
list->free = &r_debug_pid_free;
|
||||
/* TODO */
|
||||
#if __WINDOWS__
|
||||
eprintf ("pids: TODO\n");
|
||||
#elif __APPLE__
|
||||
eprintf ("pids: TODO\n");
|
||||
#else
|
||||
if (pid == 0) {
|
||||
i = 2;
|
||||
j = 99999;
|
||||
} else {
|
||||
i = pid;
|
||||
j = pid+1;
|
||||
}
|
||||
for (; i<j; i++) {
|
||||
if (kill (i, 0) == 0) {
|
||||
snprintf (cmdline, sizeof (cmdline), "/proc/%d/cmdline", i);
|
||||
fd = open (cmdline, O_RDONLY);
|
||||
cmdline[0] = '\0';
|
||||
if (fd != -1) {
|
||||
read (fd, cmdline, 1024);
|
||||
cmdline[1023] = '\0';
|
||||
close (fd);
|
||||
}
|
||||
p = r_debug_pid_new (cmdline, i, 's');
|
||||
r_list_append (list, p);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return list;
|
||||
}
|
||||
|
||||
static RList *r_debug_native_threads(int pid) {
|
||||
RList *list = r_list_new ();
|
||||
/* TODO */
|
||||
eprintf ("TODO\n");
|
||||
return list;
|
||||
}
|
||||
// TODO: what about float and hardware regs here ???
|
||||
// TODO: add flag for type
|
||||
static int r_debug_native_reg_read(RDebug *dbg, int type, ut8 *buf, int size) {
|
||||
int ret;
|
||||
int pid = dbg->pid;
|
||||
#if __WINDOWS__
|
||||
CONTEXT ctx;
|
||||
ctx.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
|
||||
if (!GetThreadContext (w32_t2h (pid), &ctx))
|
||||
return 0;
|
||||
if (sizeof (regs) < size)
|
||||
size = sizeof(regs);
|
||||
memcpy (buf, &ctx, size);
|
||||
return size;
|
||||
// XXX this must be defined somewhere else
|
||||
#if __APPLE__
|
||||
#elif __APPLE__
|
||||
thread_array_t inferior_threads = NULL;
|
||||
unsigned int inferior_thread_count = 0;
|
||||
R_DEBUG_REG_T *regs = (R_DEBUG_REG_T *)buf;
|
||||
@ -470,7 +590,11 @@ 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) {
|
||||
// XXX use switch or so
|
||||
if (type == R_REG_TYPE_GPR) {
|
||||
#if __linux__ || __sun || __NetBSD__ || __FreeBSD__ || __OpenBSD__
|
||||
#if __WINDOWS__
|
||||
CONTEXT ctx;
|
||||
ctx.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
|
||||
return SetThreadContext (w32_t2h (pid), &ctx)? 0: -1;
|
||||
#elif __linux__ || __sun || __NetBSD__ || __FreeBSD__ || __OpenBSD__
|
||||
int ret = ptrace (PTRACE_SETREGS, pid, 0, buf);
|
||||
if (sizeof (R_DEBUG_REG_T) < size)
|
||||
size = sizeof (R_DEBUG_REG_T);
|
||||
@ -485,6 +609,10 @@ static int r_debug_native_reg_write(int pid, int type, const ut8* buf, int size)
|
||||
static RList *r_debug_native_map_get(struct r_debug_t *dbg) {
|
||||
char path[1024];
|
||||
RList *list = NULL;
|
||||
#if __WINDOWS__
|
||||
list = w32_dbg_maps ();
|
||||
// TODO
|
||||
#else
|
||||
#if __sun
|
||||
/* TODO: On solaris parse /proc/%d/map */
|
||||
sprintf (path, "pmap %d > /dev/stderr", ps.tid);
|
||||
@ -584,6 +712,7 @@ static RList *r_debug_native_map_get(struct r_debug_t *dbg) {
|
||||
}
|
||||
fclose (fd);
|
||||
#endif // __sun
|
||||
#endif // __WINDOWS
|
||||
return list;
|
||||
}
|
||||
|
||||
@ -682,11 +811,14 @@ static RList *r_debug_native_frames(RDebug *dbg) {
|
||||
}
|
||||
#else
|
||||
#warning Backtrace frames not implemented for this platform
|
||||
static RList *r_debug_native_frames(RDebug *dbg) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int r_debug_native_kill(struct r_debug_t *dbg, int sig) {
|
||||
#if __WINDOWS__
|
||||
TerminateProcess (WIN32_PI(hProcess), 1);
|
||||
TerminateProcess (WIN32_PI (hProcess), 1);
|
||||
return R_FALSE;
|
||||
#else
|
||||
int ret = kill (dbg->pid, sig);
|
||||
@ -696,6 +828,14 @@ static int r_debug_native_kill(struct r_debug_t *dbg, int sig) {
|
||||
#endif
|
||||
}
|
||||
|
||||
static int r_debug_native_init(RDebug *dbg) {
|
||||
#if __WINDOWS__
|
||||
return w32_dbg_init ();
|
||||
#else
|
||||
return R_TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
struct r_debug_handle_t r_debug_plugin_native = {
|
||||
.name = "native",
|
||||
#if __i386__
|
||||
@ -716,11 +856,14 @@ struct r_debug_handle_t r_debug_plugin_native = {
|
||||
#else
|
||||
#warning food
|
||||
#endif
|
||||
.init = &r_debug_native_init,
|
||||
.step = &r_debug_native_step,
|
||||
.cont = &r_debug_native_continue,
|
||||
.contsc = &r_debug_native_continue_syscall,
|
||||
.attach = &r_debug_native_attach,
|
||||
.detach = &r_debug_native_detach,
|
||||
.pids = &r_debug_native_pids,
|
||||
.threads = &r_debug_native_threads,
|
||||
.wait = &r_debug_native_wait,
|
||||
.kill = &r_debug_native_kill,
|
||||
.frames = &r_debug_native_frames,
|
||||
|
363
libr/debug/p/native/w32.c
Normal file
363
libr/debug/p/native/w32.c
Normal file
@ -0,0 +1,363 @@
|
||||
#include <windows.h>
|
||||
#include <tlhelp32.h>
|
||||
#include <stdio.h>
|
||||
#include <winbase.h>
|
||||
#include <psapi.h>
|
||||
|
||||
#if 0
|
||||
|
||||
1860 typedef struct _FLOATING_SAVE_AREA {
|
||||
1861 DWORD ControlWord;
|
||||
1862 DWORD StatusWord;
|
||||
1863 DWORD TagWord;
|
||||
1864 DWORD ErrorOffset;
|
||||
|
||||
1865 DWORD ErrorSelector;
|
||||
1866 DWORD DataOffset;
|
||||
1867 DWORD DataSelector;
|
||||
1868 BYTE RegisterArea[80];
|
||||
1869 DWORD Cr0NpxState;
|
||||
1870 } FLOATING_SAVE_AREA;
|
||||
|
||||
1871 typedef struct _CONTEXT {
|
||||
1872 DWORD ContextFlags;
|
||||
1873 DWORD Dr0;
|
||||
1874 DWORD Dr1;
|
||||
1875 DWORD Dr2;
|
||||
1876 DWORD Dr3;
|
||||
1877 DWORD Dr6;
|
||||
1878 DWORD Dr7;
|
||||
1879 FLOATING_SAVE_AREA FloatSave;
|
||||
1880 DWORD SegGs;
|
||||
1881 DWORD SegFs;
|
||||
1882 DWORD SegEs;
|
||||
1883 DWORD SegDs;
|
||||
1884 DWORD Edi;
|
||||
1885 DWORD Esi;
|
||||
1886 DWORD Ebx;
|
||||
1887 DWORD Edx;
|
||||
1888 DWORD Ecx;
|
||||
1889 DWORD Eax;
|
||||
1890 DWORD Ebp;
|
||||
1891 DWORD Eip;
|
||||
1892 DWORD SegCs;
|
||||
1893 DWORD EFlags;
|
||||
1894 DWORD Esp;
|
||||
1895 DWORD SegSs;
|
||||
1896 BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];
|
||||
1897 } CONTEXT;
|
||||
#endif
|
||||
|
||||
BOOL WINAPI DebugActiveProcessStop(DWORD dwProcessId);
|
||||
static void (*gmbn)(HANDLE, HMODULE, LPTSTR, int) = NULL;
|
||||
static int (*gmi)(HANDLE, HMODULE, LPMODULEINFO, int) = NULL;
|
||||
static BOOL WINAPI (*w32_detach)(DWORD) = NULL;
|
||||
static HANDLE WINAPI (*w32_openthread)(DWORD, BOOL, DWORD) = NULL;
|
||||
static HANDLE WINAPI (*w32_dbgbreak)(HANDLE) = NULL;
|
||||
static DWORD WINAPI (*w32_getthreadid)(HANDLE) = NULL; // Vista
|
||||
static DWORD WINAPI (*w32_getprocessid)(HANDLE) = NULL; // XP
|
||||
|
||||
static void w32_dbg_init() {
|
||||
HANDLE lib;
|
||||
|
||||
w32_detach = (BOOL WINAPI (*)(DWORD))
|
||||
GetProcAddress (GetModuleHandle ("kernel32"),
|
||||
"DebugActiveProcessStop");
|
||||
w32_openthread = (HANDLE WINAPI (*)(DWORD, BOOL, DWORD))
|
||||
GetProcAddress (GetModuleHandle ("kernel32"), "OpenThread");
|
||||
w32_dbgbreak = (HANDLE WINAPI (*)(HANDLE))
|
||||
GetProcAddress (GetModuleHandle ("kernel32"),
|
||||
"DebugBreakProcess");
|
||||
// only windows vista :(
|
||||
w32_getthreadid = (DWORD WINAPI (*)(HANDLE))
|
||||
GetProcAddress (GetModuleHandle ("kernel32"), "GetThreadId");
|
||||
// from xp1
|
||||
w32_getprocessid = (DWORD WINAPI (*)(HANDLE))
|
||||
GetProcAddress (GetModuleHandle ("kernel32"), "GetProcessId");
|
||||
|
||||
lib = LoadLibrary("psapi.dll");
|
||||
if(lib == NULL) {
|
||||
eprintf ("Cannot load psapi.dll!!\n");
|
||||
exit (1);
|
||||
}
|
||||
gmbn = (void (*)(HANDLE, HMODULE, LPTSTR, int))
|
||||
GetProcAddress (lib, "GetModuleBaseNameA");
|
||||
gmi = (int (*)(HANDLE, HMODULE, LPMODULEINFO, int))
|
||||
GetProcAddress (lib, "GetModuleInformation");
|
||||
|
||||
if(w32_detach == NULL || w32_openthread == NULL || w32_dbgbreak == NULL ||
|
||||
gmbn == NULL || gmi == NULL) {
|
||||
// OOPS!
|
||||
eprintf("debug_init_calls:\n"
|
||||
"DebugActiveProcessStop: 0x%x\n"
|
||||
"OpenThread: 0x%x\n"
|
||||
"DebugBreakProcess: 0x%x\n"
|
||||
"GetThreadId: 0x%x\n",
|
||||
w32_detach, w32_openthread, w32_dbgbreak, w32_getthreadid);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
static HANDLE w32_t2h(pid_t tid) {
|
||||
TH_INFO *th = get_th (tid);
|
||||
if(th == NULL) {
|
||||
/* refresh thread list */
|
||||
w32_dbg_threads (tid);
|
||||
|
||||
/* try to search thread */
|
||||
if((th = get_th (tid)) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
return th->ht;
|
||||
}
|
||||
|
||||
inline static int w32_h2t(HANDLE h) {
|
||||
if (win32_getthreadid != NULL) // >= Windows Vista
|
||||
return win32_getthreadid (h);
|
||||
return ps.tid;
|
||||
if (win32_getprocessid != NULL) // >= Windows XP1
|
||||
return win32_getprocessid (h);
|
||||
return (int)h; // XXX broken
|
||||
}
|
||||
|
||||
static inline int w32_h2p(HANDLE h) {
|
||||
return GetProcessId (h);
|
||||
}
|
||||
|
||||
// TODO: not yet used !!!
|
||||
static int w32_dbg_threads(int pid) {
|
||||
HANDLE th;
|
||||
THREADENTRY32 te32;
|
||||
TH_INFO *th_i;
|
||||
int ret = -1;
|
||||
te32.dwSize = sizeof (THREADENTRY32);
|
||||
|
||||
th = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD, ps.pid);
|
||||
if (th == INVALID_HANDLE_VALUE || !Thread32First(th, &te32))
|
||||
goto err_load_th;
|
||||
|
||||
//free_th ();
|
||||
do {
|
||||
/* get all threads of process */
|
||||
if (e32.th32OwnerProcessID == pid) {
|
||||
const char *path = "unk";
|
||||
RDebugPid *pid = r_debug_pid_new (
|
||||
path, te32.th32ThreadID, 's');
|
||||
eprintf ("THREAD: id=0x%08x flags=0x%08x\n",
|
||||
te32.th32ThreadID, te32.dwFlags);
|
||||
eprintf ("HANDLER: 0x%p\n", win32_openthread (
|
||||
THREAD_ALL_ACCESS, 0, te32.th32ThreadID));
|
||||
/* open a new handler */
|
||||
//th_i->ht = win32_openthread(THREAD_ALL_ACCESS, 0,
|
||||
// te32.th32ThreadID);
|
||||
ret = te32.th32ThreadID;
|
||||
//r_list_append (list, thread);
|
||||
}
|
||||
} while (Thread32Next (th, &te32));
|
||||
|
||||
err_load_th:
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
//print_lasterr((char *)__FUNCTION__);
|
||||
|
||||
if (th != INVALID_HANDLE_VALUE)
|
||||
CloseHandle (th);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int w32_dbg_wait(int pid) {
|
||||
DEBUG_EVENT de;
|
||||
int next_event = 0;
|
||||
unsigned int code;
|
||||
|
||||
do {
|
||||
exit_wait = 0;
|
||||
|
||||
/* handle debug events */
|
||||
if (WaitForDebugEvent (&de, INFINITE) == 0) {
|
||||
print_lasterr ((char *)__FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
/* save thread id */
|
||||
ps.tid = de.dwThreadId;
|
||||
/* save registers */
|
||||
debug_getregs (ps.tid, &WS (regs));
|
||||
/* get exception code */
|
||||
code = de.dwDebugEventCode;
|
||||
/* Ctrl-C? */
|
||||
if (exit_wait == 1 && code == 0x2) {
|
||||
WS(event) = INT_EVENT;
|
||||
break;
|
||||
}
|
||||
/* set state */
|
||||
WS(event) = UNKNOWN_EVENT;
|
||||
/* get kind of event */
|
||||
switch (code) {
|
||||
case CREATE_PROCESS_DEBUG_EVENT:
|
||||
eprintf ("(%d) created process (%d:0x%x)\n",
|
||||
pid, w32_h2t (de.u.CreateProcessInfo.
|
||||
hProcess),
|
||||
de.u.CreateProcessInfo.lpStartAddress);
|
||||
r_debug_native_continue (pid, -1);
|
||||
next_event = 1;
|
||||
break;
|
||||
case EXIT_PROCESS_DEBUG_EVENT:
|
||||
eprintf ("\n\n______________[ process finished ]_______________\n\n");
|
||||
//debug_load();
|
||||
next_event = 0;
|
||||
break;
|
||||
case CREATE_THREAD_DEBUG_EVENT:
|
||||
eprintf ("(%d) created thread (0x%x)\n",
|
||||
pid, de.u.CreateThread.lpStartAddress);
|
||||
r_debug_native_continue (pid, -1);
|
||||
next_event = 1;
|
||||
break;
|
||||
case EXIT_THREAD_DEBUG_EVENT:
|
||||
eprintf("EXIT_THREAD\n");
|
||||
r_debug_native_continue (pid, -1);
|
||||
next_event = 1;
|
||||
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;
|
||||
break;
|
||||
case UNLOAD_DLL_DEBUG_EVENT:
|
||||
eprintf ("UNLOAD_DLL\n");
|
||||
r_debug_native_continue (pid, -1);
|
||||
next_event = 1;
|
||||
break;
|
||||
case OUTPUT_DEBUG_STRING_EVENT:
|
||||
eprintf("OUTPUT_DBUG_STING\n");
|
||||
r_debug_native_continue (pid, -1);
|
||||
next_event = 1;
|
||||
break;
|
||||
case RIP_EVENT:
|
||||
eprintf("RIP_EVENT\n");
|
||||
r_debug_native_continue (pid, -1);
|
||||
next_event = 1;
|
||||
break;
|
||||
case EXCEPTION_DEBUG_EVENT:
|
||||
next_event = debug_exception_event (
|
||||
de.u.Exception.ExceptionRecord.ExceptionCode);
|
||||
break;
|
||||
default:
|
||||
eprintf ("Unknown event: %d\n", code);
|
||||
return -1;
|
||||
}
|
||||
} while (next_event);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static RList *w32_dbg_maps() {
|
||||
RList *list;
|
||||
SYSTEM_INFO SysInfo;
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
LPBYTE page;
|
||||
char *mapname = NULL;
|
||||
/* DEPRECATED */
|
||||
char PeHeader[1024];
|
||||
MODULEINFO ModInfo;
|
||||
IMAGE_DOS_HEADER *dos_header;
|
||||
IMAGE_NT_HEADERS *nt_headers;
|
||||
IMAGE_SECTION_HEADER *SectionHeader;
|
||||
int NumSections, i;
|
||||
DWORD ret_len;
|
||||
RDebugMap *mr;
|
||||
|
||||
list = r_list_new ();
|
||||
|
||||
memset (&SysInfo, 0, sizeof (SysInfo));
|
||||
GetSystemInfo (&SysInfo); // TODO: check return value
|
||||
if (gmi == NULL) {
|
||||
eprintf ("w32dbg: no gmi\n");
|
||||
return 0;
|
||||
}
|
||||
if (gmbn == NULL) {
|
||||
eprintf ("w32dbg: no gmn\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (page=(LPBYTE)SysInfo.lpMinimumApplicationAddress;
|
||||
page<(LPBYTE)SysInfo.lpMaximumApplicationAddress;) {
|
||||
if (!VirtualQueryEx (WIN32_PI (hProcess), page, &mbi, sizeof (mbi))) {
|
||||
eprintf ("VirtualQueryEx ERROR, address = 0x%08X\n", page );
|
||||
return -1;
|
||||
}
|
||||
if (mbi.Type == MEM_IMAGE) {
|
||||
ReadProcessMemory (WIN32_PI (hProcess), (const void *)page,
|
||||
(LPVOID)PeHeader, sizeof (PeHeader), &ret_len);
|
||||
|
||||
if (ret_len == sizeof (PeHeader) && CheckValidPE (PeHeader)) {
|
||||
dos_header = (IMAGE_DOS_HEADER *)PeHeader;
|
||||
if (dos_header == NULL)
|
||||
break;
|
||||
nt_headers = (IMAGE_NT_HEADERS *)((char *)dos_header
|
||||
+ dos_header->e_lfanew);
|
||||
if (nt_headers == NULL) {
|
||||
/* skip before failing */
|
||||
break;
|
||||
}
|
||||
NumSections = nt_headers->FileHeader.NumberOfSections;
|
||||
SectionHeader = (IMAGE_SECTION_HEADER *) ((char *)nt_headers
|
||||
+ sizeof(IMAGE_NT_HEADERS));
|
||||
if(NumSections > 0) {
|
||||
mapname = (char *)malloc(MAX_PATH);
|
||||
if (!mapname) {
|
||||
perror (":map_reg alloc");
|
||||
return -1;
|
||||
}
|
||||
gmbn (WIN32_PI(hProcess), (HMODULE) page,
|
||||
(LPTSTR)mapname, MAX_PATH);
|
||||
|
||||
for (i=0; i<NumSections; i++) {
|
||||
mr = r_debug_map_new (mapname,
|
||||
SectionHeader->VirtualAddress + page,
|
||||
SectionHeader->VirtualAddress + page
|
||||
+ SectionHeader->Misc.VirtualSize,
|
||||
SectionHeader->Characteristics, // XXX?
|
||||
0);
|
||||
if(mr == NULL)
|
||||
return -1;
|
||||
r_list_append (list, mr);
|
||||
SectionHeader++;
|
||||
}
|
||||
free (mapname);
|
||||
}
|
||||
} else {
|
||||
eprintf ("Invalid read\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (gmi (WIN32_PI (hProcess), (HMODULE) page,
|
||||
(LPMODULEINFO) &ModInfo, sizeof(MODULEINFO)) == 0)
|
||||
return 0;
|
||||
/* THIS CODE SEGFAULTS WITH NO REASON. BYPASS IT! */
|
||||
#if 0
|
||||
eprintf("--> 0x%08x\n", ModInfo.lpBaseOfDll);
|
||||
eprintf("sz> 0x%08x\n", ModInfo.SizeOfImage);
|
||||
eprintf("rs> 0x%08x\n", mbi.RegionSize);
|
||||
/* avoid infinite loops */
|
||||
// if (ModInfo.SizeOfImage == 0)
|
||||
// return 0;
|
||||
// page += ModInfo.SizeOfImage;
|
||||
#endif
|
||||
page += mbi.RegionSize;
|
||||
} else {
|
||||
mr = r_debug_map_new ("unk", page, page+mbi.RegionSize, mbi.Protect, 0);
|
||||
if (mr == NULL) {
|
||||
eprintf ("Cannot create r_debug_map_new\n");
|
||||
// XXX leak
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r_list_apend (list, mr);
|
||||
page += mbi.RegionSize;
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
#endif
|
@ -1,11 +1,37 @@
|
||||
/* radare - LGPL - Copyright 2009 pancake<nopcode.org> */
|
||||
/* radare - LGPL - Copyright 2009-2010 pancake<nopcode.org> */
|
||||
|
||||
#include <r_debug.h>
|
||||
|
||||
R_API int r_debug_pid_list(struct r_debug_t *dbg)
|
||||
{
|
||||
//int count = 0;
|
||||
return 0;
|
||||
R_API RDebugPid *r_debug_pid_new(char *path, int pid, char status) {
|
||||
RDebugPid *p = R_NEW (RDebugPid);
|
||||
p->path = strdup (path);
|
||||
p->pid = pid;
|
||||
p->status = status;
|
||||
p->runnable = R_TRUE;
|
||||
return p;
|
||||
}
|
||||
|
||||
R_API RDebugPid *r_debug_pid_free(RDebugPid *pid) {
|
||||
//free (pid->path);
|
||||
//free (pid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
R_API int r_debug_pid_list(struct r_debug_t *dbg, int pid) {
|
||||
RList *list;
|
||||
RListIter *iter;
|
||||
if (dbg && dbg->h && dbg->h->pids) {
|
||||
list = dbg->h->pids (pid);
|
||||
if (list == NULL)
|
||||
return R_FALSE;
|
||||
iter = r_list_iterator (list);
|
||||
while (r_list_iter_next (iter)) {
|
||||
RDebugPid *p = r_list_iter_get (iter);
|
||||
eprintf (" %d %c %s\n", p->pid, p->status, p->path);
|
||||
}
|
||||
r_list_free (list);
|
||||
}
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
/* processes */
|
||||
@ -14,6 +40,7 @@ R_API int r_debug_pid_parent(RDebugPid *pid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
R_API int r_debug_pid_del(struct r_debug_t *dbg) {
|
||||
// kill da child
|
||||
return R_TRUE;
|
||||
@ -29,6 +56,7 @@ R_API int r_debug_pid_del_thread(struct r_debug_t *dbg) {
|
||||
// kill a thread in process
|
||||
return R_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* status */
|
||||
R_API int r_debug_pid_set_state(struct r_debug_t *dbg, int status) {
|
||||
|
@ -37,10 +37,8 @@ R_API int r_debug_reg_list(struct r_debug_t *dbg, int type, int size, int rad) {
|
||||
fmt2 = "%4s 0x%08llx%s";
|
||||
cols = 4;
|
||||
}
|
||||
//printf("list type=%d size=%d\n", type, size);
|
||||
list_for_each (pos, head) {
|
||||
struct r_reg_item_t *item = list_entry (pos, struct r_reg_item_t, list);
|
||||
//printf("--> t=%d\n", item->type);
|
||||
if (type != -1 && type != item->type)
|
||||
continue;
|
||||
if (size != 0 && size != item->size)
|
||||
@ -54,7 +52,7 @@ R_API int r_debug_reg_list(struct r_debug_t *dbg, int type, int size, int rad) {
|
||||
else dbg->printf (fmt, item->name, r_reg_get_value (dbg->reg, item));
|
||||
n++;
|
||||
}
|
||||
if (n>0 && rad==2 && (!(n+1)%cols))
|
||||
if (n>0 && rad==2 && (!((n+1)%cols)))
|
||||
dbg->printf ("\n");
|
||||
return n;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <r_syscall.h>
|
||||
#include "list.h"
|
||||
|
||||
// TODO Use chars!! 's' 'r' 'S' 'z' ??
|
||||
enum {
|
||||
R_DBG_PROC_STOP,
|
||||
R_DBG_PROC_RUN,
|
||||
@ -77,6 +78,8 @@ typedef struct r_debug_handle_t {
|
||||
int (*attach)(int pid);
|
||||
int (*detach)(int pid);
|
||||
int (*select)(int pid, int tid);
|
||||
RList *(*threads)(int pid);
|
||||
RList *(*pids)(int pid);
|
||||
RFList (*backtrace)(int count);
|
||||
/* flow */
|
||||
int (*step)(int pid); // if step() is NULL; reimplement it with traps
|
||||
@ -94,13 +97,14 @@ typedef struct r_debug_handle_t {
|
||||
RList *(*map_get)(RDebug *dbg);
|
||||
ut64 (*map_alloc)(RDebug *dbg, RDebugMap *map);
|
||||
int (*map_dealloc)(RDebug *dbg, ut64 addr);
|
||||
int (*init)(RDebug *dbg);
|
||||
struct list_head list;
|
||||
} RDebugHandle;
|
||||
|
||||
// TODO: rename to r_debug_process_t ? maybe a thread too ?
|
||||
typedef struct r_debug_pid_t {
|
||||
int pid;
|
||||
int status; /* stopped, running, zombie, sleeping ,... */
|
||||
char status; /* stopped, running, zombie, sleeping ,... */
|
||||
int runnable; /* when using 'run', 'continue', .. this proc will be runnable */
|
||||
const char *path;
|
||||
//struct list_head threads;
|
||||
@ -123,6 +127,9 @@ R_API int r_debug_pid_add(struct r_debug_t *dbg);
|
||||
R_API int r_debug_pid_add_thread(struct r_debug_t *dbg);
|
||||
R_API int r_debug_pid_del(struct r_debug_t *dbg);
|
||||
R_API int r_debug_pid_del_thread(struct r_debug_t *dbg);
|
||||
R_API RDebugPid *r_debug_pid_free(RDebugPid *pid);
|
||||
R_API int r_debug_pid_list(struct r_debug_t *dbg, int pid);
|
||||
R_API RDebugPid *r_debug_pid_new(char *path, int pid, char status);
|
||||
|
||||
R_API int r_debug_use(struct r_debug_t *dbg, const char *str);
|
||||
R_API int r_debug_handle_add(struct r_debug_t *dbg, struct r_debug_handle_t *foo);
|
||||
|
@ -21,7 +21,7 @@ typedef struct r_list_t {
|
||||
#define r_list_iterator(x) x->head
|
||||
#define r_list_iter_free(x) free(x)
|
||||
#define r_list_item_free(x) free(x)
|
||||
#define r_list_free(x) free(x)
|
||||
#define r_list_free(x) if(x&&x->free)x->free(x);free(x)
|
||||
#define r_list_empty(x) (x->head==NULL && x->tail==NULL)
|
||||
#define r_list_head(x) x->head
|
||||
#define r_list_tail(x) x->tail
|
||||
|
@ -54,8 +54,7 @@ R_API struct r_socket_proc_t *r_socket_proc_open(char *const argv[])
|
||||
#endif
|
||||
}
|
||||
|
||||
R_API int r_socket_proc_close(struct r_socket_proc_t *sp)
|
||||
{
|
||||
R_API int r_socket_proc_close(struct r_socket_proc_t *sp) {
|
||||
#if __UNIX__
|
||||
/* this is wrong */
|
||||
kill(sp->pid, 9);
|
||||
|
Loading…
x
Reference in New Issue
Block a user