LoadedModules.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /////////////////////////////////////////////////////////////////////////////
  2. // LoadedModules.cpp: Implementation of the CLoadedModules class.
  3. //
  4. #include "pch.h"
  5. #include "LoadedModules.h"
  6. /////////////////////////////////////////////////////////////////////////////
  7. // CLoadedModules
  8. /////////////////////////////////////////////////////////////////////////////
  9. // Construction / Destruction
  10. /////////////////////////////////////////////////////////////////////////////
  11. // Operations
  12. /////////////////////////////////////////////////////////////////////////////
  13. //
  14. void CLoadedModules::Add(void* pvImageBase, const ZString& strName)
  15. {
  16. // Create a new CLoadedModule structure
  17. CLoadedModule module;
  18. module.m_strModuleName = strName;
  19. module.m_ModuleBase = reinterpret_cast<ULONG>(pvImageBase);
  20. module.m_ModuleSize = 0;
  21. // Add the object to the map
  22. m_Modules[module.m_ModuleBase] = module;
  23. }
  24. /////////////////////////////////////////////////////////////////////////////
  25. //
  26. void CLoadedModules::Remove(void* pvImageBase)
  27. {
  28. // Remove the specified image from the map
  29. XLoadedModuleIt it = m_Modules.find(reinterpret_cast<ULONG>(pvImageBase));
  30. if (it != m_Modules.end())
  31. m_Modules.erase(it);
  32. }
  33. /////////////////////////////////////////////////////////////////////////////
  34. //
  35. CLoadedModuleIt CLoadedModules::findAddress(void* pvAddress)
  36. {
  37. const ULONG nAddress = reinterpret_cast<ULONG>(pvAddress);
  38. for (CLoadedModuleIt it = begin(); it != end(); ++it)
  39. {
  40. const CLoadedModule& m = it->second;
  41. if (m.m_ModuleBase < nAddress && nAddress < (m.m_ModuleBase + m.m_ModuleSize))
  42. break;
  43. }
  44. return it;
  45. }
  46. /////////////////////////////////////////////////////////////////////////////
  47. //
  48. void CLoadedModules::Dump()
  49. {
  50. #if defined(_DEBUG)
  51. debugf("Loaded Modules By Address:\n");
  52. for (CLoadedModuleIt it = begin(); it != end(); ++it)
  53. {
  54. const CLoadedModule& m = it->second;
  55. debugf(" %08X-%08X %s\n", m.m_ModuleBase,
  56. m.m_ModuleBase + m.m_ModuleSize, (LPCTSTR)m.m_strModuleName);
  57. }
  58. #else // defined(_DEBUG)
  59. // Does nothing in non-debug builds
  60. #endif // defined(_DEBUG)
  61. }
  62. /////////////////////////////////////////////////////////////////////////////
  63. // Implementation
  64. /////////////////////////////////////////////////////////////////////////////
  65. //
  66. BOOL CALLBACK CLoadedModules::EnumLoadedModulesProc(PSTR ModuleName,
  67. ULONG ModuleBase, ULONG ModuleSize, PVOID UserContext)
  68. {
  69. // Reinterpret the UserContext
  70. CLoadedModules* pThis = reinterpret_cast<CLoadedModules*>(UserContext);
  71. // Find the specified module if it's already in the map
  72. XLoadedModuleIt it = pThis->m_Modules.find(ModuleBase);
  73. if (it != pThis->m_Modules.end())
  74. {
  75. // Update the size field of the existing CLoadedModule structure
  76. CLoadedModule& module = it->second;
  77. module.m_ModuleSize = ModuleSize;
  78. }
  79. // Continue enumeration
  80. return true;
  81. }
  82. /////////////////////////////////////////////////////////////////////////////
  83. //
  84. void CLoadedModules::ResolveEmptyNames(HANDLE hProcess)
  85. {
  86. // Shouldn't have to do anything under Win9x
  87. if (IsWin9x())
  88. return;
  89. // Loop through each entry
  90. for (XLoadedModuleIt it = m_Modules.begin(); it != m_Modules.end(); ++it)
  91. {
  92. CLoadedModule& m = it->second;
  93. if (m.m_strModuleName.IsEmpty())
  94. {
  95. // Use the module base address as the HMODULE
  96. HMODULE hModule = reinterpret_cast<HMODULE>(m.m_ModuleBase);
  97. // Get the module file name
  98. TCHAR szModule[_MAX_PATH * 2];
  99. if (::GetModuleFileNameEx(hProcess, hModule, szModule, sizeofArray(szModule)))
  100. m.m_strModuleName = szModule;
  101. }
  102. }
  103. }
  104. /////////////////////////////////////////////////////////////////////////////
  105. //
  106. void CLoadedModules::ResolveUnknownSizes(HANDLE hProcessSym)
  107. {
  108. // Loop through each entry
  109. for (XLoadedModuleIt it = m_Modules.begin(); it != m_Modules.end(); ++it)
  110. {
  111. // Determine if the current path name is fully-qualified
  112. CLoadedModule& m = it->second;
  113. TCHAR szDrive[_MAX_DRIVE], szDir[_MAX_DIR];
  114. _tsplitpath(m.m_strModuleName, szDrive, szDir, NULL, NULL);
  115. bool bFullyQualified = TEXT('\0') != szDrive[0] || TEXT('\0') != szDir[0];
  116. // If we don't have enough information about the module, get some more
  117. if (!m.m_ModuleSize || !bFullyQualified)
  118. {
  119. IMAGEHLP_MODULE mi = {sizeof(mi)};
  120. if (::SymGetModuleInfo(hProcessSym, m.m_ModuleBase, &mi))
  121. {
  122. m.m_ModuleSize = mi.ImageSize;
  123. if (!bFullyQualified)
  124. m.m_strModuleName = mi.ImageName;
  125. }
  126. }
  127. }
  128. }