From 37f2029c42d56e0d7a868eda1e2f2c62897fb9b0 Mon Sep 17 00:00:00 2001 From: "caitkp@chromium.org" Date: Tue, 18 Mar 2014 21:01:10 +0000 Subject: Make chrome_elf use thunks instead of function pointers. 1. Add functionality to ServiceResolverThunk to copy a thunk without patching. 2. Move chrome_elf thunk-handling code to a common location. 3. Use a thunk instead of a f'n ptr for redirects. BUG=334379 Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=255151 Review URL: https://codereview.chromium.org/183833004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@257749 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome_elf/blacklist/blacklist.cc | 136 +++----------------------------------- 1 file changed, 8 insertions(+), 128 deletions(-) (limited to 'chrome_elf/blacklist/blacklist.cc') diff --git a/chrome_elf/blacklist/blacklist.cc b/chrome_elf/blacklist/blacklist.cc index 23a06b4..19c7641 100644 --- a/chrome_elf/blacklist/blacklist.cc +++ b/chrome_elf/blacklist/blacklist.cc @@ -11,9 +11,9 @@ #include "chrome_elf/blacklist/blacklist_interceptions.h" #include "chrome_elf/chrome_elf_constants.h" #include "chrome_elf/chrome_elf_util.h" +#include "chrome_elf/thunk_getter.h" #include "sandbox/win/src/interception_internal.h" #include "sandbox/win/src/internal_types.h" -#include "sandbox/win/src/sandbox_utils.h" #include "sandbox/win/src/service_resolver.h" // http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx @@ -42,109 +42,10 @@ __declspec(allocate(".crthunk")) sandbox::ThunkData g_thunk_storage; namespace { -enum Version { - VERSION_PRE_XP_SP2 = 0, // Not supported. - VERSION_XP_SP2, - VERSION_SERVER_2003, // Also includes XP Pro x64 and Server 2003 R2. - VERSION_VISTA, // Also includes Windows Server 2008. - VERSION_WIN7, // Also includes Windows Server 2008 R2. - VERSION_WIN8, // Also includes Windows Server 2012. - VERSION_WIN8_1, - VERSION_WIN_LAST, // Indicates error condition. -}; - -// Whether a process is running under WOW64 (the wrapper that allows 32-bit -// processes to run on 64-bit versions of Windows). This will return -// WOW64_DISABLED for both "32-bit Chrome on 32-bit Windows" and "64-bit -// Chrome on 64-bit Windows". WOW64_UNKNOWN means "an error occurred", e.g. -// the process does not have sufficient access rights to determine this. -enum WOW64Status { - WOW64_DISABLED, - WOW64_ENABLED, - WOW64_UNKNOWN, -}; - // Record if the blacklist was successfully initialized so processes can easily // determine if the blacklist is enabled for them. bool g_blacklist_initialized = false; -WOW64Status GetWOW64StatusForCurrentProcess() { - typedef BOOL (WINAPI* IsWow64ProcessFunc)(HANDLE, PBOOL); - IsWow64ProcessFunc is_wow64_process = reinterpret_cast( - GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process")); - if (!is_wow64_process) - return WOW64_DISABLED; - BOOL is_wow64 = FALSE; - if (!(*is_wow64_process)(GetCurrentProcess(), &is_wow64)) - return WOW64_UNKNOWN; - return is_wow64 ? WOW64_ENABLED : WOW64_DISABLED; -} - -class OSInfo { - public: - struct VersionNumber { - int major; - int minor; - int build; - }; - - struct ServicePack { - int major; - int minor; - }; - - OSInfo() { - OSVERSIONINFOEX version_info = { sizeof(version_info) }; - GetVersionEx(reinterpret_cast(&version_info)); - version_number_.major = version_info.dwMajorVersion; - version_number_.minor = version_info.dwMinorVersion; - version_number_.build = version_info.dwBuildNumber; - if ((version_number_.major == 5) && (version_number_.minor > 0)) { - // Treat XP Pro x64, Home Server, and Server 2003 R2 as Server 2003. - version_ = (version_number_.minor == 1) ? VERSION_XP_SP2 : - VERSION_SERVER_2003; - if (version_ == VERSION_XP_SP2 && version_info.wServicePackMajor < 2) - version_ = VERSION_PRE_XP_SP2; - } else if (version_number_.major == 6) { - switch (version_number_.minor) { - case 0: - // Treat Windows Server 2008 the same as Windows Vista. - version_ = VERSION_VISTA; - break; - case 1: - // Treat Windows Server 2008 R2 the same as Windows 7. - version_ = VERSION_WIN7; - break; - case 2: - // Treat Windows Server 2012 the same as Windows 8. - version_ = VERSION_WIN8; - break; - default: - version_ = VERSION_WIN8_1; - break; - } - } else if (version_number_.major > 6) { - version_ = VERSION_WIN_LAST; - } else { - version_ = VERSION_PRE_XP_SP2; - } - - service_pack_.major = version_info.wServicePackMajor; - service_pack_.minor = version_info.wServicePackMinor; - } - - Version version() const { return version_; } - VersionNumber version_number() const { return version_number_; } - ServicePack service_pack() const { return service_pack_; } - - private: - Version version_; - VersionNumber version_number_; - ServicePack service_pack_; - - DISALLOW_COPY_AND_ASSIGN(OSInfo); -}; - // Record that the thunk setup completed succesfully and close the registry // key handle since it is no longer needed. void RecordSuccessfulThunkSetup(HKEY* key) { @@ -343,17 +244,16 @@ bool Initialize(bool force) { if (!force && !LeaveSetupBeacon()) return false; - // Don't try blacklisting on unsupported OS versions. - OSInfo os_info; - if (os_info.version() <= VERSION_PRE_XP_SP2) - return false; - - // Pseudo-handle, no need to close. - HANDLE current_process = ::GetCurrentProcess(); - // Tells the resolver to patch already patched functions. const bool kRelaxed = true; + // Create a thunk via the appropriate ServiceResolver instance. + sandbox::ServiceResolverThunk* thunk = GetThunk(kRelaxed); + + // Don't try blacklisting on unsupported OS versions. + if (!thunk) + return false; + // Record that we are starting the thunk setup code. HKEY key = NULL; DWORD disposition = 0; @@ -378,26 +278,6 @@ bool Initialize(bool force) { key = NULL; } - // Create a thunk via the appropriate ServiceResolver instance. - sandbox::ServiceResolverThunk* thunk = NULL; -#if defined(_WIN64) - // Because Windows 8 and 8.1 have different stubs in 64-bit, - // ServiceResolverThunk can handle all the formats in 64-bit (instead only - // handling 1 like it does in 32-bit versions). - thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed); -#else - if (GetWOW64StatusForCurrentProcess() == WOW64_ENABLED) { - if (os_info.version() >= VERSION_WIN8) - thunk = new sandbox::Wow64W8ResolverThunk(current_process, kRelaxed); - else - thunk = new sandbox::Wow64ResolverThunk(current_process, kRelaxed); - } else if (os_info.version() >= VERSION_WIN8) { - thunk = new sandbox::Win8ResolverThunk(current_process, kRelaxed); - } else { - thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed); - } -#endif - // Record that we have initialized the blacklist. g_blacklist_initialized = true; -- cgit v1.1