|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "InjectCrashReporter.h" |
|
7 #include "nsDirectoryServiceUtils.h" |
|
8 #include "nsDirectoryServiceDefs.h" |
|
9 #include "client/windows/crash_generation/crash_generation_client.h" |
|
10 #include "nsExceptionHandler.h" |
|
11 #include "LoadLibraryRemote.h" |
|
12 #include "nsWindowsHelpers.h" |
|
13 |
|
14 using google_breakpad::CrashGenerationClient; |
|
15 using CrashReporter::GetChildNotificationPipe; |
|
16 |
|
17 namespace mozilla { |
|
18 |
|
19 InjectCrashRunnable::InjectCrashRunnable(DWORD pid) |
|
20 : mPID(pid) |
|
21 { |
|
22 nsCOMPtr<nsIFile> dll; |
|
23 nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(dll)); |
|
24 if (NS_SUCCEEDED(rv)) { |
|
25 dll->Append(NS_LITERAL_STRING("breakpadinjector.dll")); |
|
26 dll->GetPath(mInjectorPath); |
|
27 } |
|
28 } |
|
29 |
|
30 NS_IMETHODIMP |
|
31 InjectCrashRunnable::Run() |
|
32 { |
|
33 if (mInjectorPath.IsEmpty()) |
|
34 return NS_OK; |
|
35 |
|
36 nsAutoHandle hProcess( |
|
37 OpenProcess(PROCESS_CREATE_THREAD | |
|
38 PROCESS_QUERY_INFORMATION | |
|
39 PROCESS_DUP_HANDLE | |
|
40 PROCESS_VM_OPERATION | |
|
41 PROCESS_VM_WRITE | |
|
42 PROCESS_VM_READ, FALSE, mPID)); |
|
43 if (!hProcess) { |
|
44 NS_WARNING("Unable to open remote process handle for crashreporter injection."); |
|
45 return NS_OK; |
|
46 } |
|
47 |
|
48 void* proc = LoadRemoteLibraryAndGetAddress(hProcess, mInjectorPath.get(), |
|
49 "Start"); |
|
50 if (!proc) { |
|
51 NS_WARNING("Unable to inject crashreporter DLL."); |
|
52 return NS_OK; |
|
53 } |
|
54 |
|
55 HANDLE hRemotePipe = |
|
56 CrashGenerationClient::DuplicatePipeToClientProcess( |
|
57 NS_ConvertASCIItoUTF16(GetChildNotificationPipe()).get(), |
|
58 hProcess); |
|
59 if (INVALID_HANDLE_VALUE == hRemotePipe) { |
|
60 NS_WARNING("Unable to duplicate crash reporter pipe to process."); |
|
61 return NS_OK; |
|
62 } |
|
63 |
|
64 nsAutoHandle hThread(CreateRemoteThread(hProcess, nullptr, 0, |
|
65 (LPTHREAD_START_ROUTINE) proc, |
|
66 (void*) hRemotePipe, 0, nullptr)); |
|
67 if (!hThread) { |
|
68 NS_WARNING("Unable to CreateRemoteThread"); |
|
69 |
|
70 // We have to close the remote pipe or else our crash generation client |
|
71 // will be stuck unable to accept other remote requests. |
|
72 HANDLE toClose = INVALID_HANDLE_VALUE; |
|
73 if (DuplicateHandle(hProcess, hRemotePipe, ::GetCurrentProcess(), |
|
74 &toClose, 0, FALSE, |
|
75 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { |
|
76 CloseHandle(toClose); |
|
77 return NS_OK; |
|
78 } |
|
79 } |
|
80 |
|
81 return NS_OK; |
|
82 } |
|
83 |
|
84 } // namespace mozilla |