13f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// found in the LICENSE file. 4513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 5513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/enumerate_modules_model_win.h" 6513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 7513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include <Tlhelp32.h> 8513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include <wintrust.h> 9513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 10513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/command_line.h" 11513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/environment.h" 12513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/file_path.h" 13513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/file_version_info_win.h" 14201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "base/metrics/histogram.h" 15513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/string_number_conversions.h" 16513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/string_util.h" 17201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "base/time.h" 18513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/utf_string_conversions.h" 19513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/values.h" 20513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/version.h" 21201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "base/win/registry.h" 223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/win/scoped_handle.h" 23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/sha2.h" 24513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/net/service_providers_win.h" 25513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/common/chrome_constants.h" 26513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/common/chrome_switches.h" 27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h" 28513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "grit/generated_resources.h" 2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 30513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 31513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// The period of time (in milliseconds) to wait until checking to see if any 32513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// incompatible modules exist. 33513209b27ff55e2841eac0e4120199c23acce758Ben Murdochstatic const int kModuleCheckDelayMs = 60 * 1000; 34513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 35201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// The path to the Shell Extension key in the Windows registry. 36201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstatic const wchar_t kRegPath[] = 37201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"; 38201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 39201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Short-hand for things on the blacklist you should simply get rid of. 40201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstatic const ModuleEnumerator::RecommendedAction kUninstallLink = 41201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static_cast<ModuleEnumerator::RecommendedAction>( 42201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ModuleEnumerator::UNINSTALL | ModuleEnumerator::SEE_LINK); 43201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Short-hand for things on the blacklist we are investigating and have info. 45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const ModuleEnumerator::RecommendedAction kInvestigatingLink = 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static_cast<ModuleEnumerator::RecommendedAction>( 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ModuleEnumerator::INVESTIGATING | ModuleEnumerator::SEE_LINK); 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 49201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// A sort method that sorts by bad modules first, then by full name (including 50201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// path). 51513209b27ff55e2841eac0e4120199c23acce758Ben Murdochstatic bool ModuleSort(const ModuleEnumerator::Module& a, 52513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const ModuleEnumerator::Module& b) { 53201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (a.status != b.status) 54201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return a.status > b.status; 55201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 56513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (a.location == b.location) 57513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return a.name < b.name; 58513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 59513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return a.location < b.location; 60513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 61513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 62513209b27ff55e2841eac0e4120199c23acce758Ben Murdochnamespace { 63513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 64513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Used to protect the LoadedModuleVector which is accessed 65513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// from both the UI thread and the FILE thread. 6672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbase::Lock* lock = NULL; 67513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 68201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// A struct to help de-duping modules before adding them to the enumerated 69201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// modules vector. 70201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstruct FindModule { 71201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch public: 72201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch explicit FindModule(const ModuleEnumerator::Module& x) 73201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch : module(x) {} 74201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch bool operator()(const ModuleEnumerator::Module& module_in) const { 75201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return (module.location == module_in.location) && 76201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch (module.name == module_in.name); 77201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 78201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 79201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const ModuleEnumerator::Module& module; 80201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}; 81201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 8272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Returns the long path name given a short path name. A short path name is a 8372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// path that follows the 8.3 convention and has ~x in it. If the path is already 8472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// a long path name, the function returns the current path without modification. 8572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool ConvertToLongPath(const string16& short_path, string16* long_path) { 8672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen wchar_t long_path_buf[MAX_PATH]; 8772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DWORD return_value = GetLongPathName(short_path.c_str(), long_path_buf, 8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen MAX_PATH); 8972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (return_value != 0 && return_value < MAX_PATH) { 9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *long_path = long_path_buf; 9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 95513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 96513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} // namespace 9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 99201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// The browser process module blacklist. This lists modules that are known 100513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// to cause compatibility issues within the browser process. When adding to this 101513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// list, make sure that all paths are lower-case, in long pathname form, end 102513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// with a slash and use environments variables (or just look at one of the 103513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// comments below and keep it consistent with that). When adding an entry with 104513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// an environment variable not currently used in the list below, make sure to 105513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// update the list in PreparePathMappings. Filename, Description/Signer, and 106513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Location must be entered as hashes (see GenerateHash). Filename is mandatory. 107513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Entries without any Description, Signer info, or Location will never be 108513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// marked as confirmed bad (only as suspicious). 109513209b27ff55e2841eac0e4120199c23acce758Ben Murdochconst ModuleEnumerator::BlacklistEntry ModuleEnumerator::kModuleBlacklist[] = { 110513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // NOTE: Please keep this list sorted by dll name, then location. 111513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Version 3.2.1.6 seems to be implicated in most cases (and 3.2.2.2 in some). 113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // There is a more recent version available for download. 114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // accelerator.dll, "%programfiles%\\speedbit video accelerator\\". 115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { "7ba9402f", "c9132d48", "", "", "", kInvestigatingLink }, 116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 117201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // apiqq0.dll, "%temp%\\". 118201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "26134911", "59145acf", "", "", "", kUninstallLink }, 119201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 120201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // arking0.dll, "%systemroot%\\system32\\". 121201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "f5d8f549", "23d01d5b", "", "", "", kUninstallLink }, 122201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 123201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // arking1.dll, "%systemroot%\\system32\\". 124201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "c60ca062", "23d01d5b", "", "", "", kUninstallLink }, 125201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Said to belong to Killer NIC from BigFoot Networks (not verified). Versions 127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // 6.0.0.7 and 6.0.0.10 implicated. 128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // bfllr.dll, "%systemroot%\\system32\\". 129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { "6bb57633", "23d01d5b", "", "", "", kInvestigatingLink }, 130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 131201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // clickpotatolitesahook.dll, "". Different version each report. 132201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "0396e037.dll", "", "", "", "", kUninstallLink }, 133201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 134201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // cvasds0.dll, "%temp%\\". 135201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "5ce0037c", "59145acf", "", "", "", kUninstallLink }, 136201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 137201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // cwalsp.dll, "%systemroot%\\system32\\". 138201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "e579a039", "23d01d5b", "", "", "", kUninstallLink }, 139201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 140201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // dsoqq0.dll, "%temp%\\". 141201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "1c4df325", "59145acf", "", "", "", kUninstallLink }, 142201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // This looks like a malware edition of a Brazilian Bank plugin, sometimes 144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // referred to as Malware.Banc.A. 145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // gbieh.dll, "%programfiles%\\gbplugin\\". 146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { "4cb4f2e3", "88e4a3b1", "", "", "", kUninstallLink }, 147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 148201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // hblitesahook.dll. Each report has different version number in location. 149201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "5d10b363", "", "", "", "", kUninstallLink }, 150201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 151201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // icf.dll, "%systemroot%\\system32\\". 152201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "303825ed", "23d01d5b", "", "", "", INVESTIGATING }, 153201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 154201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // idmmbc.dll (IDM), "%systemroot%\\system32\\". See: http://crbug.com/26892/. 155201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "b8dce5c3", "23d01d5b", "", "", "6.03", 156201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static_cast<RecommendedAction>(UPDATE | DISABLE) }, 157201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 158201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // imon.dll (NOD32), "%systemroot%\\system32\\". See: http://crbug.com/21715. 159201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "8f42f22e", "23d01d5b", "", "", "4.0", 160201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static_cast<RecommendedAction>(UPDATE | DISABLE) }, 161201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 162201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // is3lsp.dll, "%commonprogramfiles%\\is3\\anti-spyware\\". 1633f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen { "7ffbdce9", "bc5673f2", "", "", "", 1643f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen static_cast<RecommendedAction>(UPDATE | DISABLE | SEE_LINK) }, 165201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 166201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // jsi.dll, "%programfiles%\\profilecraze\\". 167201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "f9555eea", "e3548061", "", "", "", kUninstallLink }, 168201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 169201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // kernel.dll, "%programfiles%\\contentwatch\\internet protection\\modules\\". 170201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "ead2768e", "4e61ce60", "", "", "", INVESTIGATING }, 171201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 172201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // mgking0.dll, "%systemroot%\\system32\\". 173201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "d0893e38", "23d01d5b", "", "", "", kUninstallLink }, 174201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 175201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // mgking0.dll, "%temp%\\". 176201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "d0893e38", "59145acf", "", "", "", kUninstallLink }, 177201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 178201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // mgking1.dll, "%systemroot%\\system32\\". 179201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "3e837222", "23d01d5b", "", "", "", kUninstallLink }, 180201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 181201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // mgking1.dll, "%temp%\\". 182201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "3e837222", "59145acf", "", "", "", kUninstallLink }, 183513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 184201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // mstcipha.ime, "%systemroot%\\system32\\". 185201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "5523579e", "23d01d5b", "", "", "", INVESTIGATING }, 186513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 187201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // mwtsp.dll, "%systemroot%\\system32\\". 188201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "9830bff6", "23d01d5b", "", "", "", kUninstallLink }, 189513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 190201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // nodqq0.dll, "%temp%\\". 191201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "b86ce04d", "59145acf", "", "", "", kUninstallLink }, 192513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // nProtect GameGuard Anti-cheat system. Every report has a different 194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // location, since it is installed into and run from a game folder. Various 195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // versions implicated. 196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // npggnt.des, no fixed location. 197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { "f2c8790d", "", "", "", "", kInvestigatingLink }, 198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 199201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // nvlsp.dll, 200201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // "%programfiles%\\nvidia corporation\\networkaccessmanager\\bin32\\". 201201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "37f907e2", "3ad0ff23", "", "", "", INVESTIGATING }, 202513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // post0.dll, "%systemroot%\\system32\\". 204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { "7405c0c8", "23d01d5b", "", "", "", kUninstallLink }, 205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 206201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // radhslib.dll (Naomi web filter), "%programfiles%\\rnamfler\\". 207201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // See http://crbug.com/12517. 208201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "7edcd250", "0733dc3e", "", "", "", INVESTIGATING }, 209513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 210201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // rlls.dll, "%programfiles%\\relevantknowledge\\". 211201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "a1ed94a7", "ea9d6b36", "", "", "", kUninstallLink }, 212513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 213201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // rooksdol.dll, "%programfiles%\\trusteer\\rapport\\bin\\". 214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { "802aefef", "06120e13", "", "", "3.5.1008.40", INVESTIGATING }, 215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // sdata.dll, "%programdata%\\srtserv\\". 217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { "1936d5cc", "223c44be", "", "", "", kUninstallLink }, 218513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 219201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // searchtree.dll, 220201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // "%programfiles%\\contentwatch\\internet protection\\modules\\". 221201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "f6915a31", "4e61ce60", "", "", "", INVESTIGATING }, 222513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 223201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // sgprxy.dll, "%commonprogramfiles%\\is3\\anti-spyware\\". 224201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "005965ea", "bc5673f2", "", "", "", INVESTIGATING }, 225201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // swi_filter_0001.dll (Sophos Web Intelligence), 227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // "%programfiles%\\sophos\\sophos anti-virus\\web intelligence\\". 228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // A small random sample all showed version 1.0.5.0. 229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { "61112d7b", "25fb120f", "", "", "", kInvestigatingLink }, 230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 231201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // twking0.dll, "%systemroot%\\system32\\". 232201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "0355549b", "23d01d5b", "", "", "", kUninstallLink }, 233201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 234201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // twking1.dll, "%systemroot%\\system32\\". 235201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "02e44508", "23d01d5b", "", "", "", kUninstallLink }, 236201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 237201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // vksaver.dll, "%systemroot%\\system32\\". 238201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "c4a784d5", "23d01d5b", "", "", "", kUninstallLink }, 239201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 240201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // vlsp.dll (Venturi Firewall?), "%systemroot%\\system32\\". 241201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "2e4eb93d", "23d01d5b", "", "", "", INVESTIGATING }, 242201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 243201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // vmn3_1dn.dll, "%appdata%\\roaming\\vmndtxtb\\". 244201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "bba2037d", "9ab68585", "", "", "", kUninstallLink }, 245201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 246201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // webanalyzer.dll, 247201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // "%programfiles%\\contentwatch\\internet protection\\modules\\". 248201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "c70b697d", "4e61ce60", "", "", "", INVESTIGATING }, 249201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 250201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // wowst0.dll, "%systemroot%\\system32\\". 251201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "38ad9963", "23d01d5b", "", "", "", kUninstallLink }, 252201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 253201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // wxbase28u_vc_cw.dll, "%systemroot%\\system32\\". 254201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { "e967210d", "23d01d5b", "", "", "", kUninstallLink }, 255513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}; 256513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 257513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Generates an 8 digit hash from the input given. 258513209b27ff55e2841eac0e4120199c23acce758Ben Murdochstatic void GenerateHash(const std::string& input, std::string* output) { 259513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (input.empty()) { 260513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch *output = ""; 261513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return; 262513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 263513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 264513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch uint8 hash[4]; 265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen crypto::SHA256HashString(input, hash, sizeof(hash)); 266513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch *output = StringToLowerASCII(base::HexEncode(hash, sizeof(hash))); 267513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 268513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 269513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// ----------------------------------------------------------------------------- 270513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 271513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static 272513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid ModuleEnumerator::NormalizeModule(Module* module) { 273513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch string16 path = module->location; 27472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!ConvertToLongPath(path, &module->location)) 275513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch module->location = path; 276513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 277513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch module->location = l10n_util::ToLower(module->location); 278513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 279513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Location contains the filename, so the last slash is where the path 280513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // ends. 281513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch size_t last_slash = module->location.find_last_of(L"\\"); 282513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (last_slash != string16::npos) { 283513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch module->name = module->location.substr(last_slash + 1); 284513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch module->location = module->location.substr(0, last_slash + 1); 285513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } else { 286513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch module->name = module->location; 287513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch module->location.clear(); 288513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 289513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 290513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Some version strings have things like (win7_rtm.090713-1255) appended 291513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // to them. Remove that. 292513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch size_t first_space = module->version.find_first_of(L" "); 293513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (first_space != string16::npos) 294513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch module->version = module->version.substr(0, first_space); 295513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 296513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch module->normalized = true; 297513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 298513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 299513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static 300513209b27ff55e2841eac0e4120199c23acce758Ben MurdochModuleEnumerator::ModuleStatus ModuleEnumerator::Match( 301513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const ModuleEnumerator::Module& module, 302513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const ModuleEnumerator::BlacklistEntry& blacklisted) { 303513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // All modules must be normalized before matching against blacklist. 304513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(module.normalized); 305513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Filename is mandatory and version should not contain spaces. 306513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(strlen(blacklisted.filename) > 0); 307513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(!strstr(blacklisted.version_from, " ")); 308513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(!strstr(blacklisted.version_to, " ")); 309513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 310513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::string filename_hash, location_hash; 311513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GenerateHash(WideToUTF8(module.name), &filename_hash); 312513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GenerateHash(WideToUTF8(module.location), &location_hash); 313513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 314513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Filenames are mandatory. Location is mandatory if given. 315513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (filename_hash == blacklisted.filename && 316513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch (std::string(blacklisted.location).empty() || 317513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch location_hash == blacklisted.location)) { 318513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // We have a name match against the blacklist (and possibly location match 319513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // also), so check version. 320513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_ptr<Version> module_version( 32121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen Version::GetVersionFromString(UTF16ToASCII(module.version))); 322513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_ptr<Version> version_min( 323513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Version::GetVersionFromString(blacklisted.version_from)); 324513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_ptr<Version> version_max( 325513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Version::GetVersionFromString(blacklisted.version_to)); 326513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool version_ok = !version_min.get() && !version_max.get(); 327513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!version_ok) { 328513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool too_low = version_min.get() && 329513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch (!module_version.get() || 330513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch module_version->CompareTo(*version_min.get()) < 0); 331513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool too_high = version_max.get() && 332513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch (!module_version.get() || 333201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch module_version->CompareTo(*version_max.get()) >= 0); 334513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch version_ok = !too_low && !too_high; 335513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 336513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 337513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (version_ok) { 338513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // At this point, the names match and there is no version specified 339513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // or the versions also match. 340513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 341513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::string desc_or_signer(blacklisted.desc_or_signer); 342513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::string signer_hash, description_hash; 343513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GenerateHash(WideToUTF8(module.digital_signer), &signer_hash); 344513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GenerateHash(WideToUTF8(module.description), &description_hash); 345513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 3463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // If signatures match (or both are empty), then we have a winner. 3473f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (signer_hash == desc_or_signer) 348513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return CONFIRMED_BAD; 349513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 3503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // If descriptions match (or both are empty) and the locations match, then 3513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // we also have a confirmed match. 3523f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (description_hash == desc_or_signer && 353513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch !location_hash.empty() && location_hash == blacklisted.location) { 354513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return CONFIRMED_BAD; 355513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 356513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 357513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // We are not sure, but it is likely bad. 358513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return SUSPECTED_BAD; 359513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 360513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 361513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 362513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return NOT_MATCHED; 363513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 364513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 365513209b27ff55e2841eac0e4120199c23acce758Ben MurdochModuleEnumerator::ModuleEnumerator(EnumerateModulesModel* observer) 36672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen : enumerated_modules_(NULL), 36772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen observer_(observer), 3683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen limited_mode_(false), 369201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch callback_thread_id_(BrowserThread::ID_COUNT) { 370513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 371513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 372513209b27ff55e2841eac0e4120199c23acce758Ben MurdochModuleEnumerator::~ModuleEnumerator() { 373513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 374513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 3753f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid ModuleEnumerator::ScanNow(ModulesVector* list, bool limited_mode) { 376513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch enumerated_modules_ = list; 3773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 3783f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen limited_mode_ = limited_mode; 3793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 3803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (!limited_mode_) { 3813f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen CHECK(BrowserThread::GetCurrentThreadIdentifier(&callback_thread_id_)); 3823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::FILE)); 3833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen BrowserThread::PostTask( 3843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen BrowserThread::FILE, FROM_HERE, 3853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen NewRunnableMethod(this, &ModuleEnumerator::ScanImpl)); 3863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } else { 3873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // Run it synchronously. 3883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ScanImpl(); 3893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 390513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 391513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 3923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid ModuleEnumerator::ScanImpl() { 393201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch base::TimeTicks start_time = base::TimeTicks::Now(); 394201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 395513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch enumerated_modules_->clear(); 396513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 397513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Make sure the path mapping vector is setup so we can collapse paths. 398513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch PreparePathMappings(); 399513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 400201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Enumerating loaded modules must happen first since the other types of 401201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // modules check for duplication against the loaded modules. 4023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::TimeTicks checkpoint = base::TimeTicks::Now(); 403201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EnumerateLoadedModules(); 4043f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::TimeTicks checkpoint2 = base::TimeTicks::Now(); 4053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen UMA_HISTOGRAM_TIMES("Conflicts.EnumerateLoadedModules", 4063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen checkpoint2 - checkpoint); 407201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 4083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen checkpoint = checkpoint2; 409201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EnumerateShellExtensions(); 4103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen checkpoint2 = base::TimeTicks::Now(); 4113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen UMA_HISTOGRAM_TIMES("Conflicts.EnumerateShellExtensions", 4123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen checkpoint2 - checkpoint); 413201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 4143f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen checkpoint = checkpoint2; 415201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EnumerateWinsockModules(); 4163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen checkpoint2 = base::TimeTicks::Now(); 4173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen UMA_HISTOGRAM_TIMES("Conflicts.EnumerateWinsockModules", 4183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen checkpoint2 - checkpoint); 419201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 420201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MatchAgainstBlacklist(); 421201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 422201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::sort(enumerated_modules_->begin(), 423201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch enumerated_modules_->end(), ModuleSort); 424201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 4253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (!limited_mode_) { 4263f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // Send a reply back on the UI thread. 4273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen BrowserThread::PostTask( 4283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen callback_thread_id_, FROM_HERE, 4293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen NewRunnableMethod(this, &ModuleEnumerator::ReportBack)); 4303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } else { 4313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // We are on the main thread already. 4323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ReportBack(); 4333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 434201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 4353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen UMA_HISTOGRAM_TIMES("Conflicts.EnumerationTotalTime", 4363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::TimeTicks::Now() - start_time); 437201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 438201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 439201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid ModuleEnumerator::EnumerateLoadedModules() { 440513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Get all modules in the current process. 4413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::win::ScopedHandle snap(::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 4423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ::GetCurrentProcessId())); 443513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!snap.Get()) 444513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return; 445513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 446513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Walk the module list. 447513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MODULEENTRY32 module = { sizeof(module) }; 448513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!::Module32First(snap.Get(), &module)) 449513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return; 450513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 451513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch do { 452513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // It would be weird to present chrome.exe as a loaded module. 453513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (_wcsicmp(chrome::kBrowserProcessExecutableName, module.szModule) == 0) 454513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch continue; 455513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 456513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Module entry; 457513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch entry.type = LOADED_MODULE; 458513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch entry.location = module.szExePath; 459201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch PopulateModuleInformation(&entry); 460513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 461513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NormalizeModule(&entry); 462513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CollapsePath(&entry); 463513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch enumerated_modules_->push_back(entry); 464513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } while (::Module32Next(snap.Get(), &module)); 465201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 466201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 467201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid ModuleEnumerator::EnumerateShellExtensions() { 468201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ReadShellExtensions(HKEY_LOCAL_MACHINE); 469201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ReadShellExtensions(HKEY_CURRENT_USER); 470201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 471201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 472201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid ModuleEnumerator::ReadShellExtensions(HKEY parent) { 473201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch base::win::RegistryValueIterator registration(parent, kRegPath); 474201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch while (registration.Valid()) { 475201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::wstring key(std::wstring(L"CLSID\\") + registration.Name() + 476201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch L"\\InProcServer32"); 477201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch base::win::RegKey clsid; 47872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (clsid.Open(HKEY_CLASSES_ROOT, key.c_str(), KEY_READ) != ERROR_SUCCESS) { 479201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ++registration; 480201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch continue; 481201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 482201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch string16 dll; 48372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (clsid.ReadValue(L"", &dll) != ERROR_SUCCESS) { 484201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ++registration; 485201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch continue; 486201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 487201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch clsid.Close(); 488201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 489201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch Module entry; 490201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch entry.type = SHELL_EXTENSION; 491201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch entry.location = dll; 492201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch PopulateModuleInformation(&entry); 493201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 494201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NormalizeModule(&entry); 495201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CollapsePath(&entry); 496201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch AddToListWithoutDuplicating(entry); 497201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 498201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ++registration; 499201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 500201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 501513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 502201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid ModuleEnumerator::EnumerateWinsockModules() { 503513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Add to this list the Winsock LSP DLLs. 504513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch WinsockLayeredServiceProviderList layered_providers; 505513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GetWinsockLayeredServiceProviders(&layered_providers); 506513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (size_t i = 0; i < layered_providers.size(); ++i) { 507513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Module entry; 508513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch entry.type = WINSOCK_MODULE_REGISTRATION; 509513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch entry.status = NOT_MATCHED; 510513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch entry.normalized = false; 511513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch entry.location = layered_providers[i].path; 512513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch entry.description = layered_providers[i].name; 513513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch entry.recommended_action = NONE; 514201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch entry.duplicate_count = 0; 515513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 516513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch wchar_t expanded[MAX_PATH]; 517513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DWORD size = ExpandEnvironmentStrings( 518513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch entry.location.c_str(), expanded, MAX_PATH); 519513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (size != 0 && size <= MAX_PATH) { 520513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch entry.digital_signer = 521513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GetSubjectNameFromDigitalSignature(FilePath(expanded)); 522513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 523513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch entry.version = base::IntToString16(layered_providers[i].version); 524513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 525513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Paths have already been collapsed. 526513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NormalizeModule(&entry); 527201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch AddToListWithoutDuplicating(entry); 528513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 529201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 530513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 531201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid ModuleEnumerator::PopulateModuleInformation(Module* module) { 532201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch module->status = NOT_MATCHED; 533201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch module->duplicate_count = 0; 534201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch module->normalized = false; 535201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch module->digital_signer = 536201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch GetSubjectNameFromDigitalSignature(FilePath(module->location)); 537201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch module->recommended_action = NONE; 538201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<FileVersionInfo> version_info( 539201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch FileVersionInfo::CreateFileVersionInfo(FilePath(module->location))); 540201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (version_info.get()) { 541201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch FileVersionInfoWin* version_info_win = 542201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static_cast<FileVersionInfoWin*>(version_info.get()); 543201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 544201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch VS_FIXEDFILEINFO* fixed_file_info = version_info_win->fixed_file_info(); 545201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (fixed_file_info) { 546201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch module->description = version_info_win->file_description(); 547201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch module->version = version_info_win->file_version(); 548201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch module->product_name = version_info_win->product_name(); 549201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 550201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 551201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 552513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 553201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid ModuleEnumerator::AddToListWithoutDuplicating(const Module& module) { 554201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(module.normalized); 555201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // These are registered modules, not loaded modules so the same module 556201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // can be registered multiple times, often dozens of times. There is no need 557201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // to list each registration, so we just increment the count for each module 558201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // that is counted multiple times. 559201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ModulesVector::iterator iter; 560201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch iter = std::find_if(enumerated_modules_->begin(), 561201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch enumerated_modules_->end(), 562201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch FindModule(module)); 563201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (iter != enumerated_modules_->end()) { 564201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch iter->duplicate_count++; 565201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch iter->type = static_cast<ModuleType>(iter->type | module.type); 566201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } else { 567201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch enumerated_modules_->push_back(module); 568201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 569513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 570513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 571513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid ModuleEnumerator::PreparePathMappings() { 572513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch path_mapping_.clear(); 573513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 574513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_ptr<base::Environment> environment(base::Environment::Create()); 575513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::vector<string16> env_vars; 576513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch env_vars.push_back(L"LOCALAPPDATA"); 577513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch env_vars.push_back(L"ProgramFiles"); 578ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen env_vars.push_back(L"ProgramData"); 579513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch env_vars.push_back(L"USERPROFILE"); 580513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch env_vars.push_back(L"SystemRoot"); 581513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch env_vars.push_back(L"TEMP"); 582201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch env_vars.push_back(L"TMP"); 583201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch env_vars.push_back(L"CommonProgramFiles"); 584513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (std::vector<string16>::const_iterator variable = env_vars.begin(); 585513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch variable != env_vars.end(); ++variable) { 586513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::string path; 587513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (environment->GetVar(WideToASCII(*variable).c_str(), &path)) { 588513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch path_mapping_.push_back( 589513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::make_pair(l10n_util::ToLower(UTF8ToWide(path)) + L"\\", 590513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch L"%" + l10n_util::ToLower(*variable) + L"%")); 591513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 592513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 593513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 594513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 595513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid ModuleEnumerator::CollapsePath(Module* entry) { 596513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Take the path and see if we can use any of the substitution values 597513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // from the vector constructed above to replace c:\windows with, for 598201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // example, %systemroot%. The most collapsed path (the one with the 599201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // minimum length) wins. 600201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch size_t min_length = MAXINT; 601201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch string16 location = entry->location; 602513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (PathMapping::const_iterator mapping = path_mapping_.begin(); 603513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch mapping != path_mapping_.end(); ++mapping) { 604513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch string16 prefix = mapping->first; 605201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (StartsWith(location, prefix, false)) { 606201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch string16 new_location = mapping->second + 607201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch location.substr(prefix.length() - 1); 608201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch size_t length = new_location.length() - mapping->second.length(); 609201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (length < min_length) { 610201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch entry->location = new_location; 611201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch min_length = length; 612201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 613513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 614513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 615513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 616513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 617513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid ModuleEnumerator::MatchAgainstBlacklist() { 618513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (size_t m = 0; m < enumerated_modules_->size(); ++m) { 619513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Match this module against the blacklist. 620513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Module* module = &(*enumerated_modules_)[m]; 621513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch module->status = GOOD; // We change this below potentially. 622513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (size_t i = 0; i < arraysize(kModuleBlacklist); ++i) { 623513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch #if !defined(NDEBUG) 624513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // This saves time when constructing the blacklist. 625513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::string hashes(kModuleBlacklist[i].filename); 626513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::string hash1, hash2, hash3; 627513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GenerateHash(kModuleBlacklist[i].filename, &hash1); 628513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch hashes += " - " + hash1; 629513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GenerateHash(kModuleBlacklist[i].location, &hash2); 630513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch hashes += " - " + hash2; 631513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GenerateHash(kModuleBlacklist[i].desc_or_signer, &hash3); 632513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch hashes += " - " + hash3; 633513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch #endif 634513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 635513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ModuleStatus status = Match(*module, kModuleBlacklist[i]); 636513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (status != NOT_MATCHED) { 637513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // We have a match against the blacklist. Mark it as such. 638513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch module->status = status; 639513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch module->recommended_action = kModuleBlacklist[i].help_tip; 640513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch break; 641513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 642513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 643201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 644201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Modules loaded from these locations are frequently malicious 645201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // and notorious for changing frequently so they are not good candidates 646201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // for blacklisting individually. Mark them as suspicious if we haven't 647201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // classified them as bad yet. 648201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (module->status == NOT_MATCHED || module->status == GOOD) { 649201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (StartsWith(module->location, L"%temp%", false) || 650201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch StartsWith(module->location, L"%tmp%", false)) { 651201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch module->status = SUSPECTED_BAD; 652201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 653201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 654513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 655513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 656513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 657513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid ModuleEnumerator::ReportBack() { 6583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (!limited_mode_) 6593f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen DCHECK(BrowserThread::CurrentlyOn(callback_thread_id_)); 660513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch observer_->DoneScanning(); 661513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 662513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 663513209b27ff55e2841eac0e4120199c23acce758Ben Murdochstring16 ModuleEnumerator::GetSubjectNameFromDigitalSignature( 664513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const FilePath& filename) { 665513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch HCERTSTORE store = NULL; 666513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch HCRYPTMSG message = NULL; 667513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 668513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Find the crypto message for this filename. 669513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool result = !!CryptQueryObject(CERT_QUERY_OBJECT_FILE, 670513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch filename.value().c_str(), 671513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, 672513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CERT_QUERY_FORMAT_FLAG_BINARY, 673513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 0, 674513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NULL, 675513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NULL, 676513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NULL, 677513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch &store, 678513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch &message, 679513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NULL); 680513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!result) 681513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return string16(); 682513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 683513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Determine the size of the signer info data. 684513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DWORD signer_info_size = 0; 685513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch result = !!CryptMsgGetParam(message, 686513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CMSG_SIGNER_INFO_PARAM, 687513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 0, 688513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NULL, 689513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch &signer_info_size); 690513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!result) 691513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return string16(); 692513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 693513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Allocate enough space to hold the signer info. 694513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_array<BYTE> signer_info_buffer(new BYTE[signer_info_size]); 695513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CMSG_SIGNER_INFO* signer_info = 696513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch reinterpret_cast<CMSG_SIGNER_INFO*>(signer_info_buffer.get()); 697513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 698513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Obtain the signer info. 699513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch result = !!CryptMsgGetParam(message, 700513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CMSG_SIGNER_INFO_PARAM, 701513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 0, 702513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch signer_info, 703513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch &signer_info_size); 704513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!result) 705513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return string16(); 706513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 707513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Search for the signer certificate. 708513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CERT_INFO CertInfo = {0}; 709513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch PCCERT_CONTEXT cert_context = NULL; 710513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CertInfo.Issuer = signer_info->Issuer; 711513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CertInfo.SerialNumber = signer_info->SerialNumber; 712513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 713513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch cert_context = CertFindCertificateInStore( 714513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch store, 715513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 716513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 0, 717513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CERT_FIND_SUBJECT_CERT, 718513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch &CertInfo, 719513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NULL); 720513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!cert_context) 721513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return string16(); 722513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 723513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Determine the size of the Subject name. 724513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DWORD subject_name_size = 0; 725513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!(subject_name_size = CertGetNameString(cert_context, 726513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CERT_NAME_SIMPLE_DISPLAY_TYPE, 727513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 0, 728513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NULL, 729513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NULL, 730513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 0))) { 731513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return string16(); 732513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 733513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 734513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch string16 subject_name; 735513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch subject_name.resize(subject_name_size); 736513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 737513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Get subject name. 738513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!(CertGetNameString(cert_context, 739513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CERT_NAME_SIMPLE_DISPLAY_TYPE, 740513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 0, 741513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NULL, 742513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const_cast<LPWSTR>(subject_name.c_str()), 743513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch subject_name_size))) { 744513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return string16(); 745513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 746513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 747513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return subject_name; 748513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 749513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 750513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// ---------------------------------------------------------------------------- 751513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 75221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// static 75321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenEnumerateModulesModel* EnumerateModulesModel::GetInstance() { 75421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return Singleton<EnumerateModulesModel>::get(); 75521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 75621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 757ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool EnumerateModulesModel::ShouldShowConflictWarning() const { 758ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If the user has acknowledged the conflict notification, then we don't need 759ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // to show it again (because the scanning only happens once per the lifetime 760ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // of the process). If we were to run the scanning more than once, then we'd 761ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // need to clear the flag somewhere when we are ready to show it again. 762ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (conflict_notification_acknowledged_) 763ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 764ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 765ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return confirmed_bad_modules_detected_ > 0; 766ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 767ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 768ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid EnumerateModulesModel::AcknowledgeConflictNotification() { 769ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!conflict_notification_acknowledged_) { 770ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen conflict_notification_acknowledged_ = true; 771ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NotificationService::current()->Notify( 772ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NotificationType::MODULE_INCOMPATIBILITY_BADGE_CHANGE, 773ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Source<EnumerateModulesModel>(this), 774ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NotificationService::NoDetails()); 775ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 776ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 777ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 778513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid EnumerateModulesModel::ScanNow() { 779513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (scanning_) 780513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return; // A scan is already in progress. 781513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 782513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch lock->Acquire(); // Balanced in DoneScanning(); 783513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 784513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scanning_ = true; 785513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 786513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Instruct the ModuleEnumerator class to load this on the File thread. 787513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // ScanNow does not block. 788513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!module_enumerator_) 789513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch module_enumerator_ = new ModuleEnumerator(this); 7903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen module_enumerator_->ScanNow(&enumerated_modules_, limited_mode_); 791513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 792513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 793ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenListValue* EnumerateModulesModel::GetModuleList() const { 794513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (scanning_) 795513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return NULL; 796513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 797513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch lock->Acquire(); 798513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 799513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (enumerated_modules_.empty()) { 800513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch lock->Release(); 801513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return NULL; 802513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 803513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 804513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ListValue* list = new ListValue(); 805513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 806513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (ModuleEnumerator::ModulesVector::const_iterator module = 807513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch enumerated_modules_.begin(); 808513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch module != enumerated_modules_.end(); ++module) { 809513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DictionaryValue* data = new DictionaryValue(); 810513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch data->SetInteger("type", module->type); 811201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch string16 type_string; 812201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if ((module->type & ModuleEnumerator::LOADED_MODULE) == 0) { 813201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Module is not loaded, denote type of module. 814201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (module->type & ModuleEnumerator::SHELL_EXTENSION) 815201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch type_string = ASCIIToWide("Shell Extension"); 816201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (module->type & ModuleEnumerator::WINSOCK_MODULE_REGISTRATION) { 817201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (!type_string.empty()) 818201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch type_string += ASCIIToWide(", "); 819201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch type_string += ASCIIToWide("Winsock"); 820201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 821201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Must be one of the above type. 822201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(!type_string.empty()); 8233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (!limited_mode_) { 8243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen type_string += ASCIIToWide(" -- "); 8253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen type_string += l10n_util::GetStringUTF16(IDS_CONFLICTS_NOT_LOADED_YET); 8263f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 827201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 828201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch data->SetString("type_description", type_string); 829513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch data->SetInteger("status", module->status); 830513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch data->SetString("location", module->location); 831513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch data->SetString("name", module->name); 832513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch data->SetString("product_name", module->product_name); 833513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch data->SetString("description", module->description); 834201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch data->SetString("version", module->version); 835513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch data->SetString("digital_signer", module->digital_signer); 836513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 8373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (!limited_mode_) { 8383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // Figure out the possible resolution help string. 8393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen string16 actions; 8403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen string16 separator = ASCIIToWide(" ") + l10n_util::GetStringUTF16( 8413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen IDS_CONFLICTS_CHECK_POSSIBLE_ACTION_SEPERATOR) + 8423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ASCIIToWide(" "); 843513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 8443f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (module->recommended_action & ModuleEnumerator::NONE) { 8453f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen actions = l10n_util::GetStringUTF16( 8463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen IDS_CONFLICTS_CHECK_INVESTIGATING); 8473f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 8483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (module->recommended_action & ModuleEnumerator::UNINSTALL) { 8493f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (!actions.empty()) 8503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen actions += separator; 8513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen actions = l10n_util::GetStringUTF16( 8523f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen IDS_CONFLICTS_CHECK_POSSIBLE_ACTION_UNINSTALL); 8533f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 8543f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (module->recommended_action & ModuleEnumerator::UPDATE) { 8553f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (!actions.empty()) 8563f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen actions += separator; 8573f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen actions += l10n_util::GetStringUTF16( 8583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen IDS_CONFLICTS_CHECK_POSSIBLE_ACTION_UPDATE); 8593f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 8603f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (module->recommended_action & ModuleEnumerator::DISABLE) { 8613f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (!actions.empty()) 8623f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen actions += separator; 8633f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen actions += l10n_util::GetStringUTF16( 8643f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen IDS_CONFLICTS_CHECK_POSSIBLE_ACTION_DISABLE); 8653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 8663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen string16 possible_resolution = actions.empty() ? ASCIIToWide("") : 8673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen l10n_util::GetStringUTF16(IDS_CONFLICTS_CHECK_POSSIBLE_ACTIONS) + 8683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ASCIIToWide(" ") + 8693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen actions; 8703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen data->SetString("possibleResolution", possible_resolution); 8713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen data->SetString("help_url", 8723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ConstructHelpCenterUrl(*module).spec().c_str()); 873513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 874513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 875513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch list->Append(data); 876513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 877513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 878513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch lock->Release(); 879513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return list; 880513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 881513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 882513209b27ff55e2841eac0e4120199c23acce758Ben MurdochEnumerateModulesModel::EnumerateModulesModel() 883ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : limited_mode_(false), 884ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scanning_(false), 885ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen conflict_notification_acknowledged_(false), 8864a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch confirmed_bad_modules_detected_(0), 8874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch suspected_bad_modules_detected_(0) { 888513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const CommandLine& cmd_line = *CommandLine::ForCurrentProcess(); 889513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (cmd_line.HasSwitch(switches::kConflictingModulesCheck)) { 890513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch check_modules_timer_.Start( 8914a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch base::TimeDelta::FromMilliseconds(kModuleCheckDelayMs), 8924a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch this, &EnumerateModulesModel::ScanNow); 893513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 894513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 89572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen lock = new base::Lock(); 896513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 897513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 898513209b27ff55e2841eac0e4120199c23acce758Ben MurdochEnumerateModulesModel::~EnumerateModulesModel() { 899513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch delete lock; 900513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 901513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 902513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid EnumerateModulesModel::DoneScanning() { 903513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch confirmed_bad_modules_detected_ = 0; 904513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch suspected_bad_modules_detected_ = 0; 905513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (ModuleEnumerator::ModulesVector::const_iterator module = 906513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch enumerated_modules_.begin(); 907513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch module != enumerated_modules_.end(); ++module) { 908513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (module->status == ModuleEnumerator::CONFIRMED_BAD) 909513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ++confirmed_bad_modules_detected_; 910513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (module->status == ModuleEnumerator::SUSPECTED_BAD) 911513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ++suspected_bad_modules_detected_; 912513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 913513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 914513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scanning_ = false; 915513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch lock->Release(); 916513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 9173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen UMA_HISTOGRAM_COUNTS_100("Conflicts.SuspectedBadModules", 9183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen suspected_bad_modules_detected_); 9193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen UMA_HISTOGRAM_COUNTS_100("Conflicts.ConfirmedBadModules", 9203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen confirmed_bad_modules_detected_); 9213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 9223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // Notifications are not available in limited mode. 9233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (limited_mode_) 9243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return; 925201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 926513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NotificationService::current()->Notify( 927513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NotificationType::MODULE_LIST_ENUMERATED, 928513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Source<EnumerateModulesModel>(this), 929513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NotificationService::NoDetails()); 930513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 9313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // Command line flag must be enabled for the notification to get sent out. 9323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // Otherwise we'd get the badge (while the feature is disabled) when we 9333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // navigate to about:conflicts and find confirmed matches. 9343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const CommandLine& cmd_line = *CommandLine::ForCurrentProcess(); 9353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (!cmd_line.HasSwitch(switches::kConflictingModulesCheck)) 9363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return; 9373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 938ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NotificationService::current()->Notify( 939ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NotificationType::MODULE_INCOMPATIBILITY_BADGE_CHANGE, 940ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Source<EnumerateModulesModel>(this), 941ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NotificationService::NoDetails()); 942513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 943513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 944513209b27ff55e2841eac0e4120199c23acce758Ben MurdochGURL EnumerateModulesModel::ConstructHelpCenterUrl( 945ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const ModuleEnumerator::Module& module) const { 946513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!(module.recommended_action & ModuleEnumerator::SEE_LINK)) 947513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return GURL(); 948513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 949513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Construct the needed hashes. 950513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::string filename, location, description, signer; 951513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GenerateHash(WideToUTF8(module.name), &filename); 952513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GenerateHash(WideToUTF8(module.location), &location); 953513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GenerateHash(WideToUTF8(module.description), &description); 954513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GenerateHash(WideToUTF8(module.digital_signer), &signer); 955513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 9563f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen string16 url = l10n_util::GetStringFUTF16(IDS_HELP_CENTER_VIEW_CONFLICTS, 9573f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ASCIIToUTF16(filename), ASCIIToUTF16(location), 9583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ASCIIToUTF16(description), ASCIIToUTF16(signer)); 9593f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return GURL(UTF16ToUTF8(url)); 960513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 961