static gpointer timer(gpointer data) { int timeout = *(int*)data; while(timeout && !interrupted) { sleep(1); --timeout; } if (!interrupted) { interrupted = -1; drakvuf_interrupt(drakvuf, -1); } g_thread_exit(NULL); return NULL; }
static void close_handler(int sig) { drakvuf_interrupt(drakvuf, sig); }
static event_response_t hook_cb(drakvuf_t drakvuf, drakvuf_trap_info_t* info) { bsodmon* f = static_cast<bsodmon*>(info->trap->data); vmi_instance_t vmi = drakvuf_lock_and_get_vmi(drakvuf); access_context_t ctx; ctx.translate_mechanism = VMI_TM_PROCESS_DTB; ctx.dtb = info->regs->cr3; uint64_t code = 0; uint64_t params[4] = { 0 }; const char* bugcheck_name = "UNKNOWN_CODE" ; gchar* escaped_pname = NULL; bool is32bit = drakvuf_get_page_mode(drakvuf) != VMI_PM_IA32E; if (is32bit) { ctx.addr = info->regs->rsp + 4; if ( VMI_FAILURE == vmi_read_32(vmi, &ctx, (uint32_t*)&code) ) goto done; ctx.addr = info->regs->rsp + 8; if ( VMI_FAILURE == vmi_read_32(vmi, &ctx, (uint32_t*)¶ms[0]) ) goto done; ctx.addr = info->regs->rsp + 0xc; if ( VMI_FAILURE == vmi_read_32(vmi, &ctx, (uint32_t*)¶ms[1]) ) goto done; ctx.addr = info->regs->rsp + 0x10; if ( VMI_FAILURE == vmi_read_32(vmi, &ctx, (uint32_t*)¶ms[2]) ) goto done; ctx.addr = info->regs->rsp + 0x14; if ( VMI_FAILURE == vmi_read_32(vmi, &ctx, (uint32_t*)¶ms[3]) ) goto done; } else { code = info->regs->rcx; params[0] = info->regs->rdx; params[1] = info->regs->r8; params[2] = info->regs->r9; ctx.addr = info->regs->rsp + 0x20; if ( VMI_FAILURE == vmi_read_32(vmi, &ctx, (uint32_t*)¶ms[3]) ) goto done; } if ( f->bugcheck_map.find( code ) != f->bugcheck_map.end() ) bugcheck_name = f->bugcheck_map[ code ]; switch (f->format) { case OUTPUT_CSV: printf("bsodmon," FORMAT_TIMEVAL ",%" PRIu32 ",0x%" PRIx64 ",\"%s\",%" PRIi64 ",%" PRIx64 ",\"%s\",%" PRIx64 ",%" PRIx64 ",%" PRIx64 ",%" PRIx64 "\n", UNPACK_TIMEVAL(info->timestamp), info->vcpu, info->regs->cr3, info->proc_data.name, info->proc_data.userid, code, bugcheck_name, params[0], params[1], params[2], params[3]); break; case OUTPUT_KV: printf("bsodmon Time=" FORMAT_TIMEVAL ",PID=%d,PPID=%d,ProcessName=\"%s\",BugCheckCode=%" PRIx64 ",BugCheckName=\"%s\",BugCheckParameter1=%" PRIx64 ",BugCheckParameter2=%" PRIx64 ",BugCheckParameter2=%" PRIx64 ",BugCheckParameter4=%" PRIx64 "\n", UNPACK_TIMEVAL(info->timestamp), info->proc_data.pid, info->proc_data.ppid, info->proc_data.name, code, bugcheck_name, params[0], params[1], params[2], params[3]); break; case OUTPUT_JSON: escaped_pname = drakvuf_escape_str(info->proc_data.name); printf( "{" "\"Plugin\" : \"bsodmon\"," "\"TimeStamp\" :" "\"" FORMAT_TIMEVAL "\"," "\"VCPU\": %" PRIu32 "," "\"CR3\": %" PRIu64 "," "\"ProcessName\": %s," "\"UserId\": %" PRIu64 "," "\"PID\" : %d," "\"PPID\": %d," "\"BugCheckCode\": %" PRIu64 "," "\"BugCheckName\": \"%s\"," "\"BugCheckParameter1\": %" PRIu64 "," "\"BugCheckParameter2\": %" PRIu64 "," "\"BugCheckParameter3\": %" PRIu64 "," "\"BugCheckParameter4\": %" PRIu64 "}\n", UNPACK_TIMEVAL(info->timestamp), info->vcpu, info->regs->cr3, escaped_pname, info->proc_data.userid, info->proc_data.pid, info->proc_data.ppid, code, bugcheck_name, params[0], params[1], params[2], params[3]); g_free(escaped_pname); break; default: case OUTPUT_DEFAULT: printf("[BSODMON] TIME:" FORMAT_TIMEVAL " VCPU:%" PRIu32 " CR3:0x%" PRIx64 ",\"%s\" %s:%" PRIi64 " BugCheckCode:%" PRIx64 " BugCheckName:%s BugCheckParameter1:%" PRIx64 " BugCheckParameter2:%" PRIx64 " BugCheckParameter3:%" PRIx64 " BugCheckParameter4:%" PRIx64 "\n", UNPACK_TIMEVAL(info->timestamp), info->vcpu, info->regs->cr3, info->proc_data.name, USERIDSTR(drakvuf), info->proc_data.userid, code, bugcheck_name, params[0], params[1], params[2], params[3]); break; } done: drakvuf_release_vmi(drakvuf); if ( f->abort_on_bsod ) drakvuf_interrupt( drakvuf, SIGDRAKVUFERROR); return 0; }