This source file includes following definitions.
- AddressBeyondRange
- ScanImportAddressTable
- VerifyImportedModules
#include "chrome/browser/install_verification/win/imported_module_verification.h"
#include <Windows.h>
#include <algorithm>
#include <iterator>
#include <string>
#include <vector>
#include "base/logging.h"
#include "base/strings/string16.h"
#include "chrome/browser/install_verification/win/module_info.h"
namespace {
const wchar_t* const kModulesToScan[] = {
L"chrome.dll",
L"kernel32.dll",
L"user32.dll"
};
bool AddressBeyondRange(const ModuleInfo& module, uintptr_t address) {
return module.base_address + module.size < address;
}
void ScanImportAddressTable(
HMODULE module_handle,
const std::set<ModuleInfo>& loaded_modules,
std::set<base::string16>* imported_modules) {
DCHECK(module_handle);
DCHECK(imported_modules);
IMAGE_DOS_HEADER* dos_header =
reinterpret_cast<IMAGE_DOS_HEADER*>(module_handle);
DCHECK(dos_header->e_lfanew);
IMAGE_NT_HEADERS* nt_headers = reinterpret_cast<IMAGE_NT_HEADERS*>(
module_handle + dos_header->e_lfanew / sizeof(uintptr_t));
if (!nt_headers->OptionalHeader.DataDirectory[1].VirtualAddress)
return;
IMAGE_IMPORT_DESCRIPTOR* image_descriptor =
reinterpret_cast<IMAGE_IMPORT_DESCRIPTOR*>(module_handle +
nt_headers->OptionalHeader.DataDirectory[1].VirtualAddress /
sizeof(uintptr_t));
while (image_descriptor->Characteristics) {
uintptr_t* address = reinterpret_cast<uintptr_t*>(
module_handle + image_descriptor->FirstThunk / sizeof(uintptr_t));
while (*address) {
std::set<ModuleInfo>::const_iterator lower_bound = std::lower_bound(
loaded_modules.begin(), loaded_modules.end(), *address,
AddressBeyondRange);
if (lower_bound != loaded_modules.end() &&
lower_bound->ContainsAddress(*address)) {
imported_modules->insert(lower_bound->name);
}
++address;
}
image_descriptor += sizeof(image_descriptor) / sizeof(uintptr_t);
}
}
}
void VerifyImportedModules(const std::set<ModuleInfo>& loaded_modules,
const ModuleIDs& module_ids,
ModuleVerificationDelegate* delegate){
#if !defined(_WIN64)
std::set<base::string16> imported_module_names;
for (size_t i = 0; i < arraysize(kModulesToScan); ++i) {
HMODULE module_handle = ::GetModuleHandle(kModulesToScan[i]);
if (module_handle) {
ScanImportAddressTable(module_handle,
loaded_modules,
&imported_module_names);
}
}
std::vector<std::string> module_name_digests;
std::transform(imported_module_names.begin(),
imported_module_names.end(),
std::back_inserter(module_name_digests),
&CalculateModuleNameDigest);
ReportModuleMatches(module_name_digests, module_ids, delegate);
#endif
}