diff --git a/src/gui/Src/Tracer/TraceFileDump.cpp b/src/gui/Src/Tracer/TraceFileDump.cpp index 1ccd1a30a9..2068d854c0 100644 --- a/src/gui/Src/Tracer/TraceFileDump.cpp +++ b/src/gui/Src/Tracer/TraceFileDump.cpp @@ -62,6 +62,33 @@ std::vector TraceFileDump::getBytes(duint addr, duint size, unsig return buffer; } +// find references to the memory address +std::vector TraceFileDump::getReferences(duint startAddr, duint endAddr) const +{ + std::vector index; + if(endAddr < startAddr) + std::swap(endAddr, startAddr); + // find references to the memory address + auto it = dump.lower_bound({endAddr, maxIndex + 1}); + while(it != dump.end() && it->first.addr >= startAddr && it->first.addr <= endAddr) + { + index.push_back(it->first.index); + ++it; + } + if(index.empty()) + return index; + // rearrange the array and remove duplicates + std::sort(index.begin(), index.end()); + std::vector result; + result.push_back(index[0]); + for(size_t i = 1; i < index.size(); i++) + { + if(index[i] != result[result.size() - 1]) + result.push_back(index[i]); + } + return result; +} + //void TraceFileDump::addMemAccess(duint addr, DumpRecord record) //{ // Key location = {addr, maxIndex}; @@ -99,9 +126,9 @@ void TraceFileDump::findMemAreas() // find first access to addr do { - auto it = dump.lower_bound({addr - 1, maxIndex}); + auto it = dump.lower_bound({addr - 1, maxIndex + 1}); // try to find out if addr-1 is in the dump - for(; it != dump.end(); it = dump.lower_bound({addr - 1, maxIndex})) + for(; it != dump.end(); it = dump.lower_bound({addr - 1, maxIndex + 1})) { if(it->first.addr != addr - 1) break; diff --git a/src/gui/Src/Tracer/TraceFileDump.h b/src/gui/Src/Tracer/TraceFileDump.h index b6245a91ef..b1a3a8c4d3 100644 --- a/src/gui/Src/Tracer/TraceFileDump.h +++ b/src/gui/Src/Tracer/TraceFileDump.h @@ -30,6 +30,7 @@ class TraceFileDump // Read a byte at "addr" at the moment given in "index" unsigned char getByte(Key location, bool & success) const; std::vector getBytes(duint addr, duint size, unsigned long long index) const; + std::vector getReferences(duint startAddr, duint endAddr) const; // Insert a memory access record //void addMemAccess(duint addr, DumpRecord record); void addMemAccess(duint addr, const void* oldData, const void* newData, size_t size); diff --git a/src/gui/Src/Tracer/TraceFileReader.cpp b/src/gui/Src/Tracer/TraceFileReader.cpp index d835d6d2e2..11f7ebcb08 100644 --- a/src/gui/Src/Tracer/TraceFileReader.cpp +++ b/src/gui/Src/Tracer/TraceFileReader.cpp @@ -621,7 +621,7 @@ void TraceFileReader::buildDump(unsigned long long index) void TraceFileReader::buildDumpTo(unsigned long long index) { auto start = dump.getMaxIndex(); - for(auto i = start + 1; i <= index; i++) + for(auto i = start + 1; i < index; i++) { dump.increaseIndex(); buildDump(i); @@ -644,6 +644,11 @@ void TraceFileReader::debugdump(unsigned long long index) } } +std::vector TraceFileReader::getReferences(duint startAddr, duint endAddr) const +{ + return dump.getReferences(startAddr, endAddr); +} + //TraceFilePage TraceFilePage::TraceFilePage(TraceFileReader* parent, unsigned long long fileOffset, unsigned long long maxLength) { diff --git a/src/gui/Src/Tracer/TraceFileReader.h b/src/gui/Src/Tracer/TraceFileReader.h index 785bd38879..25effd5c10 100644 --- a/src/gui/Src/Tracer/TraceFileReader.h +++ b/src/gui/Src/Tracer/TraceFileReader.h @@ -40,8 +40,8 @@ class TraceFileReader : public QObject void purgeLastPage(); - void buildDump(unsigned long long index); void buildDumpTo(unsigned long long index); + std::vector getReferences(duint startAddr, duint endAddr) const; void debugdump(unsigned long long index); signals: @@ -79,6 +79,7 @@ private slots: std::map pages; TraceFilePage* getPage(unsigned long long index, unsigned long long* base); TraceFileDump dump; + void buildDump(unsigned long long index); QBeaEngine* mDisasm; }; diff --git a/src/gui/Src/Tracer/TraceFileSearch.cpp b/src/gui/Src/Tracer/TraceFileSearch.cpp index 03796538a9..ce0ea20b84 100644 --- a/src/gui/Src/Tracer/TraceFileSearch.cpp +++ b/src/gui/Src/Tracer/TraceFileSearch.cpp @@ -97,37 +97,86 @@ int TraceFileSearchMemReference(TraceFileReader* file, duint address) GuiReferenceAddColumn(100, QCoreApplication::translate("TraceFileSearch", "Disassembly").toUtf8().constData()); GuiReferenceAddCommand(QCoreApplication::translate("TraceFileSearch", "Follow index in trace").toUtf8().constData(), "gototrace 0x$1"); GuiReferenceSetRowCount(0); + bool useTraceDump = true; - for(unsigned long long index = 0; index < file->Length(); index++) + if(useTraceDump) { - bool found = false; - //Memory - duint memAddr[MAX_MEMORY_OPERANDS]; - duint memOldContent[MAX_MEMORY_OPERANDS]; - duint memNewContent[MAX_MEMORY_OPERANDS]; - bool isValid[MAX_MEMORY_OPERANDS]; - int memAccessCount = file->MemoryAccessCount(index); - if(memAccessCount > 0) + if(file->Length() > 0) { - file->MemoryAccessInfo(index, memAddr, memOldContent, memNewContent, isValid); - for(int i = 0; i < memAccessCount; i++) + file->buildDumpTo(file->Length() - 1); + auto results = file->getReferences(address, address + sizeof(duint) - 1); + for(size_t i = 0; i < results.size(); i++) { - found |= inRange(memAddr[i], address, address + sizeof(duint) - 1); + bool found = false; + unsigned long long index = results[i]; + //Memory + duint memAddr[MAX_MEMORY_OPERANDS]; + duint memOldContent[MAX_MEMORY_OPERANDS]; + duint memNewContent[MAX_MEMORY_OPERANDS]; + bool isValid[MAX_MEMORY_OPERANDS]; + int memAccessCount = file->MemoryAccessCount(index); + if(memAccessCount > 0) + { + file->MemoryAccessInfo(index, memAddr, memOldContent, memNewContent, isValid); + for(int i = 0; i < memAccessCount; i++) + { + found |= inRange(memAddr[i], address, address + sizeof(duint) - 1); + } + //Constants: TO DO + //Populate reference view + if(found) + { + GuiReferenceSetRowCount(count + 1); + GuiReferenceSetCellContent(count, 0, ToPtrString(file->Registers(index).regcontext.cip).toUtf8().constData()); + GuiReferenceSetCellContent(count, 1, file->getIndexText(index).toUtf8().constData()); + unsigned char opcode[16]; + int opcodeSize = 0; + file->OpCode(index, opcode, &opcodeSize); + zy.Disassemble(file->Registers(index).regcontext.cip, opcode, opcodeSize); + GuiReferenceSetCellContent(count, 2, zy.InstructionText(true).c_str()); + //GuiReferenceSetCurrentTaskProgress; GuiReferenceSetProgress + count++; + } + } } - //Constants: TO DO - //Populate reference view - if(found) + } + else + count = 0; + return count; + } + else + { + for(unsigned long long index = 0; index < file->Length(); index++) + { + bool found = false; + //Memory + duint memAddr[MAX_MEMORY_OPERANDS]; + duint memOldContent[MAX_MEMORY_OPERANDS]; + duint memNewContent[MAX_MEMORY_OPERANDS]; + bool isValid[MAX_MEMORY_OPERANDS]; + int memAccessCount = file->MemoryAccessCount(index); + if(memAccessCount > 0) { - GuiReferenceSetRowCount(count + 1); - GuiReferenceSetCellContent(count, 0, ToPtrString(file->Registers(index).regcontext.cip).toUtf8().constData()); - GuiReferenceSetCellContent(count, 1, file->getIndexText(index).toUtf8().constData()); - unsigned char opcode[16]; - int opcodeSize = 0; - file->OpCode(index, opcode, &opcodeSize); - zy.Disassemble(file->Registers(index).regcontext.cip, opcode, opcodeSize); - GuiReferenceSetCellContent(count, 2, zy.InstructionText(true).c_str()); - //GuiReferenceSetCurrentTaskProgress; GuiReferenceSetProgress - count++; + file->MemoryAccessInfo(index, memAddr, memOldContent, memNewContent, isValid); + for(int i = 0; i < memAccessCount; i++) + { + found |= inRange(memAddr[i], address, address + sizeof(duint) - 1); + } + //Constants: TO DO + //Populate reference view + if(found) + { + GuiReferenceSetRowCount(count + 1); + GuiReferenceSetCellContent(count, 0, ToPtrString(file->Registers(index).regcontext.cip).toUtf8().constData()); + GuiReferenceSetCellContent(count, 1, file->getIndexText(index).toUtf8().constData()); + unsigned char opcode[16]; + int opcodeSize = 0; + file->OpCode(index, opcode, &opcodeSize); + zy.Disassemble(file->Registers(index).regcontext.cip, opcode, opcodeSize); + GuiReferenceSetCellContent(count, 2, zy.InstructionText(true).c_str()); + //GuiReferenceSetCurrentTaskProgress; GuiReferenceSetProgress + count++; + } } } }