1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Wow_helper.exe is a simple Win32 64-bit executable designed to help to
6 // sandbox a 32 bit application running on a 64 bit OS. The basic idea is to
7 // perform a 64 bit interception of the target process and notify the 32-bit
8 // broker process whenever a DLL is being loaded. This allows the broker to
9 // setup the interceptions (32-bit) properly on the target.
15 #include "sandbox/win/wow_helper/service64_resolver.h"
16 #include "sandbox/win/wow_helper/target_code.h"
20 // Performs the interception of NtMapViewOfSection on the 64-bit version of
21 // ntdll.dll. 'thunk' is the buffer on the address space of process 'child',
22 // that will be used to store the information about the patch.
23 int PatchNtdll(HANDLE child
, void* thunk
, size_t thunk_bytes
) {
24 wchar_t* ntdll_name
= L
"ntdll.dll";
25 HMODULE ntdll_base
= ::GetModuleHandle(ntdll_name
);
29 Service64ResolverThunk
resolver(child
);
30 size_t used
= resolver
.GetThunkSize();
31 char* code
= reinterpret_cast<char*>(thunk
) + used
;
32 NTSTATUS ret
= resolver
.Setup(ntdll_base
, NULL
, "NtMapViewOfSection", NULL
,
33 code
, thunk
, thunk_bytes
, NULL
);
37 size_t size
= reinterpret_cast<char*>(&TargetEnd
) -
38 reinterpret_cast<char*>(&TargetNtMapViewOfSection
);
40 if (size
+ used
> thunk_bytes
)
44 if (!::WriteProcessMemory(child
, code
, &TargetNtMapViewOfSection
, size
,
54 } // namespace sandbox
56 // We must receive two arguments: the process id of the target to intercept and
57 // the address of a page of memory on that process that will be used for the
58 // interception. We receive the address because the broker will cleanup the
59 // patch when the work is performed.
61 // It should be noted that we don't wait until the real work is done; this
62 // program quits as soon as the 64-bit interception is performed.
63 int wWinMain(HINSTANCE
, HINSTANCE
, wchar_t* command_line
, int) {
64 static_assert(sizeof(void*) > sizeof(DWORD
), "unsupported 32 bits");
69 DWORD process_id
= wcstoul(command_line
, &next
, 0);
73 DWORD access
= PROCESS_VM_OPERATION
| PROCESS_VM_READ
| PROCESS_VM_WRITE
;
74 HANDLE child
= ::OpenProcess(access
, FALSE
, process_id
);
78 DWORD buffer
= wcstoul(next
, NULL
, 0);
82 void* thunk
= reinterpret_cast<void*>(static_cast<ULONG_PTR
>(buffer
));
84 const size_t kPageSize
= 4096;
85 return sandbox::PatchNtdll(child
, thunk
, kPageSize
);