1// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "sandbox/win/src/resolver.h"
6
7// For placement new. This file must not depend on the CRT at runtime, but
8// placement operator new is inline.
9#include <new>
10
11#include "sandbox/win/src/sandbox_nt_util.h"
12
13namespace {
14
15const BYTE kPushRax = 0x50;
16const USHORT kMovRax = 0xB848;
17const ULONG kMovRspRax = 0x24048948;
18const BYTE kRetNp = 0xC3;
19
20#pragma pack(push, 1)
21struct InternalThunk {
22  // This struct contains roughly the following code:
23  // 00 50                    push  rax
24  // 01 48b8f0debc9a78563412  mov   rax,123456789ABCDEF0h
25  // 0b 48890424              mov   qword ptr [rsp],rax
26  // 0f c3                    ret
27  //
28  // The code modifies rax, but that should not be an issue for the common
29  // calling conventions.
30
31  InternalThunk() {
32    push_rax = kPushRax;
33    mov_rax = kMovRax;
34    interceptor_function = 0;
35    mov_rsp_rax = kMovRspRax;
36    ret = kRetNp;
37  };
38  BYTE push_rax;        // = 50
39  USHORT mov_rax;       // = 48 B8
40  ULONG_PTR interceptor_function;
41  ULONG mov_rsp_rax;    // = 48 89 04 24
42  BYTE ret;             // = C3
43};
44#pragma pack(pop)
45
46} // namespace.
47
48namespace sandbox {
49
50size_t ResolverThunk::GetInternalThunkSize() const {
51  return sizeof(InternalThunk);
52}
53
54bool ResolverThunk::SetInternalThunk(void* storage, size_t storage_bytes,
55                                     const void* original_function,
56                                     const void* interceptor) {
57  if (storage_bytes < sizeof(InternalThunk))
58    return false;
59
60  InternalThunk* thunk = new(storage) InternalThunk;
61  thunk->interceptor_function = reinterpret_cast<ULONG_PTR>(interceptor);
62
63  return true;
64}
65
66NTSTATUS ResolverThunk::ResolveTarget(const void* module,
67                                      const char* function_name,
68                                      void** address) {
69  // We don't support sidestep & co.
70  return STATUS_NOT_IMPLEMENTED;
71}
72
73}  // namespace sandbox
74