📄 out.cc
字号:
default: putElement(ELEMENT_TYPE_HIGHLIGHT_DATA_CODE, "db ??"); } } break; } case dt_array: { if (analy->validAddress(addr, scinitialized)) { switch (cur_addr->type.array_subtype) { case dst_string: { char buf[1024]; byte bufread[1024]; char *b; int r = analy->bufPtr(addr, bufread, MIN(cur_addr->type.length, sizeof bufread)); strcpy(buf, "db \\@s\""); b = buf + 16 + escape_special(buf+16, 100, bufread, r, "\"", false); *b++ = '\"'; *b = 0; putElement(ELEMENT_TYPE_HIGHLIGHT_DATA_CODE, buf); bytes_line = want_bytes_line = cur_addr->type.length; break; } default: {assert(0);} } } else { putElement(ELEMENT_TYPE_HIGHLIGHT_DATA_CODE, "db ?"); } break; } default: { assert(0); } } } else { // not a known address bytes_line = want_bytes_line = 1; byte c; if (analy->validAddress(addr, scinitialized) && (analy->bufPtr(addr, &c, 1)==1)) { char buf[20]; sprintf(buf, "db \\@n%02xh ", c); putElement(ELEMENT_TYPE_HIGHLIGHT_DATA_CODE, buf); sprintf(buf, "; '%c'", (c<32)?32:c); putElement(ELEMENT_TYPE_COMMENT, buf); } else { putElement(ELEMENT_TYPE_HIGHLIGHT_DATA_CODE, "db ??"); } } } else { // invalid addr Address *next = analy->nextValid(Addr); int d; if (next && next->isValid() && next->difference(d, Addr)) { bytes_line += d; char buf[100]; sprintf(buf, "db ?? * %d", d); putElement(ELEMENT_TYPE_HIGHLIGHT_DATA_CODE, buf); } else { bytes_line = want_bytes_line = 1; putElement(ELEMENT_TYPE_HIGHLIGHT_DATA_CODE, "db ??"); } } } endLine(); endAddr();}Stream *AnalyserOutput::getGenerateStream(){ return NULL;}int AnalyserOutput::generateFile(Address *from, Address *to){ if (analy->active) return OUTPUT_GENERATE_ERR_ANALYSER_NOT_FINISHED; if (!from->isValid() || !to->isValid()) return OUTPUT_GENERATE_ERR_INVAL; Stream *out = getGenerateStream(); if (!out) return OUTPUT_GENERATE_ERR_INVAL; header(); int line = 0; int len = 0; while (from->compareTo(to) <= 0) { char buffer[1024]; if (getLineString(buffer, sizeof buffer, from, line)) { // FIXME: remove strlen uint wr = strlen(buffer); if (out->write(buffer, wr) != wr) return OUTPUT_GENERATE_ERR_STREAM; int tmplen; if (getLineByteLength(tmplen, from, line)) { len += tmplen; } line++; } else { from->add(len); len = 0; line = 0; } } footer(); return OUTPUT_GENERATE_ERR_OK;}void AnalyserOutput::generatePage(Address *from, int lines){}OutAddr *AnalyserOutput::getAddr(Address *Addr){ char tbuf[1024]; Addr->stringify(tbuf, 1024, 0); DPRINTF("%s -- ",tbuf); if (!addr->isValid() || Addr->compareTo(addr) != 0) { assert(addr != Addr); DPRINTF("not cached1 --"); delete addr; addr = Addr->clone(); OutAddr oatmp(addr, 0); OutAddr *oa = (OutAddr*)out_addrs->get(out_addrs->find(&oatmp)); if (!oa) { DPRINTF("generate\n"); if (out_addrs->count() > 1024) { reset(); delete addr; addr = Addr->clone(); } oa = new OutAddr(Addr, current_time); generateAddr(Addr, oa); out_addrs->insert(oa); } else { DPRINTF("but cached2 "); if (oa->time != current_time) { DPRINTF("(and generate)"); generateAddr(Addr, oa); oa->updateTime(current_time); } DPRINTF("\n"); } cur_out_addr = oa; } else { DPRINTF("Cached! "); if (cur_out_addr->time != current_time) { DPRINTF("(but generate)"); generateAddr(Addr, cur_out_addr); cur_out_addr->updateTime(current_time); } DPRINTF("\n"); } return cur_out_addr;}OutLine *AnalyserOutput::getLine(Address *Addr, int line){ return getAddr(Addr)->getLine(line);}bool AnalyserOutput::getLineString(char *buf, int maxlen, Address *Addr, int line){ OutLine *ol = getLine(Addr, line); if (ol) { if (maxlen>0) { int len = MIN(ol->textlen+1, maxlen); len--; memcpy(buf, ol->text, len); buf[len] = 0; } return true; } else { return false; }}bool AnalyserOutput::getLineByteLength(int &len, Address *Addr, int line){ OutLine *ol = getLine(Addr, line); if (ol) { len = ol->bytes; return true; } else { return false; }}int AnalyserOutput::getLineCount(Address *Addr){ return getAddr(Addr)->lines->count();}int AnalyserOutput::getAddrByteLength(Address *Addr){ return getAddr(Addr)->bytes;}void AnalyserOutput::header(){ // STUB}char *AnalyserOutput::link(char *s, Address *Addr){ strcpy((char*)temp_buffer, s); return (char*)temp_buffer;}char *AnalyserOutput::externalLink(char *s, uint32 type1, uint32 type2, uint32 type3, uint32 type4, void *special){ strcpy((char*)temp_buffer, s); return (char*)temp_buffer;}void AnalyserOutput::invalidateCache(){ DPRINTF("invalidateCache()\n"); current_time++; if ((current_time % 50)==0) { // collect garbage reset(); }}int AnalyserOutput::nextLine(Address *&Addr, int &line, int n, Address *max){ int res = 0; int len; while (n--) { if (getLineByteLength(len, Addr, line + 1)) { line++; } else { getLineByteLength(len, Addr, line); if (Addr->compareTo(max) >= 0) return res; if (!Addr->add(len)) return res; line = 0; } res++; } return res;}int AnalyserOutput::prevLine(Address *&Addr, int &line, int n, Address *min){//#undef DPRINTF2//#define DPRINTF2(msg...) {ht_snprintf(tbuf, 1024, msg); fprintf(stderr, "%s", tbuf);}// char tbuf[1024]; DPRINTF2("prev_line(%y, %d, %d, %y)\n", Addr, line, n, min); int res = 0; int cmp = Addr->compareTo(min); DPRINTF2("cmp=%d\n", cmp); /* * If we have reached |min| and line==0, we're on top */ if (cmp < 0 || (cmp == 0 && line == 0)) { DPRINTF2("geht nicht\n"); return 0; } /* * A simple case: no address-change, only line-changes. * Go up while line > 0 */ while (n && line) { DPRINTF2("simple\n"); n--; line--; res++; } DPRINTF2("test\n"); if (!n) return res; DPRINTF2("test2\n"); /* * Now it gets complicated. We have to go to an other address. * First we have to figure out where we should start to search for * the previous address. */ int min_length, max_length, min_look_ahead, avg_look_ahead, addr_align; if (analy->disasm) { analy->disasm->getOpcodeMetrics(min_length, max_length, min_look_ahead, avg_look_ahead, addr_align); } else { min_look_ahead = 1; avg_look_ahead = 1; } int l = n*avg_look_ahead; if (l < min_look_ahead) l = min_look_ahead; /* * The disassember whats us to go |l| bytes back */ Address *search_addr = Addr->clone(); if (!search_addr->add(-l) || search_addr->compareTo(min) < 0) { /* * It isnt possible, to go |l| bytes back. So we start at |min|. */ delete search_addr; search_addr = min->clone(); } DPRINTF2("search-start: %y\n", search_addr); /* * |prev| contains the previous "logical" location. * That is some address known to be "atomic". */ Location *prev = analy->enumLocationsReverse(Addr); if (prev) { DPRINTF2("prev: %y\n", prev->addr); /* * |prevnext| contains the "end address" of |prev|. * So we know how long (how much bytes) prev is. */ Address *prevnext = prev->addr->clone(); if (prevnext->add(getAddrByteLength(prev->addr))) { DPRINTF2("mid-test: prevnext %y\n", prevnext); if (prevnext->compareTo(Addr) > 0) { /* * We were in the middle of a location. * We solve this situation by starting a new search * with |prev->addr|. This is counted as "one line up". */ delete Addr; delete search_addr; delete prevnext; Addr = prev->addr->clone(); line = 0; res++; DPRINTF2("mid\n"); return prevLine(Addr, line, n-1, min)+res; } if (prevnext->compareTo(Addr) == 0) { delete Addr; delete search_addr; delete prevnext; Addr = prev->addr->clone(); line = getLineCount(prev->addr)-1; res++; DPRINTF2("mid2\n"); return prevLine(Addr, line, n-1, min)+res; } DPRINTF2("prev: %y prevnext: %y search_addr: %y\n", prev->addr, prevnext, search_addr); Address *oldprevnext = prevnext->clone(); if (prevnext->add(l) && prevnext->compareTo(Addr) >= 0) { delete search_addr; search_addr = oldprevnext; DPRINTF2("prevnext: %y Addr: %y\n", prevnext, Addr); DPRINTF2("search_addr: %y\n", search_addr); DPRINTF2("mid3\n"); } else { delete oldprevnext; } } delete prevnext; } int search_line = 0; if (search_addr->compareTo(min) < 0) { /* * We have to start the search at |min|. */ DPRINTF2("search_addr < min\n"); delete search_addr; search_addr = min->clone(); } Address *addrbuf[1024]; int linebuf[1024]; int i = 0; int len; Address *next_addr = search_addr->clone(); while (1) { DPRINTF2("search_addr: (%y, %d) ", search_addr, search_line); DPRINTF2("next_addr: %y \n", next_addr); if (search_addr->compareTo(Addr) >= 0) { if (search_line >= line || (search_addr->compareTo(Addr) > 0)) break; } if (getLineByteLength(len, search_addr, search_line)) { next_addr->add(len); search_line++; } else { delete search_addr; search_addr = next_addr->clone(); search_line = 0; continue; } addrbuf[i & 1023] = search_addr->clone(); linebuf[i & 1023] = search_line-1; i++; if (i >= 1023) break; } delete next_addr; delete search_addr; if (!i) { DPRINTF2("no i!\n"); return res; } delete Addr; if (i >= n) { Addr = addrbuf[(i-n) & 1023]->clone(); line = linebuf[(i-n) & 1023]; res += n; n = 0; } else { Addr = addrbuf[0]->clone(); line = linebuf[0]; res += i; n -= i; } for (int j=0; j < i; j++) delete addrbuf[j]; if (n) return prevLine(Addr, line, n, min) + res; return res;}void AnalyserOutput::putElement(int element_type, const char *element){ write(element);}void AnalyserOutput::reset(){ delete addr; addr = new InvalidAddress; cur_out_addr = NULL; out_addrs->delAll();}void AnalyserOutput::write(const char *s){ int len = elementLength(s); len = MIN(len, work_buffer_end-work_buffer); memcpy(work_buffer, s, len); work_buffer += len;}void AnalyserOutput::write(const char *s, int n){ n = MIN(n, work_buffer_end-work_buffer); memcpy(work_buffer, s, n); work_buffer += n;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -