1 // Copyright (c) 2014-2017, The Lemon Man, All rights reserved. LGPLv3
2 
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 3.0 of the License, or (at your option) any later version.
7 
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library.
15 
16 #include <r_io.h>
17 #include <r_lib.h>
18 #include <r_socket.h>
19 #include <r_util.h>
20 #include <transport.h>
21 #include <winkd.h>
22 
__plugin_open(RIO * io,const char * file,bool many)23 static bool __plugin_open(RIO *io, const char *file, bool many) {
24 	return (!strncmp (file, "winkd://", 8));
25 }
26 
__open(RIO * io,const char * file,int rw,int mode)27 static RIODesc *__open(RIO *io, const char *file, int rw, int mode) {
28 	if (!__plugin_open (io, file, 0)) {
29 		return NULL;
30 	}
31 
32 	// net  - host:ip:key
33 	// pipe - \\.\pipe\com_1 /tmp/windbg.pipe
34 	io_backend_t *iob = NULL;
35 	if (strchr (file + 8, ':')) {
36 		iob = &iob_net;
37 	} else {
38 		iob = &iob_pipe;
39 	}
40 
41 	if (!iob) {
42 		eprintf ("Error: Invalid WinDBG path\n");
43 		return NULL;
44 	}
45 
46 	void *io_ctx = iob->open (file + 8);
47 	if (!io_ctx) {
48 		eprintf ("Error: Could not open the %s\n", iob->name);
49 		return NULL;
50 	}
51 	eprintf ("Opened %s %s with fd %p\n", iob->name, file + 8, io_ctx);
52 
53 	io_desc_t *desc = io_desc_new (iob, io_ctx);
54 	if (!desc) {
55 		eprintf ("Error: Could not create io_desc_t\n");
56 		return NULL;
57 	}
58 
59 	WindCtx *ctx = winkd_ctx_new (desc);
60 	if (!ctx) {
61 		eprintf ("Failed to initialize winkd context\n");
62 		return NULL;
63 	}
64 	return r_io_desc_new (io, &r_io_plugin_winkd, file, rw, mode, ctx);
65 }
66 
__write(RIO * io,RIODesc * fd,const ut8 * buf,int count)67 static int __write(RIO *io, RIODesc *fd, const ut8 *buf, int count) {
68 	if (!fd) {
69 		return -1;
70 	}
71 	if (winkd_get_target (fd->data)) {
72 		return winkd_write_at_uva (fd->data, buf, io->off, count);
73 	}
74 	return winkd_write_at (fd->data, buf, io->off, count);
75 }
76 
__lseek(RIO * io,RIODesc * fd,ut64 offset,int whence)77 static ut64 __lseek(RIO *io, RIODesc *fd, ut64 offset, int whence) {
78 	switch (whence) {
79 	case R_IO_SEEK_SET:
80 		return io->off = offset;
81 	case R_IO_SEEK_CUR:
82 		return io->off + offset;
83 	case R_IO_SEEK_END:
84 		return ST64_MAX;
85 	default:
86 		return offset;
87 	}
88 }
89 
__read(RIO * io,RIODesc * fd,ut8 * buf,int count)90 static int __read(RIO *io, RIODesc *fd, ut8 *buf, int count) {
91 	if (!fd) {
92 		return -1;
93 	}
94 
95 	if (winkd_get_target (fd->data)) {
96 		return winkd_read_at_uva (fd->data, buf, io->off, count);
97 	}
98 
99 	return winkd_read_at (fd->data, buf, io->off, count);
100 }
101 
__close(RIODesc * fd)102 static int __close(RIODesc *fd) {
103 	winkd_ctx_free ((WindCtx**)&fd->data);
104 	return true;
105 }
106 
107 RIOPlugin r_io_plugin_winkd = {
108 	.name = "winkd",
109 	.desc = "Attach to a KD debugger",
110 	.uris = "winkd://",
111 	.license = "LGPL3",
112 	.open = __open,
113 	.close = __close,
114 	.read = __read,
115 	.check = __plugin_open,
116 	.lseek = __lseek,
117 	.write = __write,
118 	.isdbg = true
119 };
120 
121 #ifndef R2_PLUGIN_INCORE
122 R_API RLibStruct radare_plugin = {
123 	.type = R_LIB_TYPE_IO,
124 	.data = &r_io_plugin_winkd,
125 	.version = R2_VERSION
126 };
127 #endif
128