toolkit/xre/test/win/TestDllInterceptor.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #include <stdio.h>
michael@0 6 #include "nsWindowsDllInterceptor.h"
michael@0 7
michael@0 8 using namespace mozilla;
michael@0 9
michael@0 10 struct payload {
michael@0 11 UINT64 a;
michael@0 12 UINT64 b;
michael@0 13 UINT64 c;
michael@0 14
michael@0 15 bool operator==(const payload &other) const {
michael@0 16 return (a == other.a &&
michael@0 17 b == other.b &&
michael@0 18 c == other.c);
michael@0 19 }
michael@0 20 };
michael@0 21
michael@0 22 extern "C" __declspec(dllexport) __declspec(noinline) payload rotatePayload(payload p) {
michael@0 23 UINT64 tmp = p.a;
michael@0 24 p.a = p.b;
michael@0 25 p.b = p.c;
michael@0 26 p.c = tmp;
michael@0 27 return p;
michael@0 28 }
michael@0 29
michael@0 30 static bool patched_func_called = false;
michael@0 31
michael@0 32 static payload (*orig_rotatePayload)(payload);
michael@0 33
michael@0 34 static payload
michael@0 35 patched_rotatePayload(payload p)
michael@0 36 {
michael@0 37 patched_func_called = true;
michael@0 38 return orig_rotatePayload(p);
michael@0 39 }
michael@0 40
michael@0 41 bool TestHook(const char *dll, const char *func)
michael@0 42 {
michael@0 43 void *orig_func;
michael@0 44 bool successful = false;
michael@0 45 {
michael@0 46 WindowsDllInterceptor TestIntercept;
michael@0 47 TestIntercept.Init(dll);
michael@0 48 successful = TestIntercept.AddHook(func, 0, &orig_func);
michael@0 49 }
michael@0 50
michael@0 51 if (successful) {
michael@0 52 printf("TEST-PASS | WindowsDllInterceptor | Could hook %s from %s\n", func, dll);
michael@0 53 return true;
michael@0 54 } else {
michael@0 55 printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Failed to hook %s from %s\n", func, dll);
michael@0 56 return false;
michael@0 57 }
michael@0 58 }
michael@0 59
michael@0 60 bool TestDetour(const char *dll, const char *func)
michael@0 61 {
michael@0 62 void *orig_func;
michael@0 63 bool successful = false;
michael@0 64 {
michael@0 65 WindowsDllInterceptor TestIntercept;
michael@0 66 TestIntercept.Init(dll);
michael@0 67 successful = TestIntercept.AddDetour(func, 0, &orig_func);
michael@0 68 }
michael@0 69
michael@0 70 if (successful) {
michael@0 71 printf("TEST-PASS | WindowsDllInterceptor | Could detour %s from %s\n", func, dll);
michael@0 72 return true;
michael@0 73 } else {
michael@0 74 printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Failed to detour %s from %s\n", func, dll);
michael@0 75 return false;
michael@0 76 }
michael@0 77 }
michael@0 78
michael@0 79 int main()
michael@0 80 {
michael@0 81 payload initial = { 0x12345678, 0xfc4e9d31, 0x87654321 };
michael@0 82 payload p0, p1;
michael@0 83 ZeroMemory(&p0, sizeof(p0));
michael@0 84 ZeroMemory(&p1, sizeof(p1));
michael@0 85
michael@0 86 p0 = rotatePayload(initial);
michael@0 87
michael@0 88 {
michael@0 89 WindowsDllInterceptor ExeIntercept;
michael@0 90 ExeIntercept.Init("TestDllInterceptor.exe");
michael@0 91 if (ExeIntercept.AddHook("rotatePayload", reinterpret_cast<intptr_t>(patched_rotatePayload), (void**) &orig_rotatePayload)) {
michael@0 92 printf("TEST-PASS | WindowsDllInterceptor | Hook added\n");
michael@0 93 } else {
michael@0 94 printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Failed to add hook\n");
michael@0 95 return 1;
michael@0 96 }
michael@0 97
michael@0 98 p1 = rotatePayload(initial);
michael@0 99
michael@0 100 if (patched_func_called) {
michael@0 101 printf("TEST-PASS | WindowsDllInterceptor | Hook called\n");
michael@0 102 } else {
michael@0 103 printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Hook was not called\n");
michael@0 104 return 1;
michael@0 105 }
michael@0 106
michael@0 107 if (p0 == p1) {
michael@0 108 printf("TEST-PASS | WindowsDllInterceptor | Hook works properly\n");
michael@0 109 } else {
michael@0 110 printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Hook didn't return the right information\n");
michael@0 111 return 1;
michael@0 112 }
michael@0 113 }
michael@0 114
michael@0 115 patched_func_called = false;
michael@0 116 ZeroMemory(&p1, sizeof(p1));
michael@0 117
michael@0 118 p1 = rotatePayload(initial);
michael@0 119
michael@0 120 if (!patched_func_called) {
michael@0 121 printf("TEST-PASS | WindowsDllInterceptor | Hook was not called after unregistration\n");
michael@0 122 } else {
michael@0 123 printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Hook was still called after unregistration\n");
michael@0 124 return 1;
michael@0 125 }
michael@0 126
michael@0 127 if (p0 == p1) {
michael@0 128 printf("TEST-PASS | WindowsDllInterceptor | Original function worked properly\n");
michael@0 129 } else {
michael@0 130 printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Original function didn't return the right information\n");
michael@0 131 return 1;
michael@0 132 }
michael@0 133
michael@0 134 if (TestHook("user32.dll", "GetWindowInfo") &&
michael@0 135 #ifdef _WIN64
michael@0 136 TestHook("user32.dll", "SetWindowLongPtrA") &&
michael@0 137 TestHook("user32.dll", "SetWindowLongPtrW") &&
michael@0 138 #else
michael@0 139 TestHook("user32.dll", "SetWindowLongA") &&
michael@0 140 TestHook("user32.dll", "SetWindowLongW") &&
michael@0 141 #endif
michael@0 142 TestHook("user32.dll", "TrackPopupMenu") &&
michael@0 143 #ifdef _M_IX86
michael@0 144 // We keep this test to hook complex code on x86. (Bug 850957)
michael@0 145 TestHook("ntdll.dll", "NtFlushBuffersFile") &&
michael@0 146 #endif
michael@0 147 TestHook("ntdll.dll", "NtCreateFile") &&
michael@0 148 TestHook("ntdll.dll", "NtReadFile") &&
michael@0 149 TestHook("ntdll.dll", "NtReadFileScatter") &&
michael@0 150 TestHook("ntdll.dll", "NtWriteFile") &&
michael@0 151 TestHook("ntdll.dll", "NtWriteFileGather") &&
michael@0 152 TestHook("ntdll.dll", "NtQueryFullAttributesFile") &&
michael@0 153 // Bug 733892: toolkit/crashreporter/nsExceptionHandler.cpp
michael@0 154 TestHook("kernel32.dll", "SetUnhandledExceptionFilter") &&
michael@0 155 #ifdef _M_IX86
michael@0 156 // Bug 670967: xpcom/base/AvailableMemoryTracker.cpp
michael@0 157 TestHook("kernel32.dll", "VirtualAlloc") &&
michael@0 158 TestHook("kernel32.dll", "MapViewOfFile") &&
michael@0 159 TestHook("gdi32.dll", "CreateDIBSection") &&
michael@0 160 #endif
michael@0 161 TestDetour("ntdll.dll", "LdrLoadDll")) {
michael@0 162 printf("TEST-PASS | WindowsDllInterceptor | all checks passed\n");
michael@0 163 return 0;
michael@0 164 }
michael@0 165
michael@0 166 return 1;
michael@0 167 }

mercurial