1 // Copyright 2014 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.
5 #include "chrome/browser/safe_browsing/incident_reporting/environment_data_collection_win.h"
10 #include "base/i18n/case_conversion.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/win/registry.h"
14 #include "chrome/browser/install_verification/win/module_info.h"
15 #include "chrome/browser/install_verification/win/module_verification_common.h"
16 #include "chrome/browser/net/service_providers_win.h"
17 #include "chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win.h"
18 #include "chrome/browser/safe_browsing/path_sanitizer.h"
19 #include "chrome/common/safe_browsing/csd.pb.h"
20 #include "chrome_elf/chrome_elf_constants.h"
22 namespace safe_browsing
{
26 // The modules on which we will run VerifyModule.
27 const wchar_t* const kModulesToVerify
[] = {
33 // Helper function for expanding all environment variables in |path|.
34 std::wstring
ExpandEnvironmentVariables(const std::wstring
& path
) {
35 static const DWORD kMaxBuffer
= 32 * 1024; // Max according to MSDN.
36 std::wstring path_expanded
;
37 DWORD path_len
= MAX_PATH
;
39 DWORD result
= ExpandEnvironmentStrings(
40 path
.c_str(), WriteInto(&path_expanded
, path_len
), path_len
);
42 // Failed to expand variables. Return the original string.
46 if (result
<= path_len
)
47 return path_expanded
.substr(0, result
- 1);
49 } while (path_len
< kMaxBuffer
);
56 bool CollectDlls(ClientIncidentReport_EnvironmentData_Process
* process
) {
57 // Retrieve the module list.
58 std::set
<ModuleInfo
> loaded_modules
;
59 if (!GetLoadedModules(&loaded_modules
))
62 // Sanitize path of each module and add it to the incident report.
63 PathSanitizer path_sanitizer
;
64 for (std::set
<ModuleInfo
>::const_iterator it
= loaded_modules
.begin();
65 it
!= loaded_modules
.end();
67 base::FilePath
dll_path(it
->name
);
68 path_sanitizer
.StripHomeDirectory(&dll_path
);
70 ClientIncidentReport_EnvironmentData_Process_Dll
* dll
= process
->add_dll();
71 dll
->set_path(base::WideToUTF8(base::i18n::ToLower(dll_path
.value())));
72 dll
->set_base_address(it
->base_address
);
73 dll
->set_length(it
->size
);
79 void RecordLspFeature(ClientIncidentReport_EnvironmentData_Process
* process
) {
80 WinsockLayeredServiceProviderList lsp_list
;
81 GetWinsockLayeredServiceProviders(&lsp_list
);
83 // For each LSP, we extract and sanitize the path.
84 PathSanitizer path_sanitizer
;
85 std::set
<std::wstring
> lsp_paths
;
86 for (size_t i
= 0; i
< lsp_list
.size(); ++i
) {
87 base::FilePath
lsp_path(ExpandEnvironmentVariables(lsp_list
[i
].path
));
88 path_sanitizer
.StripHomeDirectory(&lsp_path
);
89 lsp_paths
.insert(base::i18n::ToLower(lsp_path
.value()));
92 // Look for a match between LSPs and loaded dlls.
93 for (int i
= 0; i
< process
->dll_size(); ++i
) {
94 if (lsp_paths
.count(base::UTF8ToWide(process
->dll(i
).path()))) {
95 process
->mutable_dll(i
)
96 ->add_feature(ClientIncidentReport_EnvironmentData_Process_Dll::LSP
);
101 void CollectDllBlacklistData(
102 ClientIncidentReport_EnvironmentData_Process
* process
) {
103 PathSanitizer path_sanitizer
;
104 base::win::RegistryValueIterator
iter(HKEY_CURRENT_USER
,
105 blacklist::kRegistryFinchListPath
);
106 for (; iter
.Valid(); ++iter
) {
107 base::FilePath
dll_name(iter
.Value());
108 path_sanitizer
.StripHomeDirectory(&dll_name
);
109 process
->add_blacklisted_dll(dll_name
.AsUTF8Unsafe());
113 void CollectModuleVerificationData(
114 const wchar_t* const modules_to_verify
[],
115 size_t num_modules_to_verify
,
116 ClientIncidentReport_EnvironmentData_Process
* process
) {
117 for (size_t i
= 0; i
< num_modules_to_verify
; ++i
) {
118 std::set
<std::string
> modified_exports
;
119 int modified
= VerifyModule(modules_to_verify
[i
], &modified_exports
);
121 if (modified
== MODULE_STATE_UNMODIFIED
)
124 ClientIncidentReport_EnvironmentData_Process_ModuleState
* module_state
=
125 process
->add_module_state();
127 module_state
->set_name(base::WideToUTF8(modules_to_verify
[i
]));
128 // Add 1 to the ModuleState enum to get the corresponding value in the
129 // protobuf's ModuleState enum.
130 module_state
->set_modified_state(static_cast<
131 ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState
>(
133 for (std::set
<std::string
>::iterator it
= modified_exports
.begin();
134 it
!= modified_exports
.end();
136 module_state
->add_modified_export(*it
);
141 void CollectPlatformProcessData(
142 ClientIncidentReport_EnvironmentData_Process
* process
) {
143 CollectDlls(process
);
144 RecordLspFeature(process
);
145 CollectDllBlacklistData(process
);
146 CollectModuleVerificationData(
147 kModulesToVerify
, arraysize(kModulesToVerify
), process
);
150 } // namespace safe_browsing