OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef CHROME_BROWSER_ENUMERATE_MODULES_MODEL_WIN_H_ |
| 6 #define CHROME_BROWSER_ENUMERATE_MODULES_MODEL_WIN_H_ |
| 7 #pragma once |
| 8 |
| 9 #include <utility> |
| 10 #include <vector> |
| 11 |
| 12 #include "base/ref_counted.h" |
| 13 #include "base/singleton.h" |
| 14 #include "base/string16.h" |
| 15 #include "base/timer.h" |
| 16 #include "chrome/browser/browser_thread.h" |
| 17 #include "googleurl/src/gurl.h" |
| 18 |
| 19 class EnumerateModulesModel; |
| 20 class FilePath; |
| 21 class ListValue; |
| 22 |
| 23 // A helper class that implements the enumerate module functionality on the File |
| 24 // thread. |
| 25 class ModuleEnumerator : public base::RefCountedThreadSafe<ModuleEnumerator> { |
| 26 public: |
| 27 // What type of module we are dealing with. Loaded modules are modules we |
| 28 // detect as loaded in the process at the time of scanning. The others are |
| 29 // modules of interest and may or may not be loaded in the process at the |
| 30 // time of scan. |
| 31 enum ModuleType { |
| 32 LOADED_MODULE, |
| 33 WINSOCK_MODULE_REGISTRATION, |
| 34 }; |
| 35 |
| 36 // The blacklist status of the module. Suspected Bad modules have been |
| 37 // partially matched (ie. name matches and location, but not description) |
| 38 // whereas Confirmed Bad modules have been identified further (ie. |
| 39 // AuthentiCode signer matches). |
| 40 enum ModuleStatus { |
| 41 // This is returned by the matching function when comparing against the |
| 42 // blacklist and the module does not match the current entry in the |
| 43 // blacklist. |
| 44 NOT_MATCHED, |
| 45 // The module is not on the blacklist. Assume it is good. |
| 46 GOOD, |
| 47 // Module is a suspected bad module. |
| 48 SUSPECTED_BAD, |
| 49 // Module is a bad bad dog. |
| 50 CONFIRMED_BAD, |
| 51 }; |
| 52 |
| 53 // A bitmask with the possible resolutions for bad modules. |
| 54 enum RecommendedAction { |
| 55 NONE = 0, |
| 56 INVESTIGATING = 1 << 0, |
| 57 UNINSTALL = 1 << 1, |
| 58 DISABLE = 1 << 2, |
| 59 UPDATE = 1 << 3, |
| 60 SEE_LINK = 1 << 4, |
| 61 }; |
| 62 |
| 63 // The structure we populate when enumerating modules. |
| 64 struct Module { |
| 65 // The type of module found |
| 66 ModuleType type; |
| 67 // The module status (benign/bad/etc). |
| 68 ModuleStatus status; |
| 69 // The module path, not including filename. |
| 70 string16 location; |
| 71 // The name of the module (filename). |
| 72 string16 name; |
| 73 // The name of the product the module belongs to. |
| 74 string16 product_name; |
| 75 // The module file description. |
| 76 string16 description; |
| 77 // The module version. |
| 78 string16 version; |
| 79 // The signer of the digital certificate for the module. |
| 80 string16 digital_signer; |
| 81 // The help tips bitmask. |
| 82 RecommendedAction recommended_action; |
| 83 // Whether this module has been normalized (necessary before checking it |
| 84 // against blacklist). |
| 85 bool normalized; |
| 86 }; |
| 87 |
| 88 // A vector typedef of all modules enumerated. |
| 89 typedef std::vector<Module> ModulesVector; |
| 90 |
| 91 // A structure we populate with the blacklist entries. |
| 92 struct BlacklistEntry { |
| 93 const char* filename; |
| 94 const char* location; |
| 95 const char* desc_or_signer; |
| 96 const char* version_from; |
| 97 const char* version_to; |
| 98 RecommendedAction help_tip; |
| 99 }; |
| 100 |
| 101 // A static function that normalizes the module information in the |module| |
| 102 // struct. Module information needs to be normalized before comparing against |
| 103 // the blacklist. This is because the same module can be described in many |
| 104 // different ways, ie. file paths can be presented in long/short name form, |
| 105 // and are not case sensitive on Windows. Also, the version string returned |
| 106 // can include appended text, which we don't want to use during comparison |
| 107 // against the blacklist. |
| 108 static void NormalizeModule(Module* module); |
| 109 |
| 110 // A static function that checks whether |module| has been |blacklisted|. |
| 111 static ModuleStatus Match(const Module& module, |
| 112 const BlacklistEntry& blacklisted); |
| 113 |
| 114 explicit ModuleEnumerator(EnumerateModulesModel* observer); |
| 115 virtual ~ModuleEnumerator(); |
| 116 |
| 117 // Start scanning the loaded module list (if a scan is not already in |
| 118 // progress). This function does not block while reading the module list, but |
| 119 // will notify when done through the MODULE_LIST_ENUMERATED notification. |
| 120 // The process will also send MODULE_INCOMPATIBILITY_DETECTED if an |
| 121 // incompatible module was detected. |
| 122 void ScanNow(ModulesVector* list); |
| 123 |
| 124 private: |
| 125 // The (currently) hard coded blacklist of known bad modules. |
| 126 static const BlacklistEntry kModuleBlacklist[]; |
| 127 |
| 128 // This function does the actual file scanning work on the FILE thread. It |
| 129 // enumerates all loaded modules in the process and other modules of |
| 130 // interest, such as the registered Winsock LSP modules and stores them in |
| 131 // |enumerated_modules_|. It then normalizes the module info and matches |
| 132 // them against a blacklist of known bad modules. Finally, it calls |
| 133 // ReportBack to let the observer know we are done. |
| 134 void ScanOnFileThread(); |
| 135 |
| 136 // Builds up a vector of path values mapping to environment variable, |
| 137 // with pairs like [c:\windows\, %systemroot%]. This is later used to |
| 138 // collapse paths like c:\windows\system32 into %systemroot%\system32, which |
| 139 // we can use for comparison against our blacklist (which uses only env vars). |
| 140 // NOTE: The vector will not contain an exhaustive list of environment |
| 141 // variables, only the ones currently found on the blacklist or ones that are |
| 142 // likely to appear there. |
| 143 void PreparePathMappings(); |
| 144 |
| 145 // For a given |module|, collapse the path from c:\windows to %systemroot%, |
| 146 // based on the |path_mapping_| vector. |
| 147 void CollapsePath(Module* module); |
| 148 |
| 149 // Takes each module in the |enumerated_modules_| vector and matches it |
| 150 // against a fixed blacklist of bad and suspected bad modules. |
| 151 void MatchAgainstBlacklist(); |
| 152 |
| 153 // This function executes on the UI thread when the scanning and matching |
| 154 // process is done. It notifies the observer. |
| 155 void ReportBack(); |
| 156 |
| 157 // Given a filename, returns the Subject (who signed it) retrieved from |
| 158 // the digital signature (Authenticode). |
| 159 string16 GetSubjectNameFromDigitalSignature(const FilePath& filename); |
| 160 |
| 161 // The typedef for the vector that maps a regular file path to %env_var%. |
| 162 typedef std::vector< std::pair<string16, string16> > PathMapping; |
| 163 |
| 164 // The vector of paths to %env_var%, used to account for differences in |
| 165 // where people keep there files, c:\windows vs. d:\windows, etc. |
| 166 PathMapping path_mapping_; |
| 167 |
| 168 // The vector containing all the enumerated modules (loaded and modules of |
| 169 // interest). |
| 170 ModulesVector* enumerated_modules_; |
| 171 |
| 172 // The observer, who needs to be notified when we are done. |
| 173 EnumerateModulesModel* observer_; |
| 174 |
| 175 // The thread that we need to call back on to report that we are done. |
| 176 BrowserThread::ID callback_thread_id_; |
| 177 |
| 178 DISALLOW_COPY_AND_ASSIGN(ModuleEnumerator); |
| 179 }; |
| 180 |
| 181 // This is a singleton class that enumerates all modules loaded into Chrome, |
| 182 // both currently loaded modules (called DLLs on Windows) and modules 'of |
| 183 // interest', such as WinSock LSP modules. This class also marks each module |
| 184 // as benign or suspected bad or outright bad, using a supplied blacklist that |
| 185 // is currently hard-coded. |
| 186 // |
| 187 // To use this class, grab the singleton pointer and call ScanNow(). |
| 188 // Then wait to get notified through MODULE_LIST_ENUMERATED when the list is |
| 189 // ready. |
| 190 // |
| 191 // This class can be used on the UI thread as it asynchronously offloads the |
| 192 // file work over to the FILE thread and reports back to the caller with a |
| 193 // notification. |
| 194 class EnumerateModulesModel { |
| 195 public: |
| 196 static EnumerateModulesModel* GetSingleton() { |
| 197 return Singleton<EnumerateModulesModel>::get(); |
| 198 } |
| 199 |
| 200 // Returns the number of suspected bad modules found in the last scan. |
| 201 // Returns 0 if no scan has taken place yet. |
| 202 int suspected_bad_modules_detected() { |
| 203 return suspected_bad_modules_detected_; |
| 204 } |
| 205 |
| 206 // Returns the number of confirmed bad modules found in the last scan. |
| 207 // Returns 0 if no scan has taken place yet. |
| 208 int confirmed_bad_modules_detected() { |
| 209 return confirmed_bad_modules_detected_; |
| 210 } |
| 211 |
| 212 // Asynchronously start the scan for the loaded module list. |
| 213 // When the list is ready. |
| 214 void ScanNow(); |
| 215 |
| 216 // Gets the whole module list as a ListValue. |
| 217 ListValue* GetModuleList(); |
| 218 |
| 219 private: |
| 220 friend struct DefaultSingletonTraits<EnumerateModulesModel>; |
| 221 friend class ModuleEnumerator; |
| 222 |
| 223 EnumerateModulesModel(); |
| 224 virtual ~EnumerateModulesModel(); |
| 225 |
| 226 // Called on the UI thread when the helper class is done scanning. |
| 227 void DoneScanning(); |
| 228 |
| 229 // Constructs a Help Center article URL for help with a particular module. |
| 230 // The module must have the SEE_LINK attribute for |recommended_action| set, |
| 231 // otherwise this returns a blank string. |
| 232 GURL ConstructHelpCenterUrl(const ModuleEnumerator::Module& module); |
| 233 |
| 234 // The vector containing all the modules enumerated. Will be normalized and |
| 235 // any bad modules will be marked. |
| 236 ModuleEnumerator::ModulesVector enumerated_modules_; |
| 237 |
| 238 // The object responsible for enumerating the modules on the File thread. |
| 239 scoped_refptr<ModuleEnumerator> module_enumerator_; |
| 240 |
| 241 // When this singleton object is constructed we go and fire off this timer to |
| 242 // start scanning for modules after a certain amount of time has passed. |
| 243 base::OneShotTimer<EnumerateModulesModel> check_modules_timer_; |
| 244 |
| 245 // True if we are currently scanning for modules. |
| 246 bool scanning_; |
| 247 |
| 248 // The number of confirmed bad modules (not including suspected bad ones) |
| 249 // found during last scan. |
| 250 int confirmed_bad_modules_detected_; |
| 251 |
| 252 // The number of suspected bad modules (not including confirmed bad ones) |
| 253 // found during last scan. |
| 254 int suspected_bad_modules_detected_; |
| 255 |
| 256 DISALLOW_COPY_AND_ASSIGN(EnumerateModulesModel); |
| 257 }; |
| 258 |
| 259 #endif // CHROME_BROWSER_ENUMERATE_MODULES_MODEL_WIN_H_ |
OLD | NEW |