summaryrefslogtreecommitdiffstats
path: root/sandbox
diff options
context:
space:
mode:
authorcaitkp@chromium.org <caitkp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-18 21:01:10 +0000
committercaitkp@chromium.org <caitkp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-18 21:01:10 +0000
commit37f2029c42d56e0d7a868eda1e2f2c62897fb9b0 (patch)
tree32e03a7d0b05b0e1a3e0ef9c7644f1746e0b5ef9 /sandbox
parenta34f61ee4f3ebc44edc4d144f892841c1e99619a (diff)
downloadchromium_src-37f2029c42d56e0d7a868eda1e2f2c62897fb9b0.zip
chromium_src-37f2029c42d56e0d7a868eda1e2f2c62897fb9b0.tar.gz
chromium_src-37f2029c42d56e0d7a868eda1e2f2c62897fb9b0.tar.bz2
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
Diffstat (limited to 'sandbox')
-rw-r--r--sandbox/win/src/service_resolver.h9
-rw-r--r--sandbox/win/src/service_resolver_32.cc26
-rw-r--r--sandbox/win/src/service_resolver_64.cc24
3 files changed, 59 insertions, 0 deletions
diff --git a/sandbox/win/src/service_resolver.h b/sandbox/win/src/service_resolver.h
index 0089692..20486c9 100644
--- a/sandbox/win/src/service_resolver.h
+++ b/sandbox/win/src/service_resolver.h
@@ -46,6 +46,15 @@ class ServiceResolverThunk : public ResolverThunk {
// Call this to set up ntdll_base_ which will allow for local patches.
virtual void AllowLocalPatches();
+ // Verifies that the function specified by |target_name| in |target_module| is
+ // a service and copies the data from that function into |thunk_storage|. If
+ // |storage_bytes| is too small, then the method fails.
+ virtual NTSTATUS CopyThunk(const void* target_module,
+ const char* target_name,
+ BYTE* thunk_storage,
+ size_t storage_bytes,
+ size_t* storage_used);
+
protected:
// The unit test will use this member to allow local patch on a buffer.
HMODULE ntdll_base_;
diff --git a/sandbox/win/src/service_resolver_32.cc b/sandbox/win/src/service_resolver_32.cc
index 2e69dbc..9b8bbf9 100644
--- a/sandbox/win/src/service_resolver_32.cc
+++ b/sandbox/win/src/service_resolver_32.cc
@@ -179,6 +179,32 @@ size_t ServiceResolverThunk::GetThunkSize() const {
return offsetof(ServiceFullThunk, internal_thunk) + GetInternalThunkSize();
}
+NTSTATUS ServiceResolverThunk::CopyThunk(const void* target_module,
+ const char* target_name,
+ BYTE* thunk_storage,
+ size_t storage_bytes,
+ size_t* storage_used) {
+ NTSTATUS ret = ResolveTarget(target_module, target_name, &target_);
+ if (!NT_SUCCESS(ret))
+ return ret;
+
+ size_t thunk_bytes = GetThunkSize();
+ if (storage_bytes < thunk_bytes)
+ return STATUS_UNSUCCESSFUL;
+
+ ServiceFullThunk* thunk = reinterpret_cast<ServiceFullThunk*>(thunk_storage);
+
+ if (!IsFunctionAService(&thunk->original) &&
+ (!relaxed_ || !SaveOriginalFunction(&thunk->original, thunk_storage))) {
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ if (NULL != storage_used)
+ *storage_used = thunk_bytes;
+
+ return ret;
+}
+
bool ServiceResolverThunk::IsFunctionAService(void* local_thunk) const {
ServiceEntry function_code;
SIZE_T read;
diff --git a/sandbox/win/src/service_resolver_64.cc b/sandbox/win/src/service_resolver_64.cc
index 9612418..79c6b16 100644
--- a/sandbox/win/src/service_resolver_64.cc
+++ b/sandbox/win/src/service_resolver_64.cc
@@ -116,6 +116,30 @@ size_t ServiceResolverThunk::GetThunkSize() const {
return sizeof(ServiceFullThunk);
}
+NTSTATUS ServiceResolverThunk::CopyThunk(const void* target_module,
+ const char* target_name,
+ BYTE* thunk_storage,
+ size_t storage_bytes,
+ size_t* storage_used) {
+ NTSTATUS ret = ResolveTarget(target_module, target_name, &target_);
+ if (!NT_SUCCESS(ret))
+ return ret;
+
+ size_t thunk_bytes = GetThunkSize();
+ if (storage_bytes < thunk_bytes)
+ return STATUS_UNSUCCESSFUL;
+
+ ServiceFullThunk* thunk = reinterpret_cast<ServiceFullThunk*>(thunk_storage);
+
+ if (!IsFunctionAService(&thunk->original))
+ return STATUS_UNSUCCESSFUL;
+
+ if (NULL != storage_used)
+ *storage_used = thunk_bytes;
+
+ return ret;
+}
+
bool ServiceResolverThunk::IsFunctionAService(void* local_thunk) const {
ServiceFullThunk function_code;
SIZE_T read;