toolkit/xre/test/win/TestDllInterceptor.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/xre/test/win/TestDllInterceptor.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,167 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +#include <stdio.h>
     1.9 +#include "nsWindowsDllInterceptor.h"
    1.10 +
    1.11 +using namespace mozilla;
    1.12 +
    1.13 +struct payload {
    1.14 +  UINT64 a;
    1.15 +  UINT64 b;
    1.16 +  UINT64 c;
    1.17 +
    1.18 +  bool operator==(const payload &other) const {
    1.19 +    return (a == other.a &&
    1.20 +            b == other.b &&
    1.21 +            c == other.c);
    1.22 +  }
    1.23 +};
    1.24 +
    1.25 +extern "C" __declspec(dllexport) __declspec(noinline) payload rotatePayload(payload p) {
    1.26 +  UINT64 tmp = p.a;
    1.27 +  p.a = p.b;
    1.28 +  p.b = p.c;
    1.29 +  p.c = tmp;
    1.30 +  return p;
    1.31 +}
    1.32 +
    1.33 +static bool patched_func_called = false;
    1.34 +
    1.35 +static payload (*orig_rotatePayload)(payload);
    1.36 +
    1.37 +static payload
    1.38 +patched_rotatePayload(payload p)
    1.39 +{
    1.40 +  patched_func_called = true;
    1.41 +  return orig_rotatePayload(p);
    1.42 +}
    1.43 +
    1.44 +bool TestHook(const char *dll, const char *func)
    1.45 +{
    1.46 +  void *orig_func;
    1.47 +  bool successful = false;
    1.48 +  {
    1.49 +    WindowsDllInterceptor TestIntercept;
    1.50 +    TestIntercept.Init(dll);
    1.51 +    successful = TestIntercept.AddHook(func, 0, &orig_func);
    1.52 +  }
    1.53 +
    1.54 +  if (successful) {
    1.55 +    printf("TEST-PASS | WindowsDllInterceptor | Could hook %s from %s\n", func, dll);
    1.56 +    return true;
    1.57 +  } else {
    1.58 +    printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Failed to hook %s from %s\n", func, dll);
    1.59 +    return false;
    1.60 +  }
    1.61 +}
    1.62 +
    1.63 +bool TestDetour(const char *dll, const char *func)
    1.64 +{
    1.65 +  void *orig_func;
    1.66 +  bool successful = false;
    1.67 +  {
    1.68 +    WindowsDllInterceptor TestIntercept;
    1.69 +    TestIntercept.Init(dll);
    1.70 +    successful = TestIntercept.AddDetour(func, 0, &orig_func);
    1.71 +  }
    1.72 +
    1.73 +  if (successful) {
    1.74 +    printf("TEST-PASS | WindowsDllInterceptor | Could detour %s from %s\n", func, dll);
    1.75 +    return true;
    1.76 +  } else {
    1.77 +    printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Failed to detour %s from %s\n", func, dll);
    1.78 +    return false;
    1.79 +  }
    1.80 +}
    1.81 +
    1.82 +int main()
    1.83 +{
    1.84 +  payload initial = { 0x12345678, 0xfc4e9d31, 0x87654321 };
    1.85 +  payload p0, p1;
    1.86 +  ZeroMemory(&p0, sizeof(p0));
    1.87 +  ZeroMemory(&p1, sizeof(p1));
    1.88 +
    1.89 +  p0 = rotatePayload(initial);
    1.90 +
    1.91 +  {
    1.92 +    WindowsDllInterceptor ExeIntercept;
    1.93 +    ExeIntercept.Init("TestDllInterceptor.exe");
    1.94 +    if (ExeIntercept.AddHook("rotatePayload", reinterpret_cast<intptr_t>(patched_rotatePayload), (void**) &orig_rotatePayload)) {
    1.95 +      printf("TEST-PASS | WindowsDllInterceptor | Hook added\n");
    1.96 +    } else {
    1.97 +      printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Failed to add hook\n");
    1.98 +      return 1;
    1.99 +    }
   1.100 +
   1.101 +    p1 = rotatePayload(initial);
   1.102 +
   1.103 +    if (patched_func_called) {
   1.104 +      printf("TEST-PASS | WindowsDllInterceptor | Hook called\n");
   1.105 +    } else {
   1.106 +      printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Hook was not called\n");
   1.107 +      return 1;
   1.108 +    }
   1.109 +
   1.110 +    if (p0 == p1) {
   1.111 +      printf("TEST-PASS | WindowsDllInterceptor | Hook works properly\n");
   1.112 +    } else {
   1.113 +      printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Hook didn't return the right information\n");
   1.114 +      return 1;
   1.115 +    }
   1.116 +  }
   1.117 +
   1.118 +  patched_func_called = false;
   1.119 +  ZeroMemory(&p1, sizeof(p1));
   1.120 +
   1.121 +  p1 = rotatePayload(initial);
   1.122 +
   1.123 +  if (!patched_func_called) {
   1.124 +    printf("TEST-PASS | WindowsDllInterceptor | Hook was not called after unregistration\n");
   1.125 +  } else {
   1.126 +    printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Hook was still called after unregistration\n");
   1.127 +    return 1;
   1.128 +  }
   1.129 +
   1.130 +  if (p0 == p1) {
   1.131 +    printf("TEST-PASS | WindowsDllInterceptor | Original function worked properly\n");
   1.132 +  } else {
   1.133 +    printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Original function didn't return the right information\n");
   1.134 +    return 1;
   1.135 +  }
   1.136 +
   1.137 +  if (TestHook("user32.dll", "GetWindowInfo") &&
   1.138 +#ifdef _WIN64
   1.139 +      TestHook("user32.dll", "SetWindowLongPtrA") &&
   1.140 +      TestHook("user32.dll", "SetWindowLongPtrW") &&
   1.141 +#else
   1.142 +      TestHook("user32.dll", "SetWindowLongA") &&
   1.143 +      TestHook("user32.dll", "SetWindowLongW") &&
   1.144 +#endif
   1.145 +      TestHook("user32.dll", "TrackPopupMenu") &&
   1.146 +#ifdef _M_IX86
   1.147 +      // We keep this test to hook complex code on x86. (Bug 850957)
   1.148 +      TestHook("ntdll.dll", "NtFlushBuffersFile") &&
   1.149 +#endif
   1.150 +      TestHook("ntdll.dll", "NtCreateFile") &&
   1.151 +      TestHook("ntdll.dll", "NtReadFile") &&
   1.152 +      TestHook("ntdll.dll", "NtReadFileScatter") &&
   1.153 +      TestHook("ntdll.dll", "NtWriteFile") &&
   1.154 +      TestHook("ntdll.dll", "NtWriteFileGather") &&
   1.155 +      TestHook("ntdll.dll", "NtQueryFullAttributesFile") &&
   1.156 +      // Bug 733892: toolkit/crashreporter/nsExceptionHandler.cpp
   1.157 +      TestHook("kernel32.dll", "SetUnhandledExceptionFilter") &&
   1.158 +#ifdef _M_IX86
   1.159 +      // Bug 670967: xpcom/base/AvailableMemoryTracker.cpp
   1.160 +      TestHook("kernel32.dll", "VirtualAlloc") &&
   1.161 +      TestHook("kernel32.dll", "MapViewOfFile") &&
   1.162 +      TestHook("gdi32.dll", "CreateDIBSection") &&
   1.163 +#endif
   1.164 +      TestDetour("ntdll.dll", "LdrLoadDll")) {
   1.165 +    printf("TEST-PASS | WindowsDllInterceptor | all checks passed\n");
   1.166 +    return 0;
   1.167 +  }
   1.168 +
   1.169 +  return 1;
   1.170 +}

mercurial