void CDynamoRIOView::ClearData() { if (m_stats != NULL) { free_dynamorio_stats(m_stats); m_stats = NULL; } if (m_clientMap != NULL) { assert(m_clientView != NULL); UnmapViewOfFile(m_clientView); CloseHandle(m_clientMap); m_clientMap = m_clientView = m_clientStats = NULL; } }
BOOL CDynamoRIOView::Refresh() { if (m_selected_pid <= 0) { ZeroStrings(); return TRUE; } // We have to grab new stats every refresh dr_statistics_t *new_stats = get_dynamorio_stats(m_selected_pid); if (new_stats == NULL) { if (m_stats != NULL) { // Leave the stats for an exited process in place, for viewing // and copying } else return TRUE; } else { if (m_stats != NULL) free_dynamorio_stats(m_stats); m_stats = new_stats; } uint i; #define MAX_VISIBLE_STATS 75 #define STATS_BUFSZ (MAX_VISIBLE_STATS*(sizeof(single_stat_t)*2/*cover %10u, etc.*/)) TCHAR buf[STATS_BUFSZ]; TCHAR *c = buf; buf[0] = _T('\0'); // If I just use a CString hooked up via DDX, re-setting the // text causes the top of the visible box to show the top of // the stats string; plus the scrollbar goes to the top, // unless held in place; probably any reset of the string // does an auto-reset of the display and scrollbar position. // To have all the text in there do this: // int scroll_pos = m_StatsCtl.GetScrollPos(SB_VERT); // m_StatsCtl.SetWindowText(buf); // m_StatsCtl.LineScroll(scroll_pos); // But then there's a lot of flickering: too much. // We only put visible text lines in the CEdit box, to reduce the // flicker. It's too hard to do it w/ the CEdit's own scrollbar, // which sets itself based on the actual text, so we have a // separate one. // HACK: I don't know how to find out how many lines will // fit w/o putting actual text in there if (m_StatsViewLines == 0) { for (i = 0; i < m_stats->num_stats && i < MAX_VISIBLE_STATS /* can't be more than this */; i++) { if (c >= &buf[STATS_BUFSZ-STAT_NAME_MAX_LEN*2]) break; c += PrintStat(c, i, FALSE/*no filter*/); assert(c < &buf[STATS_BUFSZ-1]); } m_StatsCtl.SetWindowText(buf); UpdateData(FALSE); // write to screen // I tried having only one screenful of string there, and // setting the scrollbar range to be larger, but it doesn't // seem to support that. RECT rect; m_StatsCtl.GetRect(&rect); CPoint pos(rect.right, rect.bottom); m_StatsViewLines = HIWORD(m_StatsCtl.CharFromPos(pos)); assert(m_StatsViewLines > 0); m_StatsSB.SetScrollRange(0, m_stats->num_stats-1, TRUE/*redraw*/); c = buf; SCROLLINFO info; info.cbSize = sizeof(SCROLLINFO); info.fMask = SIF_PAGE; info.nPage = m_StatsViewLines; m_StatsSB.SetScrollInfo(&info); } int scroll_pos = m_StatsSB.GetScrollPos(); DWORD shown = 0; uint printed; for (i = scroll_pos; i < m_stats->num_stats && shown < m_StatsViewLines; i++) { if (c >= &buf[STATS_BUFSZ-STAT_NAME_MAX_LEN*2]) break; printed = PrintStat(c, i, TRUE/*filter*/); c += printed; assert(c < &buf[STATS_BUFSZ-1]); if (printed > 0) shown++; } m_StatsCtl.SetWindowText(buf); // num_stats could have changed so update m_StatsSB.SetScrollRange(0, m_stats->num_stats-1, TRUE/*redraw*/); if (new_stats == NULL) m_Exited = _T(" Exited"); // line right end up with Running else m_Exited = _T("Running"); #ifndef DRSTATS_DEMO m_LogLevel.Format(_T("%d"), m_stats->loglevel); m_LogMask.Format(_T("0x%05X"), m_stats->logmask); m_LogDir.Format(_T("%") ASCII_PRINTF, m_stats->logdir); #endif if (m_clientStats != NULL) { #define CLIENTSTATS_BUFSZ USHRT_MAX TCHAR buf[CLIENTSTATS_BUFSZ]; PrintClientStats(buf, &buf[CLIENTSTATS_BUFSZ-1]); m_ClientStats.Format(_T("%s"), buf); } else m_ClientStats.Format(_T("")); UpdateData(FALSE); // write to screen return TRUE; }
BOOL pw_callback(process_info_t *pi, void **param) { char *resstr; char reschar; int res; WCHAR buf[MAX_CMDLINE]; DWORD version; BOOL under_dr; WCHAR qual_name[MAX_CMDLINE]; if (exe) generate_process_name(pi, qual_name, BUFFER_SIZE_ELEMENTS(qual_name)); if ( (pid && pi->ProcessID == pid) || (exe && (!wcsicmp(wexe, pi->ProcessName) || !wcsicmp(wexe, qual_name))) || listall || listdr) { version = -1; res = under_dynamorio_ex(pi->ProcessID, &version); switch (res) { case DLL_PROFILE : resstr=NAME" profile"; reschar='P'; break; case DLL_RELEASE : resstr=NAME" release"; reschar='R'; break; case DLL_DEBUG : resstr=NAME" debug"; reschar='D'; break; case DLL_CUSTOM : resstr=NAME" custom"; reschar='C'; break; case DLL_NONE : resstr="native"; reschar='N'; break; case DLL_UNKNOWN : default : resstr="<error>"; reschar='?'; } under_dr = !(res == DLL_NONE || res == DLL_UNKNOWN); if (!listdr || under_dr) { if (!nopid && !showmem) { if (onlypid) fprintf(fp, "%d\n", (DWORD) pi->ProcessID); else fprintf(fp, "PID %d, ", (DWORD) pi->ProcessID); } if (!showmem && !onlypid) { WCHAR qual_name[MAX_CMDLINE]; WCHAR *name_to_use = pi->ProcessName; #ifdef X64 HANDLE hproc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD) pi->ProcessID); if (is_wow64(hproc)) { if (!no32) fprintf(fp, "32-bit, "); /* FIXME: currently x64 process can't see 32-bit * drmarker */ resstr="<unknown>"; } CloseHandle(hproc); #endif if (!noqnames) { generate_process_name(pi, qual_name, BUFFER_SIZE_ELEMENTS(qual_name)); name_to_use = qual_name; } fprintf(fp, "Process %S, ", name_to_use); if (version == -1 || !showbuild) fprintf(fp, "running %s\n", resstr); else fprintf(fp, "running %s (build %d)\n", resstr, version); } if (cmdline) { res = get_process_cmdline(pi->ProcessID, buf, BUFFER_SIZE_ELEMENTS(buf)); NULL_TERMINATE_BUFFER(buf); if (res == ERROR_SUCCESS) { fprintf(fp, "\tCmdline: %S\n", buf); } else fprintf(fp, "\t<Cmdline err %d>\n", res); } if (qname) { WCHAR cmdline[MAX_CMDLINE]; res = get_process_cmdline(pi->ProcessID, cmdline, BUFFER_SIZE_ELEMENTS(cmdline)); NULL_TERMINATE_BUFFER(cmdline); if (res == ERROR_SUCCESS) { if (!get_commandline_qualifier(cmdline, buf, BUFFER_SIZE_ELEMENTS(buf), !strip)) buf[0] = L'\0'; /* no args */ NULL_TERMINATE_BUFFER(buf); } if (res == ERROR_SUCCESS) fprintf(fp, "\tQname: %S%s%S\n", pi->ProcessName, buf[0] == L'\0' ? "" : "-", buf); else fprintf(fp, "\t<Qname err %d>\n", res); } if (under_dr && hotp) { hotp_policy_status_table_t *status_tbl = NULL; res = get_hotp_status(pi->ProcessID, &status_tbl); if (res == ERROR_SUCCESS) { uint j; hotp_policy_status_t *cur; fprintf(fp, "\tHotpatching:\n", res); for (j = 0; j < status_tbl->num_policies; j++) { char status_buf[MAX_PATH]; cur = &(status_tbl->policy_status_array[j]); if (get_status_string(status_buf, MAX_PATH, cur->inject_status, cur->mode)) fprintf(fp, "\t Patch %s: %s\n", cur->policy_id, status_buf); } } else if (res == ERROR_DRMARKER_ERROR) { fprintf(fp, "\tHot Patching Not Enabled\n", res); } else { fprintf(fp, "\t<Hotpatch Query Error %d>\n", res); } } if (under_dr && showstats) { dr_statistics_t *stats = get_dynamorio_stats(pi->ProcessID); if (stats != NULL) { uint i; fprintf(fp, "\t%.*s\n", BUFFER_SIZE_ELEMENTS(stats->process_name), stats->process_name); for (i = 0; i < stats->num_stats; i++) { fprintf(fp, "\t%*.*s :%9d\n", BUFFER_SIZE_ELEMENTS(stats->stats[i].name), BUFFER_SIZE_ELEMENTS(stats->stats[i].name), stats->stats[i].name, stats->stats[i].value); } } free_dynamorio_stats(stats); } if (showmem) { print_mem_stats(pi, reschar, version); } count++; } } return TRUE; }