//-------------------------------------------------------------------------- void idaapi rpc_debmod_t::dbg_close_file(int fn) { bytevec_t req = prepare_rpc_packet(RPC_CLOSE_FILE); append_dd(req, fn); qfree(process_request(req)); }
//-------------------------------------------------------------------------- int idaapi rpc_debmod_t::dbg_open_file(const char *file, uint32 *fsize, bool readonly) { bytevec_t req = prepare_rpc_packet(RPC_OPEN_FILE); append_str(req, file); append_dd(req, readonly); rpc_packet_t *rp = process_request(req); if ( rp == NULL ) return -1; const uchar *answer = (uchar *)(rp+1); const uchar *end = answer + rp->length; int fn = extract_long(&answer, end); if ( fn != -1 ) { if ( fsize != NULL && readonly ) *fsize = extract_long(&answer, end); } else { qerrcode(extract_long(&answer, end)); } qfree(rp); return fn; }
//-------------------------------------------------------------------------- int rpc_debmod_t::getint2(uchar code, int x) { bytevec_t req = prepare_rpc_packet(code); append_dd(req, x); return process_long(req); }
//-------------------------------------------------------------------------- ssize_t idaapi rpc_debmod_t::dbg_read_file(int fn, uint32 off, void *buf, size_t size) { bytevec_t req = prepare_rpc_packet(RPC_READ_FILE); append_dd(req, fn); append_dd(req, off); append_dd(req, (uint32)size); rpc_packet_t *rp = process_request(req); if ( rp == NULL ) return -1; const uchar *answer = (uchar *)(rp+1); const uchar *end = answer + rp->length; int32 rsize = extract_long(&answer, end); if ( size != rsize ) qerrcode(extract_long(&answer, end)); if ( rsize > 0 ) { if ( rsize > size ) error("rpc_read_file: protocol error"); extract_memory(&answer, end, buf, rsize); } qfree(rp); return rsize; }
//-------------------------------------------------------------------------- int rpc_debmod_t::getint2(uchar code, int x) { qstring cmd = prepare_rpc_packet(code); append_long(cmd, x); return process_long(cmd); }
//-------------------------------------------------------------------------- int rpc_debmod_t::dbg_continue_after_event(const debug_event_t *event) { qstring cmd = prepare_rpc_packet(RPC_CONTINUE_AFTER_EVENT); append_debug_event(cmd, event); return process_long(cmd); }
//-------------------------------------------------------------------------- int idaapi rpc_debmod_t::dbg_attach_process(pid_t _pid, int event_id) { bytevec_t req = prepare_rpc_packet(RPC_ATTACH_PROCESS); append_dd(req, _pid); append_dd(req, event_id); return process_start_or_attach(req); }
//-------------------------------------------------------------------------- void rpc_debmod_t::dbg_close_file(int fn) { qstring cmd = prepare_rpc_packet(RPC_CLOSE_FILE); append_long(cmd, fn); qfree(process_request(cmd)); }
//-------------------------------------------------------------------------- int idaapi rpc_debmod_t::dbg_continue_after_event(const debug_event_t *event) { bytevec_t req = prepare_rpc_packet(RPC_CONTINUE_AFTER_EVENT); append_debug_event(req, event); return process_long(req); }
//-------------------------------------------------------------------------- int idaapi rpc_debmod_t::dbg_eval_lowcnd(thid_t tid, ea_t ea) { bytevec_t req = prepare_rpc_packet(RPC_EVAL_LOWCND); append_dd(req, tid); append_ea64(req, ea); return process_long(req); }
//-------------------------------------------------------------------------- gdecode_t rpc_debmod_t::dbg_get_debug_event(debug_event_t *event, int timeout_ms) { if ( has_pending_event ) { verbev(("get_debug_event => has pending event, returning it\n")); *event = pending_event; has_pending_event = false; poll_debug_events = false; return GDE_ONE_EVENT; } gdecode_t result = GDE_NO_EVENT; if ( poll_debug_events ) { // do we have something waiting? // we must use TIMEOUT here to avoid competition between // IDA analyzer and the debugger program. // The analysis will be slow during the application run. // As soon as the program is suspended, the analysis will be fast // because get_debug_event() will not be called. if ( irs_ready(irs, TIMEOUT) != 0 ) { verbev(("get_debug_event => remote has an event for us\n")); // get the packet - it should be RPC_EVENT (nothing else can be) qstring empty; int flags = timeout_ms > 0 ? SET_PRF_TIMEOUT(timeout_ms) | PRF_POLL : PRF_DONT_POLL; rpc_packet_t *rp = process_request(empty, flags); verbev(("get_debug_event => processed remote event, has=%d\n", has_pending_event)); if ( rp != NULL || !has_pending_event ) { warning("rpc: event protocol error (rp=%p has_event=%d)", rp, has_pending_event); return GDE_ERROR; } } } else { verbev(("get_debug_event => first time, send GET_DEBUG_EVENT\n")); qstring cmd = prepare_rpc_packet(RPC_GET_DEBUG_EVENT); append_long(cmd, timeout_ms); rpc_packet_t *rp = process_request(cmd); if ( rp == NULL ) return GDE_ERROR; const uchar *answer = (uchar *)(rp+1); const uchar *end = answer + rp->length; result = gdecode_t(extract_long(&answer, end)); if ( result >= GDE_ONE_EVENT ) extract_debug_event(&answer, end, event); else poll_debug_events = true; verbev(("get_debug_event => remote said %d, poll=%d now\n", result, poll_debug_events)); qfree(rp); } return result; }
//-------------------------------------------------------------------------- int rpc_debmod_t::dbg_attach_process(pid_t pid, int event_id) { qstring cmd = prepare_rpc_packet(RPC_ATTACH_PROCESS); append_long(cmd, pid); append_long(cmd, event_id); return process_long(cmd); }
//-------------------------------------------------------------------------- void rpc_debmod_t::dbg_set_exception_info(const exception_info_t *table, int qty) { qstring cmd = prepare_rpc_packet(RPC_SET_EXCEPTION_INFO); append_long(cmd, qty); append_exception_info(cmd, table, qty); qfree(process_request(cmd)); }
//-------------------------------------------------------------------------- void idaapi rpc_debmod_t::dbg_set_exception_info(const exception_info_t *table, int qty) { bytevec_t req = prepare_rpc_packet(RPC_SET_EXCEPTION_INFO); append_dd(req, qty); append_exception_info(req, table, qty); qfree(process_request(req)); }
//-------------------------------------------------------------------------- bool rpc_debmod_t::close_remote() { bytevec_t req = prepare_rpc_packet(RPC_OK); send_request(req); term_client_irs(irs); irs = NULL; network_error_code = 0; return true; }
//-------------------------------------------------------------------------- ssize_t idaapi rpc_debmod_t::dbg_write_memory(ea_t ea, const void *buffer, size_t size) { bytevec_t req = prepare_rpc_packet(RPC_WRITE_MEMORY); append_ea64(req, ea); append_dd(req, (uint32)size); append_memory(req, buffer, size); return process_long(req); }
//-------------------------------------------------------------------------- int rpc_debmod_t::dbg_del_bpt(ea_t ea, const uchar *orig_bytes, int len) { qstring cmd = prepare_rpc_packet(RPC_DEL_BPT); append_ea(cmd, ea); append_long(cmd, len); append_memory(cmd, orig_bytes, len); return process_long(cmd); }
//-------------------------------------------------------------------------- int idaapi rpc_debmod_t::dbg_write_register(thid_t tid, int reg_idx, const regval_t *value) { bytevec_t req = prepare_rpc_packet(RPC_WRITE_REG); append_dd(req, tid); append_dd(req, reg_idx); append_regvals(req, value, 1, NULL); return process_long(req); }
//-------------------------------------------------------------------------- int idaapi rpc_debmod_t::dbg_is_ok_bpt(bpttype_t type, ea_t ea, int len) { bytevec_t req = prepare_rpc_packet(RPC_ISOK_BPT); append_dd(req, type); append_ea64(req, ea); append_dd(req, len+1); return process_long(req); }
//-------------------------------------------------------------------------- int rpc_debmod_t::dbg_thread_write_register(thid_t tid, int reg_idx, const regval_t *value) { qstring cmd = prepare_rpc_packet(RPC_WRITE_REG); append_long(cmd, tid); append_long(cmd, reg_idx); append_regvals(cmd, value, 1); return process_long(cmd); }
//-------------------------------------------------------------------------- ssize_t rpc_debmod_t::dbg_write_memory(ea_t ea, const void *buffer, size_t size) { qstring cmd = prepare_rpc_packet(RPC_WRITE_MEMORY); append_ea(cmd, ea); append_long(cmd, (uint32)size); append_memory(cmd, buffer, size); return process_long(cmd); }
//-------------------------------------------------------------------------- int rpc_debmod_t::bpt(uchar code, bpttype_t type, ea_t ea, int len) { qstring cmd = prepare_rpc_packet(code); append_long(cmd, type); append_ea(cmd, ea); append_long(cmd, len); return process_long(cmd); }
//-------------------------------------------------------------------------- bool rpc_debmod_t::close_remote() { qstring cmd = prepare_rpc_packet(RPC_OK); send_request(cmd); term_client_irs(irs); irs = NULL; network_error_code = 0; return true; }
//-------------------------------------------------------------------------- int idaapi rpc_debmod_t::dbg_init(bool _debug_debugger) { has_pending_event = false; poll_debug_events = false; bytevec_t req = prepare_rpc_packet(RPC_INIT); append_dd(req, debugger.flags); append_dd(req, _debug_debugger); return process_long(req); }
//-------------------------------------------------------------------------- gdecode_t idaapi rpc_debmod_t::dbg_get_debug_event(debug_event_t *event, int timeout_ms) { if ( has_pending_event ) { verbev(("get_debug_event => has pending event, returning it\n")); *event = pending_event; has_pending_event = false; poll_debug_events = false; return GDE_ONE_EVENT; } gdecode_t result = GDE_NO_EVENT; if ( poll_debug_events ) { // do we have something waiting? if ( irs_ready(irs, timeout_ms) != 0 ) { verbev(("get_debug_event => remote has an event for us\n")); // get the packet - it should be RPC_EVENT (nothing else can be) bytevec_t empty; rpc_packet_t *rp = process_request(empty); verbev(("get_debug_event => processed remote event, has=%d\n", has_pending_event)); if ( rp != NULL || !has_pending_event ) { warning("rpc: event protocol error (rp=%p has_event=%d)", rp, has_pending_event); return GDE_ERROR; } } } else { verbev(("get_debug_event => first time, send GET_DEBUG_EVENT\n")); bytevec_t req = prepare_rpc_packet(RPC_GET_DEBUG_EVENT); append_dd(req, timeout_ms); rpc_packet_t *rp = process_request(req); if ( rp == NULL ) return GDE_ERROR; const uchar *answer = (uchar *)(rp+1); const uchar *end = answer + rp->length; result = gdecode_t(extract_long(&answer, end)); if ( result >= GDE_ONE_EVENT ) extract_debug_event(&answer, end, event); else poll_debug_events = true; verbev(("get_debug_event => remote said %d, poll=%d now\n", result, poll_debug_events)); qfree(rp); } return result; }
//-------------------------------------------------------------------------- int rpc_debmod_t::dbg_thread_read_registers(thid_t tid, regval_t *values, int n) { qstring cmd = prepare_rpc_packet(RPC_READ_REGS); append_long(cmd, tid); append_long(cmd, n); rpc_packet_t *rp = process_request(cmd); if ( rp == NULL ) return -1; const uchar *answer = (uchar *)(rp+1); const uchar *end = answer + rp->length; int result = extract_long(&answer, end); extract_regvals(&answer, end, values, n); qfree(rp); return result; }
//-------------------------------------------------------------------------- bool idaapi rpc_debmod_t::dbg_update_call_stack(thid_t tid, call_stack_t *trace) { bytevec_t req = prepare_rpc_packet(RPC_UPDATE_CALL_STACK); append_dd(req, tid); rpc_packet_t *rp = process_request(req); if ( rp == NULL ) return false; const uchar *answer = (uchar *)(rp+1); const uchar *end = answer + rp->length; bool result = extract_long(&answer, end) != 0; if ( result ) extract_call_stack(&answer, end, trace); qfree(rp); return result; }
//-------------------------------------------------------------------------- int rpc_debmod_t::dbg_start_process( const char *path, const char *args, const char *startdir, int flags, const char *input_path, uint32 input_file_crc32) { qstring cmd = prepare_rpc_packet(RPC_START_PROCESS); append_str(cmd, path); append_str(cmd, args); append_str(cmd, startdir); append_long(cmd, flags); append_str(cmd, input_path); append_long(cmd, input_file_crc32); return process_long(cmd); }
//-------------------------------------------------------------------------- int idaapi rpc_debmod_t::dbg_start_process( const char *path, const char *args, const char *startdir, int flags, const char *input_path, uint32 input_file_crc32) { bytevec_t req = prepare_rpc_packet(RPC_START_PROCESS); append_str(req, path); append_str(req, args); append_str(req, startdir); append_dd(req, flags); append_str(req, input_path); append_dd(req, input_file_crc32); return process_start_or_attach(req); }
//-------------------------------------------------------------------------- ssize_t rpc_debmod_t::dbg_read_memory(ea_t ea, void *buffer, size_t size) { qstring cmd = prepare_rpc_packet(RPC_READ_MEMORY); append_ea(cmd, ea); append_long(cmd, (uint32)size); rpc_packet_t *rp = process_request(cmd); if ( rp == NULL ) return -1; const uchar *answer = (uchar *)(rp+1); const uchar *end = answer + rp->length; int result = extract_long(&answer, end); extract_memory(&answer, end, buffer, size); qfree(rp); return result; }