Backed out changeset 76e73aad0fab, changeset be03169f5635 and changeset 1aed3d723632 (bug 681238) because of Win debug orange
authorMike Hommey <mh+mozilla@glandium.org>
Mon, 29 Aug 2011 19:49:13 +0200
changeset 76188 9f7ccdc68e3f087a805d21afd67ac6c981deb67e
parent 76187 4fc1f5dd41054e92e62fc3f34899a5c21ec5d46e
child 76189 5e6848a5ca2a26a8266df2a4c10ad5828ddbc1c7
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
bugs681238
milestone9.0a1
backs out76e73aad0fabaeb8e26a3de4a5d6df4220de3050
Backed out changeset 76e73aad0fab, changeset be03169f5635 and changeset 1aed3d723632 (bug 681238) because of Win debug orange
toolkit/xre/nsWindowsDllInterceptor.h
toolkit/xre/test/win/TestDllInterceptor.cpp
--- a/toolkit/xre/nsWindowsDllInterceptor.h
+++ b/toolkit/xre/nsWindowsDllInterceptor.h
@@ -191,41 +191,27 @@ protected:
 #if defined(_M_IX86)
     while (nBytes < 5) {
       // Understand some simple instructions that might be found in a
       // prologue; we might need to extend this as necessary.
       //
       // Note!  If we ever need to understand jump instructions, we'll
       // need to rewrite the displacement argument.
       if (origBytes[nBytes] >= 0x88 && origBytes[nBytes] <= 0x8B) {
-        // various MOVs
+        // various MOVs; but only handle the case where it truly is a 2-byte instruction
         unsigned char b = origBytes[nBytes+1];
         if (((b & 0xc0) == 0xc0) ||
             (((b & 0xc0) == 0x00) &&
-             ((b & 0x07) != 0x04) && ((b & 0x07) != 0x05)))
+             ((b & 0x38) != 0x20) && ((b & 0x38) != 0x28)))
         {
-          // REG=r, R/M=r or REG=r, R/M=[r]
           nBytes += 2;
-        } else if (((b & 0xc0) == 0x40) && ((b & 0x38) != 0x20)) {
-          // REG=r, R/M=[r + disp8]
-          nBytes += 3;
         } else {
           // complex MOV, bail
           return 0;
         }
-      } else if (origBytes[nBytes] == 0x83) {
-        // ADD|ODR|ADC|SBB|AND|SUB|XOR|CMP r/m, imm8
-        unsigned char b = origBytes[nBytes+1];
-        if ((b & 0xc0) == 0xc0) {
-          // ADD|ODR|ADC|SBB|AND|SUB|XOR|CMP r, imm8
-          nBytes += 3;
-        } else {
-          // bail
-          return 0;
-        }
       } else if (origBytes[nBytes] == 0x68) {
         // PUSH with 4-byte operand
         nBytes += 5;
       } else if ((origBytes[nBytes] & 0xf0) == 0x50) {
         // 1-byte PUSH/POP
         nBytes++;
       } else if (origBytes[nBytes] == 0x6A) {
         // PUSH imm8
@@ -266,45 +252,57 @@ protected:
         nBytes++;
 
         if (origBytes[nBytes] == 0x33) {
           // xor r32, r32
           nBytes += 2;
         } else {
           return 0;
         }
-      } else if ((origBytes[nBytes] & 0xfb) == 0x48) {
-        // REX.W | REX.WR
+      } else if (origBytes[nBytes] == 0x48) {
+        // REX.W
         nBytes++;
 
         if (origBytes[nBytes] == 0x81 && (origBytes[nBytes+1] & 0xf8) == 0xe8) {
           // sub r, dword
           nBytes += 6;
         } else if (origBytes[nBytes] == 0x83 &&
                   (origBytes[nBytes+1] & 0xf8) == 0xe8) {
           // sub r, byte
           nBytes += 3;
         } else if (origBytes[nBytes] == 0x83 &&
                   (origBytes[nBytes+1] & 0xf8) == 0x60) {
           // and [r+d], imm8
           nBytes += 5;
-        } else if ((origBytes[nBytes] & 0xfd) == 0x89) {
-          // MOV r/m64, r64 | MOV r64, r/m64
+        } else if (origBytes[nBytes] == 0x89) {
+          // MOV r/m64, r64
           if ((origBytes[nBytes+1] & 0xc0) == 0x40) {
             if ((origBytes[nBytes+1] & 0x7) == 0x04) {
-              // R/M=[SIB+disp8], REG=r64
+              // mov [SIB+disp8], r64
               nBytes += 4;
             } else {
-              // R/M=[r64+disp8], REG=r64
+              // mov [r64+disp8], r64
               nBytes += 3;
             }
-          } else if (((origBytes[nBytes+1] & 0xc0) == 0xc0) ||
-                     (((origBytes[nBytes+1] & 0xc0) == 0x00) &&
-                      ((origBytes[nBytes+1] & 0x07) != 0x04) && ((origBytes[nBytes+1] & 0x07) != 0x05))) {
-            // REG=r64, R/M=r64 or REG=r64, R/M=[r64]
+          } else {
+            // complex mov
+            return 0;
+          }
+        } else if (origBytes[nBytes] == 0x8b) {
+          // mov r64, r/m64
+          if ((origBytes[nBytes+1] & 0xc0) == 0x40) {
+            if ((origBytes[nBytes+1] & 0x7) == 0x04) {
+              // mov r64, [SIB+disp8]
+              nBytes += 4;
+            } else {
+              // mov r64, [r64+disp8]
+              nBytes += 3;
+            }
+          } else if ((origBytes[nBytes+1] & 0xc0) == 0xc0) {
+            // MOV r64, r64
             nBytes += 2;
           } else {
             // complex MOV
             return 0;
           }
         } else {
           // not support yet!
           return 0;
--- a/toolkit/xre/test/win/TestDllInterceptor.cpp
+++ b/toolkit/xre/test/win/TestDllInterceptor.cpp
@@ -33,124 +33,86 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include <stdio.h>
 #include "nsWindowsDllInterceptor.h"
 
-struct payload {
-  UINT64 a;
-  UINT64 b;
-  UINT64 c;
-
-  bool operator==(const payload &other) const {
-    return (a == other.a &&
-            b == other.b &&
-            c == other.c);
-  }
-};
-
-extern "C" __declspec(dllexport,noinline) payload rotatePayload(payload p) {
-  UINT64 tmp = p.a;
-  p.a = p.b;
-  p.b = p.c;
-  p.c = tmp;
-  return p;
-}
-
 static bool patched_func_called = false;
 
-static payload (*orig_rotatePayload)(payload);
+static BOOL (WINAPI *orig_GetVersionExA)(LPOSVERSIONINFO);
 
-static payload
-patched_rotatePayload(payload p)
+static BOOL WINAPI
+patched_GetVersionExA(LPOSVERSIONINFO lpVersionInfo)
 {
   patched_func_called = true;
-  return orig_rotatePayload(p);
+  return orig_GetVersionExA(lpVersionInfo);
 }
 
-bool TestHook(const char *dll, const char *func)
+bool osvi_equal(OSVERSIONINFO &info0, OSVERSIONINFO &info1)
 {
-  void *orig_func;
-  WindowsDllInterceptor TestIntercept;
-  TestIntercept.Init(dll);
-  if (TestIntercept.AddHook(func, 0, &orig_func)) {
-    printf("TEST-PASS | WindowsDllInterceptor | Could hook %s from %s\n", func, dll);
-    return true;
-  } else {
-    printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Failed to hook %s from %s\n", func, dll);
-    return false;
-  }
+  return (info0.dwMajorVersion == info1.dwMajorVersion &&
+          info0.dwMinorVersion == info1.dwMinorVersion &&
+          info0.dwBuildNumber == info1.dwBuildNumber &&
+          info0.dwPlatformId == info1.dwPlatformId &&
+          !strncmp(info0.szCSDVersion, info1.szCSDVersion, sizeof(info0.szCSDVersion)));
 }
 
 int main()
 {
-  payload initial = { 0x12345678, 0xfc4e9d31, 0x87654321 };
-  payload p0, p1;
-  ZeroMemory(&p0, sizeof(p0));
-  ZeroMemory(&p1, sizeof(p1));
+  OSVERSIONINFO info0, info1;
+  ZeroMemory(&info0, sizeof(OSVERSIONINFO));
+  ZeroMemory(&info1, sizeof(OSVERSIONINFO));
+  info0.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+  info1.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
 
-  p0 = rotatePayload(initial);
+  GetVersionExA(&info0);
 
   {
-    WindowsDllInterceptor ExeIntercept;
-    ExeIntercept.Init("TestDllInterceptor.exe");
-    if (ExeIntercept.AddHook("rotatePayload", reinterpret_cast<intptr_t>(patched_rotatePayload), (void**) &orig_rotatePayload)) {
+    WindowsDllInterceptor Kernel32Intercept;
+    Kernel32Intercept.Init("kernel32.dll");
+    if (Kernel32Intercept.AddHook("GetVersionExA", reinterpret_cast<intptr_t>(patched_GetVersionExA), (void**) &orig_GetVersionExA)) {
       printf("TEST-PASS | WindowsDllInterceptor | Hook added\n");
     } else {
       printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Failed to add hook\n");
       return 1;
     }
 
-    p1 = rotatePayload(initial);
+    GetVersionExA(&info1);
 
     if (patched_func_called) {
       printf("TEST-PASS | WindowsDllInterceptor | Hook called\n");
     } else {
       printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Hook was not called\n");
       return 1;
     }
 
-    if (p0 == p1) {
+    if (osvi_equal(info0, info1)) {
       printf("TEST-PASS | WindowsDllInterceptor | Hook works properly\n");
     } else {
       printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Hook didn't return the right information\n");
       return 1;
     }
   }
 
   patched_func_called = false;
-  ZeroMemory(&p1, sizeof(p1));
 
-  p1 = rotatePayload(initial);
+  GetVersionExA(&info1);
 
   if (!patched_func_called) {
     printf("TEST-PASS | WindowsDllInterceptor | Hook was not called after unregistration\n");
   } else {
     printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Hook was still called after unregistration\n");
     return 1;
   }
 
-  if (p0 == p1) {
+  if (osvi_equal(info0, info1)) {
     printf("TEST-PASS | WindowsDllInterceptor | Original function worked properly\n");
   } else {
     printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Original function didn't return the right information\n");
     return 1;
   }
 
-  if (TestHook("user32.dll", "GetWindowInfo") &&
-#ifdef _WIN64
-      TestHook("user32.dll", "SetWindowLongPtrA") &&
-      TestHook("user32.dll", "SetWindowLongPtrW") &&
-#else
-      TestHook("user32.dll", "SetWindowLongA") &&
-      TestHook("user32.dll", "SetWindowLongW") &&
-#endif
-      TestHook("user32.dll", "TrackPopupMenu") &&
-      TestHook("ntdll.dll", "LdrLoadDll")) {
-    printf("TEST-PASS | WindowsDllInterceptor | all checks passed\n");
-    return 0;
-  }
-
-  return 1;
+  printf("TEST-PASS | WindowsDllInterceptor | all checks passed\n");
+  return 0;
 }