OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
csharp
2014/07/29 14:28:15
This file should probably live a level higher and
krstnmnlsn
2014/07/29 17:30:25
Done.
| |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/safe_browsing/module_integrity_verifier.h" | |
6 | |
7 #include <windows.h> | |
8 #include <psapi.h> | |
9 | |
10 #include "base/files/file_path.h" | |
11 #include "base/files/memory_mapped_file.h" | |
12 #include "base/native_library.h" | |
13 #include "base/path_service.h" | |
14 #include "base/scoped_native_library.h" | |
15 #include "base/win/pe_image.h" | |
16 #include "testing/gtest/include/gtest/gtest.h" | |
17 | |
18 namespace safe_browsing { | |
19 | |
20 const wchar_t kTestDllName[] = L"verifier_test_dll.dll"; | |
21 | |
22 class SafeBrowsingModuleVerifierTest : public testing::Test { | |
23 protected: | |
24 SafeBrowsingModuleVerifierTest() {} | |
25 virtual ~SafeBrowsingModuleVerifierTest() {} | |
26 | |
27 base::ScopedNativeLibrary mem_dll_handle; | |
csharp
2014/07/29 14:28:15
All class data member names need to end with a tra
krstnmnlsn
2014/07/29 17:30:25
Right!
| |
28 base::MemoryMappedFile disk_dll_handle; | |
29 scoped_ptr<base::win::PEImageAsData> disk_peimage_ptr; | |
30 scoped_ptr<base::win::PEImage> mem_peimage_ptr; | |
31 | |
32 void SetUpTestDllAndPEImages() { | |
33 LoadModule(); | |
34 HMODULE mem_handle; | |
35 HMODULE disk_handle; | |
36 GetMemModuleHandle(&mem_handle); | |
37 GetDiskModuleHandle(&disk_handle); | |
38 | |
39 disk_peimage_ptr.reset(new base::win::PEImageAsData(disk_handle)); | |
40 mem_peimage_ptr.reset(new base::win::PEImage(mem_handle)); | |
41 ASSERT_TRUE(disk_peimage_ptr->VerifyMagic()); | |
csharp
2014/07/29 14:28:15
Move up a line to check right after creation
krstnmnlsn
2014/07/29 17:30:25
Done.
| |
42 ASSERT_TRUE(mem_peimage_ptr->VerifyMagic()); | |
43 } | |
44 | |
45 void LoadModule() { | |
46 base::FilePath current_dir; | |
47 ASSERT_TRUE(PathService::Get(base::DIR_EXE, ¤t_dir)); | |
48 mem_dll_handle.Reset( | |
49 LoadNativeLibrary(current_dir.Append(kTestDllName), NULL)); | |
50 ASSERT_TRUE(mem_dll_handle.is_valid()); | |
51 } | |
52 | |
53 void GetMemModuleHandle(HMODULE* mem_handle) { | |
54 *mem_handle = GetModuleHandle(kTestDllName); | |
55 ASSERT_TRUE(NULL != *mem_handle); | |
56 } | |
57 | |
58 void GetDiskModuleHandle(HMODULE* disk_handle) { | |
59 // Use the module handle to find the it on disk, then load as a file. | |
60 HMODULE module_handle = GetModuleHandle(kTestDllName); | |
61 ASSERT_TRUE(NULL != module_handle); | |
62 | |
63 WCHAR module_path[MAX_PATH] = {}; | |
64 DWORD length = | |
65 GetModuleFileName(module_handle, module_path, arraysize(module_path)); | |
66 ASSERT_NE(length, arraysize(module_path)); | |
67 | |
68 ASSERT_TRUE(disk_dll_handle.Initialize(base::FilePath(module_path))); | |
69 *disk_handle = reinterpret_cast<HMODULE>( | |
70 const_cast<uint8*>(disk_dll_handle.data())); | |
71 } | |
72 | |
73 private: | |
74 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingModuleVerifierTest); | |
75 }; | |
76 | |
77 TEST_F(SafeBrowsingModuleVerifierTest, CountBytesDiffInPtr) { | |
78 // Construct test pointer and try with CountBytesDiffInPtr. | |
csharp
2014/07/29 14:28:15
nit: pointer -> pointers
krstnmnlsn
2014/07/29 17:30:25
Done.
| |
79 // The first Bytes differ. | |
80 intptr_t num_a = 0xFF; | |
81 intptr_t num_b = 0x00; | |
82 | |
83 // Any inbetween Bytes are identical. | |
84 int num_bytes_to_add = sizeof(num_a) - 2; | |
85 for (int i = 0; i < num_bytes_to_add; ++i) { | |
86 num_a <<= 8; | |
87 num_b <<= 8; | |
88 num_a += 0xFF; | |
89 num_b += 0xFF; | |
90 } | |
91 | |
92 // The last Bytes differ. | |
93 num_a <<= 8; | |
94 num_b <<= 8; | |
95 num_a += 0x0F; | |
96 num_b += 0xFF; | |
97 | |
98 EXPECT_EQ(2, CountBytesDiffInPtr(num_a, num_b)); | |
csharp
2014/07/29 14:28:15
also check "EXPECT_EQ(2, CountBytesDiffInPtr(num_b
krstnmnlsn
2014/07/29 17:30:25
Good idea.
| |
99 EXPECT_EQ(0, CountBytesDiffInPtr(num_a, num_a)); | |
100 } | |
101 | |
102 TEST_F(SafeBrowsingModuleVerifierTest, VerifyModuleUnmodified) { | |
103 // Call VerifyModule before the module has been loaded, should fail. | |
104 EXPECT_EQ(MODULE_STATE_UNKNOWN, VerifyModule(kTestDllName)); | |
105 | |
106 // On loading, the module should be identical (up to relocations) in memory as | |
107 // on disk. | |
108 SetUpTestDllAndPEImages(); | |
109 EXPECT_EQ(MODULE_STATE_UNMODIFIED, VerifyModule(kTestDllName)); | |
110 } | |
111 | |
112 TEST_F(SafeBrowsingModuleVerifierTest, VerifyModuleModified) { | |
113 // Confirm the module is identical in memory as on disk before we begin. | |
114 SetUpTestDllAndPEImages(); | |
115 EXPECT_EQ(MODULE_STATE_UNMODIFIED, VerifyModule(kTestDllName)); | |
116 | |
117 BYTE* mem_code_addr = NULL; | |
118 BYTE* disk_code_addr = NULL; | |
119 SIZE_T code_size = 0; | |
120 EXPECT_TRUE(GetCodeAddrsAndSize(*mem_peimage_ptr, | |
121 *disk_peimage_ptr, | |
122 &mem_code_addr, | |
123 &disk_code_addr, | |
124 &code_size)); | |
125 | |
126 // Edit the first byte of the code section of the module. | |
127 BYTE new_val = (*mem_code_addr) + 1; | |
128 SIZE_T bytes_written = 0; | |
129 WriteProcessMemory(GetCurrentProcess(), | |
130 mem_code_addr, | |
131 reinterpret_cast<void*>(&new_val), | |
132 1, | |
133 &bytes_written); | |
134 EXPECT_EQ(1, bytes_written); | |
135 | |
136 // VerifyModule should detect the change. | |
137 EXPECT_EQ(MODULE_STATE_MODIFIED, VerifyModule(kTestDllName)); | |
138 } | |
139 | |
140 } // namespace safe_browsing | |
OLD | NEW |