Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Side by Side Diff: chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win.cc

Issue 1083193007: Remove legacy Module Verifier. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: sync to position 330514; updated histograms.xml Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/safe_browsing/incident_reporting/module_integrity_verif ier_win.h" 5 #include "chrome/browser/safe_browsing/incident_reporting/module_integrity_verif ier_win.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string>
8 #include <vector> 9 #include <vector>
9 10
10 #include "base/containers/hash_tables.h"
11 #include "base/files/file_path.h" 11 #include "base/files/file_path.h"
12 #include "base/files/memory_mapped_file.h" 12 #include "base/files/memory_mapped_file.h"
13 #include "base/metrics/sparse_histogram.h" 13 #include "base/metrics/sparse_histogram.h"
14 #include "base/scoped_native_library.h" 14 #include "base/scoped_native_library.h"
15 #include "base/strings/utf_string_conversions.h"
15 #include "base/win/pe_image.h" 16 #include "base/win/pe_image.h"
16 #include "build/build_config.h" 17 #include "chrome/common/safe_browsing/csd.pb.h"
17 18
18 namespace safe_browsing { 19 namespace safe_browsing {
19 20
20 namespace { 21 namespace {
21 22
22 // The maximum amount of bytes that can be reported as modified by 23 // The maximum amount of bytes that can be reported as modified by VerifyModule.
23 // NewVerifyModule.
24 const int kMaxModuleModificationBytes = 256; 24 const int kMaxModuleModificationBytes = 256;
25 25
26 struct Export { 26 struct Export {
27 Export(void* addr, const std::string& name); 27 Export(void* addr, const std::string& name);
28 ~Export(); 28 ~Export();
29 29
30 bool operator<(const Export& other) const { 30 bool operator<(const Export& other) const {
31 return addr < other.addr; 31 return addr < other.addr;
32 } 32 }
33 33
(...skipping 14 matching lines...) Expand all
48 base::win::PEImageAsData disk_peimage; 48 base::win::PEImageAsData disk_peimage;
49 49
50 // The module's preferred base address minus the base address it actually 50 // The module's preferred base address minus the base address it actually
51 // loaded at. 51 // loaded at.
52 intptr_t image_base_delta; 52 intptr_t image_base_delta;
53 53
54 // The location of the disk_peimage module's code section minus that of the 54 // The location of the disk_peimage module's code section minus that of the
55 // mem_peimage module's code section. 55 // mem_peimage module's code section.
56 intptr_t code_section_delta; 56 intptr_t code_section_delta;
57 57
58 // The bytes corrected by relocs.
59 base::hash_set<uintptr_t> reloc_addr;
60
61 // Set true if the relocation table contains a reloc of type that we don't 58 // Set true if the relocation table contains a reloc of type that we don't
62 // currently handle. 59 // currently handle.
63 bool unknown_reloc_type; 60 bool unknown_reloc_type;
64 61
65 // The start of the code section of the in-memory binary. 62 // The start of the code section of the in-memory binary.
66 uint8_t* mem_code_addr; 63 uint8_t* mem_code_addr;
67 64
68 // The start of the code section of the on-disk binary. 65 // The start of the code section of the on-disk binary.
69 uint8_t* disk_code_addr; 66 uint8_t* disk_code_addr;
70 67
71 // The size of the binary's code section. 68 // The size of the binary's code section.
72 uint32_t code_size; 69 uint32_t code_size;
73 70
74 // The exports of the DLL, sorted by address in ascending order. 71 // The exports of the DLL, sorted by address in ascending order.
75 std::vector<Export> exports; 72 std::vector<Export> exports;
76 73
77 // The location in the in-memory binary of the latest reloc encountered by 74 // The location in the in-memory binary of the latest reloc encountered by
78 // |NewEnumRelocsCallback|. 75 // |EnumRelocsCallback|.
79 uint8_t* last_mem_reloc_position; 76 uint8_t* last_mem_reloc_position;
80 77
81 // The location in the on-disk binary of the latest reloc encountered by 78 // The location in the on-disk binary of the latest reloc encountered by
82 // |NewEnumRelocsCallback|. 79 // |EnumRelocsCallback|.
83 uint8_t* last_disk_reloc_position; 80 uint8_t* last_disk_reloc_position;
84 81
85 // The number of bytes with a different value on disk and in memory, as 82 // The number of bytes with a different value on disk and in memory, as
86 // computed by |NewVerifyModule|. 83 // computed by |VerifyModule|.
87 int bytes_different; 84 int bytes_different;
88 85
89 // The module state protobuf object that |NewVerifyModule| will populate. 86 // The module state protobuf object that |VerifyModule| will populate.
90 ClientIncidentReport_EnvironmentData_Process_ModuleState* module_state; 87 ClientIncidentReport_EnvironmentData_Process_ModuleState* module_state;
91 88
92 private: 89 private:
93 DISALLOW_COPY_AND_ASSIGN(ModuleVerificationState); 90 DISALLOW_COPY_AND_ASSIGN(ModuleVerificationState);
94 }; 91 };
95 92
96 ModuleVerificationState::ModuleVerificationState(HMODULE hModule) 93 ModuleVerificationState::ModuleVerificationState(HMODULE hModule)
97 : disk_peimage(hModule), 94 : disk_peimage(hModule),
98 image_base_delta(0), 95 image_base_delta(0),
99 code_section_delta(0), 96 code_section_delta(0),
100 reloc_addr(),
101 unknown_reloc_type(false), 97 unknown_reloc_type(false),
102 mem_code_addr(nullptr), 98 mem_code_addr(nullptr),
103 disk_code_addr(nullptr), 99 disk_code_addr(nullptr),
104 code_size(0), 100 code_size(0),
105 last_mem_reloc_position(nullptr), 101 last_mem_reloc_position(nullptr),
106 last_disk_reloc_position(nullptr), 102 last_disk_reloc_position(nullptr),
107 bytes_different(0), 103 bytes_different(0),
108 module_state(nullptr) { 104 module_state(nullptr) {
109 } 105 }
110 106
111 ModuleVerificationState::~ModuleVerificationState() { 107 ModuleVerificationState::~ModuleVerificationState() {
112 } 108 }
113 109
114 bool ByteAccountedForByReloc(uint8_t* byte_addr,
115 const ModuleVerificationState& state) {
116 return ((state.reloc_addr.count(reinterpret_cast<uintptr_t>(byte_addr))) > 0);
117 }
118
119 // Find which export a modification at address |mem_address| is in. Looks for 110 // Find which export a modification at address |mem_address| is in. Looks for
120 // the largest export address still smaller than |mem_address|. |start| and 111 // the largest export address still smaller than |mem_address|. |start| and
121 // |end| must come from a sorted collection. 112 // |end| must come from a sorted collection.
122 std::vector<Export>::const_iterator FindModifiedExport( 113 std::vector<Export>::const_iterator FindModifiedExport(
123 uint8_t* mem_address, 114 uint8_t* mem_address,
124 std::vector<Export>::const_iterator start, 115 std::vector<Export>::const_iterator start,
125 std::vector<Export>::const_iterator end) { 116 std::vector<Export>::const_iterator end) {
126 // We get the largest export address still smaller than |addr|. It is 117 // We get the largest export address still smaller than |addr|. It is
127 // possible that |addr| belongs to some nonexported function located 118 // possible that |addr| belongs to some nonexported function located
128 // between this export and the following one. 119 // between this export and the following one.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 int bytes_in_modification = mem_start - range_start; 158 int bytes_in_modification = mem_start - range_start;
168 bytes_different += bytes_in_modification; 159 bytes_different += bytes_in_modification;
169 modification->set_byte_count(bytes_in_modification); 160 modification->set_byte_count(bytes_in_modification);
170 modification->set_modified_bytes( 161 modification->set_modified_bytes(
171 range_start, 162 range_start,
172 std::min(bytes_in_modification, kMaxModuleModificationBytes)); 163 std::min(bytes_in_modification, kMaxModuleModificationBytes));
173 } 164 }
174 return bytes_different; 165 return bytes_different;
175 } 166 }
176 167
177 // Checks each byte in the module's code section again the corresponding byte on
178 // disk, returning the number of bytes differing between the two. Also adds the
179 // names of any modfied functions exported by name to |modified_exports|.
180 // |state.exports| must be sorted.
181 int ExamineBytesDiffInMemory(uint8_t* disk_code_start,
182 uint8_t* mem_code_start,
183 uint32_t code_size,
184 const ModuleVerificationState& state,
185 std::set<std::string>* modified_exports) {
186 int bytes_different = 0;
187 std::vector<Export>::const_iterator export_it = state.exports.begin();
188
189 for (uint8_t* end = mem_code_start + code_size; mem_code_start != end;
190 ++mem_code_start) {
191 if ((*disk_code_start++ != *mem_code_start) &&
192 !ByteAccountedForByReloc(mem_code_start, state)) {
193 std::vector<Export>::const_iterator modified_export_it =
194 FindModifiedExport(mem_code_start, export_it, state.exports.end());
195
196 if (modified_export_it != state.exports.begin())
197 modified_exports->insert((modified_export_it - 1)->name);
198 ++bytes_different;
199
200 // No later byte can belong to an earlier export.
201 export_it = modified_export_it;
202 }
203 }
204 return bytes_different;
205 }
206
207 // Adds to |state->reloc_addr| the bytes of the pointer at |address| that are
208 // corrected by adding |image_base_delta|.
209 void AddBytesCorrectedByReloc(uintptr_t address,
210 ModuleVerificationState* state) {
211 #if defined(ARCH_CPU_LITTLE_ENDIAN)
212 # define OFFSET(i) i
213 #else
214 # define OFFSET(i) (sizeof(uintptr_t) - i)
215 #endif
216
217 uintptr_t orig_mem_value = *reinterpret_cast<uintptr_t*>(address);
218 uintptr_t fixed_mem_value = orig_mem_value + state->image_base_delta;
219 uintptr_t disk_value =
220 *reinterpret_cast<uintptr_t*>(address + state->code_section_delta);
221
222 uintptr_t diff_before = orig_mem_value ^ disk_value;
223 uintptr_t shared_after = ~(fixed_mem_value ^ disk_value);
224 int i = 0;
225 for (uintptr_t fixed = diff_before & shared_after; fixed; fixed >>= 8, ++i) {
226 if (fixed & 0xFF)
227 state->reloc_addr.insert(address + OFFSET(i));
228 }
229 #undef OFFSET
230 }
231
232 bool AddrIsInCodeSection(void* address, 168 bool AddrIsInCodeSection(void* address,
233 uint8_t* code_addr, 169 uint8_t* code_addr,
234 uint32_t code_size) { 170 uint32_t code_size) {
235 return (code_addr <= address && address < code_addr + code_size); 171 return (code_addr <= address && address < code_addr + code_size);
236 } 172 }
237 173
238 bool NewEnumRelocsCallback(const base::win::PEImage& mem_peimage, 174 bool EnumRelocsCallback(const base::win::PEImage& mem_peimage,
239 WORD type, 175 WORD type,
240 void* address, 176 void* address,
241 void* cookie) { 177 void* cookie) {
242 ModuleVerificationState* state = 178 ModuleVerificationState* state =
243 reinterpret_cast<ModuleVerificationState*>(cookie); 179 reinterpret_cast<ModuleVerificationState*>(cookie);
244 180
245 // If not in the code section return true to continue to the next reloc. 181 // If not in the code section return true to continue to the next reloc.
246 if (!AddrIsInCodeSection(address, state->mem_code_addr, state->code_size)) 182 if (!AddrIsInCodeSection(address, state->mem_code_addr, state->code_size))
247 return true; 183 return true;
248 184
249 switch (type) { 185 switch (type) {
250 case IMAGE_REL_BASED_ABSOLUTE: // 0 186 case IMAGE_REL_BASED_ABSOLUTE: // 0
251 break; 187 break;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 default: 248 default:
313 // TODO(robertshield): Find a reliable description of the behaviour of the 249 // TODO(robertshield): Find a reliable description of the behaviour of the
314 // remaining types of relocation and handle them. 250 // remaining types of relocation and handle them.
315 UMA_HISTOGRAM_SPARSE_SLOWLY("SafeBrowsing.ModuleBaseRelocation", type); 251 UMA_HISTOGRAM_SPARSE_SLOWLY("SafeBrowsing.ModuleBaseRelocation", type);
316 state->unknown_reloc_type = true; 252 state->unknown_reloc_type = true;
317 break; 253 break;
318 } 254 }
319 return true; 255 return true;
320 } 256 }
321 257
322 bool EnumRelocsCallback(const base::win::PEImage& mem_peimage,
323 WORD type,
324 void* address,
325 void* cookie) {
326 ModuleVerificationState* state =
327 reinterpret_cast<ModuleVerificationState*>(cookie);
328
329 uint8_t* mem_code_addr = NULL;
330 uint8_t* disk_code_addr = NULL;
331 uint32_t code_size = 0;
332 if (!GetCodeAddrsAndSize(mem_peimage,
333 state->disk_peimage,
334 &mem_code_addr,
335 &disk_code_addr,
336 &code_size))
337 return false;
338
339 // If not in the code section return true to continue to the next reloc.
340 if (!AddrIsInCodeSection(address, mem_code_addr, code_size))
341 return true;
342
343 switch (type) {
344 case IMAGE_REL_BASED_ABSOLUTE: // 0
345 // Absolute type relocations are a noop, sometimes used to pad a section
346 // of relocations.
347 break;
348 case IMAGE_REL_BASED_HIGHLOW: // 3
349 // The base relocation applies all 32 bits of the difference to the 32-bit
350 // field at offset.
351 AddBytesCorrectedByReloc(reinterpret_cast<uintptr_t>(address), state);
352 break;
353 case IMAGE_REL_BASED_DIR64: // 10
354 // The base relocation applies the difference to the 64-bit field at
355 // offset.
356 // TODO(robertshield): Handle this type of reloc.
357 break;
358 default:
359 // TODO(robertshield): Find a reliable description of the behaviour of the
360 // remaining types of relocation and handle them.
361 UMA_HISTOGRAM_SPARSE_SLOWLY("SafeBrowsing.ModuleBaseRelocation", type);
362 state->unknown_reloc_type = true;
363 break;
364 }
365 return true;
366 }
367
368 bool EnumExportsCallback(const base::win::PEImage& mem_peimage, 258 bool EnumExportsCallback(const base::win::PEImage& mem_peimage,
369 DWORD ordinal, 259 DWORD ordinal,
370 DWORD hint, 260 DWORD hint,
371 LPCSTR name, 261 LPCSTR name,
372 PVOID function_addr, 262 PVOID function_addr,
373 LPCSTR forward, 263 LPCSTR forward,
374 PVOID cookie) { 264 PVOID cookie) {
375 std::vector<Export>* exports = reinterpret_cast<std::vector<Export>*>(cookie); 265 std::vector<Export>* exports = reinterpret_cast<std::vector<Export>*>(cookie);
376 if (name) 266 if (name)
377 exports->push_back(Export(function_addr, std::string(name))); 267 exports->push_back(Export(function_addr, std::string(name)));
(...skipping 25 matching lines...) Expand all
403 // Get the address of the code section in the module mapped as data from disk. 293 // Get the address of the code section in the module mapped as data from disk.
404 DWORD disk_code_offset = 0; 294 DWORD disk_code_offset = 0;
405 if (!mem_peimage.ImageAddrToOnDiskOffset( 295 if (!mem_peimage.ImageAddrToOnDiskOffset(
406 reinterpret_cast<void*>(*mem_code_addr), &disk_code_offset)) 296 reinterpret_cast<void*>(*mem_code_addr), &disk_code_offset))
407 return false; 297 return false;
408 *disk_code_addr = 298 *disk_code_addr =
409 reinterpret_cast<uint8_t*>(disk_peimage.module()) + disk_code_offset; 299 reinterpret_cast<uint8_t*>(disk_peimage.module()) + disk_code_offset;
410 return true; 300 return true;
411 } 301 }
412 302
413 VerificationResult NewVerifyModule( 303 bool VerifyModule(
414 const wchar_t* module_name, 304 const wchar_t* module_name,
415 ClientIncidentReport_EnvironmentData_Process_ModuleState* module_state) { 305 ClientIncidentReport_EnvironmentData_Process_ModuleState* module_state,
416 VerificationResult result = { MODULE_STATE_UNKNOWN, 0, false, }; 306 int* num_bytes_different) {
307 using ModuleState = ClientIncidentReport_EnvironmentData_Process_ModuleState;
308 *num_bytes_different = 0;
309 module_state->set_name(base::WideToUTF8(module_name));
310 module_state->set_modified_state(ModuleState::MODULE_STATE_UNKNOWN);
417 311
418 // Get module handle, load a copy from disk as data and create PEImages. 312 // Get module handle, load a copy from disk as data and create PEImages.
419 HMODULE module_handle = NULL; 313 HMODULE module_handle = NULL;
420 if (!GetModuleHandleEx(0, module_name, &module_handle)) 314 if (!GetModuleHandleEx(0, module_name, &module_handle))
421 return result; 315 return false;
422 base::ScopedNativeLibrary native_library(module_handle); 316 base::ScopedNativeLibrary native_library(module_handle);
423 317
424 WCHAR module_path[MAX_PATH] = {}; 318 WCHAR module_path[MAX_PATH] = {};
425 DWORD length = 319 DWORD length =
426 GetModuleFileName(module_handle, module_path, arraysize(module_path)); 320 GetModuleFileName(module_handle, module_path, arraysize(module_path));
427 if (!length || length == arraysize(module_path)) 321 if (!length || length == arraysize(module_path))
428 return result; 322 return false;
429 323
430 base::MemoryMappedFile mapped_module; 324 base::MemoryMappedFile mapped_module;
431 if (!mapped_module.Initialize(base::FilePath(module_path))) 325 if (!mapped_module.Initialize(base::FilePath(module_path)))
432 return result; 326 return false;
433 ModuleVerificationState state( 327 ModuleVerificationState state(
434 reinterpret_cast<HMODULE>(const_cast<uint8*>(mapped_module.data()))); 328 reinterpret_cast<HMODULE>(const_cast<uint8*>(mapped_module.data())));
435 329
436 base::win::PEImage mem_peimage(module_handle); 330 base::win::PEImage mem_peimage(module_handle);
437 if (!mem_peimage.VerifyMagic() || !state.disk_peimage.VerifyMagic()) 331 if (!mem_peimage.VerifyMagic() || !state.disk_peimage.VerifyMagic())
438 return result; 332 return false;
439 333
440 // Get the list of exports and sort them by address for efficient lookups. 334 // Get the list of exports and sort them by address for efficient lookups.
441 mem_peimage.EnumExports(EnumExportsCallback, &state.exports); 335 mem_peimage.EnumExports(EnumExportsCallback, &state.exports);
442 std::sort(state.exports.begin(), state.exports.end()); 336 std::sort(state.exports.begin(), state.exports.end());
443 337
444 // Get the addresses of the code sections then calculate |code_section_delta| 338 // Get the addresses of the code sections then calculate |code_section_delta|
445 // and |image_base_delta|. 339 // and |image_base_delta|.
446 if (!GetCodeAddrsAndSize(mem_peimage, 340 if (!GetCodeAddrsAndSize(mem_peimage,
447 state.disk_peimage, 341 state.disk_peimage,
448 &state.mem_code_addr, 342 &state.mem_code_addr,
449 &state.disk_code_addr, 343 &state.disk_code_addr,
450 &state.code_size)) 344 &state.code_size))
451 return result; 345 return false;
452 346
453 state.module_state = module_state; 347 state.module_state = module_state;
454 state.last_mem_reloc_position = state.mem_code_addr; 348 state.last_mem_reloc_position = state.mem_code_addr;
455 state.last_disk_reloc_position = state.disk_code_addr; 349 state.last_disk_reloc_position = state.disk_code_addr;
456 state.code_section_delta = state.disk_code_addr - state.mem_code_addr; 350 state.code_section_delta = state.disk_code_addr - state.mem_code_addr;
457 351
458 uint8_t* preferred_image_base = reinterpret_cast<uint8_t*>( 352 uint8_t* preferred_image_base = reinterpret_cast<uint8_t*>(
459 state.disk_peimage.GetNTHeaders()->OptionalHeader.ImageBase); 353 state.disk_peimage.GetNTHeaders()->OptionalHeader.ImageBase);
460 state.image_base_delta = 354 state.image_base_delta =
461 preferred_image_base - reinterpret_cast<uint8_t*>(mem_peimage.module()); 355 preferred_image_base - reinterpret_cast<uint8_t*>(mem_peimage.module());
462 356
463 state.last_mem_reloc_position = state.mem_code_addr; 357 state.last_mem_reloc_position = state.mem_code_addr;
464 state.last_disk_reloc_position = state.disk_code_addr; 358 state.last_disk_reloc_position = state.disk_code_addr;
465 359
466 // Enumerate relocations and verify the bytes between them. 360 // Enumerate relocations and verify the bytes between them.
467 result.verification_completed = 361 bool scan_complete = mem_peimage.EnumRelocs(EnumRelocsCallback, &state);
468 mem_peimage.EnumRelocs(NewEnumRelocsCallback, &state);
469 362
470 if (result.verification_completed) { 363 if (scan_complete) {
471 size_t range_size = 364 size_t range_size =
472 state.code_size - (state.last_mem_reloc_position - state.mem_code_addr); 365 state.code_size - (state.last_mem_reloc_position - state.mem_code_addr);
473 // Inspect the last chunk spanning from the furthest relocation to the end 366 // Inspect the last chunk spanning from the furthest relocation to the end
474 // of the code section. 367 // of the code section.
475 state.bytes_different += ExamineByteRangeDiff( 368 state.bytes_different += ExamineByteRangeDiff(
476 state.last_disk_reloc_position, 369 state.last_disk_reloc_position,
477 state.last_mem_reloc_position, 370 state.last_mem_reloc_position,
478 range_size, 371 range_size,
479 &state); 372 &state);
480 } 373 }
481 result.num_bytes_different = state.bytes_different; 374 *num_bytes_different = state.bytes_different;
482 375
483 // Report STATE_MODIFIED if any difference was found, regardless of whether or 376 // Report STATE_MODIFIED if any difference was found, regardless of whether or
484 // not the entire module was scanned. Report STATE_UNMODIFIED only if the 377 // not the entire module was scanned. Report STATE_UNMODIFIED only if the
485 // entire module was scanned and understood. 378 // entire module was scanned and understood.
486 if (state.bytes_different) 379 if (state.bytes_different)
487 result.state = MODULE_STATE_MODIFIED; 380 module_state->set_modified_state(ModuleState::MODULE_STATE_MODIFIED);
488 else if (!state.unknown_reloc_type && result.verification_completed) 381 else if (!state.unknown_reloc_type && scan_complete)
489 result.state = MODULE_STATE_UNMODIFIED; 382 module_state->set_modified_state(ModuleState::MODULE_STATE_UNMODIFIED);
490 383
491 return result; 384 return scan_complete;
492 }
493
494 ModuleState VerifyModule(const wchar_t* module_name,
495 std::set<std::string>* modified_exports,
496 int* num_bytes_different) {
497 // Get module handle, load a copy from disk as data and create PEImages.
498 HMODULE module_handle = NULL;
499 if (!GetModuleHandleEx(0, module_name, &module_handle))
500 return MODULE_STATE_UNKNOWN;
501 base::ScopedNativeLibrary native_library(module_handle);
502
503 WCHAR module_path[MAX_PATH] = {};
504 DWORD length =
505 GetModuleFileName(module_handle, module_path, arraysize(module_path));
506 if (!length || length == arraysize(module_path))
507 return MODULE_STATE_UNKNOWN;
508
509 base::MemoryMappedFile mapped_module;
510 if (!mapped_module.Initialize(base::FilePath(module_path)))
511 return MODULE_STATE_UNKNOWN;
512 ModuleVerificationState state(
513 reinterpret_cast<HMODULE>(const_cast<uint8*>(mapped_module.data())));
514
515 base::win::PEImage mem_peimage(module_handle);
516 if (!mem_peimage.VerifyMagic() || !state.disk_peimage.VerifyMagic())
517 return MODULE_STATE_UNKNOWN;
518
519 // Get the list of exports.
520 mem_peimage.EnumExports(EnumExportsCallback, &state.exports);
521 std::sort(state.exports.begin(), state.exports.end());
522
523 // Get the addresses of the code sections then calculate |code_section_delta|
524 // and |image_base_delta|.
525 uint8_t* mem_code_addr = NULL;
526 uint8_t* disk_code_addr = NULL;
527 uint32_t code_size = 0;
528 if (!GetCodeAddrsAndSize(mem_peimage,
529 state.disk_peimage,
530 &mem_code_addr,
531 &disk_code_addr,
532 &code_size))
533 return MODULE_STATE_UNKNOWN;
534
535 state.code_section_delta = disk_code_addr - mem_code_addr;
536
537 uint8_t* preferred_image_base = reinterpret_cast<uint8_t*>(
538 state.disk_peimage.GetNTHeaders()->OptionalHeader.ImageBase);
539 state.image_base_delta =
540 preferred_image_base - reinterpret_cast<uint8_t*>(mem_peimage.module());
541
542 // Get the relocations.
543 mem_peimage.EnumRelocs(EnumRelocsCallback, &state);
544 if (state.unknown_reloc_type)
545 return MODULE_STATE_UNKNOWN;
546
547 // Count the modified bytes (after accounting for relocs) and get the set of
548 // modified functions.
549 *num_bytes_different = ExamineBytesDiffInMemory(disk_code_addr,
550 mem_code_addr,
551 code_size,
552 state,
553 modified_exports);
554
555 return *num_bytes_different ? MODULE_STATE_MODIFIED : MODULE_STATE_UNMODIFIED;
556 } 385 }
557 386
558 } // namespace safe_browsing 387 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698