15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/service_resolver.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "sandbox/win/src/sandbox_nt_util.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/win_utils.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma pack(push, 1) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ULONG kMmovR10EcxMovEax = 0xB8D18B4C; 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const USHORT kSyscall = 0x050F; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const BYTE kRetNp = 0xC3; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ULONG64 kMov1 = 0x54894808244C8948; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ULONG64 kMov2 = 0x4C182444894C1024; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ULONG kMov3 = 0x20244C89; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Service code for 64 bit systems. 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ServiceEntry { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This struct contains roughly the following code: 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 00 mov r10,rcx 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 03 mov eax,52h 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 08 syscall 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 0a ret 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 0b xchg ax,ax 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 0e xchg ax,ax 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ULONG mov_r10_rcx_mov_eax; // = 4C 8B D1 B8 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ULONG service_id; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT syscall; // = 0F 05 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BYTE ret; // = C3 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BYTE pad; // = 66 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT xchg_ax_ax1; // = 66 90 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT xchg_ax_ax2; // = 66 90 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Service code for 64 bit Windows 8. 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ServiceEntryW8 { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This struct contains the following code: 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 00 48894c2408 mov [rsp+8], rcx 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 05 4889542410 mov [rsp+10], rdx 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 0a 4c89442418 mov [rsp+18], r8 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 0f 4c894c2420 mov [rsp+20], r9 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 14 4c8bd1 mov r10,rcx 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 17 b825000000 mov eax,25h 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1c 0f05 syscall 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1e c3 ret 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1f 90 nop 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ULONG64 mov_1; // = 48 89 4C 24 08 48 89 54 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ULONG64 mov_2; // = 24 10 4C 89 44 24 18 4C 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ULONG mov_3; // = 89 4C 24 20 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ULONG mov_r10_rcx_mov_eax; // = 4C 8B D1 B8 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ULONG service_id; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT syscall; // = 0F 05 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BYTE ret; // = C3 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BYTE nop; // = 90 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We don't have an internal thunk for x64. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ServiceFullThunk { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ServiceEntry original; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ServiceEntryW8 original_w8; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma pack(pop) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsService(const void* source) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ServiceEntry* service = 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const ServiceEntry*>(source); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (kMmovR10EcxMovEax == service->mov_r10_rcx_mov_eax && 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kSyscall == service->syscall && kRetNp == service->ret); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; // namespace 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sandbox { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NTSTATUS ServiceResolverThunk::Setup(const void* target_module, 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* interceptor_module, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* target_name, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* interceptor_name, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* interceptor_entry_point, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* thunk_storage, 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t storage_bytes, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t* storage_used) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NTSTATUS ret = Init(target_module, interceptor_module, target_name, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) interceptor_name, interceptor_entry_point, 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thunk_storage, storage_bytes); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!NT_SUCCESS(ret)) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t thunk_bytes = GetThunkSize(); 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<char[]> thunk_buffer(new char[thunk_bytes]); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ServiceFullThunk* thunk = reinterpret_cast<ServiceFullThunk*>( 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thunk_buffer.get()); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsFunctionAService(&thunk->original)) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return STATUS_UNSUCCESSFUL; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = PerformPatch(thunk, thunk_storage); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL != storage_used) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *storage_used = thunk_bytes; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t ServiceResolverThunk::GetThunkSize() const { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sizeof(ServiceFullThunk); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)NTSTATUS ServiceResolverThunk::CopyThunk(const void* target_module, 12023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const char* target_name, 12123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) BYTE* thunk_storage, 12223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) size_t storage_bytes, 12323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) size_t* storage_used) { 12423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NTSTATUS ret = ResolveTarget(target_module, target_name, &target_); 12523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!NT_SUCCESS(ret)) 12623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return ret; 12723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 12823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) size_t thunk_bytes = GetThunkSize(); 12923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (storage_bytes < thunk_bytes) 13023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return STATUS_UNSUCCESSFUL; 13123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 13223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ServiceFullThunk* thunk = reinterpret_cast<ServiceFullThunk*>(thunk_storage); 13323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 13423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!IsFunctionAService(&thunk->original)) 13523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return STATUS_UNSUCCESSFUL; 13623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 13723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (NULL != storage_used) 13823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) *storage_used = thunk_bytes; 13923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 14023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return ret; 14123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 14223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ServiceResolverThunk::IsFunctionAService(void* local_thunk) const { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ServiceFullThunk function_code; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SIZE_T read; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!::ReadProcessMemory(process_, target_, &function_code, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(function_code), &read)) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sizeof(function_code) != read) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsService(&function_code)) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See if it's the Win8 signature. 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ServiceEntryW8* w8_service = &function_code.original_w8; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsService(&w8_service->mov_r10_rcx_mov_eax) || 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w8_service->mov_1 != kMov1 || w8_service->mov_1 != kMov1 || 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) w8_service->mov_1 != kMov1) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Save the verified code. 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(local_thunk, &function_code, sizeof(function_code)); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NTSTATUS ServiceResolverThunk::PerformPatch(void* local_thunk, 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* remote_thunk) { 171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ServiceFullThunk* full_local_thunk = 172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) reinterpret_cast<ServiceFullThunk*>(local_thunk); 173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ServiceFullThunk* full_remote_thunk = 174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) reinterpret_cast<ServiceFullThunk*>(remote_thunk); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Patch the original code. 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ServiceEntry local_service; 178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK_NT(GetInternalThunkSize() >= sizeof(local_service)); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SetInternalThunk(&local_service, sizeof(local_service), NULL, 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) interceptor_)) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return STATUS_UNSUCCESSFUL; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy the local thunk buffer to the child. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SIZE_T actual; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!::WriteProcessMemory(process_, remote_thunk, local_thunk, 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(ServiceFullThunk), &actual)) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return STATUS_UNSUCCESSFUL; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sizeof(ServiceFullThunk) != actual) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return STATUS_UNSUCCESSFUL; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // And now change the function to intercept, on the child. 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL != ntdll_base_) { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Running a unit test. 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!::WriteProcessMemory(process_, target_, &local_service, 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(local_service), &actual)) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return STATUS_UNSUCCESSFUL; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!WriteProtectedChildMemory(process_, target_, &local_service, 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(local_service))) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return STATUS_UNSUCCESSFUL; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return STATUS_SUCCESS; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Wow64ResolverThunk::IsFunctionAService(void* local_thunk) const { 208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) NOTREACHED_NT(); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace sandbox 213