OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // This file contains unit tests for ServiceResolverThunk. | 5 // This file contains unit tests for ServiceResolverThunk. |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/win/windows_version.h" | 9 #include "base/win/windows_version.h" |
10 #include "sandbox/win/src/resolver.h" | 10 #include "sandbox/win/src/resolver.h" |
(...skipping 26 matching lines...) Expand all Loading... |
37 const void* interceptor_entry_point, | 37 const void* interceptor_entry_point, |
38 void* thunk_storage, | 38 void* thunk_storage, |
39 size_t storage_bytes) { | 39 size_t storage_bytes) { |
40 NTSTATUS ret = STATUS_SUCCESS; | 40 NTSTATUS ret = STATUS_SUCCESS; |
41 ret = ResolverThunk::Init(target_module, interceptor_module, target_name, | 41 ret = ResolverThunk::Init(target_module, interceptor_module, target_name, |
42 interceptor_name, interceptor_entry_point, | 42 interceptor_name, interceptor_entry_point, |
43 thunk_storage, storage_bytes); | 43 thunk_storage, storage_bytes); |
44 EXPECT_EQ(STATUS_SUCCESS, ret); | 44 EXPECT_EQ(STATUS_SUCCESS, ret); |
45 | 45 |
46 target_ = fake_target_; | 46 target_ = fake_target_; |
47 ntdll_base_ = ::GetModuleHandle(L"ntdll.dll"); | 47 |
48 return ret; | 48 return ret; |
49 }; | 49 }; |
50 | 50 |
51 private: | 51 private: |
52 // Holds the address of the fake target. | 52 // Holds the address of the fake target. |
53 void* fake_target_; | 53 void* fake_target_; |
54 | 54 |
55 DISALLOW_COPY_AND_ASSIGN(ResolverThunkTest); | 55 DISALLOW_COPY_AND_ASSIGN(ResolverThunkTest); |
56 }; | 56 }; |
57 | 57 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 memcpy(service, target, sizeof(service)); | 101 memcpy(service, target, sizeof(service)); |
102 | 102 |
103 static_cast<WinXpResolverTest*>(resolver)->set_target(service); | 103 static_cast<WinXpResolverTest*>(resolver)->set_target(service); |
104 | 104 |
105 // Any pointer will do as an interception_entry_point | 105 // Any pointer will do as an interception_entry_point |
106 void* function_entry = resolver; | 106 void* function_entry = resolver; |
107 size_t thunk_size = resolver->GetThunkSize(); | 107 size_t thunk_size = resolver->GetThunkSize(); |
108 scoped_ptr<char[]> thunk(new char[thunk_size]); | 108 scoped_ptr<char[]> thunk(new char[thunk_size]); |
109 size_t used; | 109 size_t used; |
110 | 110 |
| 111 resolver->AllowLocalPatches(); |
| 112 |
111 NTSTATUS ret = resolver->Setup(ntdll_base, NULL, function, NULL, | 113 NTSTATUS ret = resolver->Setup(ntdll_base, NULL, function, NULL, |
112 function_entry, thunk.get(), thunk_size, | 114 function_entry, thunk.get(), thunk_size, |
113 &used); | 115 &used); |
114 if (NT_SUCCESS(ret)) { | 116 if (NT_SUCCESS(ret)) { |
115 EXPECT_EQ(thunk_size, used); | 117 EXPECT_EQ(thunk_size, used); |
116 EXPECT_NE(0, memcmp(service, target, sizeof(service))); | 118 EXPECT_NE(0, memcmp(service, target, sizeof(service))); |
117 EXPECT_NE(kJump32, service[0]); | 119 EXPECT_NE(kJump32, service[0]); |
118 | 120 |
119 if (relaxed) { | 121 if (relaxed) { |
120 // It's already patched, let's patch again, and simulate a direct patch. | 122 // It's already patched, let's patch again, and simulate a direct patch. |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 EXPECT_EQ(STATUS_SUCCESS, ret) << "NtCreateMutant, last error: " << | 219 EXPECT_EQ(STATUS_SUCCESS, ret) << "NtCreateMutant, last error: " << |
218 ::GetLastError(); | 220 ::GetLastError(); |
219 | 221 |
220 ret = PatchNtdllWithResolver("NtMapViewOfSection", true, resolver); | 222 ret = PatchNtdllWithResolver("NtMapViewOfSection", true, resolver); |
221 EXPECT_EQ(STATUS_SUCCESS, ret) << "NtMapViewOfSection, last error: " << | 223 EXPECT_EQ(STATUS_SUCCESS, ret) << "NtMapViewOfSection, last error: " << |
222 ::GetLastError(); | 224 ::GetLastError(); |
223 delete resolver; | 225 delete resolver; |
224 #endif | 226 #endif |
225 } | 227 } |
226 | 228 |
| 229 TEST(ServiceResolverTest, LocalPatchesAllowed) { |
| 230 sandbox::ServiceResolverThunk* resolver = GetTestResolver(true); |
| 231 |
| 232 HMODULE ntdll_base = ::GetModuleHandle(L"ntdll.dll"); |
| 233 ASSERT_TRUE(NULL != ntdll_base); |
| 234 |
| 235 const char kFunctionName[] = "NtClose"; |
| 236 |
| 237 void* target = ::GetProcAddress(ntdll_base, kFunctionName); |
| 238 ASSERT_TRUE(NULL != target); |
| 239 |
| 240 BYTE service[50]; |
| 241 memcpy(service, target, sizeof(service)); |
| 242 static_cast<WinXpResolverTest*>(resolver)->set_target(service); |
| 243 |
| 244 // Any pointer will do as an interception_entry_point |
| 245 void* function_entry = resolver; |
| 246 size_t thunk_size = resolver->GetThunkSize(); |
| 247 scoped_ptr<char[]> thunk(new char[thunk_size]); |
| 248 size_t used; |
| 249 |
| 250 NTSTATUS ret = STATUS_UNSUCCESSFUL; |
| 251 |
| 252 // First try patching without having allowed local patches. |
| 253 ret = resolver->Setup(ntdll_base, NULL, kFunctionName, NULL, |
| 254 function_entry, thunk.get(), thunk_size, |
| 255 &used); |
| 256 EXPECT_FALSE(NT_SUCCESS(ret)); |
| 257 |
| 258 // Now allow local patches and check that things work. |
| 259 resolver->AllowLocalPatches(); |
| 260 ret = resolver->Setup(ntdll_base, NULL, kFunctionName, NULL, |
| 261 function_entry, thunk.get(), thunk_size, |
| 262 &used); |
| 263 EXPECT_EQ(STATUS_SUCCESS, ret); |
| 264 } |
| 265 |
227 } // namespace | 266 } // namespace |
OLD | NEW |