summaryrefslogtreecommitdiffstats
path: root/sandbox/src
diff options
context:
space:
mode:
authorrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-03 19:35:40 +0000
committerrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-03 19:35:40 +0000
commitbb3dc256b24a68e9fbe152599845d4a9a5956c68 (patch)
tree777bc9f350445a0644ef9fc5ba98e890a333ebfb /sandbox/src
parentc6976260126c8f26c5b570750c29d10a2c9b486b (diff)
downloadchromium_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')
-rw-r--r--sandbox/src/service_resolver.cc52
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 {