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

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

mercurial