📄 htanaly.cc
字号:
void ht_aviewer::showCallChain(Address *Addr){ Location *a = analy->getFunctionByAddress(Addr); if (!a) return; Bounds b; b.w = 60; b.h = 16; center_bounds(&b); char str[256]; global_analyser_address_string_format = ADDRESS_STRING_FORMAT_LEADING_ZEROS; ht_snprintf(str, sizeof str, "call chain of address %y", Addr); ht_dialog *dialog = new ht_dialog(); dialog->init(&b, str, FS_KILLER | FS_TITLE | FS_MOVE); b.assign(1, 0, 56, 10); ht_statictext *text = new ht_statictext(); if (a->label) { ht_snprintf(str, sizeof str, "function %s %s", a->label->name, "is referenced by .."); } else { ht_snprintf(str, sizeof str, "address %y %s", a->addr, "is referenced by .."); } text->init(&b, str, align_left); dialog->insert(text); b.assign(1, 1, 56, 10); CallChain *cc; NEW_OBJECT(cc, CallChain, &b, analy, Addr, NULL); cc->adjust(cc->get_root(), true); dialog->insert(cc); b.assign(15, 12, 9, 2); ht_button *bt; NEW_OBJECT(bt, ht_button, &b, "O~k", button_ok); dialog->insert(bt); b.assign(35, 12, 9, 2); NEW_OBJECT(bt, ht_button, &b, "~Cancel", button_cancel); dialog->insert(bt); int r = dialog->run(false); if (r == button_ok) { ht_treeview_data tvd; ViewDataBuf vdb(dialog, &tvd, sizeof tvd); gotoAddress(((CallChainNode*)tvd.selected)->xa, this); } dialog->done(); delete dialog;}void ht_aviewer::showComments(Address *Addr){ if (!analy) return; if (!canCreateAddress(Addr, true)) { return; } CommentList *comment = analy->getComments(Addr); // prepare mem_file MemoryFile *mem_file = new MemoryFile(); if (comment) { int c1 = comment->count(); for (int i=0; i < c1; i++) { const char *c = comment->getName(i); int len = strlen(c); if (len) mem_file->write(c, len); if (i+1<c1) mem_file->write((void*)"\n", 1); } } /* ht_c_syntax_lexer *lexer = new ht_c_syntax_lexer(); lexer->init();*/ // prepare textfile ht_ltextfile text_file(mem_file, true, NULL); // create dialog Bounds b; b.w = 60; b.h = 16; center_bounds(&b); ht_dialog *dialog = new ht_dialog(); dialog->init(&b, "edit comments", FS_KILLER | FS_TITLE | FS_MOVE); b.assign(1, 1, 55, 10); ht_text_editor *text_editor = new ht_text_editor(); text_editor->init(&b, false, &text_file, NULL, TEXTEDITOPT_UNDO); dialog->insert(text_editor); /* FIXME: scrollbar BOUNDS_ASSIGN(b, 56, 1, 1, 10); */ ht_button *b1; b.assign(18, 12, 9, 2); NEW_OBJECT(b1, ht_button, &b, "O~k", button_ok); dialog->insert(b1); b.assign(32, 12, 9, 2); NEW_OBJECT(b1, ht_button, &b, "~Cancel", button_cancel); dialog->insert(b1); if (dialog->run(false) == button_ok) { Location *a = analy->getLocationByAddress(Addr); if (a) analy->freeComments(a); uint c = text_file.linecount(); char buf[1024]; bool empty=false; if (c == 1) { uint l = 0; text_file.getline(0, 0, buf, 1024, &l, NULL); empty=(l==0); } if (!empty) { for (uint i=0; i<c; i++) { uint l; if (text_file.getline(i, 0, buf, 1024, &l, NULL)) { buf[l]=0; analy->addComment(Addr, 0, buf); } } } analy->makeDirty(); analy_sub->output->invalidateCache(); } dialog->done(); delete dialog;}void ht_aviewer::showInfo(Address *Addr){ Bounds c, b; app->getbounds(&c); b.w=c.w*5/6; b.h=c.h*5/6; center_bounds(&b); char str[100]; strcpy(str, "Analyser information"); ht_dialog *dialog = new ht_dialog(); dialog->init(&b, str, FS_KILLER | FS_TITLE | FS_MOVE); b.assign(1, 0, b.w-4, 10); AnalyserInformation *text = new AnalyserInformation(); text->init(&b, this); dialog->insert(text); dialog->run(false); dialog->done(); delete dialog;}void ht_aviewer::showSymbols(Address *addr){ if (!analy) return; Location *loc = analy->getPreviousSymbolByAddress(addr); Bounds b; b.w = 60; b.h = 15; center_bounds(&b); ht_dialog *dialog = new ht_dialog(); dialog->init(&b, "symbols", FS_KILLER | FS_TITLE | FS_MOVE | FS_RESIZE); /* pull down */ b.assign(30, 0, 20, 1);/* ht_listpopup *lp = new ht_listpopup(); lp->init(&b); lp->insertstring("show all"); lp->insertstring("only functions"); lp->insertstring("only labels"); lp->insertstring("only offsets (code)"); lp->insertstring("only data"); dialog->insert(lp);*/ /* text */ b.assign(1, 0, 56, 1); ht_listbox_title *text = new ht_listbox_title(); text->init(&b); text->setText(3, "Address", "Type", "Name"); /* list */ b.assign(1, 1, 56, 12); SymbolBox *sym = new SymbolBox(); sym->init(&b, analy); if (loc && loc->label) { sym->gotoItemByEntry(sym->quickfind(loc->label->name)); } dialog->insert(sym); dialog->insert(text); sym->attachTitle(text); register_idle_object(sym); int r = dialog->run(false); unregister_idle_object(sym); if (r == button_ok) { // goto selected symbol ht_listbox_data d; ViewDataBuf vdb(sym, &d, sizeof d); if (d.data->cursor_ptr) gotoAddress(((Symbol *)d.data->cursor_ptr)->location->addr, this); } dialog->done(); delete dialog;}void ht_aviewer::showXRefs(Address *Addr){ if (!analy->getXRefs(Addr)) { if (confirmbox("No xrefs for address %y!\nSearch for xrefs?", Addr) == button_yes) { searchForXRefs(Addr); } } Bounds c, b; app->getbounds(&c); b.w = c.w*5/6; b.h = c.h*5/6; center_bounds(&b); int result; do { Container *x_tree = analy->getXRefs(Addr); uint bw = b.w; uint bh = b.h; char str[256]; global_analyser_address_string_format = ADDRESS_STRING_FORMAT_COMPACT | ADDRESS_STRING_FORMAT_ADD_0X; ht_snprintf(str, sizeof str, "xrefs of address %y", Addr); ht_dialog *dialog = new ht_dialog(); dialog->init(&b, str, FS_KILLER | FS_TITLE | FS_MOVE | FS_RESIZE); b.assign(1, 0, bw-4, 1); ht_listbox_title *text = new ht_listbox_title(); text->init(&b); text->setText(3, "xref to", "type", "from function"); b.y = 1; b.h = bh-6; ht_text_listbox *list; NEW_OBJECT(list, ht_text_listbox, &b, 3, 2); b.assign(2, bh-4, 26, 2); ht_button *search_for_xrefs; NEW_OBJECT(search_for_xrefs, ht_button, &b, "~Search for more XRefs", 666); search_for_xrefs->growmode = MK_GM(GMH_LEFT, GMV_BOTTOM); b.assign(29, bh-4, 11, 2); ht_button *delete_xref; NEW_OBJECT(delete_xref, ht_button, &b, "~Delete", 667); delete_xref->growmode = MK_GM(GMH_LEFT, GMV_BOTTOM); // FIXME: disable button when possible b.assign(41, bh-4, 10, 2); ht_button *new_xref; NEW_OBJECT(new_xref, ht_button, &b, "~Add", 668); new_xref->growmode = MK_GM(GMH_LEFT, GMV_BOTTOM); char str2[1024]; int xcount=0; if (x_tree) foreach(AddrXRef, x, *x_tree, { xcount++; global_analyser_address_string_format = ADDRESS_STRING_FORMAT_LEADING_WHITESPACE; ht_snprintf(str, sizeof str, "%y", x->addr); Location *a = analy->getFunctionByAddress(x->addr); const char *func = analy->getSymbolNameByLocation(a); if (func) { int d=0; x->addr->difference(d, a->addr); char sign = '+'; if (d < 0) { d = -d; sign = '-'; } ht_snprintf(str2, sizeof str2, "%s%c%x", func, sign, d); } else { strcpy(str2, "?"); } list->insert_str_extra(xcount, x->addr, str, xref_type(x->type), str2); }); list->attachTitle(text); list->update(); dialog->insert(text); dialog->insert(list); dialog->insert(search_for_xrefs); dialog->insert(delete_xref); dialog->insert(new_xref); result = dialog->run(false); ht_listbox_data data; ViewDataBuf vdb(list, &data, sizeof data); switch (result) { case 666: searchForXRefs(Addr); break; case 667: if (xcount) { analy->deleteXRef(Addr, (Address*)list->getExtra(data.data->cursor_ptr)); analy->makeDirty(); analy_sub->output->invalidateCache(); } break; case 668: { char result[256]; ht_snprintf(str, sizeof str, "add xref from %y", Addr); result[0] = 0; while (inputbox(str, "to ~address: ", result, 255, HISTATOM_GOTO)) { viewer_pos res_pos; if (!string_to_pos(result, &res_pos)) { errorbox(globalerror); continue; } Address *a; if (!convertViewerPosToAddress(res_pos, &a)) { errorbox("invalid address"); delete a; continue; } if (!analy->addXRef(Addr, a, xrefoffset)) { // FIXME: some error msg } delete a; analy->makeDirty(); analy_sub->output->invalidateCache(); break; } break; } case button_ok: if (xcount) gotoAddress((Address*)list->getExtra(data.data->cursor_ptr), this); break; } dialog->getbounds(&b); dialog->done(); delete dialog; } while (result >= 666 && result <= 668);}bool ht_aviewer::func_handler(eval_scalar *result, char *name, eval_scalarlist *params){ eval_func myfuncs[] = { {"addressOf", (void*)&aviewer_func_address_of, {SCALAR_STR}, "return address of symbol"}, {"fileofs", (void*)&aviewer_func_fileofs, {SCALAR_INT}, "convert file offset to address"},// {"addr", (void*)&aviewer_func_addr, {SCALAR_STR}}, "", {NULL} }; return std_eval_func_handler(result, name, params, myfuncs);}bool ht_aviewer::symbol_handler(eval_scalar *result, char *name){ uint64 v; viewer_pos vp; Address *w; if (*name == '@') { name++; if (parseIntStr(name, v, 10)) { if (*name) return false; if (!offset_to_pos(v, &vp)) { set_eval_error("invalid offset: %08qx", v); return false; } convertViewerPosToAddress(vp, &w); uint64 b = 0; w->putIntoUInt64(b); delete w; scalar_create_int_q(result, b); return true; } // invalid number after @ } else { if (strcmp(name, "$")==0) { if (getCurrentAddress(&w)) { uint64 b = 0; w->putIntoUInt64(b); scalar_create_int_q(result, b); delete w; return true; } else { return false; } } Symbol *l = analy->getSymbolByName(name); if (l) { w=l->location->addr; uint64 b; w->putIntoUInt64(b); scalar_create_int_q(result, b); return true; } } return ht_uformat_viewer::symbol_handler(result, name);} bool ht_aviewer::qword_to_pos(uint64 q, viewer_pos *pos){ if (!analy) return false; Address *a=analy->createAddress(); a->getFromUInt64(q); if (analy->validAddress(a, scvalid)) { bool res = convertAddressToViewerPos(a, pos); delete a; return res; } else { global_analyser_address_string_format = ADDRESS_STRING_FORMAT_LEADING_ZEROS; ht_snprintf(globalerror, GLOBAL_ERROR_SIZE, "address %y is invalid", a); } delete a; return false;}/* * CLASS ht_analy_sub */void ht_analy_sub::init(File *file, ht_aviewer *A, Analyser *analyser, Address *Lowestaddress, Address *Highestaddress){ ht_sub::init(file); aviewer = A; analy = analyser; output = new AnalyserHTOutput(); ((AnalyserHTOutput*)output)->init(analy); lowestaddress = Lowestaddress->clone(); highestaddress = Highestaddress->clone();}void ht_analy_sub::done(){ delete lowestaddress; delete highestaddress; output->done(); delete output; ht_sub::done();}bool ht_analy_sub::closest_line_id(LINE_ID *line_id){ if (!prev_line_id(line_id, 1)) { if (!next_line_id(line_id, 1)) { first_line_id(line_id); } } return true;}bool ht_analy_sub::convert_ofs_to_id(const FileOfs offset, LINE_ID *line_id){ viewer_pos a; if (!uformat_viewer->offset_to_pos(offset, &a)) return false; *line_id = a.u.line_id; return true;}void ht_analy_sub::first_line_id(LINE_ID *line_id){ clear_line_id(line_id); uint64 u; lowestaddress->putIntoUInt64(u); line_id->id1 = u >> 32; line_id->id2 = u;}bool ht_analy_sub::getline(char *line, int maxlen, const LINE_ID line_id){ if (!analy) return false; Address *a = analy->createAddress(); a->getFromUInt64((uint64(line_id.id1) << 32) + line_id.id2); bool res = output->getLineString(line, maxlen, a, (int)line_id.id3); delete a; return res;}void ht_analy_sub::last_line_id(LINE_ID *line_id){ clear_line_id(line_id); uint64 u; highestaddress->putIntoUInt64(u); line_id->id1 = u >> 32; line_id->id2 = u;}int ht_analy_sub::next_line_id(LINE_ID *line_id, int n){ if (!analy) return false; Address *a = analy->createAddress(); a->getFromUInt64((uint64(line_id->id1) << 32) + line_id->id2); int line = line_id->id3; int res = output->nextLine(a, line, n, highestaddress); if (res) { line_id->id3 = line; uint64 u; a->putIntoUInt64(u); line_id->id1 = u >> 32; line_id->id2 = u; } delete a; return res;}int ht_analy_sub::prev_line_id(LINE_ID *line_id, int n){ if (!analy) return false; Address *a = analy->createAddress(); a->getFromUInt64((uint64(line_id->id1) << 32) + line_id->id2); int line = line_id->id3; int res = output->prevLine(a, line, n, lowestaddress); if (res) { line_id->id3 = line; uint64 u; a->putIntoUInt64(u); line_id->id1 = u >> 32; line_id->id2 = u; } delete a; return res;}ht_search_result *ht_analy_sub::search(ht_search_request *search, FileOfs start, FileOfs end){ // FIXME: viewer pos Address *st = NULL; ht_search_result *r = NULL; while (!r) { st = (Address *)analy->initialized->findNext(st); if (!st) break; area_s *s = analy->initialized->getArea(st); if (!s) break; st = (Address *)s->end; FileOfs fstart, fend; FileOfs fsize; viewer_pos vp_start, vp_end; aviewer->convertAddressToViewerPos((Address *)s->start, &vp_start); if (!aviewer->pos_to_offset(vp_start, &fstart)) assert(0); Address *send = (Address*)s->end->clone(); send->add(-1); aviewer->convertAddressToViewerPos(send, &vp_end); delete send; if (!aviewer->pos_to_offset(vp_end, &fend)) assert(0); fsize = fend - fstart; if (search->search_class == SC_PHYSICAL && search->type == ST_EXPR) { r = linear_expr_search(search, start, end, this, uformat_viewer, fstart, fsize); } else if (search->search_class == SC_PHYSICAL && search->type == ST_FXBIN) { r = linear_bin_search(search, start, end, file, fstart, fsize); } } return r;}void ht_analy_sub::setAnalyser(Analyser *Analy){ analy = Analy; output->analy = Analy; output->invalidateCache();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -