Coverage for /Syzygy/agent/asan/hot_patching_asan_runtime_unittest.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
95.6%43450.C++test

Line-by-line coverage:

   1    :  // Copyright 2015 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  
  15    :  #include "syzygy/agent/asan/hot_patching_asan_runtime.h"
  16    :  
  17    :  #include "gtest/gtest.h"
  18    :  
  19    :  #include "syzygy/agent/asan/unittest_util.h"
  20    :  #include "syzygy/instrument/transforms/asan_transform.h"
  21    :  #include "syzygy/pe/pe_relinker.h"
  22    :  #include "syzygy/pe/unittest_util.h"
  23    :  
  24    :  namespace agent {
  25    :  namespace asan {
  26    :  
  27    :  // This helper class creates a hot patching Asan instrumented test_dll.dll.
  28    :  class HotPatchingAsanRelinkHelper : public testing::PELibUnitTest {
  29    :   public:
  30    :    HotPatchingAsanRelinkHelper()
  31    :        : relinker_(&policy_),
  32  E :          test_dll_path_(testing::GetExeRelativePath(testing::kTestDllName)) {
  33  E :      transform_.set_hot_patching(true);
  34  E :    }
  35    :  
  36  E :    void SetUp() override {
  37  E :      this->CreateTemporaryDir(&temp_dir_);
  38  E :      hp_test_dll_path_ = temp_dir_.Append(testing::kTestDllName);
  39  E :    }
  40    :  
  41    :    // This is a workaround so that we can use this class in the unittest
  42    :    // fixture below that inherits from a different base class.
  43  i :    void TestBody() override {
  44  i :    }
  45    :  
  46    :    // Relinks test_dll.dll using hot patching Asan transform.
  47  E :    void InstrumentAndLoadTestDll() {
  48    :      // Set up relinker.
  49  E :      relinker_.set_input_path(test_dll_path_);
  50  E :      relinker_.set_output_path(hp_test_dll_path_);
  51  E :      relinker_.set_allow_overwrite(true);
  52  E :      ASSERT_TRUE(relinker_.Init());
  53    :  
  54  E :      relinker_.AppendTransform(&transform_);
  55    :  
  56    :      // Perform the actual relink.
  57  E :      ASSERT_TRUE(relinker_.Relink());
  58    :  
  59    :      // Validate that the binary still loads.
  60  E :      ASSERT_NO_FATAL_FAILURE(CheckTestDll(hp_test_dll_path_));
  61  E :    }
  62    :  
  63    :    // The module handle of the loaded hot patching Asan transformed
  64    :    // test_dll.dll.
  65    :    testing::ScopedHMODULE module_;
  66    :  
  67    :    pe::PETransformPolicy policy_;
  68    :    pe::PERelinker relinker_;
  69    :  
  70    :    // Path of the original test_dll.dll.
  71    :    base::FilePath test_dll_path_;
  72    :    // Path of the temporary directory where the hot patchable DLL will be saved.
  73    :    base::FilePath temp_dir_;
  74    :    // Path of the hot patchable test_dll.dll.
  75    :    base::FilePath hp_test_dll_path_;
  76    :  
  77    :    // The transform used to make test_dll.dll hot patchable.
  78    :    instrument::transforms::AsanTransform transform_;
  79    :  };
  80    :  
  81    :  // Function pointer type for hp_asan_GetActiveHotPatchingRuntime.
  82    :  typedef agent::asan::HotPatchingAsanRuntime*
  83    :      (__stdcall* GetActiveHotPatchingRuntimeFunctionPtr)();
  84    :  
  85    :  class HotPatchingAsanRuntimeTest : public testing::TestWithAsanLogger {
  86    :   public:
  87    :    HotPatchingAsanRuntimeTest() : asan_hp_rtl_(nullptr),
  88  E :                                   runtime_(nullptr) {
  89  E :    }
  90    :  
  91  E :    void SetUp() override {
  92  E :      testing::TestWithAsanLogger::SetUp();
  93    :  
  94    :      // Load the Asan runtime library.
  95    :      base::FilePath asan_hp_rtl_path =
  96  E :          testing::GetExeRelativePath(L"syzyasan_hp.dll");
  97  E :      asan_hp_rtl_ = ::LoadLibrary(asan_hp_rtl_path.value().c_str());
  98  E :      ASSERT_NE(nullptr, asan_hp_rtl_);
  99    :  
 100    :      // Load the function that exposes the hot patching Asan runtime.
 101    :      GetActiveHotPatchingRuntimeFunctionPtr runtime_getter =
 102    :          reinterpret_cast<GetActiveHotPatchingRuntimeFunctionPtr>(
 103    :              ::GetProcAddress(asan_hp_rtl_,
 104  E :                               "hp_asan_GetActiveHotPatchingAsanRuntime"));
 105  E :      ASSERT_NE(nullptr, runtime_getter);
 106    :  
 107    :      // Get the hot patching Asan runtime.
 108  E :      runtime_ = runtime_getter();
 109  E :      ASSERT_NE(static_cast<agent::asan::HotPatchingAsanRuntime*>(nullptr),
 110    :                runtime_);
 111  E :    }
 112    :  
 113  E :    void TearDown() override {
 114  E :      if (asan_hp_rtl_ != nullptr) {
 115  E :        ::FreeLibrary(asan_hp_rtl_);
 116  E :        asan_hp_rtl_ = nullptr;
 117    :      }
 118    :  
 119  E :      testing::TestWithAsanLogger::TearDown();
 120  E :    }
 121    :  
 122    :   protected:
 123    :    // The hot patching Asan runtime module to test.
 124    :    HMODULE asan_hp_rtl_;
 125    :  
 126    :    // The hot patching Asan runtime.
 127    :    agent::asan::HotPatchingAsanRuntime* runtime_;
 128    :  };
 129    :  
 130  E :  TEST_F(HotPatchingAsanRuntimeTest, TestRuntime) {
 131  E :    HotPatchingAsanRelinkHelper relink_helper;
 132  E :    relink_helper.SetUp();
 133  E :    relink_helper.InstrumentAndLoadTestDll();
 134    :  
 135    :    // Load hot patched library into memory. This should construct a runtime
 136    :    // that we can query.
 137    :    relink_helper.LoadTestDll(relink_helper.hp_test_dll_path_,
 138  E :                              &relink_helper.module_);
 139    :  
 140    :    // The hot patching Asan runtime must have been activated by loading the
 141    :    // instrumented dll.
 142  E :    ASSERT_EQ(1U, runtime_->hot_patched_modules().count(relink_helper.module_));
 143    :  
 144    :    // The module is already hot patched, this is essentially a no-op.
 145  E :    ASSERT_TRUE(runtime_->HotPatch(relink_helper.module_));
 146    :  
 147    :    // The test module should remain in set of hot patched modules.
 148  E :    ASSERT_EQ(1U, runtime_->hot_patched_modules().count(relink_helper.module_));
 149  E :  }
 150    :  
 151    :  }  // namespace asan
 152    :  }  // namespace agent

Coverage information generated Thu Jan 14 17:40:38 2016.