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 <map> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/policy_broker.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/pe_image.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/windows_version.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/interception.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/interceptors.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/policy_target.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/process_thread_interception.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox_nt_types.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox_types.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/target_process.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This code executes on the broker side, as a callback from the policy on the 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// target side (the child). 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sandbox { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is the list of all imported symbols from ntdll.dll. 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SANDBOX_INTERCEPT NtExports g_nt; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INIT_GLOBAL_NT(member) \ 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_nt.member = reinterpret_cast<Nt##member##Function>( \ 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntdll_image.GetProcAddress("Nt" #member)); \ 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL == g_nt.member) \ 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INIT_GLOBAL_RTL(member) \ 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_nt.member = reinterpret_cast<member##Function>( \ 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntdll_image.GetProcAddress(#member)); \ 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL == g_nt.member) \ 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SetupNtdllImports(TargetProcess *child) { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMODULE ntdll = ::GetModuleHandle(kNtdllName); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::PEImage ntdll_image(ntdll); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Bypass purify's interception. 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wchar_t* loader_get = reinterpret_cast<wchar_t*>( 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntdll_image.GetProcAddress("LdrGetDllHandle")); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (loader_get) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loader_get, &ntdll); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_NT(AllocateVirtualMemory); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_NT(Close); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_NT(DuplicateObject); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_NT(FreeVirtualMemory); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_NT(MapViewOfSection); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_NT(ProtectVirtualMemory); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_NT(QueryInformationProcess); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_NT(QueryObject); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_NT(QuerySection); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_NT(QueryVirtualMemory); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_NT(UnmapViewOfSection); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_RTL(RtlAllocateHeap); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_RTL(RtlAnsiStringToUnicodeString); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_RTL(RtlCompareUnicodeString); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_RTL(RtlCreateHeap); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_RTL(RtlCreateUserThread); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_RTL(RtlDestroyHeap); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_RTL(RtlFreeHeap); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_RTL(_strnicmp); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_RTL(strlen); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_RTL(wcslen); 76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) INIT_GLOBAL_RTL(memcpy); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that the structure is fully initialized. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < sizeof(g_nt)/sizeof(void*); i++) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(reinterpret_cast<char**>(&g_nt)[i]); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (SBOX_ALL_OK == child->TransferVariable("g_nt", &g_nt, sizeof(g_nt))); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef INIT_GLOBAL_NT 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef INIT_GLOBAL_RTL 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SetupBasicInterceptions(InterceptionManager* manager) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Interceptions provided by process_thread_policy, without actual policy. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!INTERCEPT_NT(manager, NtOpenThread, OPEN_TREAD_ID, 20) || 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !INTERCEPT_NT(manager, NtOpenProcess, OPEN_PROCESS_ID, 20) || 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !INTERCEPT_NT(manager, NtOpenProcessToken, OPEN_PROCESS_TOKEN_ID, 16)) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Interceptions with neither policy nor IPC. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!INTERCEPT_NT(manager, NtSetInformationThread, SET_INFORMATION_THREAD_ID, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20) || 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !INTERCEPT_NT(manager, NtOpenThreadToken, OPEN_THREAD_TOKEN_ID, 20)) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::win::GetVersion() >= base::win::VERSION_XP) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Bug 27218: We don't have dispatch for some x64 syscalls. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This one is also provided by process_thread_policy. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!INTERCEPT_NT(manager, NtOpenProcessTokenEx, OPEN_PROCESS_TOKEN_EX_ID, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20)) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return INTERCEPT_NT(manager, NtOpenThreadTokenEx, OPEN_THREAD_TOKEN_EX_ID, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace sandbox 117