diff --git a/src/dbg/_scriptapi_argument.cpp b/src/dbg/_scriptapi_argument.cpp index cc2ccaa2..ef0fa647 100644 --- a/src/dbg/_scriptapi_argument.cpp +++ b/src/dbg/_scriptapi_argument.cpp @@ -29,7 +29,7 @@ SCRIPT_EXPORT bool Script::Argument::GetInfo(duint addr, ArgumentInfo* info) return false; if(info) { - strcpy_s(info->mod, argument.mod); + strcpy_s(info->mod, argument.mod().c_str()); info->rvaStart = argument.start; info->rvaEnd = argument.end; info->manual = argument.manual; @@ -67,7 +67,7 @@ SCRIPT_EXPORT bool Script::Argument::GetList(ListOf(ArgumentInfo) list) for(const auto & argument : argumentList) { ArgumentInfo scriptArgument; - strcpy_s(scriptArgument.mod, argument.mod); + strcpy_s(scriptArgument.mod, argument.mod().c_str()); scriptArgument.rvaStart = argument.start; scriptArgument.rvaEnd = argument.end; scriptArgument.manual = argument.manual; diff --git a/src/dbg/_scriptapi_bookmark.cpp b/src/dbg/_scriptapi_bookmark.cpp index f3a649f8..41d7ceb6 100644 --- a/src/dbg/_scriptapi_bookmark.cpp +++ b/src/dbg/_scriptapi_bookmark.cpp @@ -29,7 +29,7 @@ SCRIPT_EXPORT bool Script::Bookmark::GetInfo(duint addr, BookmarkInfo* info) return false; if(info) { - strcpy_s(info->mod, comment.mod); + strcpy_s(info->mod, comment.mod().c_str()); info->rva = comment.addr; info->manual = comment.manual; } @@ -60,7 +60,7 @@ SCRIPT_EXPORT bool Script::Bookmark::GetList(ListOf(BookmarkInfo) list) for(const auto & bookmark : bookmarkList) { BookmarkInfo scriptComment; - strcpy_s(scriptComment.mod, bookmark.mod); + strcpy_s(scriptComment.mod, bookmark.mod().c_str()); scriptComment.rva = bookmark.addr; scriptComment.manual = bookmark.manual; bookmarkScriptList.push_back(scriptComment); diff --git a/src/dbg/_scriptapi_comment.cpp b/src/dbg/_scriptapi_comment.cpp index bada3823..8c08cbf4 100644 --- a/src/dbg/_scriptapi_comment.cpp +++ b/src/dbg/_scriptapi_comment.cpp @@ -29,9 +29,9 @@ SCRIPT_EXPORT bool Script::Comment::GetInfo(duint addr, CommentInfo* info) return false; if(info) { - strcpy_s(info->mod, comment.mod); + strcpy_s(info->mod, comment.mod().c_str()); info->rva = comment.addr; - strcpy_s(info->text, comment.text); + strcpy_s(info->text, comment.text.c_str()); info->manual = comment.manual; } return true; @@ -61,9 +61,9 @@ SCRIPT_EXPORT bool Script::Comment::GetList(ListOf(CommentInfo) list) for(const auto & comment : commentList) { CommentInfo scriptComment; - strcpy_s(scriptComment.mod, comment.mod); + strcpy_s(scriptComment.mod, comment.mod().c_str()); scriptComment.rva = comment.addr; - strcpy_s(scriptComment.text, comment.text); + strcpy_s(scriptComment.text, comment.text.c_str()); scriptComment.manual = comment.manual; commentScriptList.push_back(scriptComment); } diff --git a/src/dbg/_scriptapi_function.cpp b/src/dbg/_scriptapi_function.cpp index 90817380..9288fb6c 100644 --- a/src/dbg/_scriptapi_function.cpp +++ b/src/dbg/_scriptapi_function.cpp @@ -29,7 +29,7 @@ SCRIPT_EXPORT bool Script::Function::GetInfo(duint addr, FunctionInfo* info) return false; if(info) { - strcpy_s(info->mod, function.mod); + strcpy_s(info->mod, function.mod().c_str()); info->rvaStart = function.start; info->rvaEnd = function.end; info->manual = function.manual; @@ -72,7 +72,7 @@ SCRIPT_EXPORT bool Script::Function::GetList(ListOf(FunctionInfo) list) for(const auto & function : functionList) { FunctionInfo scriptFunction; - strcpy_s(scriptFunction.mod, function.mod); + strcpy_s(scriptFunction.mod, function.mod().c_str()); scriptFunction.rvaStart = function.start; scriptFunction.rvaEnd = function.end; scriptFunction.manual = function.manual; diff --git a/src/dbg/_scriptapi_label.cpp b/src/dbg/_scriptapi_label.cpp index f12599bf..5a0531f4 100644 --- a/src/dbg/_scriptapi_label.cpp +++ b/src/dbg/_scriptapi_label.cpp @@ -34,9 +34,9 @@ SCRIPT_EXPORT bool Script::Label::GetInfo(duint addr, LabelInfo* info) return false; if(info) { - strcpy_s(info->mod, label.mod); + strcpy_s(info->mod, label.mod().c_str()); info->rva = label.addr; - strcpy_s(info->text, label.text); + strcpy_s(info->text, label.text.c_str()); info->manual = label.manual; } return true; @@ -66,9 +66,9 @@ SCRIPT_EXPORT bool Script::Label::GetList(ListOf(LabelInfo) list) for(const auto & label : labelList) { LabelInfo scriptLabel; - strcpy_s(scriptLabel.mod, label.mod); + strcpy_s(scriptLabel.mod, label.mod().c_str()); scriptLabel.rva = label.addr; - strcpy_s(scriptLabel.text, label.text); + strcpy_s(scriptLabel.text, label.text.c_str()); scriptLabel.manual = label.manual; labelScriptList.push_back(scriptLabel); } diff --git a/src/dbg/argument.cpp b/src/dbg/argument.cpp index 8889e6e0..172ceae6 100644 --- a/src/dbg/argument.cpp +++ b/src/dbg/argument.cpp @@ -7,7 +7,7 @@ struct ArgumentSerializer : JSONWrapper { bool Save(const ARGUMENTSINFO & value) override { - setString("module", value.mod); + setString("module", value.mod()); setHex("start", value.start); setHex("end", value.end); setHex("icount", value.instructioncount); @@ -17,8 +17,11 @@ struct ArgumentSerializer : JSONWrapper bool Load(ARGUMENTSINFO & value) override { - return getString("module", value.mod) && - getHex("start", value.start) && + std::string mod; + if(!getString("module", mod)) + return false; + value.modhash = ModHashFromName(mod.c_str()); + return getHex("start", value.start) && getHex("end", value.end) && getBool("manual", value.manual) && getHex("icount", value.instructioncount) && @@ -30,7 +33,7 @@ struct Arguments : SerializableModuleRangeMap bool Save(const ENCODEMAP & value) override { AddrInfoSerializer::Save(value); - setString("data", StringUtils::ToCompressedHex(value.data, value.size).c_str()); + setString("data", StringUtils::ToCompressedHex(value.data, value.size)); return true; } diff --git a/src/dbg/function.cpp b/src/dbg/function.cpp index 418fb92c..ad935c4c 100644 --- a/src/dbg/function.cpp +++ b/src/dbg/function.cpp @@ -7,7 +7,7 @@ struct FunctionSerializer : JSONWrapper { bool Save(const FUNCTIONSINFO & value) override { - setString("module", value.mod); + setString("module", value.mod()); setHex("start", value.start); setHex("end", value.end); setHex("icount", value.instructioncount); @@ -20,8 +20,11 @@ struct FunctionSerializer : JSONWrapper //legacy support value.manual = true; getBool("manual", value.manual); - return getString("module", value.mod) && - getHex("start", value.start) && + std::string mod; + if(!getString("module", mod)) + return false; + value.modhash = ModHashFromName(mod.c_str()); + return getHex("start", value.start) && getHex("end", value.end) && getHex("icount", value.instructioncount) && value.end >= value.start; @@ -32,7 +35,7 @@ struct Functions : SerializableModuleRangeMapmod); + duint modbase = ModBaseFromName(List->mod().c_str()); List->start += modbase; List->end += modbase; @@ -290,5 +289,6 @@ bool LoopEnum(LOOPSINFO* List, size_t* Size) void LoopClear() { EXCLUSIVE_ACQUIRE(LockLoops); - loops.clear(); + std::map empty; + std::swap(loops, empty); } \ No newline at end of file diff --git a/src/dbg/loop.h b/src/dbg/loop.h index 9b405a4a..c8afff6d 100644 --- a/src/dbg/loop.h +++ b/src/dbg/loop.h @@ -5,13 +5,18 @@ struct LOOPSINFO { - char mod[MAX_MODULE_SIZE]; + duint modhash; duint start; duint end; duint parent; int depth; bool manual; duint instructioncount; + + std::string mod() const + { + return ModNameFromHash(modhash); + } }; bool LoopAdd(duint Start, duint End, bool Manual, duint InstructionCount = 0); diff --git a/src/dbg/module.cpp b/src/dbg/module.cpp index 05846fdf..ea524d6d 100644 --- a/src/dbg/module.cpp +++ b/src/dbg/module.cpp @@ -7,6 +7,7 @@ #include "label.h" std::map modinfo; +std::unordered_map hashNameMap; void GetModuleInfo(MODINFO & Info, ULONG_PTR FileMapVA) { @@ -197,20 +198,26 @@ bool ModUnload(duint Base) void ModClear() { - // Clean up all the modules - EXCLUSIVE_ACQUIRE(LockModules); - - for(const auto & mod : modinfo) { - // Unload the mapped file from memory - const auto & info = mod.second; - if(info.fileMapVA) - StaticFileUnloadW(StringUtils::Utf8ToUtf16(info.path).c_str(), false, info.fileHandle, info.loadedSize, info.fileMap, info.fileMapVA); + // Clean up all the modules + EXCLUSIVE_ACQUIRE(LockModules); + + for(const auto & mod : modinfo) + { + // Unload the mapped file from memory + const auto & info = mod.second; + if(info.fileMapVA) + StaticFileUnloadW(StringUtils::Utf8ToUtf16(info.path).c_str(), false, info.fileHandle, info.loadedSize, info.fileMap, info.fileMapVA); + } + + modinfo.clear(); } - modinfo.clear(); - - EXCLUSIVE_RELEASE(); + { + // Clean up the reverse hash map + EXCLUSIVE_ACQUIRE(LockModuleHashes); + hashNameMap.clear(); + } // Tell the symbol updater GuiSymbolUpdateModuleList(0, nullptr); @@ -285,8 +292,19 @@ duint ModHashFromName(const char* Module) auto len = int(strlen(Module)); if(!len) return 0; + auto hash = murmurhash(Module, len); - return murmurhash(Module, len); + //update the hash cache + SHARED_ACQUIRE(LockModuleHashes); + auto hashInCache = hashNameMap.find(hash) != hashNameMap.end(); + SHARED_RELEASE(); + if(!hashInCache) + { + EXCLUSIVE_ACQUIRE(LockModuleHashes); + hashNameMap[hash] = Module; + } + + return hash; } duint ModBaseFromName(const char* Module) @@ -325,6 +343,15 @@ duint ModSizeFromAddr(duint Address) return module->size; } +std::string ModNameFromHash(duint Hash) +{ + SHARED_ACQUIRE(LockModuleHashes); + auto found = hashNameMap.find(Hash); + if(found == hashNameMap.end()) + return std::string(); + return found->second; +} + bool ModSectionsFromAddr(duint Address, std::vector* Sections) { SHARED_ACQUIRE(LockModules); @@ -444,4 +471,4 @@ void ModSetParty(duint Address, int Party) return; module->party = Party; -} +} \ No newline at end of file diff --git a/src/dbg/module.h b/src/dbg/module.h index 80cbb513..3a80bc29 100644 --- a/src/dbg/module.h +++ b/src/dbg/module.h @@ -49,6 +49,7 @@ duint ModHashFromAddr(duint Address); duint ModHashFromName(const char* Module); duint ModBaseFromName(const char* Module); duint ModSizeFromAddr(duint Address); +std::string ModNameFromHash(duint Hash); bool ModSectionsFromAddr(duint Address, std::vector* Sections); bool ModImportsFromAddr(duint Address, std::vector* Imports); duint ModEntryFromAddr(duint Address); diff --git a/src/dbg/serializablemap.h b/src/dbg/serializablemap.h index ee8b7ff2..8d805fad 100644 --- a/src/dbg/serializablemap.h +++ b/src/dbg/serializablemap.h @@ -20,24 +20,21 @@ public: virtual bool Load(TValue & value) = 0; protected: - void setString(const char* key, const char* value) + void setString(const char* key, const std::string & value) { - set(key, json_string(value)); + set(key, json_string(value.c_str())); } - template - bool getString(const char* key, char(&_Dest)[TSize]) const + bool getString(const char* key, std::string & dest) const { auto jsonValue = get(key); if(!jsonValue) return false; auto str = json_string_value(jsonValue); - if(str && strlen(str) < TSize) - { - strcpy_s(_Dest, str); - return true; - } - return false; + if(!str) + return false; + dest = str; + return true; } void setHex(const char* key, duint value) @@ -162,7 +159,8 @@ public: void Clear() { EXCLUSIVE_ACQUIRE(TLock); - mMap.clear(); + TMap empty; + std::swap(mMap, empty); } void CacheSave(JSON root) const @@ -329,9 +327,14 @@ struct SerializableModuleHashMap : SerializableUnorderedMap @@ -341,7 +344,7 @@ struct AddrInfoSerializer : JSONWrapper bool Save(const TValue & value) override { - setString("module", value.mod); + setString("module", value.mod()); setHex("address", value.addr); setBool("manual", value.manual); return true; @@ -351,8 +354,11 @@ struct AddrInfoSerializer : JSONWrapper { value.manual = true; //legacy support getBool("manual", value.manual); - return getString("module", value.mod) && - getHex("address", value.addr); + std::string mod; + if(!getString("module", mod)) + return false; + value.modhash = ModHashFromName(mod.c_str()); + return getHex("address", value.addr); } }; @@ -364,17 +370,17 @@ struct AddrInfoHashMap : SerializableModuleHashMap void AdjustValue(TValue & value) const override { - value.addr += ModBaseFromName(value.mod); + value.addr += ModBaseFromName(value.mod().c_str()); } bool PrepareValue(TValue & value, duint addr, bool manual) { if(!MemIsValidReadPtr(addr)) return false; - if(!ModNameFromAddr(addr, value.mod, true)) - *value.mod = '\0'; + auto base = ModBaseFromAddr(addr); + value.modhash = ModHashFromAddr(base); value.manual = manual; - value.addr = addr - ModBaseFromAddr(addr); + value.addr = addr - base; return true; } @@ -391,6 +397,6 @@ struct AddrInfoHashMap : SerializableModuleHashMap protected: duint makeKey(const TValue & value) const override { - return ModHashFromName(value.mod) + value.addr; + return value.modhash + value.addr; } }; \ No newline at end of file diff --git a/src/dbg/threading.h b/src/dbg/threading.h index ea360085..16fcf9da 100644 --- a/src/dbg/threading.h +++ b/src/dbg/threading.h @@ -70,6 +70,7 @@ enum SectionLock LockSymbolCache, LockLineCache, LockTypeManager, + LockModuleHashes, // Number of elements in this enumeration. Must always be the last // index.