HookBase.cpp
上传用户:kittypts
上传日期:2018-02-11
资源大小:241k
文件大小:5k
源码类别:

PlugIns编程

开发平台:

Visual C++

  1. /*
  2. *
  3. *  This file is
  4. *    Copyright (C) 2006-2008 Nektra S.A.
  5. *  
  6. *  This program is free software; you can redistribute it and/or modify
  7. *  it under the terms of the GNU Lesser General Public License as published by
  8. *  the Free Software Foundation; either version 2, or (at your option)
  9. *  any later version.
  10. *  
  11. *  This program is distributed in the hope that it will be useful,
  12. *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. *  GNU General Public License for more details.
  15. *  
  16. */
  17. #include "HookBase.h"
  18. #include "Utils.h"
  19. #include "LocalFunction.h"
  20. #include "NtApi.h"
  21. #include "types.h"
  22. ///
  23. /// Statics:
  24. ///
  25. BOOL NktHookBase::hooksDisabled = FALSE;
  26. ///
  27. /// Helpers:
  28. ///
  29. #define EV_LOCK(evName) (NktNtApi::CreateEvent(NULL, FALSE, FALSE, evName))
  30. #define EV_UNLOCK(h) ((h)? NktNtApi::CloseHandle(h) : 0)
  31. #define EV_GET(evName) (NktNtApi::OpenEvent(EVENT_ALL_ACCESS, FALSE, evName))
  32. ///
  33. /// Constructors / Destructor
  34. ///
  35. NktHookBase::NktHookBase()
  36. {
  37. _disabled = TRUE;
  38. _userData = 0;
  39. _flags = 0;
  40. }
  41. NktHookBase::~NktHookBase() {}
  42. ///
  43. /// CAPIHook::InternalHandler [fastcall]
  44. ///
  45. void NktHookBase::InternalHandler(NktRegisters* registers, INT_PTR tag)
  46. {
  47. NktHandlerParams handlerParams;
  48. handlerParams.userData = _userData;
  49. handlerParams.teb = NktNtApi::CurrentTEB();
  50. handlerParams.handlerData = 0;
  51. handlerParams.callCookie = (INT_PTR)&handlerParams.handlerData;
  52. handlerParams.iHook = this;
  53. //Init context:
  54. //FIXME: functions with no param should set pms in NULL.
  55. NktHookCallContext* ctx = &handlerParams.context;
  56. ctx->pms = (void*)(registers->ESP + sizeof(INT_PTR));
  57. ctx->regs = registers;
  58. ctx->state = _ctx_none;
  59. ctx->tag = tag;
  60. //Ignore call if report is disabled:
  61. BOOL noreport = _disabled || hooksDisabled || !_handler.isValid() || IsThreadDisabled();
  62. if (noreport)
  63. {
  64. CallFunction(ctx);
  65. return;
  66. }
  67. if(_flags & (_call_before | _call_custom))
  68. {
  69. handlerParams.flags = _flags & (_call_before | _call_custom);
  70. LPCVOID pm = &handlerParams;
  71. _handler.Call(&pm, sizeof(pm));
  72. }
  73. if (!(_flags & _call_async) && (ctx->state == _ctx_none))
  74. {
  75. CallFunction(ctx);
  76. }
  77. if ((_flags & _call_after) && !(_flags & _call_async) && (ctx->state & _ctx_called))
  78. {
  79. handlerParams.flags = _call_after;
  80. LPCVOID pm = &handlerParams;
  81. _handler.Call(&pm, sizeof(pm));
  82. }
  83. }
  84. ///
  85. /// CAPIHook::CallFunction
  86. ///
  87. void NktHookBase::CallFunction(NktHookCallContext* ctx)
  88. {
  89. _ASSERT(ctx && !(ctx->state & (_ctx_called | _ctx_skip_call)));
  90. RawCallFunction(ctx);
  91. ctx->state |= _ctx_called;
  92. }
  93. ///
  94. /// CAPIHook::SkipCall
  95. ///
  96. void NktHookBase::SkipCall(NktHookCallContext* ctx, INT_PTR retVal)
  97. {
  98. //FIXME: Extend to other calling conventions. Ex: __cdecl returns in fd0 with floating point.
  99. ctx->regs->EAX = retVal; 
  100. ctx->state |= _ctx_skip_call;
  101. }
  102. ///
  103. /// Handler
  104. ///
  105. void NktHookBase::SetHandler(const NktLocalFunction& fnc)
  106. _handler = fnc;
  107. }
  108. const NktFunctionWrapper& NktHookBase::GetHandler() const { return _handler; }
  109. ///
  110. /// Flags
  111. ///
  112. void NktHookBase::SetFlags(int f) { InterlockedExchange((LONG*)&_flags , f); }
  113. int NktHookBase::GetFlags() const { return _flags; }
  114. ///
  115. /// UserData
  116. ///
  117. void NktHookBase::SetUserData(INT_PTR data) { InterlockedExchange((LONG*)&_userData, (LONG)data); }
  118. INT_PTR NktHookBase::GetUserData() const { return _userData; }
  119. ///
  120. /// Enabled
  121. ///
  122. void NktHookBase::SetEnabled(BOOL b) { InterlockedExchange((LONG*)&_disabled, !b); }
  123. BOOL NktHookBase::GetEnabled() const { return !_disabled; }
  124. ///
  125. /// CAPIHook: Global Enabled.
  126. ///
  127. void NktHookBase::SetGlobalEnabled(BOOL enable) { InterlockedExchange((LONG*)&hooksDisabled, !enable); }
  128. BOOL NktHookBase::GetGlobalEnabled() { return !hooksDisabled; }
  129. ///
  130. /// CHookBase::SetReturnValue
  131. ///
  132. void NktHookBase::SetReturnValue(NktHookCallContext* ctx, INT_PTR retVal)
  133. {
  134. _ASSERT(ctx);
  135. ctx->regs->EAX = retVal;
  136. }
  137. ///
  138. /// CHookBase::SetLastError
  139. ///
  140. void NktHookBase::SetLastError(NktHookCallContext* ctx, INT_PTR err)
  141. {
  142. _ASSERT(ctx);
  143. ctx->regs->lastError = err;
  144. }
  145. ///
  146. /// CAPIHook::DisableThreadReportes [static]
  147. ///
  148. HANDLE NktHookBase::DisableThreadReports()
  149. {
  150. WCHAR buffer[EV_NAME_SIZE];
  151. NktUtils::GetThreadString(buffer);
  152. return EV_LOCK(buffer);
  153. }
  154. ///
  155. /// CAPIHook::RestoreThreadReports [static]
  156. ///
  157. void NktHookBase::RestoreThreadReports(HANDLE h)
  158. {
  159. EV_UNLOCK(h);
  160. }
  161. ///
  162. /// CAPIHook::IsThreadDisabled [static]
  163. ///
  164. BOOL NktHookBase::IsThreadDisabled()
  165. {
  166. WCHAR buffer[EV_NAME_SIZE];
  167. NktUtils::GetThreadString(buffer);
  168. HANDLE hLock = EV_GET(buffer);
  169. BOOL ret = (hLock != NULL);
  170. EV_UNLOCK(hLock);
  171. return ret;
  172. }