Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorvald Natvig <slicer@users.sourceforge.net>2010-02-28 20:15:56 +0300
committerThorvald Natvig <slicer@users.sourceforge.net>2010-02-28 20:16:27 +0300
commitd44c84cb1aa6883864c4669cc6b0b9262a157c59 (patch)
treedcd5f854a827f80e4bd82f030feab74459a784ec /overlay
parentf223a8292f93db1e287b2132758090cb92dfee0f (diff)
This is not the window you are looking for
Diffstat (limited to 'overlay')
-rw-r--r--overlay/HardHook.cpp283
-rw-r--r--overlay/HardHook.h70
-rw-r--r--overlay/lib.cpp219
-rw-r--r--overlay/lib.h23
-rw-r--r--overlay/overlay.pro4
5 files changed, 356 insertions, 243 deletions
diff --git a/overlay/HardHook.cpp b/overlay/HardHook.cpp
new file mode 100644
index 000000000..5f11f1f7f
--- /dev/null
+++ b/overlay/HardHook.cpp
@@ -0,0 +1,283 @@
+/* Copyright (C) 2005-2010, Thorvald Natvig <thorvald@natvig.com>
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ - Neither the name of the Mumble Developers nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "HardHook.h"
+
+void *HardHook::pCode = NULL;
+unsigned int HardHook::uiCode = 0;
+
+static void __cdecl ods(const char *format, ...) {
+ char buf[4096], *p = buf;
+ va_list args;
+
+ va_start(args, format);
+ int len = _vsnprintf_s(p, sizeof(buf) - 1, _TRUNCATE, format, args);
+ va_end(args);
+
+ if (len <= 0)
+ return;
+
+ p += len;
+
+ while (p > buf && isspace(p[-1]))
+ *--p = '\0';
+
+ *p++ = '\r';
+ *p++ = '\n';
+ *p = '\0';
+
+ OutputDebugStringA(buf);
+}
+
+
+HardHook::HardHook() {
+ int i;
+ baseptr = NULL;
+ for (i=0;i<6;i++)
+ orig[i]=replace[i]=0;
+}
+
+HardHook::HardHook(voidFunc func, voidFunc replacement) {
+ int i;
+ baseptr = NULL;
+ for (i=0;i<6;i++)
+ orig[i]=replace[i]=0;
+ setup(func, replacement);
+}
+
+static unsigned int modrmbytes(unsigned char a, unsigned char b) {
+ unsigned char lower = (a & 0x0f);
+ if (a >= 0xc0) {
+ return 0;
+ } else if (a >= 0x80) {
+ if ((lower == 4) || (lower == 12))
+ return 5;
+ else
+ return 4;
+ } else if (a >= 0x40) {
+ if ((lower == 4) || (lower == 12))
+ return 2;
+ else
+ return 1;
+
+ } else {
+ if ((lower == 4) || (lower == 12)) {
+ if ((b & 0x07) == 0x05)
+ return 5;
+ else
+ return 1;
+ } else if ((lower == 5) || (lower == 13))
+ return 4;
+ return 0;
+ }
+}
+
+void *HardHook::cloneCode(void **porig) {
+ if (! pCode || uiCode > 4000) {
+ uiCode = 0;
+ pCode = VirtualAlloc(NULL, 4096, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+ }
+
+ unsigned char *o = (unsigned char *) *porig;
+ unsigned char *n = (unsigned char *) pCode;
+ n += uiCode;
+ unsigned int idx = 0;
+
+ while (*o == 0xe9) {
+ int *iptr = reinterpret_cast<int *>(o+1);
+ o += *iptr + 5;
+
+ ods("HardHook: Chaining from %p to %p", *porig, o);
+ *porig = o;
+ }
+
+ do {
+ unsigned char opcode = o[idx];
+ unsigned char a = o[idx+1];
+ unsigned char b = o[idx+2];
+ unsigned int extra = 0;
+
+ n[idx] = opcode;
+ idx++;
+
+ switch (opcode) {
+ case 0x50: // PUSH
+ case 0x51:
+ case 0x52:
+ case 0x53:
+ case 0x54:
+ case 0x55:
+ case 0x56:
+ case 0x57:
+ case 0x58: // POP
+ case 0x59:
+ case 0x5a:
+ case 0x5b:
+ case 0x5c:
+ case 0x5d:
+ case 0x5e:
+ case 0x5f:
+ break;
+ case 0x68:
+ extra = 4;
+ break;
+ case 0x81: // CMP immediate
+ extra = modrmbytes(a,b) + 5;
+ break;
+ case 0x83: // CMP
+ extra = modrmbytes(a,b) + 2;
+ break;
+ case 0x8b: // MOV
+ extra = modrmbytes(a,b) + 1;
+ break;
+ default:
+ ods("HardHook: Unknown opcode at %d: %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x", idx-1, o[0], o[1], o[2], o[3], o[4], o[5], o[6], o[7], o[8], o[9], o[10], o[11]);
+ return NULL;
+ break;
+ }
+ for (unsigned int i=0;i<extra;++i)
+ n[idx+i] = o[idx+i];
+ idx += extra;
+
+ } while (idx < 6);
+
+ n[idx++] = 0xe9;
+ int offs = o - n - 5;
+
+ int *iptr = reinterpret_cast<int *>(&n[idx]);
+ *iptr = offs;
+ idx += 4;
+
+ uiCode += idx;
+ FlushInstructionCache(GetCurrentProcess(), n, idx);
+
+ return n;
+}
+
+void HardHook::setup(voidFunc func, voidFunc replacement) {
+ int i;
+ DWORD oldProtect, restoreProtect;
+
+ if (baseptr)
+ return;
+
+ unsigned char *fptr = reinterpret_cast<unsigned char *>(func);
+ unsigned char *nptr = reinterpret_cast<unsigned char *>(replacement);
+
+ ods("HardHook: Asked to replace %p with %p", func, replacement);
+
+ if (VirtualProtect(fptr, 16, PAGE_EXECUTE_READ, &oldProtect)) {
+ call = (voidFunc) cloneCode((void **) &fptr);
+
+ if (call) {
+ bTrampoline = true;
+ } else {
+ bTrampoline = false;
+ call = func;
+ }
+
+ unsigned char **iptr = reinterpret_cast<unsigned char **>(&replace[1]);
+ *iptr = nptr;
+ replace[0] = 0x68;
+ replace[5] = 0xc3;
+
+ for (i=0;i<6;i++)
+ orig[i]=fptr[i];
+
+ baseptr = fptr;
+ inject(true);
+
+ VirtualProtect(fptr, 16, oldProtect, &restoreProtect);
+ } else {
+ ods("Failed initial vprotect");
+ }
+}
+
+void HardHook::setupInterface(IUnknown *unkn, LONG funcoffset, voidFunc replacement) {
+ ods("HardHook: Replacing %p function #%ld", unkn, funcoffset);
+ void **ptr = reinterpret_cast<void **>(unkn);
+ ptr = reinterpret_cast<void **>(ptr[0]);
+ setup(reinterpret_cast<voidFunc>(ptr[funcoffset]), replacement);
+}
+
+void HardHook::inject(bool force) {
+ DWORD oldProtect, restoreProtect;
+ int i;
+
+ if (! baseptr)
+ return;
+ if (! force && bTrampoline)
+ return;
+
+ if (VirtualProtect(baseptr, 6, PAGE_EXECUTE_READWRITE, &oldProtect)) {
+ for (i=0;i<6;i++)
+ baseptr[i] = replace[i];
+ VirtualProtect(baseptr, 6, oldProtect, &restoreProtect);
+ FlushInstructionCache(GetCurrentProcess(),baseptr, 6);
+ }
+ for (i=0;i<6;i++)
+ if (baseptr[i] != replace[i])
+ ods("HH: Injection failure at byte %d", i);
+}
+
+void HardHook::restore(bool force) {
+ DWORD oldProtect, restoreProtect;
+ int i;
+
+ if (! baseptr)
+ return;
+ if (! force && bTrampoline)
+ return;
+
+ if (VirtualProtect(baseptr, 6, PAGE_EXECUTE_READWRITE, &oldProtect)) {
+ for (i=0;i<6;i++)
+ baseptr[i] = orig[i];
+ VirtualProtect(baseptr, 6, oldProtect, &restoreProtect);
+ FlushInstructionCache(GetCurrentProcess(),baseptr, 6);
+ }
+}
+
+void HardHook::print() {
+ ods("HardHook: %02x %02x %02x %02x %02x => %02x %02x %02x %02x %02x (%02x %02x %02x %02x %02x)",
+ orig[0], orig[1], orig[2], orig[3], orig[4],
+ replace[0], replace[1], replace[2], replace[3], replace[4],
+ baseptr[0], baseptr[1], baseptr[2], baseptr[3], baseptr[4]);
+}
+
+void HardHook::check() {
+ if (memcmp(baseptr, replace, 6) != 0) {
+ if (memcmp(baseptr, orig, 6) == 0) {
+ ods("HH: Restoring function %p", baseptr);
+ inject(true);
+ } else {
+ ods("HH: Function %p replaced by third party. Lost.");
+ }
+ }
+}
diff --git a/overlay/HardHook.h b/overlay/HardHook.h
new file mode 100644
index 000000000..86488092a
--- /dev/null
+++ b/overlay/HardHook.h
@@ -0,0 +1,70 @@
+/* Copyright (C) 2005-2010, Thorvald Natvig <thorvald@natvig.com>
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ - Neither the name of the Mumble Developers nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef _HARDHOOK_H
+#define _HARDHOOK_H
+
+#define _UNICODE
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0501
+#endif
+#include <stdio.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <windows.h>
+#include <math.h>
+#include <map>
+#include <vector>
+#include <string>
+
+typedef void *(*voidFunc)();
+
+struct HardHook {
+ unsigned char *baseptr;
+ unsigned char orig[6];
+ unsigned char replace[6];
+ bool bTrampoline;
+ voidFunc call;
+
+ static void *pCode;
+ static unsigned int uiCode;
+
+ HardHook();
+ HardHook(voidFunc func, voidFunc replacement);
+ void *cloneCode(void **orig);
+ void setup(voidFunc func, voidFunc replacement);
+ void setupInterface(IUnknown *intf, LONG funcoffset, voidFunc replacement);
+ void inject(bool force = false);
+ void restore(bool force = false);
+ void print();
+ void check();
+};
+
+#endif
diff --git a/overlay/lib.cpp b/overlay/lib.cpp
index 380158434..658abeda0 100644
--- a/overlay/lib.cpp
+++ b/overlay/lib.cpp
@@ -40,228 +40,9 @@ static BOOL bDebug = FALSE;
static HardHook hhLoad;
static HardHook hhLoadW;
-void *HardHook::pCode = NULL;
-unsigned int HardHook::uiCode = 0;
static SharedData *sd;
-HardHook::HardHook() {
- int i;
- baseptr = NULL;
- for (i=0;i<6;i++)
- orig[i]=replace[i]=0;
-}
-
-static unsigned int modrmbytes(unsigned char a, unsigned char b) {
- unsigned char lower = (a & 0x0f);
- if (a >= 0xc0) {
- return 0;
- } else if (a >= 0x80) {
- if ((lower == 4) || (lower == 12))
- return 5;
- else
- return 4;
- } else if (a >= 0x40) {
- if ((lower == 4) || (lower == 12))
- return 2;
- else
- return 1;
-
- } else {
- if ((lower == 4) || (lower == 12)) {
- if ((b & 0x07) == 0x05)
- return 5;
- else
- return 1;
- } else if ((lower == 5) || (lower == 13))
- return 4;
- return 0;
- }
-}
-
-void *HardHook::cloneCode(void **porig) {
- if (! pCode || uiCode > 4000) {
- uiCode = 0;
- pCode = VirtualAlloc(NULL, 4096, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
- }
-
- unsigned char *o = (unsigned char *) *porig;
- unsigned char *n = (unsigned char *) pCode;
- n += uiCode;
- unsigned int idx = 0;
-
- while (*o == 0xe9) {
- int *iptr = reinterpret_cast<int *>(o+1);
- o += *iptr + 5;
-
- ods("Chaining from %p to %p", *porig, o);
- *porig = o;
- }
-
- do {
- unsigned char opcode = o[idx];
- unsigned char a = o[idx+1];
- unsigned char b = o[idx+2];
- unsigned int extra = 0;
-
- n[idx] = opcode;
- idx++;
-
- switch (opcode) {
- case 0x50: // PUSH
- case 0x51:
- case 0x52:
- case 0x53:
- case 0x54:
- case 0x55:
- case 0x56:
- case 0x57:
- case 0x58: // POP
- case 0x59:
- case 0x5a:
- case 0x5b:
- case 0x5c:
- case 0x5d:
- case 0x5e:
- case 0x5f:
- break;
- case 0x68:
- extra = 4;
- break;
- case 0x81: // CMP immediate
- extra = modrmbytes(a,b) + 5;
- break;
- case 0x83: // CMP
- extra = modrmbytes(a,b) + 2;
- break;
- case 0x8b: // MOV
- extra = modrmbytes(a,b) + 1;
- break;
- default:
- fods("Unknown opcode at %d: %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x", idx-1, o[0], o[1], o[2], o[3], o[4], o[5], o[6], o[7], o[8], o[9], o[10], o[11]);
- return NULL;
- break;
- }
- for (unsigned int i=0;i<extra;++i)
- n[idx+i] = o[idx+i];
- idx += extra;
-
- } while (idx < 6);
-
- n[idx++] = 0xe9;
- int offs = o - n - 5;
-
- int *iptr = reinterpret_cast<int *>(&n[idx]);
- *iptr = offs;
- idx += 4;
-
- uiCode += idx;
- FlushInstructionCache(GetCurrentProcess(), n, idx);
-
- return n;
-}
-
-void HardHook::setup(voidFunc func, voidFunc replacement) {
- int i;
- DWORD oldProtect, restoreProtect;
-
- if (baseptr)
- return;
-
- unsigned char *fptr = reinterpret_cast<unsigned char *>(func);
- unsigned char *nptr = reinterpret_cast<unsigned char *>(replacement);
-
- ods("HH: Asked to replace %p with %p", func, replacement);
-
- if (VirtualProtect(fptr, 16, PAGE_EXECUTE_READ, &oldProtect)) {
- call = (voidFunc) cloneCode((void **) &fptr);
-
- if (call) {
- bTrampoline = true;
- } else {
- bTrampoline = false;
- call = func;
- }
-
- unsigned char **iptr = reinterpret_cast<unsigned char **>(&replace[1]);
- *iptr = nptr;
- replace[0] = 0x68;
- replace[5] = 0xc3;
-
- for (i=0;i<6;i++)
- orig[i]=fptr[i];
-
- baseptr = fptr;
- inject(true);
-
- VirtualProtect(fptr, 16, oldProtect, &restoreProtect);
- } else {
- ods("Failed initial vprotect");
- }
-}
-
-void HardHook::setupInterface(IUnknown *unkn, LONG funcoffset, voidFunc replacement) {
- ods("HH: Replacing %p function #%ld", unkn, funcoffset);
- void **ptr = reinterpret_cast<void **>(unkn);
- ptr = reinterpret_cast<void **>(ptr[0]);
- setup(reinterpret_cast<voidFunc>(ptr[funcoffset]), replacement);
-}
-
-void HardHook::inject(bool force) {
- DWORD oldProtect, restoreProtect;
- int i;
-
- if (! baseptr)
- return;
- if (! force && bTrampoline)
- return;
-
- if (VirtualProtect(baseptr, 6, PAGE_EXECUTE_READWRITE, &oldProtect)) {
- for (i=0;i<6;i++)
- baseptr[i] = replace[i];
- VirtualProtect(baseptr, 6, oldProtect, &restoreProtect);
- FlushInstructionCache(GetCurrentProcess(),baseptr, 6);
- }
- for (i=0;i<6;i++)
- if (baseptr[i] != replace[i])
- ods("HH: Injection failure at byte %d", i);
-}
-
-void HardHook::restore(bool force) {
- DWORD oldProtect, restoreProtect;
- int i;
-
- if (! baseptr)
- return;
- if (! force && bTrampoline)
- return;
-
- if (VirtualProtect(baseptr, 6, PAGE_EXECUTE_READWRITE, &oldProtect)) {
- for (i=0;i<6;i++)
- baseptr[i] = orig[i];
- VirtualProtect(baseptr, 6, oldProtect, &restoreProtect);
- FlushInstructionCache(GetCurrentProcess(),baseptr, 6);
- }
-}
-
-void HardHook::print() {
- ods("HH: %02x %02x %02x %02x %02x => %02x %02x %02x %02x %02x (%02x %02x %02x %02x %02x)",
- orig[0], orig[1], orig[2], orig[3], orig[4],
- replace[0], replace[1], replace[2], replace[3], replace[4],
- baseptr[0], baseptr[1], baseptr[2], baseptr[3], baseptr[4]);
-}
-
-void HardHook::check() {
- if (memcmp(baseptr, replace, 6) != 0) {
- if (memcmp(baseptr, orig, 6) == 0) {
- ods("HH: Restoring function %p", baseptr);
- inject(true);
- } else {
- ods("HH: Function %p replaced by third party. Lost.");
- }
- }
-}
-
FakeInterface::FakeInterface(IUnknown *orig, int entries) {
this->pOriginal = orig;
pAssembly = VirtualAlloc(NULL, entries * 256, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
diff --git a/overlay/lib.h b/overlay/lib.h
index 216c6ad8c..f06b32957 100644
--- a/overlay/lib.h
+++ b/overlay/lib.h
@@ -42,6 +42,7 @@
#include <vector>
#include <string>
#include "overlay.h"
+#include "HardHook.h"
#define lround(x) static_cast<long int>((x) + (((x) >= 0.0) ? 0.5 : -0.5))
@@ -50,28 +51,6 @@ using namespace std;
void __cdecl fods(const char *format, ...);
void __cdecl ods(const char *format, ...);
-typedef void *(*voidFunc)();
-
-struct HardHook {
- unsigned char *baseptr;
- unsigned char orig[6];
- unsigned char replace[6];
- bool bTrampoline;
- voidFunc call;
-
- static void *pCode;
- static unsigned int uiCode;
-
- HardHook();
- void *cloneCode(void **orig);
- void setup(voidFunc func, voidFunc replacement);
- void setupInterface(IUnknown *intf, LONG funcoffset, voidFunc replacement);
- void inject(bool force = false);
- void restore(bool force = false);
- void print();
- void check();
-};
-
struct Direct3D9Data {
int iOffsetCreate;
int iOffsetCreateEx;
diff --git a/overlay/overlay.pro b/overlay/overlay.pro
index 4b5c52cff..59d919616 100644
--- a/overlay/overlay.pro
+++ b/overlay/overlay.pro
@@ -5,9 +5,9 @@ CONFIG -= qt
CONFIG *= dll shared debug_and_release warn_on
CONFIG -= embed_manifest_dll
TARGET = mumble_ol
-SOURCES = lib.cpp d3d9.cpp d3d10.cpp opengl.cpp
+SOURCES = lib.cpp d3d9.cpp d3d10.cpp opengl.cpp HardHook.cpp
EFFECTS = overlay.fx
-DIST = overlay.h overlay.fx
+DIST = overlay.h overlay.fx HardHook.h
DEFINES -= UNICODE