mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-24 14:26:09 +03:00
92 lines
3.0 KiB
C++
92 lines
3.0 KiB
C++
|
// Copyright 2018 The Chromium Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style license that can be
|
||
|
// found in the LICENSE file.
|
||
|
|
||
|
#include "base/sampling_heap_profiler/module_cache.h"
|
||
|
|
||
|
#include <objbase.h>
|
||
|
#include <psapi.h>
|
||
|
|
||
|
#include "base/process/process_handle.h"
|
||
|
#include "base/stl_util.h"
|
||
|
#include "base/strings/string_util.h"
|
||
|
#include "base/strings/stringprintf.h"
|
||
|
#include "base/strings/utf_string_conversions.h"
|
||
|
#include "base/win/pe_image.h"
|
||
|
#include "base/win/scoped_handle.h"
|
||
|
|
||
|
namespace base {
|
||
|
|
||
|
namespace {
|
||
|
|
||
|
// Gets the unique build ID for a module. Windows build IDs are created by a
|
||
|
// concatenation of a GUID and AGE fields found in the headers of a module. The
|
||
|
// GUID is stored in the first 16 bytes and the AGE is stored in the last 4
|
||
|
// bytes. Returns the empty string if the function fails to get the build ID.
|
||
|
//
|
||
|
// Example:
|
||
|
// dumpbin chrome.exe /headers | find "Format:"
|
||
|
// ... Format: RSDS, {16B2A428-1DED-442E-9A36-FCE8CBD29726}, 10, ...
|
||
|
//
|
||
|
// The resulting buildID string of this instance of chrome.exe is
|
||
|
// "16B2A4281DED442E9A36FCE8CBD2972610".
|
||
|
//
|
||
|
// Note that the AGE field is encoded in decimal, not hex.
|
||
|
std::string GetBuildIDForModule(HMODULE module_handle) {
|
||
|
GUID guid;
|
||
|
DWORD age;
|
||
|
if (!win::PEImage(module_handle)
|
||
|
.GetDebugId(&guid, &age, /* pdb_filename= */ nullptr,
|
||
|
/* pdb_filename_length= */ nullptr)) {
|
||
|
return std::string();
|
||
|
}
|
||
|
const int kGUIDSize = 39;
|
||
|
string16 build_id;
|
||
|
int result =
|
||
|
::StringFromGUID2(guid, WriteInto(&build_id, kGUIDSize), kGUIDSize);
|
||
|
if (result != kGUIDSize)
|
||
|
return std::string();
|
||
|
RemoveChars(build_id, L"{}-", &build_id);
|
||
|
build_id += StringPrintf(L"%d", age);
|
||
|
return UTF16ToUTF8(build_id);
|
||
|
}
|
||
|
|
||
|
} // namespace
|
||
|
|
||
|
// static
|
||
|
ModuleCache::Module ModuleCache::CreateModuleForAddress(uintptr_t address) {
|
||
|
HMODULE module_handle = nullptr;
|
||
|
if (!::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
|
||
|
reinterpret_cast<LPCTSTR>(address),
|
||
|
&module_handle)) {
|
||
|
DCHECK_EQ(ERROR_MOD_NOT_FOUND, static_cast<int>(::GetLastError()));
|
||
|
return Module();
|
||
|
}
|
||
|
Module module = CreateModuleForHandle(module_handle);
|
||
|
::CloseHandle(module_handle);
|
||
|
return module;
|
||
|
}
|
||
|
|
||
|
// static
|
||
|
ModuleCache::Module ModuleCache::CreateModuleForHandle(HMODULE module_handle) {
|
||
|
wchar_t module_name[MAX_PATH];
|
||
|
DWORD result_length =
|
||
|
::GetModuleFileName(module_handle, module_name, size(module_name));
|
||
|
if (result_length == 0)
|
||
|
return Module();
|
||
|
const std::string& module_id = GetBuildIDForModule(module_handle);
|
||
|
if (module_id.empty())
|
||
|
return Module();
|
||
|
|
||
|
MODULEINFO module_info;
|
||
|
if (!::GetModuleInformation(GetCurrentProcessHandle(), module_handle,
|
||
|
&module_info, sizeof(module_info))) {
|
||
|
return Module();
|
||
|
}
|
||
|
|
||
|
return Module(reinterpret_cast<uintptr_t>(module_info.lpBaseOfDll), module_id,
|
||
|
FilePath(module_name), module_info.SizeOfImage);
|
||
|
}
|
||
|
|
||
|
} // namespace base
|