Index: chrome_elf/blacklist/test/blacklist_test.cc |
diff --git a/chrome_elf/blacklist/test/blacklist_test.cc b/chrome_elf/blacklist/test/blacklist_test.cc |
index 7eb18f2ab2872f4c5a42b47f5b621f8af5413a1f..a0c55f2f5bba3862c3830a0b5649a48271474b1d 100644 |
--- a/chrome_elf/blacklist/test/blacklist_test.cc |
+++ b/chrome_elf/blacklist/test/blacklist_test.cc |
@@ -7,6 +7,7 @@ |
#include <memory> |
#include "base/environment.h" |
+#include "base/files/file.h" |
#include "base/files/file_path.h" |
#include "base/files/scoped_temp_dir.h" |
#include "base/i18n/case_conversion.h" |
@@ -20,8 +21,8 @@ |
#include "base/win/registry.h" |
#include "chrome/common/chrome_version.h" |
#include "chrome_elf/blacklist/blacklist.h" |
-#include "chrome_elf/blacklist/test/blacklist_test_main_dll.h" |
#include "chrome_elf/chrome_elf_constants.h" |
+#include "chrome_elf/nt_registry/nt_registry.h" |
#include "testing/gtest/include/gtest/gtest.h" |
const wchar_t kTestDllName1[] = L"blacklist_test_dll_1.dll"; |
@@ -33,24 +34,31 @@ const wchar_t kDll3Beacon[] = L"{9E056AEC-169E-400c-B2D0-5A07E3ACE2EB}"; |
extern const wchar_t* kEnvVars[]; |
-extern "C" { |
-// When modifying the blacklist in the test process, use the exported test dll |
-// functions on the test blacklist dll, not the ones linked into the test |
-// executable itself. |
-__declspec(dllimport) void TestDll_AddDllsFromRegistryToBlacklist(); |
-__declspec(dllimport) bool TestDll_AddDllToBlacklist(const wchar_t* dll_name); |
-__declspec(dllimport) int TestDll_BlacklistSize(); |
-__declspec(dllimport) void TestDll_BlockedDll(size_t blocked_index); |
-__declspec(dllimport) int TestDll_GetBlacklistIndex(const wchar_t* dll_name); |
-__declspec(dllimport) bool TestDll_IsBlacklistInitialized(); |
-__declspec(dllimport) bool TestDll_RemoveDllFromBlacklist( |
- const wchar_t* dll_name); |
-__declspec(dllimport) bool TestDll_SuccessfullyBlocked( |
+namespace { |
+ |
+// Functions we need from blacklist_test_main_dll.dll |
+typedef void (*TestDll_AddDllsFromRegistryToBlacklistFunction)(); |
+typedef bool (*TestDll_AddDllToBlacklistFunction)(const wchar_t* dll_name); |
+typedef int (*TestDll_BlacklistSizeFunction)(); |
+typedef void (*TestDll_BlockedDllFunction)(size_t blocked_index); |
+typedef int (*TestDll_GetBlacklistIndexFunction)(const wchar_t* dll_name); |
+typedef bool (*TestDll_IsBlacklistInitializedFunction)(); |
+typedef bool (*TestDll_RemoveDllFromBlacklistFunction)(const wchar_t* dll_name); |
+typedef bool (*TestDll_SuccessfullyBlockedFunction)( |
const wchar_t** blocked_dlls, |
int* size); |
-} |
- |
-namespace { |
+typedef void (*InitTestDllFunction)(); |
+ |
+TestDll_AddDllsFromRegistryToBlacklistFunction |
+ TestDll_AddDllsFromRegistryToBlacklist = nullptr; |
+TestDll_AddDllToBlacklistFunction TestDll_AddDllToBlacklist = nullptr; |
+TestDll_BlacklistSizeFunction TestDll_BlacklistSize = nullptr; |
+TestDll_BlockedDllFunction TestDll_BlockedDll = nullptr; |
+TestDll_GetBlacklistIndexFunction TestDll_GetBlacklistIndex = nullptr; |
+TestDll_IsBlacklistInitializedFunction TestDll_IsBlacklistInitialized = nullptr; |
+TestDll_RemoveDllFromBlacklistFunction TestDll_RemoveDllFromBlacklist = nullptr; |
+TestDll_SuccessfullyBlockedFunction TestDll_SuccessfullyBlocked = nullptr; |
+InitTestDllFunction InitTestDll = nullptr; |
struct TestData { |
const wchar_t* dll_name; |
@@ -63,7 +71,6 @@ struct TestData { |
class BlacklistTest : public testing::Test { |
protected: |
BlacklistTest() : override_manager_(), num_initially_blocked_(0) { |
- override_manager_.OverrideRegistry(HKEY_CURRENT_USER); |
} |
void CheckBlacklistedDllsNotLoaded() { |
@@ -125,9 +132,71 @@ class BlacklistTest : public testing::Test { |
int num_initially_blocked_; |
private: |
+ // This function puts registry-key redirection paths into |
+ // process-specific environment variables, for our test DLLs to access. |
+ // This will only work as long as the IPC is within the same process. |
+ void IpcOverrides() { |
+ if (::wcslen(nt::HKCU_override) != 0) { |
+ ASSERT_TRUE( |
+ ::SetEnvironmentVariableW(L"hkcu_override", nt::HKCU_override)); |
+ } |
+ if (::wcslen(nt::HKLM_override) != 0) { |
+ ASSERT_TRUE( |
+ ::SetEnvironmentVariableW(L"hklm_override", nt::HKLM_override)); |
+ } |
+ } |
+ |
void SetUp() override { |
- // Force an import from blacklist_test_main_dll. |
- InitBlacklistTestDll(); |
+ base::string16 temp; |
+ override_manager_.OverrideRegistry(HKEY_CURRENT_USER, &temp); |
+ ::wcsncpy(nt::HKCU_override, temp.c_str(), nt::g_kRegMaxPathLen - 1); |
+ |
+ // Make the override path available to our test DLL. |
+ IpcOverrides(); |
+ |
+ // Load the main test Dll now. |
+ // Note: this has to happen after we set up the registry overrides. |
+ HMODULE dll = nullptr; |
+ dll = ::LoadLibraryW(L"blacklist_test_main_dll.dll"); |
+ if (!dll) |
+ return; |
+ TestDll_AddDllsFromRegistryToBlacklist = |
+ reinterpret_cast<TestDll_AddDllsFromRegistryToBlacklistFunction>( |
+ ::GetProcAddress(dll, "TestDll_AddDllsFromRegistryToBlacklist")); |
+ TestDll_AddDllToBlacklist = |
+ reinterpret_cast<TestDll_AddDllToBlacklistFunction>( |
+ ::GetProcAddress(dll, "TestDll_AddDllToBlacklist")); |
+ TestDll_BlacklistSize = reinterpret_cast<TestDll_BlacklistSizeFunction>( |
+ ::GetProcAddress(dll, "TestDll_BlacklistSize")); |
+ TestDll_BlockedDll = reinterpret_cast<TestDll_BlockedDllFunction>( |
+ ::GetProcAddress(dll, "TestDll_BlockedDll")); |
+ TestDll_GetBlacklistIndex = |
+ reinterpret_cast<TestDll_GetBlacklistIndexFunction>( |
+ ::GetProcAddress(dll, "TestDll_GetBlacklistIndex")); |
+ TestDll_IsBlacklistInitialized = |
+ reinterpret_cast<TestDll_IsBlacklistInitializedFunction>( |
+ ::GetProcAddress(dll, "TestDll_IsBlacklistInitialized")); |
+ TestDll_RemoveDllFromBlacklist = |
+ reinterpret_cast<TestDll_RemoveDllFromBlacklistFunction>( |
+ ::GetProcAddress(dll, "TestDll_RemoveDllFromBlacklist")); |
+ TestDll_SuccessfullyBlocked = |
+ reinterpret_cast<TestDll_SuccessfullyBlockedFunction>( |
+ ::GetProcAddress(dll, "TestDll_SuccessfullyBlocked")); |
+ InitTestDll = reinterpret_cast<InitTestDllFunction>( |
+ ::GetProcAddress(dll, "InitTestDll")); |
+ if (!TestDll_AddDllsFromRegistryToBlacklist || !TestDll_AddDllToBlacklist || |
+ !TestDll_BlacklistSize || !TestDll_BlockedDll || |
+ !TestDll_GetBlacklistIndex || !TestDll_IsBlacklistInitialized || |
+ !TestDll_RemoveDllFromBlacklist || !TestDll_SuccessfullyBlocked || |
+ !InitTestDll) |
+ return; |
+ |
+ // We have to call this exported function every time this test setup runs. |
+ // If the tests are running in single process mode, the test DLL does not |
+ // get reloaded everytime - but we need to make sure it updates |
+ // appropriately. |
+ InitTestDll(); |
+ |
blacklist_registry_key_.reset( |
new base::win::RegKey(HKEY_CURRENT_USER, |
blacklist::kRegistryBeaconPath, |
@@ -142,6 +211,9 @@ class BlacklistTest : public testing::Test { |
TestDll_RemoveDllFromBlacklist(kTestDllName2); |
TestDll_RemoveDllFromBlacklist(kTestDllName3); |
} |
+ |
+ // A scoped temporary directory to be destroyed with this test. |
+ base::ScopedTempDir reg_override_dir_; |
}; |
TEST_F(BlacklistTest, Beacon) { |
@@ -254,15 +326,27 @@ TEST_F(BlacklistTest, AddDllsFromRegistryToBlacklist) { |
KEY_QUERY_VALUE | KEY_SET_VALUE); |
key.DeleteKey(L""); |
- // Add the test dlls to the registry (with their name as both key and value). |
+ // Add the test dlls to the registry. |
+ // (REG_MULTI_SZ: eos separated, double null terminated.) |
base::win::RegKey finch_blacklist_registry_key( |
HKEY_CURRENT_USER, |
blacklist::kRegistryFinchListPath, |
KEY_QUERY_VALUE | KEY_SET_VALUE); |
+ |
+ std::vector<wchar_t>(reg_buffer); |
for (size_t i = 0; i < arraysize(test_data); ++i) { |
- finch_blacklist_registry_key.WriteValue(test_data[i].dll_name, |
- test_data[i].dll_name); |
+ if (reg_buffer.size() > 0) |
+ reg_buffer.push_back(L'\0'); |
+ const wchar_t* dll = test_data[i].dll_name; |
+ // Append the name, not including terminator. |
+ reg_buffer.insert(reg_buffer.end(), dll, dll + ::wcslen(dll)); |
} |
+ reg_buffer.push_back(L'\0'); |
+ reg_buffer.push_back(L'\0'); |
+ |
+ finch_blacklist_registry_key.WriteValue( |
+ blacklist::kRegistryFinchListValueName, reg_buffer.data(), |
+ (DWORD)(reg_buffer.size() * sizeof(wchar_t)), REG_MULTI_SZ); |
TestDll_AddDllsFromRegistryToBlacklist(); |
CheckBlacklistedDllsNotLoaded(); |