Index: syzygy/instrument/transforms/security_cookie_check_hook_transform_unittest.cc |
diff --git a/syzygy/instrument/transforms/security_cookie_check_hook_transform_unittest.cc b/syzygy/instrument/transforms/security_cookie_check_hook_transform_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ec71385ae91302c731cf590d93aa86b9a004e2a5 |
--- /dev/null |
+++ b/syzygy/instrument/transforms/security_cookie_check_hook_transform_unittest.cc |
@@ -0,0 +1,113 @@ |
+// Copyright 2017 Google Inc. All Rights Reserved. |
+// |
+// Licensed under the Apache License, Version 2.0 (the "License"); |
+// you may not use this file except in compliance with the License. |
+// You may obtain a copy of the License at |
+// |
+// http://www.apache.org/licenses/LICENSE-2.0 |
+// |
+// Unless required by applicable law or agreed to in writing, software |
+// distributed under the License is distributed on an "AS IS" BASIS, |
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+// See the License for the specific language governing permissions and |
+// limitations under the License. |
+// |
+ |
+#include "syzygy/instrument/transforms/security_cookie_check_hook_transform.h" |
+ |
+#include "gtest/gtest.h" |
+#include "syzygy/block_graph/basic_block.h" |
+#include "syzygy/block_graph/basic_block_decomposer.h" |
+#include "syzygy/block_graph/basic_block_subgraph.h" |
+#include "syzygy/block_graph/block_graph.h" |
+#include "syzygy/core/unittest_util.h" |
+#include "syzygy/instrument/transforms/unittest_util.h" |
+#include "syzygy/pe/unittest_util.h" |
+ |
+#include "mnemonics.h" // NOLINT |
+ |
+namespace instrument { |
+namespace transforms { |
+namespace { |
+ |
+using block_graph::BasicBlock; |
+using block_graph::BasicBlockDecomposer; |
+using block_graph::BasicBlockSubGraph; |
+using block_graph::BasicCodeBlock; |
+using block_graph::BlockGraph; |
+using block_graph::Instruction; |
+ |
+class SecurityCookieCheckHookTransformTest |
+ : public testing::TestDllTransformTest { |
+ protected: |
+ void CheckBasicBlockInstrumentation(); |
+ |
+ SecurityCookieCheckHookTransform security_cookie_check_hook_; |
+}; |
+ |
+void SecurityCookieCheckHookTransformTest::CheckBasicBlockInstrumentation() { |
+ bool hit = false; |
+ |
+ BlockGraph::BlockMap::const_iterator block_iter = |
+ block_graph_.blocks().begin(); |
+ for (; block_iter != block_graph_.blocks().end(); ++block_iter) { |
+ const BlockGraph::Block& block = block_iter->second; |
+ |
+ // Skip everything but __syzygy_report_gsfailure. |
+ if (block.name() != |
+ SecurityCookieCheckHookTransform::kSyzygyReportGsFailure) |
+ continue; |
+ |
+ hit = true; |
+ |
+ // Decompose the block to basic-blocks. |
+ BasicBlockSubGraph subgraph; |
+ BasicBlockDecomposer bb_decomposer(&block, &subgraph); |
+ ASSERT_TRUE(bb_decomposer.Decompose()); |
+ |
+ // Retrieve the first basic block. |
+ ASSERT_EQ(1, subgraph.block_descriptions().size()); |
+ const BasicBlockSubGraph::BasicBlockOrdering& original_order = |
+ subgraph.block_descriptions().front().basic_block_order; |
+ BasicCodeBlock* first_bb = BasicCodeBlock::Cast(*original_order.begin()); |
+ ASSERT_NE(first_bb, nullptr); |
+ |
+ // Check if the stub is a 'mov [deadbeef], eax' instruction. |
+ BasicBlockSubGraph::BBCollection::const_iterator bb_iter = |
+ subgraph.basic_blocks().begin(); |
+ for (; bb_iter != subgraph.basic_blocks().end(); ++bb_iter) { |
+ const BasicCodeBlock* bb = BasicCodeBlock::Cast(*bb_iter); |
+ if (bb == nullptr || bb->is_padding()) |
+ continue; |
+ |
+ BasicBlock::Instructions::const_iterator inst_iter = |
+ bb->instructions().begin(), |
+ end_iter = |
+ bb->instructions().end(); |
+ ASSERT_NE(inst_iter, end_iter); |
+ // mov [deadbeef], eax |
+ const Instruction& inst = *inst_iter; |
+ const _DInst& representation = inst.representation(); |
+ EXPECT_EQ(I_MOV, representation.opcode); |
+ EXPECT_EQ(representation.ops[0].type, O_DISP); |
+ EXPECT_EQ(representation.disp, |
+ SecurityCookieCheckHookTransform::kInvalidUserAddress); |
+ } |
+ } |
+ |
+ EXPECT_TRUE(hit); |
+} |
+ |
+} // namespace |
+ |
+TEST_F(SecurityCookieCheckHookTransformTest, ApplyTranform) { |
+ ASSERT_NO_FATAL_FAILURE(DecomposeTestDll()); |
+ |
+ ASSERT_TRUE(block_graph::ApplyBlockGraphTransform( |
+ &security_cookie_check_hook_, policy_, &block_graph_, header_block_)); |
+ |
+ ASSERT_NO_FATAL_FAILURE(CheckBasicBlockInstrumentation()); |
+} |
+ |
+} // namespace transforms |
+} // namespace instrument |