security/sandbox/win/src/eat_resolver.cc

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/sandbox/win/src/eat_resolver.cc	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,91 @@
     1.4 +// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
     1.5 +// Use of this source code is governed by a BSD-style license that can be
     1.6 +// found in the LICENSE file.
     1.7 +
     1.8 +#include "sandbox/win/src/eat_resolver.h"
     1.9 +
    1.10 +#include "base/win/pe_image.h"
    1.11 +#include "sandbox/win/src/sandbox_nt_util.h"
    1.12 +
    1.13 +namespace sandbox {
    1.14 +
    1.15 +NTSTATUS EatResolverThunk::Setup(const void* target_module,
    1.16 +                                 const void* interceptor_module,
    1.17 +                                 const char* target_name,
    1.18 +                                 const char* interceptor_name,
    1.19 +                                 const void* interceptor_entry_point,
    1.20 +                                 void* thunk_storage,
    1.21 +                                 size_t storage_bytes,
    1.22 +                                 size_t* storage_used) {
    1.23 +  NTSTATUS ret = Init(target_module, interceptor_module, target_name,
    1.24 +                      interceptor_name, interceptor_entry_point,
    1.25 +                      thunk_storage, storage_bytes);
    1.26 +  if (!NT_SUCCESS(ret))
    1.27 +    return ret;
    1.28 +
    1.29 +  if (!eat_entry_)
    1.30 +    return STATUS_INVALID_PARAMETER;
    1.31 +
    1.32 +  size_t thunk_bytes = GetInternalThunkSize();
    1.33 +
    1.34 +#if defined(_WIN64)
    1.35 +  // We have two thunks, in order: the return path and the forward path.
    1.36 +  if (!SetInternalThunk(thunk_storage, storage_bytes, NULL, target_))
    1.37 +    return STATUS_BUFFER_TOO_SMALL;
    1.38 +
    1.39 +  storage_bytes -= thunk_bytes;
    1.40 +  thunk_storage = reinterpret_cast<char*>(thunk_storage) + thunk_bytes;
    1.41 +#endif
    1.42 +
    1.43 +  if (!SetInternalThunk(thunk_storage, storage_bytes, target_, interceptor_))
    1.44 +    return STATUS_BUFFER_TOO_SMALL;
    1.45 +
    1.46 +  AutoProtectMemory memory;
    1.47 +  ret = memory.ChangeProtection(eat_entry_, sizeof(DWORD), PAGE_READWRITE);
    1.48 +  if (!NT_SUCCESS(ret))
    1.49 +    return ret;
    1.50 +
    1.51 +  // Perform the patch.
    1.52 +#pragma warning(push)
    1.53 +#pragma warning(disable: 4311)
    1.54 +  // These casts generate warnings because they are 32 bit specific.
    1.55 +  *eat_entry_ = reinterpret_cast<DWORD>(thunk_storage) -
    1.56 +                reinterpret_cast<DWORD>(target_module);
    1.57 +#pragma warning(pop)
    1.58 +
    1.59 +  if (NULL != storage_used)
    1.60 +    *storage_used = GetThunkSize();
    1.61 +
    1.62 +  return ret;
    1.63 +}
    1.64 +
    1.65 +NTSTATUS EatResolverThunk::ResolveTarget(const void* module,
    1.66 +                                         const char* function_name,
    1.67 +                                         void** address) {
    1.68 +  DCHECK_NT(address);
    1.69 +  if (!module)
    1.70 +    return STATUS_INVALID_PARAMETER;
    1.71 +
    1.72 +  base::win::PEImage pe(module);
    1.73 +  if (!pe.VerifyMagic())
    1.74 +    return STATUS_INVALID_IMAGE_FORMAT;
    1.75 +
    1.76 +  eat_entry_ = pe.GetExportEntry(function_name);
    1.77 +
    1.78 +  if (!eat_entry_)
    1.79 +    return STATUS_PROCEDURE_NOT_FOUND;
    1.80 +
    1.81 +  *address = pe.RVAToAddr(*eat_entry_);
    1.82 +
    1.83 +  return STATUS_SUCCESS;
    1.84 +}
    1.85 +
    1.86 +size_t EatResolverThunk::GetThunkSize() const {
    1.87 +#if defined(_WIN64)
    1.88 +  return GetInternalThunkSize() * 2;
    1.89 +#else
    1.90 +  return GetInternalThunkSize();
    1.91 +#endif
    1.92 +}
    1.93 +
    1.94 +}  // namespace sandbox

mercurial