From c991fc0c40816b677785d5bf1fe4dc18aec5583c Mon Sep 17 00:00:00 2001 From: Torusrxxx Date: Sat, 29 Apr 2017 14:24:35 +0000 Subject: [PATCH] Warn the user about mismatch of database and executable (#1570) --- src/dbg/database.cpp | 36 ++++++++++++++++++++++++++++++++++++ src/dbg/database.h | 1 + src/dbg/debugger.cpp | 8 ++++++-- src/dbg/module.cpp | 15 +++++++++++++++ src/dbg/module.h | 1 + 5 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/dbg/database.cpp b/src/dbg/database.cpp index 858d3600..f475be74 100644 --- a/src/dbg/database.cpp +++ b/src/dbg/database.cpp @@ -31,6 +31,11 @@ */ char dbbasepath[deflen]; +/** +\brief The hash of the debuggee stored in the database +*/ +duint dbhash = 0; + /** \brief Path of the current program database. UTF-8 encoding. */ @@ -66,6 +71,11 @@ void DbSave(DbLoadSaveType saveType, const char* dbfile, bool disablecompression TraceRecord.saveToDb(root); BpCacheSave(root); WatchCacheSave(root); + if(dbhash != 0) + { + json_object_set_new(root, "hashAlgorithm", json_string("murmurhash")); + json_object_set_new(root, "hash", json_hex(dbhash)); + } //save notes char* text = nullptr; @@ -215,6 +225,11 @@ void DbLoad(DbLoadSaveType loadType, const char* dbfile) if(loadType == DbLoadSaveType::DebugData || loadType == DbLoadSaveType::All) { + if(strcmp(json_string_value(json_object_get(root, "hashAlgorithm")), "murmurhash") == 0) //Checking checksum of the debuggee. + dbhash = json_hex_value(json_object_get(root, "hash")); + else + dbhash = 0; + // Finally load all structures CommentCacheLoad(root); LabelCacheLoad(root); @@ -287,7 +302,10 @@ void DbClear(bool terminating) GuiSetDebuggeeNotes(""); if(terminating) + { PatchClear(); + dbhash = 0; + } } void DbSetPath(const char* Directory, const char* ModulePath) @@ -371,3 +389,21 @@ void DbSetPath(const char* Directory, const char* ModulePath) dprintf(QT_TRANSLATE_NOOP("DBG", "Database file: %s\n"), dbpath); } } + +/** +\brief Warn the user if the hash in the database and the executable mismatch. +*/ +bool DbCheckHash(duint currentHash) +{ + if(dbhash != 0 && currentHash != 0 && dbhash != currentHash) + { + dputs(QT_TRANSLATE_NOOP("DBG", "WARNING: The database has a checksum that is different from the module you are debugging. It is possible that your debuggee has been modified since last session. The content of this database may be incorrect.")); + dbhash = currentHash; + return false; + } + else + { + dbhash = currentHash; + return true; + } +} \ No newline at end of file diff --git a/src/dbg/database.h b/src/dbg/database.h index 8394585c..7a4c3b60 100644 --- a/src/dbg/database.h +++ b/src/dbg/database.h @@ -15,5 +15,6 @@ void DbLoad(DbLoadSaveType loadType, const char* dbfile = nullptr); void DbClose(); void DbClear(bool terminating = false); void DbSetPath(const char* Directory, const char* ModulePath); +bool DbCheckHash(duint currentHash); #endif // _DATABASE_H \ No newline at end of file diff --git a/src/dbg/debugger.cpp b/src/dbg/debugger.cpp index aff2f0f1..279dbf20 100644 --- a/src/dbg/debugger.cpp +++ b/src/dbg/debugger.cpp @@ -31,7 +31,9 @@ #include "cmd-watch-control.h" #include "filemap.h" #include "jit.h" - +/** +\brief Conditional tracing structures +*/ struct TraceCondition { ExpressionParser condition; @@ -217,7 +219,7 @@ private: BufferedWriter* logWriter = nullptr; bool writeUtf16 = false; }; - +// Debugging variables static PROCESS_INFORMATION g_pi = {0, 0, 0, 0}; static char szBaseFileName[MAX_PATH] = ""; static TraceState traceState; @@ -1463,6 +1465,7 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo) if(!bFileIsDll && !bIsAttached) //Set entry breakpoint { pDebuggedBase = pCreateProcessBase; //debugged base = executable + DbCheckHash(ModContentHashFromAddr(pDebuggedBase)); //Check hash mismatch char command[deflen] = ""; if(settingboolget("Events", "TlsCallbacks")) @@ -1762,6 +1765,7 @@ static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll) { bIsDebuggingThis = true; pDebuggedBase = (duint)base; + DbCheckHash(ModContentHashFromAddr(pDebuggedBase)); //Check hash mismatch if(settingboolget("Events", "EntryBreakpoint")) { bAlreadySetEntry = true; diff --git a/src/dbg/module.cpp b/src/dbg/module.cpp index ea524d6d..abc9a8f8 100644 --- a/src/dbg/module.cpp +++ b/src/dbg/module.cpp @@ -285,6 +285,21 @@ duint ModHashFromAddr(duint Address) return module->hash + (Address - module->base); } +duint ModContentHashFromAddr(duint Address) +{ + SHARED_ACQUIRE(LockModules); + + auto module = ModInfoFromAddr(Address); + + if(!module) + return 0; + + if(module->fileMapVA != 0 && module->loadedSize > 0) + return murmurhash((void*)module->fileMapVA, module->loadedSize); + else + return 0; +} + duint ModHashFromName(const char* Module) { // return MODINFO.hash (based on the name) diff --git a/src/dbg/module.h b/src/dbg/module.h index 3a80bc29..d15918ef 100644 --- a/src/dbg/module.h +++ b/src/dbg/module.h @@ -47,6 +47,7 @@ bool ModNameFromAddr(duint Address, char* Name, bool Extension); duint ModBaseFromAddr(duint Address); duint ModHashFromAddr(duint Address); duint ModHashFromName(const char* Module); +duint ModContentHashFromAddr(duint Address); duint ModBaseFromName(const char* Module); duint ModSizeFromAddr(duint Address); std::string ModNameFromHash(duint Hash);