summaryrefslogtreecommitdiffstats
path: root/security/sandbox/chromium/sandbox/win/src/resolver_32.cc
diff options
context:
space:
mode:
Diffstat (limited to 'security/sandbox/chromium/sandbox/win/src/resolver_32.cc')
-rw-r--r--security/sandbox/chromium/sandbox/win/src/resolver_32.cc94
1 files changed, 94 insertions, 0 deletions
diff --git a/security/sandbox/chromium/sandbox/win/src/resolver_32.cc b/security/sandbox/chromium/sandbox/win/src/resolver_32.cc
new file mode 100644
index 000000000..25df11cc4
--- /dev/null
+++ b/security/sandbox/chromium/sandbox/win/src/resolver_32.cc
@@ -0,0 +1,94 @@
+// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "sandbox/win/src/resolver.h"
+
+#include <stddef.h>
+
+// For placement new. This file must not depend on the CRT at runtime, but
+// placement operator new is inline.
+#include <new>
+
+#include "sandbox/win/src/sandbox_nt_util.h"
+
+namespace {
+
+#pragma pack(push, 1)
+struct InternalThunk {
+ // This struct contains roughly the following code:
+ // sub esp, 8 // Create working space
+ // push edx // Save register
+ // mov edx, [esp + 0xc] // Get return adddress
+ // mov [esp + 8], edx // Store return address
+ // mov dword ptr [esp + 0xc], 0x7c401200 // Store extra argument
+ // mov dword ptr [esp + 4], 0x40010203 // Store address to jump to
+ // pop edx // Restore register
+ // ret // Jump to interceptor
+ //
+ // This code only modifies esp and eip so it must work with to normal calling
+ // convention. It is assembled as:
+ //
+ // 00 83ec08 sub esp,8
+ // 03 52 push edx
+ // 04 8b54240c mov edx,dword ptr [esp + 0Ch]
+ // 08 89542408 mov dword ptr [esp + 8], edx
+ // 0c c744240c0012407c mov dword ptr [esp + 0Ch], 7C401200h
+ // 14 c744240403020140 mov dword ptr [esp + 4], 40010203h
+ // 1c 5a pop edx
+ // 1d c3 ret
+ InternalThunk() {
+ opcodes_1 = 0x5208ec83;
+ opcodes_2 = 0x0c24548b;
+ opcodes_3 = 0x08245489;
+ opcodes_4 = 0x0c2444c7;
+ opcodes_5 = 0x042444c7;
+ opcodes_6 = 0xc35a;
+ extra_argument = 0;
+ interceptor_function = 0;
+ };
+ ULONG opcodes_1; // = 0x5208ec83
+ ULONG opcodes_2; // = 0x0c24548b
+ ULONG opcodes_3; // = 0x08245489
+ ULONG opcodes_4; // = 0x0c2444c7
+ ULONG extra_argument;
+ ULONG opcodes_5; // = 0x042444c7
+ ULONG interceptor_function;
+ USHORT opcodes_6; // = 0xc35a
+};
+#pragma pack(pop)
+
+}; // namespace
+
+namespace sandbox {
+
+bool ResolverThunk::SetInternalThunk(void* storage, size_t storage_bytes,
+ const void* original_function,
+ const void* interceptor) {
+ if (storage_bytes < sizeof(InternalThunk))
+ return false;
+
+ InternalThunk* thunk = new(storage) InternalThunk;
+
+#pragma warning(push)
+#pragma warning(disable: 4311)
+ // These casts generate warnings because they are 32 bit specific.
+ thunk->interceptor_function = reinterpret_cast<ULONG>(interceptor);
+ thunk->extra_argument = reinterpret_cast<ULONG>(original_function);
+#pragma warning(pop)
+
+ return true;
+}
+
+size_t ResolverThunk::GetInternalThunkSize() const {
+ return sizeof(InternalThunk);
+}
+
+NTSTATUS ResolverThunk::ResolveTarget(const void* module,
+ const char* function_name,
+ void** address) {
+ const void** casted = const_cast<const void**>(address);
+ return ResolverThunk::ResolveInterceptor(module, function_name, casted);
+}
+
+} // namespace sandbox