当调用DLL钩子函数的原始版本时,我得到无限递归

时间:2015-03-06 00:17:25

标签: c++ winapi dll

我想覆盖某些winapi函数SetWindowPos的部分功能。我只是试图阻止任何Z轴操作 - 把窗户放在后面或顶部。我的基本伪代码理念是:

bool NewSetWindowPos(zaxis_argument, ...) {
  return OldSetWindowPos(NULL, ...);
}

我使用Mhook库,它完美无缺。

实现有点笨拙,因为我将变量转换为总是看起来很奇怪的函数:

//Get the function refference for overriding with mhook
PNT_QUERY_SYSTEM_INFORMATION OriginalSetWindowPos = 
  (PNT_QUERY_SYSTEM_INFORMATION)::GetProcAddress( 
  ::GetModuleHandle( L"user32" ), "SetWindowPos" );

我定义了一个遵循原始函数参数count的类型:

//Define type for the original SetWindowPos function
typedef BOOL(*SetWindowPos_type)(
  _In_      HWND hWnd,
  _In_opt_  HWND hWndInsertAfter,
  _In_      int X,
  _In_      int Y,
  _In_      int cx,
  _In_      int cy,
  _In_      UINT uFlags
);

这是我的新功能:

BOOL WINAPI
HookedSetWindowPos(
  _In_      HWND hWnd,
  _In_opt_  HWND hWndInsertAfter,
  _In_      int X,
  _In_      int Y,
  _In_      int cx,
  _In_      int cy,
  _In_      UINT uFlags
  ) {
  //The |SWP_NOZORDER adds flag that instructs the function to ignore any Z-order operations.
  //Ther than Z-order functionality is still available, I just pass the original arguments
  return ((SetWindowPos_type)OriginalSetWindowPos)(hWnd, 0, X, Y, cx, cy, uFlags|SWP_NOZORDER);
}

我在DLL init上挂了那个函数:

  case DLL_PROCESS_ATTACH:
      //Override function
      Mhook_SetHook( (PVOID*)&OriginalSetWindowPos,  HookedSetWindowPos );
      //Force create console window
      createConsole();
      break;

问题是OriginalSetWindowPos以某种方式映射到HookedSetWindowPos。调用SetWindowPos后,HookedSetWindowPos调用OriginalSetWindowPos实际上也是HookedSetWindowPos - 并且永远循环,或者至少直到进程因堆栈溢出而崩溃。

:我在DLL中挂钩函数后如何调用原始函数?

1 个答案:

答案 0 :(得分:2)

好的,为了帮助您解决此问题,我将向您展示此代码。这是原始函数的类型定义,我将其命名为oSetWindowPos,在其下面是即将被挂钩的函数hSetWindowPos

BOOL(__stdcall WINAPI *oSetWindowPos)(
   _In_      HWND hWnd,
   _In_opt_  HWND hWndInsertAfter,
   _In_      int X,
   _In_      int Y,
   _In_      int cx,
   _In_      int cy,
   _In_      UINT uFlags
) = SetWindowPos;

BOOL __stdcall WINAPI hSetWindowPos(HWND hWnd, HWND hWnd_ia, int x, int y, int cx, int cy, UINT uFlags)
{
     OutputDebugStringA(" - Inside setwindowpos trampoline..");
     return oSetWindowPos(hWnd, hWnd_ia, x, y, cx, cy, uFlags);
}

我还没有使用MHook库,虽然我用Google搜索并遇到了basic example of hooking in MHook。似乎MHook与MS Detours(我使用过的库)的工作方式相同。

void Hook() {
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    if (DetourAttach(&(PVOID&)oSetWindowPos, hSetWindowPos) == NO_ERROR)
    {
        OutputDebugStringA(" - setwindowpos succesfully hooked");
    }
    DetourTransactionCommit();
}

正如我之前所说的那样,我还没有使用过MHook,所以这可能是他们身边的问题,但是如果你坚持使用MHook需要使用以下代码来挂钩函数:

BOOL bHook = Mhook_SetHook((PVOID*)&oSetWindowPos, hSetWindowPos);

让我知道它是否适合你。