diff options
author | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-03 19:35:40 +0000 |
---|---|---|
committer | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-03 19:35:40 +0000 |
commit | bb3dc256b24a68e9fbe152599845d4a9a5956c68 (patch) | |
tree | 777bc9f350445a0644ef9fc5ba98e890a333ebfb /sandbox/src/service_resolver.cc | |
parent | c6976260126c8f26c5b570750c29d10a2c9b486b (diff) | |
download | chromium_src-bb3dc256b24a68e9fbe152599845d4a9a5956c68.zip chromium_src-bb3dc256b24a68e9fbe152599845d4a9a5956c68.tar.gz chromium_src-bb3dc256b24a68e9fbe152599845d4a9a5956c68.tar.bz2 |
Sandbox: Add support for Windows 7 - 64 bit.
BUG=4324
TEST=IntegrationTestsTest.*
Review URL: http://codereview.chromium.org/20023
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9096 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox/src/service_resolver.cc')
-rw-r--r-- | sandbox/src/service_resolver.cc | 52 |
1 files changed, 40 insertions, 12 deletions
diff --git a/sandbox/src/service_resolver.cc b/sandbox/src/service_resolver.cc index c7ebb58..2ad07a4 100644 --- a/sandbox/src/service_resolver.cc +++ b/sandbox/src/service_resolver.cc @@ -24,7 +24,10 @@ const USHORT kJmpEdx = 0xE2FF; const USHORT kXorEcx = 0xC933; const ULONG kLeaEdx = 0x0424548D; const ULONG kCallFs1 = 0xC015FF64; -const ULONG kCallFs2Ret = 0xC2000000; +const USHORT kCallFs2 = 0; +const BYTE kCallFs3 = 0; +const BYTE kAddEsp1 = 0x83; +const USHORT kAddEsp2 = 0x4C4; const BYTE kJmp32 = 0xE9; const int kMaxService = 1000; @@ -33,11 +36,11 @@ const int kMaxService = 1000; // NOTE: on win2003 "call dword ptr [edx]" is "call edx". struct ServiceEntry { // this struct contains roughly the following code: - // mov eax,25h - // mov edx,offset SharedUserData!SystemCallStub (7ffe0300) - // call dword ptr [edx] - // ret 2Ch - // nop + // 00 mov eax,25h + // 05 mov edx,offset SharedUserData!SystemCallStub (7ffe0300) + // 0a call dword ptr [edx] + // 0c ret 2Ch + // 0f nop BYTE mov_eax; // = B8 ULONG service_id; BYTE mov_edx; // = BA @@ -46,25 +49,45 @@ struct ServiceEntry { BYTE ret; // = C2 USHORT num_params; BYTE nop; + ULONG pad1; // Extend the structure to be the same size as the + ULONG pad2; // 64 version (Wow64Entry) }; // Service code for a 32 bit process running on a 64 bit os. struct Wow64Entry { - // this struct contains roughly the following code: + // This struct may contain one of two versions of code: + // 1. For XP, Vista and 2K3: // 00 b852000000 mov eax, 25h // 05 33c9 xor ecx, ecx // 07 8d542404 lea edx, [esp + 4] // 0b 64ff15c0000000 call dword ptr fs:[0C0h] // 12 c22c00 ret 2Ch + // + // 2. For Windows 7: + // 00 b852000000 mov eax, 25h + // 05 33c9 xor ecx, ecx + // 07 8d542404 lea edx, [esp + 4] + // 0b 64ff15c0000000 call dword ptr fs:[0C0h] + // 12 83c404 add esp, 4 + // 15 c22c00 ret 2Ch + // + // So we base the structure on the bigger one: BYTE mov_eax; // = B8 ULONG service_id; USHORT xor_ecx; // = 33 C9 ULONG lea_edx; // = 8D 54 24 04 ULONG call_fs1; // = 64 FF 15 C0 - ULONG call_fs2_ret; // = 00 00 00 C2 + USHORT call_fs2; // = 00 00 + BYTE call_fs3; // = 00 + BYTE add_esp1; // = 83 or ret + USHORT add_esp2; // = C4 04 or num_params + BYTE ret; // = C2 USHORT num_params; }; +// Make sure that relaxed patching works as expected. +COMPILE_ASSERT(sizeof(ServiceEntry) == sizeof(Wow64Entry), wrong_service_len); + struct ServiceFullThunk { union { ServiceEntry original; @@ -337,13 +360,18 @@ bool Wow64ResolverThunk::IsFunctionAService(void* local_thunk) const { if (kMovEax != function_code.mov_eax || kXorEcx != function_code.xor_ecx || kLeaEdx != function_code.lea_edx || kCallFs1 != function_code.call_fs1 || - kCallFs2Ret != function_code.call_fs2_ret) + kCallFs2 != function_code.call_fs2 || kCallFs3 != function_code.call_fs3) return false; - // Save the verified code - memcpy(local_thunk, &function_code, sizeof(function_code)); + if ((kAddEsp1 == function_code.add_esp1 && + kAddEsp2 == function_code.add_esp2 && + kRet == function_code.ret) || kRet == function_code.add_esp1) { + // Save the verified code + memcpy(local_thunk, &function_code, sizeof(function_code)); + return true; + } - return true; + return false; } bool Win2kResolverThunk::IsFunctionAService(void* local_thunk) const { |