//-------------------------------------------------------------------------- ea_t idaapi rpc_debmod_t::dbg_appcall( ea_t func_ea, thid_t tid, int stkarg_nbytes, const struct regobjs_t *regargs, struct relobj_t *stkargs, struct regobjs_t *retregs, qstring *errbuf, debug_event_t *event, int flags) { bytevec_t req = prepare_rpc_packet(RPC_APPCALL); append_ea64(req, func_ea); append_dd(req, tid); append_dd(req, stkarg_nbytes); append_dd(req, flags); regobjs_t *rr = (flags & APPCALL_MANUAL) == 0 ? retregs : NULL; append_appcall(req, *regargs, *stkargs, rr); rpc_packet_t *rp = process_request(req); if ( rp == NULL ) return BADADDR; const uchar *answer = (uchar *)(rp+1); const uchar *end = answer + rp->length; ea_t sp = extract_ea64(&answer, end); if ( sp == BADADDR ) { if ( (flags & APPCALL_DEBEV) != 0 ) extract_debug_event(&answer, end, event); if ( errbuf != NULL ) *errbuf = extract_str(&answer, end); } else if ( (flags & APPCALL_MANUAL) == 0 ) { if ( retregs != NULL ) extract_regobjs(&answer, end, retregs, true); } qfree(rp); return sp; }
//-------------------------------------------------------------------------- int idaapi rpc_debmod_t::dbg_thread_get_sreg_base(thid_t tid, int sreg_value, ea_t *ea) { bytevec_t req = prepare_rpc_packet(RPC_GET_SREG_BASE); append_dd(req, tid); append_dd(req, sreg_value); rpc_packet_t *rp = process_request(req); if ( rp == NULL ) return -1; const uchar *answer = (uchar *)(rp+1); const uchar *end = answer + rp->length; bool result = extract_long(&answer, end) != 0; if ( result ) *ea = extract_ea64(&answer, end); qfree(rp); return result; }
//---------------------------------------------------------- main thread --- int idaapi win32_debmod_t::handle_ioctl( int fn, const void *buf, size_t size, void **poutbuf, ssize_t *poutsize) { qnotused(size); switch ( fn ) { case WIN32_IOCTL_RDMSR: QASSERT(30119, size == sizeof(uval_t)); { uint64 value; uval_t reg = *(uval_t *)buf; int code = rdmsr(reg, &value); if ( SUCCEEDED(code) ) { *poutbuf = qalloc(sizeof(value)); if ( *poutbuf != NULL ) { memcpy(*poutbuf, &value, sizeof(value)); *poutsize = sizeof(value); } } return code; } case WIN32_IOCTL_WRMSR: QASSERT(30120, size == sizeof(win32_wrmsr_t)); { win32_wrmsr_t &msr = *(win32_wrmsr_t *)buf; return wrmsr(msr.reg, msr.value); } #ifdef ENABLE_REMOTEPDB case WIN32_IOCTL_STARTPDB: QASSERT(30192, size >= sizeof(uint64)); { qstring errmsg; if ( pdbthread.is_running() ) { errmsg = "Only one PDB conversion at a time is supported!"; PDBERROR: *poutsize = errmsg.size(); *poutbuf = errmsg.extract(); return -2; } const uchar *ptr = (const uchar *)buf; const uchar *end = ptr + size; compiler_info_t cc; extract_memory(&ptr, end, &cc, sizeof(cc)); ea_t base_ea = extract_ea64(&ptr, end); const char *pdbfile = extract_str(&ptr, end); const char *dpath = extract_str(&ptr, end); const char *spath = extract_str(&ptr, end); if ( !pdbthread.do_convert(cc, base_ea, pdbfile, dpath, spath) ) { errmsg = "Error starting PDB conversion!"; goto PDBERROR; } return 0x1234; // dummy ID } case WIN32_IOCTL_DONEPDB: { qstring errmsg; if ( !pdbthread.is_running() ) { errmsg = "PDB conversion is not started!"; PDBERROR2: *poutsize = errmsg.size(); *poutbuf = errmsg.extract(); return -2; } const uchar *ptr = (const uchar *)buf; const uchar *end = ptr + size; uint32 id = extract_long(&ptr, end); if ( id != 0x1234 ) { errmsg = "Bad conversion ID"; goto PDBERROR2; } if ( pdbthread.is_waiting_req() ) { // we've got a read request, handle it now handle_pdb_request(); pdbthread.post_req_done(); } if ( pdbthread.is_done() ) { // done pdbthread.finalize(); *poutsize = pdbthread.tilfname.size(); *poutbuf = pdbthread.tilfname.extract(); return 2; } else { // not done yet return 1; } } case WIN32_IOCTL_RMFILE: { qstring errmsg; const uchar *ptr = (const uchar *)buf; const uchar *end = ptr + size; const char *filename = extract_str(&ptr, end); if ( filename == NULL ) { errmsg = "Filename missing"; PDBERROR3: *poutsize = errmsg.size(); *poutbuf = errmsg.extract(); return -2; } if ( unlink(filename) != 0 ) { errmsg = "Error deleting file"; goto PDBERROR3; } return 1; } #endif // REMOTEPDB default: break; } return 0; }