Commit 0ec367d2 authored by Cliff Smolinsky's avatar Cliff Smolinsky Committed by Commit Bot

Ensure __HrLoadAllImportsForDll only runs once per dll.

If we patch a function in a delayloaded dll, __HrLoadAllImportsForDll is
called to load everything before the patch. If we then patch another
method in the same dll, __HrLoadAllImportsForDll is called again and
this will overwrite the original patch. This change adds tracking to
ensure the load only occurs once per dll.

Bug: 1012424
Change-Id: Ib20fe38461a7eab3735f851bdfd53f9cf99fc5d9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1848362Reviewed-by: default avatarGreg Thompson <grt@chromium.org>
Commit-Queue: Cliff Smolinsky <cliffsmo@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#706944}
parent 62e19332
...@@ -26,6 +26,7 @@ buildflag_header("base_win_buildflags") { ...@@ -26,6 +26,7 @@ buildflag_header("base_win_buildflags") {
static_library("pe_image") { static_library("pe_image") {
sources = [ sources = [
"../no_destructor.h",
"current_module.h", "current_module.h",
"pe_image.cc", "pe_image.cc",
"pe_image.h", "pe_image.h",
......
...@@ -9,7 +9,10 @@ ...@@ -9,7 +9,10 @@
#include <delayimp.h> #include <delayimp.h>
#include <stddef.h> #include <stddef.h>
#include <set>
#include <string>
#include "base/no_destructor.h"
#include "base/win/current_module.h" #include "base/win/current_module.h"
namespace base { namespace base {
...@@ -48,6 +51,11 @@ struct PdbInfo { ...@@ -48,6 +51,11 @@ struct PdbInfo {
char PdbFileName[1]; char PdbFileName[1];
}; };
#define LDR_IS_DATAFILE(handle) (((ULONG_PTR)(handle)) & (ULONG_PTR)1)
#define LDR_IS_IMAGEMAPPING(handle) (((ULONG_PTR)(handle)) & (ULONG_PTR)2)
#define LDR_IS_RESOURCE(handle) \
(LDR_IS_IMAGEMAPPING(handle) || LDR_IS_DATAFILE(handle))
} // namespace } // namespace
// Callback used to enumerate imports. See EnumImportChunksFunction. // Callback used to enumerate imports. See EnumImportChunksFunction.
...@@ -494,8 +502,12 @@ bool PEImage::EnumDelayImportChunks(EnumDelayImportChunksFunction callback, ...@@ -494,8 +502,12 @@ bool PEImage::EnumDelayImportChunks(EnumDelayImportChunksFunction callback,
// current module is the module whose IAT we are enumerating. // current module is the module whose IAT we are enumerating.
// Use the module_name as retrieved from the IAT because this method // Use the module_name as retrieved from the IAT because this method
// is case sensitive. // is case sensitive.
if (module_ == CURRENT_MODULE()) if (module_ == CURRENT_MODULE() && !LDR_IS_RESOURCE(module_)) {
::__HrLoadAllImportsForDll(module_name); static base::NoDestructor<std::set<std::string>> loaded_dlls;
// pair.second is true if this is a new element
if (loaded_dlls.get()->emplace(module_name).second)
::__HrLoadAllImportsForDll(module_name);
}
} }
if (!callback(*this, delay_descriptor, module_name, name_table, iat, if (!callback(*this, delay_descriptor, module_name, name_table, iat,
......
...@@ -2221,6 +2221,7 @@ test("content_unittests") { ...@@ -2221,6 +2221,7 @@ test("content_unittests") {
"dwrite.lib", "dwrite.lib",
"wtsapi32.lib", "wtsapi32.lib",
] ]
configs += [ "//build/config/win:delayloads" ]
} }
if (is_mac) { if (is_mac) {
deps += [ deps += [
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment