//-------------------------------------------------------------------------- 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; }
//-------------------------------------------------------------------------- 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; }
//-------------------------------------------------------------------------- ssize_t idaapi rpc_debmod_t::dbg_read_memory(ea_t ea, void *buffer, size_t size) { bytevec_t req = prepare_rpc_packet(RPC_READ_MEMORY); append_ea64(req, ea); 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; int result = extract_long(&answer, end); if ( result > 0 ) extract_memory(&answer, end, buffer, result); 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; }
//-------------------------------------------------------------------------- int idaapi rpc_debmod_t::dbg_update_bpts(update_bpt_info_t *ubpts, int nadd, int ndel) { int skipped = 0; update_bpt_info_t *b; update_bpt_info_t *bend = ubpts + nadd; for ( b=ubpts; b != bend; b++ ) if ( b->code != BPT_OK ) skipped++; if ( skipped == nadd && ndel == 0 ) return 0; // no bpts to update bytevec_t req = prepare_rpc_packet(RPC_UPDATE_BPTS); append_dd(req, nadd-skipped); append_dd(req, ndel); ea_t ea = 0; for ( b=ubpts; b != bend; b++ ) { if ( b->code == BPT_OK ) { append_ea64(req, b->ea-ea); ea = b->ea; append_dd(req, b->size); append_dd(req, b->type); } } ea = 0; bend += ndel; for ( ; b != bend; b++ ) { append_ea64(req, b->ea-ea); ea = b->ea; append_db(req, b->orgbytes.size()); append_memory(req, b->orgbytes.begin(), b->orgbytes.size()); append_dd(req, b->type); } rpc_packet_t *rp = process_request(req); if ( rp == NULL ) return -1; const uchar *ptr = (uchar *)(rp+1); const uchar *end = ptr + rp->length; int ret = extract_long(&ptr, end); bend = ubpts + nadd; for ( b=ubpts; b != bend; b++ ) { if ( b->code == BPT_OK ) { b->code = extract_byte(&ptr, end); if ( b->code == BPT_OK && b->type == BPT_SOFT ) { uchar len = extract_byte(&ptr, end); b->orgbytes.resize(len); extract_memory(&ptr, end, b->orgbytes.begin(), len); } } } bend += ndel; for ( ; b != bend; b++ ) b->code = extract_byte(&ptr, end); return ret; }
//------------------------------------------------------------------------- bool varser_t::deserialize(VARIANT &var, const uchar **in, const uchar * const end) { var.vt = unpack_dw(in, end); if ( (var.vt & VT_BYREF) == VT_BYREF || (var.vt & VT_ARRAY) == VT_ARRAY ) { return false; } bool ok = false; switch ( var.vt ) { case VT_EMPTY: // = 0x0000, case VT_NULL: // = 0x0001, break; case VT_I2: // = 0x0002, case VT_UI2: // = 0x0012, var.uiVal = unpack_dw(in, end); ok = true; break; case VT_I4: // = 0x0003, case VT_UI4: // = 0x0013, var.ulVal = unpack_dd(in, end); ok = true; break; case VT_R4: // = 0x0004, { uint32 res = unpack_dd(in, end); var.fltVal = *(FLOAT*)&res; ok = true; } break; case VT_R8: // = 0x0005, { uint64 res = unpack_dq(in, end); var.dblVal = *(DOUBLE*)&res; ok = true; } break; case VT_CY: // = 0x0006, case VT_DATE: // = 0x0007, break; case VT_BSTR: // = 0x0008, { uint32 bcnt = unpack_dd(in, end); uint8 *raw = (uint8 *) qalloc(bcnt + 4 + 2); // +2 for terminating null character. if ( raw != NULL ) { * (uint32*) raw = bcnt; raw += 4; extract_memory(in, end, raw, bcnt); raw[bcnt] = '\0'; raw[bcnt+1] = '\0'; var.bstrVal = raw; ok = true; } } break; case VT_LPSTR: // = 0x001E, case VT_LPWSTR: // = 0x001F, { char *tmp = qstrdup(unpack_str(in, end)); var.byref = tmp; ok = true; } break; case VT_DISPATCH: // = 0x0009, case VT_ERROR: // = 0x000A, case VT_BOOL: // = 0x000B, case VT_VARIANT: // = 0x000C, case VT_UNKNOWN: // = 0x000D, case VT_DECIMAL: // = 0x000E, case VT_I1: // = 0x0010, case VT_UI1: // = 0x0011, var.bVal = unpack_db(in, end); ok = true; break; case VT_I8: // = 0x0014, case VT_UI8: // = 0x0015, var.ullVal = unpack_dq(in, end); ok = true; break; case VT_INT: // = 0x0016, case VT_UINT: // = 0x0017, case VT_HRESULT: // = 0x0019, var.uintVal = unpack_dd(in, end); ok = true; break; case VT_VOID: // = 0x0018, case VT_PTR: // = 0x001A, case VT_SAFEARRAY: // = 0x001B, case VT_CARRAY: // = 0x001C, case VT_USERDEFINED: // = 0x001D, case VT_RECORD: // = 0x0024, case VT_INT_PTR: // = 0x0025, case VT_UINT_PTR: // = 0x0026, break; default: break; } return ok; }