diff options
author | finnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-20 10:00:19 +0000 |
---|---|---|
committer | finnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-20 10:00:19 +0000 |
commit | 47db01d1fac5cd29e6e24571aebc75cf1c1aea6d (patch) | |
tree | c9806e0b4491f2f7d5665cf5d244c8740765426b /chrome | |
parent | f7458a0f0349d1496aea93d48fc6549a57cf8eec (diff) | |
download | chromium_src-47db01d1fac5cd29e6e24571aebc75cf1c1aea6d.zip chromium_src-47db01d1fac5cd29e6e24571aebc75cf1c1aea6d.tar.gz chromium_src-47db01d1fac5cd29e6e24571aebc75cf1c1aea6d.tar.bz2 |
Polish the Enumerate Modules implementation a bit.
1) De-dup the registered DLLs since a lot of the same DLLs will be registered multiple times, ie. mswsock.dll
2) Every module loaded from a %temp% dir should be viewed as suspicious.
3) Add some histogram counters (xml changes coming in a followup CL).
BUG=http://crbug.com/51105
TEST=None
Review URL: http://codereview.chromium.org/5183007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@66880 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/enumerate_modules_model_win.cc | 76 | ||||
-rw-r--r-- | chrome/browser/enumerate_modules_model_win.h | 9 |
2 files changed, 80 insertions, 5 deletions
diff --git a/chrome/browser/enumerate_modules_model_win.cc b/chrome/browser/enumerate_modules_model_win.cc index d771b0e..9645d3c 100644 --- a/chrome/browser/enumerate_modules_model_win.cc +++ b/chrome/browser/enumerate_modules_model_win.cc @@ -13,10 +13,12 @@ #include "base/environment.h" #include "base/file_path.h" #include "base/file_version_info_win.h" +#include "base/metrics/histogram.h" #include "base/scoped_handle.h" #include "base/sha2.h" #include "base/string_number_conversions.h" #include "base/string_util.h" +#include "base/time.h" #include "base/utf_string_conversions.h" #include "base/values.h" #include "base/version.h" @@ -53,6 +55,21 @@ namespace { // from both the UI thread and the FILE thread. Lock* lock = NULL; +// A struct to help de-duping modules before adding them to the enumerated +// modules vector. +struct FindModule { + public: + explicit FindModule(const ModuleEnumerator::Module& x) + : module(x) {} + bool operator()(ModuleEnumerator::Module module_in) const { + return (module.type == module_in.type) && + (module.location == module_in.location) && + (module.name == module_in.name); + } + + const ModuleEnumerator::Module& module; +}; + } // The browser process module blacklist. This lists all modules that are known @@ -226,14 +243,27 @@ void ModuleEnumerator::ScanNow(ModulesVector* list) { } void ModuleEnumerator::ScanOnFileThread() { + base::TimeTicks start_time = base::TimeTicks::Now(); + enumerated_modules_->clear(); // Make sure the path mapping vector is setup so we can collapse paths. PreparePathMappings(); + base::TimeTicks checkpoint = base::TimeTicks::Now(); EnumerateLoadedModules(); + HISTOGRAM_TIMES("Conflicts.EnumerateLoadedModules", + base::TimeTicks::Now() - checkpoint); + + checkpoint = base::TimeTicks::Now(); EnumerateShellExtensions(); - EnumerateWinsockModule(); + HISTOGRAM_TIMES("Conflicts.EnumerateShellExtensions", + base::TimeTicks::Now() - checkpoint); + + checkpoint = base::TimeTicks::Now(); + EnumerateWinsockModules(); + HISTOGRAM_TIMES("Conflicts.EnumerateWinsockModules", + base::TimeTicks::Now() - checkpoint); MatchAgainstBlacklist(); @@ -244,6 +274,9 @@ void ModuleEnumerator::ScanOnFileThread() { BrowserThread::PostTask( callback_thread_id_, FROM_HERE, NewRunnableMethod(this, &ModuleEnumerator::ReportBack)); + + HISTOGRAM_TIMES("Conflicts.EnumerationTotalTime", + base::TimeTicks::Now() - start_time); } void ModuleEnumerator::EnumerateLoadedModules() { @@ -303,13 +336,13 @@ void ModuleEnumerator::ReadShellExtensions(HKEY parent) { NormalizeModule(&entry); CollapsePath(&entry); - enumerated_modules_->push_back(entry); + AddToListWithoutDuplicating(entry); ++registration; } } -void ModuleEnumerator::EnumerateWinsockModule() { +void ModuleEnumerator::EnumerateWinsockModules() { // Add to this list the Winsock LSP DLLs. WinsockLayeredServiceProviderList layered_providers; GetWinsockLayeredServiceProviders(&layered_providers); @@ -321,6 +354,7 @@ void ModuleEnumerator::EnumerateWinsockModule() { entry.location = layered_providers[i].path; entry.description = layered_providers[i].name; entry.recommended_action = NONE; + entry.duplicate_count = 0; wchar_t expanded[MAX_PATH]; DWORD size = ExpandEnvironmentStrings( @@ -333,12 +367,13 @@ void ModuleEnumerator::EnumerateWinsockModule() { // Paths have already been collapsed. NormalizeModule(&entry); - enumerated_modules_->push_back(entry); + AddToListWithoutDuplicating(entry); } } void ModuleEnumerator::PopulateModuleInformation(Module* module) { module->status = NOT_MATCHED; + module->duplicate_count = 0; module->normalized = false; module->digital_signer = GetSubjectNameFromDigitalSignature(FilePath(module->location)); @@ -358,6 +393,22 @@ void ModuleEnumerator::PopulateModuleInformation(Module* module) { } } +void ModuleEnumerator::AddToListWithoutDuplicating(const Module& module) { + DCHECK(module.normalized); + // These are registered modules, not loaded modules so the same module + // can be registered multiple times, often dozens of times. There is no need + // to list each registration, so we just increment the count for each module + // that is counted multiple times. + ModulesVector::iterator iter; + iter = std::find_if(enumerated_modules_->begin(), + enumerated_modules_->end(), + FindModule(module)); + if (iter != enumerated_modules_->end()) + iter->duplicate_count++; + else + enumerated_modules_->push_back(module); +} + void ModuleEnumerator::PreparePathMappings() { path_mapping_.clear(); @@ -368,6 +419,7 @@ void ModuleEnumerator::PreparePathMappings() { env_vars.push_back(L"USERPROFILE"); env_vars.push_back(L"SystemRoot"); env_vars.push_back(L"TEMP"); + env_vars.push_back(L"TMP"); for (std::vector<string16>::const_iterator variable = env_vars.begin(); variable != env_vars.end(); ++variable) { std::string path; @@ -420,6 +472,17 @@ void ModuleEnumerator::MatchAgainstBlacklist() { break; } } + + // Modules loaded from these locations are frequently malicious + // and notorious for changing frequently so they are not good candidates + // for blacklising individually. Mark them as suspicious if we haven't + // classified them as bad yet. + if (module->status == NOT_MATCHED || module->status == GOOD) { + if (StartsWith(module->location, L"%temp%", false) || + StartsWith(module->location, L"%tmp%", false)) { + module->status = SUSPECTED_BAD; + } + } } } @@ -646,6 +709,11 @@ void EnumerateModulesModel::DoneScanning() { scanning_ = false; lock->Release(); + HISTOGRAM_COUNTS_100("Conflicts.SuspectedBadModules", + suspected_bad_modules_detected_); + HISTOGRAM_COUNTS_100("Conflicts.ConfirmedBadModules", + confirmed_bad_modules_detected_); + NotificationService::current()->Notify( NotificationType::MODULE_LIST_ENUMERATED, Source<EnumerateModulesModel>(this), diff --git a/chrome/browser/enumerate_modules_model_win.h b/chrome/browser/enumerate_modules_model_win.h index 73d05a1..cf65eaf 100644 --- a/chrome/browser/enumerate_modules_model_win.h +++ b/chrome/browser/enumerate_modules_model_win.h @@ -81,6 +81,8 @@ class ModuleEnumerator : public base::RefCountedThreadSafe<ModuleEnumerator> { string16 digital_signer; // The help tips bitmask. RecommendedAction recommended_action; + // The duplicate count within each category of modules. + int duplicate_count; // Whether this module has been normalized (necessary before checking it // against blacklist). bool normalized; @@ -141,7 +143,7 @@ class ModuleEnumerator : public base::RefCountedThreadSafe<ModuleEnumerator> { void EnumerateShellExtensions(); // Enumerate all registered Winsock LSP modules. - void EnumerateWinsockModule(); + void EnumerateWinsockModules(); // Reads the registered shell extensions found under |parent| key in the // registry. @@ -151,6 +153,11 @@ class ModuleEnumerator : public base::RefCountedThreadSafe<ModuleEnumerator> { // information using the location field of the module. void PopulateModuleInformation(Module* module); + // Checks the module list to see if a |module| of the same type, location + // and name has been added before and if so, increments its duplication + // counter. If it doesn't appear in the list, it is added. + void AddToListWithoutDuplicating(const Module&); + // Builds up a vector of path values mapping to environment variable, // with pairs like [c:\windows\, %systemroot%]. This is later used to // collapse paths like c:\windows\system32 into %systemroot%\system32, which |