mirror of
https://github.com/radareorg/radare2.git
synced 2024-10-08 19:33:31 +00:00
* Initial work on w32dbg IO, fork and attach still incomplete
- Not yet linked with debugger backend
This commit is contained in:
parent
64acd4eeae
commit
193bdb886d
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
125
libr/io/p/io_w32dbg.c
Normal 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
8
libr/io/p/w32dbg.mk
Normal 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}
|
@ -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__
|
||||
|
@ -26,6 +26,7 @@ crypto.aes
|
||||
debug.native
|
||||
io.debug
|
||||
io.mach
|
||||
io.w32dbg
|
||||
io.malloc
|
||||
io.ptrace
|
||||
parse.dummy
|
||||
|
Loading…
Reference in New Issue
Block a user