📄 htanaly.cc
字号:
if (o != INVALID_FILE_OFS) { *ofs=o; return true; } } return false;}bool ht_aviewer::pos_to_string(viewer_pos p, char *result, int maxlen){ if (!analy) return false; Address *a; if (!convertViewerPosToAddress(p, &a)) return false; Location *addr = analy->getLocationByAddress(a); if (addr && addr->label) { ht_strlcpy(result, addr->label->name, maxlen); return true; } addr = analy->getFunctionByAddress(a); if (addr && addr->label) { int d = 0; a->difference(d, addr->addr); ht_snprintf(result, maxlen, "%s+0%xh", addr->label->name, d); return true; } global_analyser_address_string_format = ADDRESS_STRING_FORMAT_LEADING_ZEROS | ADDRESS_STRING_FORMAT_ADD_H; ht_snprintf(result, maxlen, "%y", a); return true;}bool ht_aviewer::convertViewerPosToAddress(const viewer_pos &p, Address **a){ *a = analy->createAddress(); (*a)->getFromUInt64((uint64(p.u.line_id.id1) << 32) + p.u.line_id.id2); return true;}bool ht_aviewer::convertAddressToViewerPos(Address *a, viewer_pos *p){ if (a && a->isValid()) { clear_viewer_pos(p); p->u.sub = analy_sub; uint64 u; a->putIntoUInt64(u); p->u.line_id.id1 = u >> 32; p->u.line_id.id2 = u; p->u.line_id.id3 = 0; return true; } else { return false; }}const char *ht_aviewer::func(uint i, bool execute){ switch (i) { case 8: if (execute) { sendmsg(cmd_analyser_symbols); } return "symbols"; default: return ht_uformat_viewer::func(i, execute); } return NULL;}static int aviewer_func_addr(eval_scalar *result, eval_str *str){ ht_aviewer *aviewer = (ht_aviewer*)eval_get_context(); Address *addr = aviewer->analy->createAddress(); int l = addr->parseString(str->value, str->len, aviewer->analy); if (l) { uint64 q; if (addr->putIntoUInt64(q)) { scalar_create_int_q(result, q); return 1; } } else { char buffer[1024]; bin2str(buffer, str->value, MIN((uint)str->len, sizeof buffer)); set_eval_error("invalid address '%s'", buffer); } return 0;}static int aviewer_func_address_of(eval_scalar *result, eval_str *str){ ht_aviewer *aviewer = (ht_aviewer*)eval_get_context(); char buffer[1024]; bin2str(buffer, str->value, MIN((uint)str->len, sizeof buffer)); Symbol *l; if ((l = aviewer->analy->getSymbolByName(buffer))) { uint64 q; if (l->location->addr->putIntoUInt64(q)) { scalar_create_int_q(result, q); return 1; } } else { set_eval_error("invalid label '%s'", buffer); } return 0;}static int aviewer_func_fileofs(eval_scalar *result, eval_int *i){ ht_aviewer *aviewer = (ht_aviewer*)eval_get_context(); viewer_pos p; if (aviewer->offset_to_pos(i->value, &p)) { Address *a; uint64 q; aviewer->convertViewerPosToAddress(p, &a); std::auto_ptr<Address> blub(a); if (a->putIntoUInt64(q)) { scalar_create_int_q(result, q); return 1; } } else { set_eval_error("invalid file offset or no corresponding address for '0%xh'", i->value); } return 0;}/* * for assembler */static int ht_aviewer_symbol_to_addr(void *Aviewer, const char *s, uint64 &v){ // FIXNEW ht_aviewer *aviewer = (ht_aviewer*)Aviewer; Address *a; if (*s == '@') { s++; if (str2int(s, v, 10)) { viewer_pos vp; if (!aviewer->offset_to_pos(v, &vp)) { set_eval_error("invalid offset: %08qx", v); return false; } aviewer->convertViewerPosToAddress(vp, &a); std::auto_ptr<Address> blub(a); if (a->putIntoUInt64(v)) { return true; } } // invalid number after @ return false; } else if (strcmp(s, "&") ==0) { if (aviewer->getCurrentAddress(&a)) { a->putIntoUInt64(v); delete a; return true; } else { return false; } } else { Symbol *l = aviewer->analy->getSymbolByName(s); if (l) { // Label a = l->location->addr; if (a->putIntoUInt64(v)) { return true; } } } return false;}static void setdatastr(ht_view *v, char *str){ ht_inputfield_data id; id.textlen = strlen(str); id.text = (byte*)str; v->databuf_set(&id, sizeof id);}static void getdatastr(ht_inputfield_data *id, char *result){ memcpy(result, id->text, id->textlen); result[id->textlen]=0;}struct output_dialog_data { ht_inputfield_data id1; ht_listpopup_data lp; ht_inputfield_data id2; ht_inputfield_data id3;};void ht_aviewer::generateOutputDialog(){ if (!analy) return; if (analy->active) { infobox("Please wait until analyser has finished before generating output file!"); if (analy->active) return; } Bounds b; b.w=50; b.h=15; center_bounds(&b); ht_dialog *dialog; NEW_OBJECT(dialog, ht_dialog, &b, "generate analyser output", FS_KILLER | FS_TITLE | FS_MOVE); ht_view *v1, *v2; b.assign(2, 2, 25, 1); NEW_OBJECT(v1, ht_strinputfield, &b, 260); dialog->insert(v1); b.assign(2, 1, 25, 1); NEW_OBJECT(v2, ht_label, &b, "output ~filename:", v1); dialog->insert(v2); String filename, basename, basename2, suffix; file->getFilename(filename); filename.rightSplit('/', suffix, basename2); basename2.rightSplit('.', basename, suffix); basename += ".out"; setdatastr(v1, basename.contentChar()); b.assign(29, 2, 15, 1); NEW_OBJECT(v1, ht_listpopup, &b); ((ht_listpopup*)v1)->insertstring("HTML"); ((ht_listpopup*)v1)->insertstring("plain text"); dialog->insert(v1); b.assign(29, 1, 15, 1); NEW_OBJECT(v2, ht_label, &b, "~output format:", v1); dialog->insert(v2); b.assign(2, 5, 35, 1); NEW_OBJECT(v1, ht_strinputfield, &b, 260); dialog->insert(v1); b.assign(2, 4, 35, 1); NEW_OBJECT(v2, ht_label, &b, "~start address:", v1); viewer_pos cur; if (get_current_pos(&cur)) { char str[1024]; pos_to_string(cur, str, sizeof str); setdatastr(v1, str); } dialog->insert(v2); b.assign(2, 8, 35, 1); NEW_OBJECT(v1, ht_strinputfield, &b, 260); dialog->insert(v1); b.assign(2, 7, 35, 1); NEW_OBJECT(v2, ht_label, &b, "~end address:", v1); dialog->insert(v2);// setdatastr(v1, "#1000"); if (get_current_pos(&cur)) { char str[1024]; pos_to_string(cur, str, sizeof str); strcat(str, "+20"); setdatastr(v1, str); } b.assign(13, 11, 9, 2); NEW_OBJECT(v1, ht_button, &b, "O~k", button_ok); dialog->insert(v1); b.assign(27, 11, 9, 2); NEW_OBJECT(v1, ht_button, &b, "~Cancel", button_cancel); dialog->insert(v1); while (dialog->run(false) == button_ok) { char filename[260]; char start_str[1024], end_str[1024]; viewer_pos start, end; bool by_lines; output_dialog_data odd; ViewDataBuf vdb(dialog, &odd, sizeof odd); getdatastr(&odd.id1, filename); getdatastr(&odd.id2, start_str); getdatastr(&odd.id3, end_str); if (start_str[0] == 0) { convertAddressToViewerPos(analy_sub->lowestaddress, &start); } else { if (!string_to_pos(start_str, &start)) { errorbox(globalerror); continue; } } if (end_str[0] == 0) { convertAddressToViewerPos(analy_sub->highestaddress, &end); } else { if (!string_to_pos(end_str, &end)) { errorbox(globalerror); continue; } } Address *start_addr, *end_addr; if (!convertViewerPosToAddress(start, &start_addr) || !convertViewerPosToAddress(end, &end_addr)) { errorbox("invalid address"); continue; } try { String name(filename); LocalFile s(name, IOAM_WRITE, FOM_CREATE); AnalyserOutput *out; switch (odd.lp.cursor_pos) { case 0: out = new AnalyserHTMLOutput(); ((AnalyserHTMLOutput*)out)->init(analy, &s); break; case 1: out = new AnalyserTxtOutput(); ((AnalyserTxtOutput*)out)->init(analy, &s); break; } out->generateFile(start_addr, end_addr); out->done(); delete out; } catch (const IOException &e) { infobox("couldnt create file '%y': %y.", &filename, &e); continue; } break; } dialog->done(); delete dialog;}bool ht_aviewer::canCreateAddress(Address *addr, bool error_msg){ Location *ctx = analy->getLocationContextByAddress(addr); if (ctx && ctx->addr->compareTo(addr) != 0) { if (error_msg) { global_analyser_address_string_format = ADDRESS_STRING_FORMAT_LEADING_ZEROS; errorbox("Can't create new symbol: Address %y belongs to %y (%s)", addr, ctx->addr, ctx->label ? ctx->label->name : "unnamed"); } return false; } return true;}void ht_aviewer::dataIntDialog(taddr_int_subtype subtype, int length){ if (!analy) return; Address *current_address; if (!getCurrentAddress(¤t_address)) return; if (!canCreateAddress(current_address, true)) { delete current_address; return; } if (analy->validAddress(current_address, scinitialized)) { analy->data->setIntAddressType(current_address, subtype, length); } delete current_address;}void ht_aviewer::dataStringDialog(){ if (!analy) return; Address *current_address; if (!getCurrentAddress(¤t_address)) return; if (!canCreateAddress(current_address, true)) { delete current_address; return; }/* Bounds b; b.w=50; b.h=15; center_bounds(&b); ht_dialog *dialog; NEW_OBJECT(dialog, ht_dialog, &b, "interprete data as string", FS_KILLER | FS_TITLE | FS_MOVE); while (dialog->run(false)==button_ok) { } dialog->done(); delete dialog;*/ if (analy->validAddress(current_address, scinitialized)) { byte buffer[1024]; Location *a = analy->enumLocations(current_address); int d = sizeof buffer; if (a) a->addr->difference(d, current_address); uint bz = analy->bufPtr(current_address, buffer, MIN(sizeof buffer, (uint)d)); if (bz > 2) { analy_string *str = string_test(buffer, bz); if (str) { char string1[128], string2[128]; str->render_string(string2, sizeof string2); ht_snprintf(string1, sizeof string1, "%s_%s", str->name(), string2); make_valid_name(string2, string1); if (analy->addAddressSymbol(current_address, string2, label_data)) { analy->addComment(current_address, 0, ""); } analy->data->setArrayAddressType(current_address, dst_string, str->length()); str->done(); delete str; } } } delete current_address;}struct export_dialog_data { ht_inputfield_data id1; ht_listpopup_data lp;};void ht_aviewer::exportFileDialog(){ if (!analy) return; if (analy->active) { infobox("Please wait until analyser has finished before exporting file!"); if (analy->active) return; } Bounds b; b.w=50; b.h=12; center_bounds(&b); ht_dialog *dialog; NEW_OBJECT(dialog, ht_dialog, &b, "export analyser information", FS_KILLER | FS_TITLE | FS_MOVE); ht_view *v1, *v2; b.assign(2, 2, 35, 1); NEW_OBJECT(v1, ht_strinputfield, &b, 260); dialog->insert(v1); b.assign(2, 1, 35, 1); NEW_OBJECT(v2, ht_label, &b, "output ~filename:", v1); dialog->insert(v2); String filename, basename, suffix; file->getFilename(filename); filename.rightSplit('.', basename, suffix); basename += ".exp"; setdatastr(v1, basename.contentChar()); b.assign(2, 5, 25, 1); NEW_OBJECT(v1, ht_listpopup, &b); ((ht_listpopup*)v1)->insertstring(".sym symbol file"); dialog->insert(v1); b.assign(2, 4, 25, 1); NEW_OBJECT(v2, ht_label, &b, "~export format:", v1); dialog->insert(v2); b.assign(13, 8, 9, 2); NEW_OBJECT(v1, ht_button, &b, "O~k", button_ok); dialog->insert(v1); b.assign(27, 8, 9, 2); NEW_OBJECT(v1, ht_button, &b, "~Cancel", button_cancel); dialog->insert(v1); while (dialog->run(false) == button_ok) { char filename[260]; export_dialog_data edd; ViewDataBuf vdb(dialog, &edd, sizeof edd); getdatastr(&edd.id1, filename); String name(filename); LocalFile s(name, IOAM_WRITE, FOM_CREATE); try { switch (edd.lp.cursor_pos) { case 0: export_to_sym(analy, &s); break; } } catch (const IOException &) { infobox("couldnt create file '%s'.", filename); continue; } break; } dialog->done(); delete dialog;}bool ht_aviewer::getCurrentAddress(Address **a){ viewer_pos vp; if (!get_current_pos(&vp)) return false; return convertViewerPosToAddress(vp, a);}bool ht_aviewer::get_current_offset(FileOfs *ofs){ if (ht_uformat_viewer::get_current_offset(ofs)) { return true; } else { Address *a; if (!getCurrentAddress(&a)) return false; *ofs = analy->addressToFileofs(a); delete a; return *ofs != INVALID_FILE_OFS; }}bool ht_aviewer::get_hscrollbar_pos(int *pstart, int *psize){ if (analy_sub) { // FIXNEW/* if (analy_sub->highestaddress->difference(s, analy_sub->lowestaddress) && s) { int z=MIN(size.h*16, (int)(top.line_id.id1-analy_sub->lowestaddress)); return scrollbar_pos(top.line_id.id1-analy_sub->lowestaddress, z, s, pstart, psize); }*/ } return false;}void ht_aviewer::getminbounds(int *width, int *height){ *width = 25; *height = 4;}int ht_aviewer::get_pindicator_str(char *buf, int max_len){ Address *addr; if (analy && getCurrentAddress(&addr)) { std::auto_ptr<Address> blub(addr); FileOfs o; global_analyser_address_string_format = ADDRESS_STRING_FORMAT_COMPACT; if (get_current_offset(&o)) { return ht_snprintf(buf, max_len, " %y/@%08qx%s ", addr, o, (analy->isDirty())?" dirty":""); } else { return ht_snprintf(buf, max_len, " %y%s ", addr, (analy->isDirty())?" dirty":""); } } else { return ht_snprintf(buf, max_len, " ? "); }}bool ht_aviewer::gotoAddress(Address *a, ht_view *source_object){ viewer_pos p; if (analy) { if (!analy->validAddress(a, scvalid)) return false; } // FIXME: insert a->compare(hi, low address) here if (convertAddressToViewerPos(a, &p)) { return goto_pos(p, source_object); } return false;}void ht_aviewer::handlemsg(htmsg *msg){ switch (msg->msg) { case msg_contextmenuquery: { ht_static_context_menu *m = new ht_static_context_menu(); m->init("~Analyser");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -