diff options
author | wfh <wfh@chromium.org> | 2015-08-20 14:48:05 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-08-20 21:48:35 +0000 |
commit | 1453ac3a6d190b21e04d578d5cf71ce19877db47 (patch) | |
tree | c89492e5a7f8d0ab8b3c826a9e7f4d39ff269237 | |
parent | f02092e10ceb38ff5a52b49787c640985db59806 (diff) | |
download | chromium_src-1453ac3a6d190b21e04d578d5cf71ce19877db47.zip chromium_src-1453ac3a6d190b21e04d578d5cf71ce19877db47.tar.gz chromium_src-1453ac3a6d190b21e04d578d5cf71ce19877db47.tar.bz2 |
Add support for int 2e fallback system call stub in Win10.
BUG=522201
TEST=sbox_integration_tests on Win 10 build 10525
Review URL: https://codereview.chromium.org/1291043003
Cr-Commit-Position: refs/heads/master@{#344588}
-rw-r--r-- | sandbox/win/src/service_resolver_64.cc | 61 |
1 files changed, 52 insertions, 9 deletions
diff --git a/sandbox/win/src/service_resolver_64.cc b/sandbox/win/src/service_resolver_64.cc index 8c0ae96..c0e684c 100644 --- a/sandbox/win/src/service_resolver_64.cc +++ b/sandbox/win/src/service_resolver_64.cc @@ -17,6 +17,10 @@ const BYTE kRetNp = 0xC3; const ULONG64 kMov1 = 0x54894808244C8948; const ULONG64 kMov2 = 0x4C182444894C1024; const ULONG kMov3 = 0x20244C89; +const USHORT kTestByte = 0x04F6; +const BYTE kPtr = 0x25; +const BYTE kRet = 0xC3; +const USHORT kJne = 0x0375; // Service code for 64 bit systems. struct ServiceEntry { @@ -60,11 +64,37 @@ struct ServiceEntryW8 { BYTE nop; // = 90 }; +// Service code for 64 bit systems with int 2e fallback. +struct ServiceEntryWithInt2E { + // This struct contains roughly the following code: + // 00 4c8bd1 mov r10,rcx + // 03 b855000000 mov eax,52h + // 08 f604250803fe7f01 test byte ptr SharedUserData!308, 1 + // 10 7503 jne [over syscall] + // 12 0f05 syscall + // 14 c3 ret + // 15 cd2e int 2e + // 17 c3 ret + + ULONG mov_r10_rcx_mov_eax; // = 4C 8B D1 B8 + ULONG service_id; + USHORT test_byte; // = F6 04 + BYTE ptr; // = 25 + ULONG user_shared_data_ptr; + BYTE one; // = 01 + USHORT jne_over_syscall; // = 75 03 + USHORT syscall; // = 0F 05 + BYTE ret; // = C3 + USHORT int2e; // = CD 2E + BYTE ret2; // = C3 +}; + // We don't have an internal thunk for x64. struct ServiceFullThunk { union { ServiceEntry original; ServiceEntryW8 original_w8; + ServiceEntryWithInt2E original_int2e_fallback; }; }; @@ -78,6 +108,25 @@ bool IsService(const void* source) { kSyscall == service->syscall && kRetNp == service->ret); } +bool IsServiceW8(const void* source) { + const ServiceEntryW8* service = + reinterpret_cast<const ServiceEntryW8*>(source); + + return (kMmovR10EcxMovEax == service->mov_r10_rcx_mov_eax && + kMov1 == service->mov_1 && kMov2 == service->mov_2 && + kMov3 == service->mov_3); +} + +bool IsServiceWithInt2E(const void* source) { + const ServiceEntryWithInt2E* service = + reinterpret_cast<const ServiceEntryWithInt2E*>(source); + + return (kMmovR10EcxMovEax == service->mov_r10_rcx_mov_eax && + kTestByte == service->test_byte && kPtr == service->ptr && + kJne == service->jne_over_syscall && kSyscall == service->syscall && + kRet == service->ret && kRet == service->ret2); +} + }; // namespace namespace sandbox { @@ -150,15 +199,9 @@ bool ServiceResolverThunk::IsFunctionAService(void* local_thunk) const { if (sizeof(function_code) != read) return false; - if (!IsService(&function_code)) { - // See if it's the Win8 signature. - ServiceEntryW8* w8_service = &function_code.original_w8; - if (!IsService(&w8_service->mov_r10_rcx_mov_eax) || - w8_service->mov_1 != kMov1 || w8_service->mov_2 != kMov2 || - w8_service->mov_3 != kMov3) { - return false; - } - } + if (!IsService(&function_code) && !IsServiceW8(&function_code) && + !IsServiceWithInt2E(&function_code)) + return false; // Save the verified code. memcpy(local_thunk, &function_code, sizeof(function_code)); |