diff --git a/x64_dbg_dbg/_global.h b/x64_dbg_dbg/_global.h index c3f6fcfd..b752b2b7 100644 --- a/x64_dbg_dbg/_global.h +++ b/x64_dbg_dbg/_global.h @@ -1,7 +1,7 @@ #ifndef _GLOBAL_H #define _GLOBAL_H -#define _WIN32_WINNT 0x0501 +#define _WIN32_WINNT 0x0600 #define WINVER 0x0501 #define _WIN32_IE 0x0500 diff --git a/x64_dbg_dbg/error.cpp b/x64_dbg_dbg/error.cpp index c950011d..a23875eb 100644 --- a/x64_dbg_dbg/error.cpp +++ b/x64_dbg_dbg/error.cpp @@ -2197,6 +2197,7 @@ void errorinit() const char* errornamefromcode(unsigned int ErrorCode) { if(!errorNames.count(ErrorCode)) - return 0; + return nullptr; + return errorNames[ErrorCode]; } \ No newline at end of file diff --git a/x64_dbg_dbg/module.cpp b/x64_dbg_dbg/module.cpp index 3d4c91cf..91e82c0f 100644 --- a/x64_dbg_dbg/module.cpp +++ b/x64_dbg_dbg/module.cpp @@ -77,10 +77,12 @@ bool modload(uint base, uint size, const char* fullpath) bool modunload(uint base) { - CriticalSectionLocker locker(LockModules); + EXCLUSIVE_ACQUIRE(LockModules); + const ModulesInfo::iterator found = modinfo.find(Range(base, base)); if(found == modinfo.end()) //not found return false; + modinfo.erase(found); symupdatemodulelist(); return true; @@ -88,8 +90,12 @@ bool modunload(uint base) void modclear() { - CriticalSectionLocker locker(LockModules); - ModulesInfo().swap(modinfo); + EXCLUSIVE_ACQUIRE(LockModules); + + // Remove all modules in the list + modinfo.clear(); + + // Tell the symbol updater symupdatemodulelist(); } @@ -97,98 +103,143 @@ bool modnamefromaddr(uint addr, char* modname, bool extension) { if(!modname) return false; - *modname = '\0'; - CriticalSectionLocker locker(LockModules); - const ModulesInfo::iterator found = modinfo.find(Range(addr, addr)); - if(found == modinfo.end()) //not found + + SHARED_ACQUIRE(LockModules); + + // Was the module found with this address? + auto found = modinfo.find(Range(addr, addr)); + + if(found == modinfo.end()) return false; - String mod = found->second.name; + + // Zero buffer first + memset(modname, 0, MAX_MODULE_SIZE); + + // Append the module path/name + strcat_s(modname, MAX_MODULE_SIZE, found->second.name); + + // Append the extension if(extension) - mod += found->second.extension; - strcpy_s(modname, MAX_MODULE_SIZE, mod.c_str()); + strcat_s(modname, MAX_MODULE_SIZE, found->second.extension); + return true; } uint modbasefromaddr(uint addr) { - CriticalSectionLocker locker(LockModules); - const ModulesInfo::iterator found = modinfo.find(Range(addr, addr)); - if(found == modinfo.end()) //not found + SHARED_ACQUIRE(LockModules); + + // Was the module found with this address? + auto found = modinfo.find(Range(addr, addr)); + + if(found == modinfo.end()) return 0; + return found->second.base; } -uint modhashfromva(uint va) //return a unique hash from a VA +uint modhashfromva(uint va) { - CriticalSectionLocker locker(LockModules); - const ModulesInfo::iterator found = modinfo.find(Range(va, va)); - if(found == modinfo.end()) //not found + // + // Returns a unique hash from a virtual address + // + SHARED_ACQUIRE(LockModules); + + // Was the module found with this address? + auto found = modinfo.find(Range(va, va)); + + if(found == modinfo.end()) return va; + return found->second.hash + (va - found->second.base); } -uint modhashfromname(const char* mod) //return MODINFO.hash +uint modhashfromname(const char* mod) { - if(!mod or !*mod) + // + // return MODINFO.hash (based on the name) + // + if(!mod || !mod[0]) return 0; - int len = (int)strlen(mod); - return murmurhash(mod, len); + + return murmurhash(mod, (int)strlen(mod)); } uint modbasefromname(const char* modname) { - if(!modname or strlen(modname) >= MAX_MODULE_SIZE) + if(!modname || strlen(modname) >= MAX_MODULE_SIZE) return 0; - CriticalSectionLocker locker(LockModules); - for(ModulesInfo::iterator i = modinfo.begin(); i != modinfo.end(); ++i) + + SHARED_ACQUIRE(LockModules); + + for(auto itr = modinfo.begin(); itr != modinfo.end(); itr++) { - MODINFO* curMod = &i->second; - char curmodname[MAX_MODULE_SIZE] = ""; - sprintf(curmodname, "%s%s", curMod->name, curMod->extension); - if(!_stricmp(curmodname, modname)) //with extension - return curMod->base; - if(!_stricmp(curMod->name, modname)) //without extension - return curMod->base; + char curmodname[MAX_MODULE_SIZE]; + sprintf(curmodname, "%s%s", itr->second.name, itr->second.extension); + + // Test with extension + if(!_stricmp(curmodname, modname)) + return itr->second.base; + + // Test without extension + if(!_stricmp(itr->second.name, modname)) + return itr->second.base; } + return 0; } uint modsizefromaddr(uint addr) { - CriticalSectionLocker locker(LockModules); - const ModulesInfo::iterator found = modinfo.find(Range(addr, addr)); - if(found == modinfo.end()) //not found + SHARED_ACQUIRE(LockModules); + + // Was the module found with this address? + auto found = modinfo.find(Range(addr, addr)); + + if(found == modinfo.end()) return 0; + return found->second.size; } bool modsectionsfromaddr(uint addr, std::vector* sections) { - CriticalSectionLocker locker(LockModules); - const ModulesInfo::iterator found = modinfo.find(Range(addr, addr)); - if(found == modinfo.end()) //not found + SHARED_ACQUIRE(LockModules); + + // Was the module found with this address? + auto found = modinfo.find(Range(addr, addr)); + + if(found == modinfo.end()) return false; + + // Copy vector <-> vector *sections = found->second.sections; return true; } uint modentryfromaddr(uint addr) { - CriticalSectionLocker locker(LockModules); - const ModulesInfo::iterator found = modinfo.find(Range(addr, addr)); + SHARED_ACQUIRE(LockModules); + + // Was the module found with this address? + auto found = modinfo.find(Range(addr, addr)); + if(found == modinfo.end()) //not found return 0; + return found->second.entry; } int modpathfromaddr(duint addr, char* path, int size) { Memory wszModPath(size * sizeof(wchar_t), "modpathfromaddr:wszModPath"); + if(!GetModuleFileNameExW(fdProcessInfo->hProcess, (HMODULE)modbasefromaddr(addr), wszModPath, size)) { *path = '\0'; return 0; } + strcpy_s(path, size, StringUtils::Utf16ToUtf8(wszModPath()).c_str()); return (int)strlen(path); } @@ -196,4 +247,4 @@ int modpathfromaddr(duint addr, char* path, int size) int modpathfromname(const char* modname, char* path, int size) { return modpathfromaddr(modbasefromname(modname), path, size); -} +} \ No newline at end of file diff --git a/x64_dbg_dbg/thread.cpp b/x64_dbg_dbg/thread.cpp index 59279f4c..149b3b04 100644 --- a/x64_dbg_dbg/thread.cpp +++ b/x64_dbg_dbg/thread.cpp @@ -65,7 +65,7 @@ void threadclear() bool ThreadGetTeb(uint TEBAddress, TEB* Teb) { // - // TODO: Keep a cached copy of this inside of the vector + // TODO: Keep a cached copy inside the vector // memset(Teb, 0, sizeof(TEB)); @@ -107,7 +107,7 @@ DWORD ThreadGetLastError(uint tebAddress) TEB teb; if(!ThreadGetTeb(tebAddress, &teb)) { - // TODO: Assert + // TODO: Assert (Why would the TEB fail?) return 0; } @@ -116,7 +116,7 @@ DWORD ThreadGetLastError(uint tebAddress) void ThreadGetList(THREADLIST* list) { - EXCLUSIVE_ACQUIRE(LockThreads); + SHARED_ACQUIRE(LockThreads); // // This function converts a C++ std::vector to a C-style THREADLIST[] @@ -151,7 +151,7 @@ void ThreadGetList(THREADLIST* list) bool ThreadIsValid(DWORD dwThreadId) { - EXCLUSIVE_ACQUIRE(LockThreads); + SHARED_ACQUIRE(LockThreads); for(auto itr = threadList.begin(); itr != threadList.end(); itr++) { @@ -166,6 +166,7 @@ bool ThreadSetName(DWORD dwThreadId, const char* name) { EXCLUSIVE_ACQUIRE(LockThreads); + // This modifies a variable (name), so an exclusive lock is required for(auto itr = threadList.begin(); itr != threadList.end(); itr++) { if(itr->ThreadId == dwThreadId) @@ -182,7 +183,7 @@ bool ThreadSetName(DWORD dwThreadId, const char* name) HANDLE ThreadGetHandle(DWORD dwThreadId) { - EXCLUSIVE_ACQUIRE(LockThreads); + SHARED_ACQUIRE(LockThreads); for(auto itr = threadList.begin(); itr != threadList.end(); itr++) { @@ -197,16 +198,24 @@ HANDLE ThreadGetHandle(DWORD dwThreadId) DWORD ThreadGetId(HANDLE hThread) { - EXCLUSIVE_ACQUIRE(LockThreads); + SHARED_ACQUIRE(LockThreads); + // Search for the ID in the local list for(auto itr = threadList.begin(); itr != threadList.end(); itr++) { if(itr->Handle == hThread) return itr->ThreadId; } + // Wasn't found, check with Windows + // This also returns 0 on error + /* + REQUIRES VISTA+ + + return GetThreadId(hThread); + */ + // TODO: Same problem with threadgethandle() - // TODO: Different handles can map to the same thread return 0; } @@ -217,7 +226,10 @@ int ThreadGetCount() int ThreadSuspendAll() { - EXCLUSIVE_ACQUIRE(LockThreads); + // + // SuspendThread does not modify any internal variables + // + SHARED_ACQUIRE(LockThreads); int count = 0; for(auto itr = threadList.begin(); itr != threadList.end(); itr++) @@ -231,6 +243,9 @@ int ThreadSuspendAll() int ThreadResumeAll() { + // + // ResumeThread does not modify any internal variables + // EXCLUSIVE_ACQUIRE(LockThreads); int count = 0; diff --git a/x64_dbg_dbg/threading.cpp b/x64_dbg_dbg/threading.cpp index 8c303968..fbe0cfa9 100644 --- a/x64_dbg_dbg/threading.cpp +++ b/x64_dbg_dbg/threading.cpp @@ -29,7 +29,7 @@ bool waitislocked(WAIT_ID id) } bool CriticalSectionLocker::m_Initialized = false; -CRITICAL_SECTION CriticalSectionLocker::m_Locks[LockLast]; +SRWLOCK CriticalSectionLocker::m_Locks[LockLast]; void CriticalSectionLocker::Initialize() { @@ -40,7 +40,7 @@ void CriticalSectionLocker::Initialize() memset(m_Locks, 0, sizeof(m_Locks)); for(int i = 0; i < LockLast; i++) - InitializeCriticalSection(&m_Locks[i]); + InitializeSRWLock(&m_Locks[i]); m_Initialized = true; } @@ -53,28 +53,28 @@ void CriticalSectionLocker::Deinitialize() for(int i = 0; i < LockLast; i++) { // Wait for the lock's ownership to be released - EnterCriticalSection(&m_Locks[i]); - LeaveCriticalSection(&m_Locks[i]); + AcquireSRWLockExclusive(&m_Locks[i]); + ReleaseSRWLockExclusive(&m_Locks[i]); - // Render the lock data invalid - DeleteCriticalSection(&m_Locks[i]); + // Invalidate data + memset(&m_Locks[i], 0, sizeof(SRWLOCK)); } m_Initialized = false; } -CriticalSectionLocker::CriticalSectionLocker(CriticalSectionLock LockIndex) +CriticalSectionLocker::CriticalSectionLocker(CriticalSectionLock LockIndex, bool Shared) { - m_Section = &m_Locks[LockIndex]; + m_Lock = &m_Locks[LockIndex]; m_LockCount = 0; - Lock(); + Lock(Shared); } CriticalSectionLocker::~CriticalSectionLocker() { if(m_LockCount > 0) - LeaveCriticalSection(m_Section); + Unlock(); // TODO: Assert that the lock count is zero on destructor } @@ -82,24 +82,20 @@ CriticalSectionLocker::~CriticalSectionLocker() void CriticalSectionLocker::Unlock() { m_LockCount--; - LeaveCriticalSection(m_Section); + + if(m_Shared) + ReleaseSRWLockShared(m_Lock); + else + ReleaseSRWLockExclusive(m_Lock); } -void CriticalSectionLocker::Lock() +void CriticalSectionLocker::Lock(bool Shared) { - EnterCriticalSection(m_Section); + if(Shared) + AcquireSRWLockShared(m_Lock); + else + AcquireSRWLockExclusive(m_Lock); + + m_Shared = Shared; m_LockCount++; -} - -bool CriticalSectionLocker::TryLock() -{ - // Only enter the critical section if it's currently owned by the - // thread, or if it is not being used at all - if(TryEnterCriticalSection(m_Section)) - { - Lock(); - return true; - } - - return false; } \ No newline at end of file diff --git a/x64_dbg_dbg/threading.h b/x64_dbg_dbg/threading.h index 512116a4..061bc43f 100644 --- a/x64_dbg_dbg/threading.h +++ b/x64_dbg_dbg/threading.h @@ -18,9 +18,19 @@ void lock(WAIT_ID id); void unlock(WAIT_ID id); bool waitislocked(WAIT_ID id); -#define EXCLUSIVE_ACQUIRE(Index) CriticalSectionLocker __ThreadLock(Index); +// +// THREAD SYNCHRONIZATION +// +// Better, but requires VISTA+ +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa904937%28v=vs.85%29.aspx +// + +#define EXCLUSIVE_ACQUIRE(Index) CriticalSectionLocker __ThreadLock(Index, false); #define EXCLUSIVE_RELEASE() __ThreadLock.Unlock(); +#define SHARED_ACQUIRE(Index) CriticalSectionLocker __SThreadLock(Index, true); +#define SHARED_RELEASE() __SThreadLock.Unlock(); + enum CriticalSectionLock { LockMemoryPages, @@ -44,18 +54,18 @@ public: static void Initialize(); static void Deinitialize(); - CriticalSectionLocker(CriticalSectionLock LockIndex); + CriticalSectionLocker(CriticalSectionLock LockIndex, bool Shared); ~CriticalSectionLocker(); void Unlock(); - void Lock(); - bool TryLock(); + void Lock(bool Shared); private: static bool m_Initialized; - static CRITICAL_SECTION m_Locks[LockLast]; + static SRWLOCK m_Locks[LockLast]; - CRITICAL_SECTION* m_Section; + SRWLOCK* m_Lock; + bool m_Shared; BYTE m_LockCount; };