* Initial work on w32dbg IO, fork and attach still incomplete

- Not yet linked with debugger backend
This commit is contained in:
pancake 2010-04-14 23:56:27 +02:00
parent 64acd4eeae
commit 193bdb886d
9 changed files with 268 additions and 16 deletions

View File

@ -247,6 +247,7 @@ R_API int r_io_desc_generate(RIO *io);
/* plugins */
extern struct r_io_handle_t r_io_plugin_malloc;
extern struct r_io_handle_t r_io_plugin_ptrace;
extern struct r_io_handle_t r_io_plugin_w32dbg;
extern struct r_io_handle_t r_io_plugin_mach;
extern struct r_io_handle_t r_io_plugin_debug;
extern struct r_io_handle_t r_io_plugin_shm;

View File

@ -255,6 +255,7 @@ R_API int r_file_exist(const char *str);
R_API char *r_file_slurp_line(const char *file, int line, int context);
R_API ut64 r_sys_now();
R_API void r_sys_perror(const char *fun);
R_API int r_sys_mkdir(const char *dir);
R_API int r_sys_sleep(int secs);
R_API int r_sys_usleep(int usecs);

View File

@ -104,13 +104,12 @@ R_API int r_io_open(struct r_io_t *io, const char *file, int flags, int mode) {
r_io_desc_add (io, fd, file, flags, io->plugin);
} else fd = -1;
free((void *)uri);
free ((void *)uri);
return fd;
}
// TODO: Rename to use_fd ?
R_API int r_io_set_fd(struct r_io_t *io, int fd)
{
R_API int r_io_set_fd(struct r_io_t *io, int fd) {
if (fd != -1 && fd != io->fd) {
io->plugin = r_io_handle_resolve_fd (io, fd);
io->fd = fd;

View File

@ -5,7 +5,7 @@ include ../../config.mk
foo: all
ALL_TARGETS=
DEBUGS=ptrace.mk debug.mk malloc.mk shm.mk mach.mk
DEBUGS=ptrace.mk debug.mk malloc.mk shm.mk mach.mk w32dbg.mk
include ${DEBUGS}
#ALL_TARGETS+=io_ewf.so

View File

@ -4,13 +4,16 @@
#include <r_lib.h>
#include <r_util.h>
#if __linux__ || __NetBSD__ || __FreeBSD__ || __OpenBSD__ || __APPLE__ || __WINDOWS__
#if __linux__ || __NetBSD__ || __FreeBSD__ || __OpenBSD__ || __APPLE__
#define MAGIC_EXIT 31337
#include <signal.h>
#if __UNIX__
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#endif
static void inferior_abort_handler(int pid) {
eprintf ("Inferior received signal SIGABRT. Executing BKPT.\n");
@ -34,6 +37,124 @@ static void inferior_abort_handler(int pid) {
#endif
/*
* Creates a new process and returns the result:
* -1 : error
* 0 : ok
*/
#if __WINDOWS__
#include <windows.h>
#include <tlhelp32.h>
#include <winbase.h>
#include <psapi.h>
static int setup_tokens() {
HANDLE tok;
TOKEN_PRIVILEGES tp;
DWORD err;
tok = NULL;
err = -1;
if (!OpenProcessToken (GetCurrentProcess (), TOKEN_ADJUST_PRIVILEGES, &tok))
goto err_enable;
tp.PrivilegeCount = 1;
if (!LookupPrivilegeValue (NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid))
goto err_enable;
//tp.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
tp.Privileges[0].Attributes = 0; //SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges (tok, 0, &tp, sizeof (tp), NULL, NULL))
goto err_enable;
err = 0;
err_enable:
if (tok != NULL)
CloseHandle (tok);
if (err)
r_sys_perror ("setup_tokens");
return err;
}
static int fork_and_ptraceme(const char *cmd) {
PROCESS_INFORMATION pi;
STARTUPINFO si = { sizeof (si) };
DEBUG_EVENT de;
int pid, tid;
HANDLE h, th = INVALID_HANDLE_VALUE;
setup_tokens ();
/* TODO: with args */
if( !CreateProcess (cmd, NULL,
NULL, NULL, FALSE,
CREATE_NEW_CONSOLE | DEBUG_ONLY_THIS_PROCESS,
NULL, NULL, &si, &pi ) ) {
r_sys_perror ("CreateProcess");
return -1;
}
/* get process id and thread id */
pid = pi.dwProcessId;
tid = pi.dwThreadId;
/* load thread list */
{
THREADENTRY32 te32;
HANDLE WINAPI (*win32_openthread)(DWORD, BOOL, DWORD) = NULL;
win32_openthread = (HANDLE WINAPI (*)(DWORD, BOOL, DWORD))
GetProcAddress (GetModuleHandle ("kernel32"), "OpenThread");
th = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD, pid);
if (th == INVALID_HANDLE_VALUE || !Thread32First(th, &te32)) {
r_sys_perror ("CreateToolhelp32Snapshot");
}
do {
if (te32.th32OwnerProcessID == pid) {
h = win32_openthread (THREAD_ALL_ACCESS, 0, te32.th32ThreadID);
if (h == NULL) {
r_sys_perror ("OpenThread");
} else eprintf ("HANDLE=%p\n", h);
}
} while (Thread32Next (th, &te32));
}
#if 0
// Access denied here :?
if (ContinueDebugEvent (pid, tid, DBG_CONTINUE) == 0) {
r_sys_perror ("ContinueDebugEvent");
goto err_fork;
}
#endif
/* catch create process event */
if (!WaitForDebugEvent (&de, 10000))
goto err_fork;
/* check if is a create process debug event */
if (de.dwDebugEventCode != CREATE_PROCESS_DEBUG_EVENT) {
eprintf ("exception code %d\n",
de.dwDebugEventCode);
goto err_fork;
}
if (th != INVALID_HANDLE_VALUE)
CloseHandle (th);
eprintf ("PID=%d\n", pid);
eprintf ("TID=%d\n", tid);
return pid;
err_fork:
TerminateProcess (pi.hProcess, 1);
if (th != INVALID_HANDLE_VALUE)
CloseHandle (th);
return -1;
}
#else
static int __waitpid(int pid) {
int st = 0;
if (waitpid(pid, &st, 0) == -1)
@ -47,12 +168,6 @@ static int __waitpid(int pid) {
return R_TRUE;
}
/*
* Creates a new process and returns the result:
* -1 : error
* 0 : ok
*/
#define MAGIC_EXIT 31337
static int fork_and_ptraceme(const char *cmd) {
char **argv;
int status, pid = -1;
@ -94,9 +209,9 @@ static int fork_and_ptraceme(const char *cmd) {
break;
}
printf ("PID = %d\n", pid);
return pid;
}
#endif
static int __handle_open(struct r_io_t *io, const char *file) {
if (!memcmp (file, "dbg://", 6))
@ -112,13 +227,15 @@ static int __open(struct r_io_t *io, const char *file, int rw, int mode) {
pid = fork_and_ptraceme(file+6);
if (pid==-1)
return -1;
#if __APPLE__
#if __WINDOWS__
sprintf (uri, "w32dbg://%d", pid);
#elif __APPLE__
sprintf (uri, "mach://%d", pid);
#else
sprintf (uri, "ptrace://%d", pid);
#endif
r_io_redirect (io, uri);
return -1;
eprintf ("io_redirect: %s\n", uri);
return r_io_redirect (io, uri);
} else {
sprintf (uri, "attach://%d", pid);
r_io_redirect (io, uri);

125
libr/io/p/io_w32dbg.c Normal file
View File

@ -0,0 +1,125 @@
/* radare - LGPL - Copyright 2008-2010 pancake<nopcode.org> */
#include <r_userconf.h>
#include <r_io.h>
#include <r_lib.h>
#include <r_cons.h>
#if __WINDOWS__
#undef R_IO_NFDS
#define R_IO_NFDS 2
extern int errno;
static int fds[3];
#include <windows.h>
static PROCESS_INFORMATION pi;
// FIX: the goto 'err' is buggy
static int debug_os_read_at(int pid, void *buf, int len, ut64 addr) {
PDWORD ret;
ReadProcessMemory(pi.hProcess, (PCVOID)(ULONG)addr,
buf, len, &ret);
return (int)ret;
}
static int __read(struct r_io_t *io, int pid, ut8 *buf, int len) {
ut64 addr = io->off;
memset (buf, '\xff', len); // TODO: only memset the non-readed bytes
return debug_os_read_at (pid, buf, len, addr);
}
static int w32dbg_write_at(int pid, const ut8 *buf, int len, ut64 addr) {
PDWORD ret;
WriteProcessMemory (pi.hProcess, (PCVOID)(ULONG)addr,
buf, len, &ret);
return ret;
}
static int __write(struct r_io_t *io, int pid, const ut8 *buf, int len) {
return w32dbg_write_at(pid, buf, len, io->off);
}
static int __handle_open(struct r_io_t *io, const char *file) {
if (!memcmp (file, "w32dbg://", 9))
return R_TRUE;
return R_FALSE;
}
static int __attach (int pid) {
eprintf ("---> attach to %d\n", pid);
return pid;
}
static int __open(struct r_io_t *io, const char *file, int rw, int mode) {
int ret = -1;
if (__handle_open (io, file)) {
int pid = atoi (file+9);
ret = __attach (pid);
}
fds[0] = ret;
return ret;
}
static ut64 __lseek(struct r_io_t *io, int fildes, ut64 offset, int whence) {
return offset;
}
static int __close(struct r_io_t *io, int pid) {
// TODO: detach
return R_TRUE;
}
static int __system(struct r_io_t *io, int fd, const char *cmd) {
//printf("w32dbg io command (%s)\n", cmd);
/* XXX ugly hack for testing purposes */
if (!strcmp (cmd, "pid")) {
int pid = atoi (cmd+4);
if (pid != 0)
io->fd = pid;
//printf("PID=%d\n", io->fd);
return io->fd;
} else eprintf ("Try: '|pid'\n");
return R_TRUE;
}
static int __init(struct r_io_t *io) {
eprintf ("w32dbg init\n");
return R_TRUE;
}
// TODO: rename w32dbg to io_w32dbg .. err io.w32dbg ??
struct r_io_handle_t r_io_plugin_w32dbg = {
//void *handle;
.name = "io_w32dbg",
.desc = "w32dbg io",
.open = __open,
.close = __close,
.read = __read,
.handle_open = __handle_open,
.lseek = __lseek,
.system = __system,
.init = __init,
.write = __write,
//void *widget;
/*
struct debug_t *debug;
ut32 (*write)(int fd, const ut8 *buf, ut32 count);
int fds[R_IO_NFDS];
*/
};
#else
struct r_io_handle_t r_io_plugin_w32dbg = {
.name = "w32dbg",
.desc = "w32dbg io (NOT SUPPORTED FOR THIS PLATFORM)",
};
#endif
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_IO,
.data = &r_io_plugin_w32dbg
};
#endif

8
libr/io/p/w32dbg.mk Normal file
View File

@ -0,0 +1,8 @@
OBJ_W32DBG=io_w32dbg.o
STATIC_OBJ+=${OBJ_W32DBG}
TARGET_W32DBG=io_w32dbg.${EXT_SO}
ALL_TARGETS+=${TARGET_W32DBG}
${TARGET_W32DBG}: ${OBJ_W32DBG}
${CC} -shared ${CFLAGS} -o ${TARGET_W32DBG} ${OBJ_W32DBG}

View File

@ -208,7 +208,7 @@ R_API int r_sys_mkdir(const char *dir) {
return (ret != -1);
}
void r_sys_perror(const char *fun) {
R_API void r_sys_perror(const char *fun) {
#if __UNIX__
perror (fun);
#elif __WINDOWS__

View File

@ -26,6 +26,7 @@ crypto.aes
debug.native
io.debug
io.mach
io.w32dbg
io.malloc
io.ptrace
parse.dummy