qira/ida/template.cpp

186 lines
4.4 KiB
C++
Raw Normal View History

2014-06-26 14:52:25 -07:00
#include <ida.hpp>
#include <idp.hpp>
#include <loader.hpp>
2014-07-06 12:36:57 +09:00
#include <bytes.hpp>
2014-06-26 14:52:25 -07:00
2014-07-18 20:01:39 -07:00
//#define DEBUG
2014-06-26 14:52:25 -07:00
// ***************** WEBSOCKETS *******************
#include <libwebsockets.h>
static int callback_http(struct libwebsocket_context* context,
struct libwebsocket* wsi,
enum libwebsocket_callback_reasons reason, void* user,
void* in, size_t len) {
return 0;
}
static void thread_safe_jump_to(ea_t a) {
struct uireq_jumpto_t: public ui_request_t {
uireq_jumpto_t(ea_t a) {
la = a;
}
virtual bool idaapi run() {
jumpto(la);
return false;
}
ea_t la;
};
execute_ui_requests(new uireq_jumpto_t(a), NULL);
}
struct libwebsocket* gwsi = NULL;
static int callback_qira(struct libwebsocket_context* context,
struct libwebsocket* wsi,
enum libwebsocket_callback_reasons reason, void* user,
void* in, size_t len) {
//msg("QIRA CALLBACK: %d\n", reason);
switch(reason) {
case LWS_CALLBACK_ESTABLISHED:
// we only support one client
gwsi = wsi;
2014-07-02 11:31:15 -07:00
msg("QIRA web connected\n");
2014-06-26 14:52:25 -07:00
break;
case LWS_CALLBACK_RECEIVE:
#ifdef DEBUG
2014-07-06 11:46:39 +09:00
msg("QIRARX:%s\n", (char *)in);
2014-06-26 14:52:25 -07:00
#endif
2014-07-06 11:46:39 +09:00
if (memcmp(in, "setaddress ", sizeof("setaddress ")-1) == 0) {
ea_t addr = atoi((char*)in+sizeof("setaddress ")-1);
2014-06-26 14:52:25 -07:00
thread_safe_jump_to(addr);
}
break;
2014-07-06 11:46:39 +09:00
default:
break;
2014-06-26 14:52:25 -07:00
}
return 0;
}
static void ws_send(char *str) {
#ifdef DEBUG
msg("QIRATX:%s\n", str);
#endif
int len = strlen(str);
unsigned char *buf = (unsigned char*)
malloc(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING);
memcpy(&buf[LWS_SEND_BUFFER_PRE_PADDING], str, len);
if (gwsi != NULL) {
libwebsocket_write(gwsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], len, LWS_WRITE_TEXT);
}
free(buf);
}
// ***************** IDAPLUGIN *******************
2014-07-06 12:36:57 +09:00
static void update_address(const char *type, ea_t addr) {
2014-06-26 14:52:25 -07:00
//msg("addr 0x%x\n", addr);
char tmp[100];
2014-07-18 16:02:51 -07:00
#ifdef __EA64__
qsnprintf(tmp, 100-1, "set%s %llu", type, addr);
#else
qsnprintf(tmp, 100-1, "set%s %u", type, addr);
#endif
2014-06-26 14:52:25 -07:00
ws_send(tmp);
}
2014-07-21 03:20:28 -07:00
static int idaapi hook(void *user_data, int event_id, va_list va) {
2014-06-26 14:52:25 -07:00
static ea_t old_addr = 0;
ea_t addr;
2014-07-06 12:36:57 +09:00
if (event_id == view_curpos) {
2014-06-26 14:52:25 -07:00
addr = get_screen_ea();
if (old_addr != addr) {
2014-07-06 12:36:57 +09:00
if (isCode(getFlags(addr))) {
update_address("iaddr", addr);
} else {
update_address("daddr", addr);
}
2014-06-26 14:52:25 -07:00
}
old_addr = addr;
}
return 0;
}
// ***************** WEBSOCKETS BOILERPLATE *******************
static struct libwebsocket_protocols protocols[] = {
{ "http-only", callback_http, 0 },
{ "qira", callback_qira, 0 },
{ NULL, NULL, 0 }
};
qthread_t websockets_thread;
int websockets_running;
2014-07-21 03:20:28 -07:00
int idaapi websocket_thread(void *) {
2014-06-26 14:52:25 -07:00
struct libwebsocket_context* context;
struct lws_context_creation_info info;
memset(&info, 0, sizeof info);
info.port = 3003;
info.iface = NULL;
info.protocols = protocols;
info.extensions = libwebsocket_get_internal_extensions();
info.gid = -1;
info.uid = -1;
info.options = 0;
context = libwebsocket_create_context(&info);
msg("yay websockets\n");
while (websockets_running) {
libwebsocket_service(context, 50);
}
libwebsocket_context_destroy(context);
return 0;
}
void start_websocket_thread() {
websockets_running = 1;
websockets_thread = qthread_create(websocket_thread, NULL);
}
void exit_websocket_thread() {
websockets_running = 0;
qthread_join(websockets_thread);
}
// ***************** IDAPLUGIN BOILERPLATE *******************
2014-07-21 03:20:28 -07:00
int idaapi IDAP_init(void) {
2014-07-06 11:46:39 +09:00
hook_to_notification_point(HT_VIEW, hook, NULL);
2014-06-26 14:52:25 -07:00
start_websocket_thread();
return PLUGIN_KEEP;
}
2014-07-21 03:20:28 -07:00
void idaapi IDAP_term(void) {
2014-07-06 11:46:39 +09:00
unhook_from_notification_point(HT_VIEW, hook);
2014-07-01 16:53:55 -07:00
exit_websocket_thread();
2014-06-26 14:52:25 -07:00
return;
}
2014-07-21 03:20:28 -07:00
void idaapi IDAP_run(int arg) {
2014-06-26 14:52:25 -07:00
msg("installing book\n");
return;
}
char IDAP_comment[] = "This is my test plug-in";
char IDAP_help[] = "My plugin";
char IDAP_name[] = "QIRA server";
char IDAP_hotkey[] = "Alt-X";
plugin_t PLUGIN = {
IDP_INTERFACE_VERSION, // IDA version plug-in is written for
0, // Flags (see below)
IDAP_init, // Initialisation function
IDAP_term, // Clean-up function
IDAP_run, // Main plug-in body
IDAP_comment, // Comment
IDAP_help, // As above
IDAP_name, // Plug-in name shown in
IDAP_hotkey // Hot key to run the plug-in
};