NtProcessMonitor.cpp
上传用户:jstlsd
上传日期:2007-01-13
资源大小:186k
文件大小:7k
源码类别:

钩子与API截获

开发平台:

Visual C++

  1. //---------------------------------------------------------------------------
  2. //
  3. // NtProcessMonitor.h
  4. //
  5. // SUBSYSTEM: 
  6. // API Hooking system
  7. // MODULE:    
  8. // Implements a thread that uses an NT device driver
  9. //              for monitoring process creation
  10. //
  11. // DESCRIPTION:
  12. //
  13. // AUTHOR: Ivo Ivanov (ivopi@hotmail.com)
  14. //                                                                         
  15. //---------------------------------------------------------------------------
  16. #include "..CommonCommon.h"
  17. #include "NtProcessMonitor.h"
  18. #include "..CommonSysUtils.h"
  19. #include <process.h>
  20. #include <winioctl.h>
  21. #include "NtDriverController.h"
  22. //---------------------------------------------------------------------------
  23. //
  24. // File scope consts and typedefs
  25. //
  26. //---------------------------------------------------------------------------
  27. #define FILE_DEVICE_UNKNOWN             0x00000022
  28. #define IOCTL_UNKNOWN_BASE              FILE_DEVICE_UNKNOWN
  29. #define IOCTL_PROCVIEW_GET_PROCINFO     CTL_CODE(IOCTL_UNKNOWN_BASE, 0x0800, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
  30. //---------------------------------------------------------------------------
  31. //
  32. // Thread function prototype
  33. //
  34. //---------------------------------------------------------------------------
  35. typedef unsigned (__stdcall *PTHREAD_START) (void *);
  36. //---------------------------------------------------------------------------
  37. //
  38. // class CNtProcessMonitor
  39. //
  40. //---------------------------------------------------------------------------
  41. CNtProcessMonitor::CNtProcessMonitor():
  42. m_hShutdownEvent(NULL),
  43. m_hProcessEvent(NULL),
  44. m_bThreadActive(FALSE),
  45. m_dwThreadId(0),
  46. m_hDriver(INVALID_HANDLE_VALUE),
  47. m_pDriverCtl(NULL)
  48. {
  49. if (!IsWindows9x())
  50. m_pDriverCtl = new CNtDriverController();
  51. }
  52. CNtProcessMonitor::~CNtProcessMonitor()
  53. {
  54. delete m_pDriverCtl;
  55. }
  56. //
  57. // Accessor method
  58. //
  59. BOOL CNtProcessMonitor::Get_ThreadActive()
  60. {
  61. CLockMgr<CCSWrapper> lockMgr(m_CritSec, TRUE);
  62. return m_bThreadActive;
  63. }
  64. //
  65. // Accessor method
  66. //
  67. void CNtProcessMonitor::Set_ThreadActive(BOOL val)
  68. {
  69. CLockMgr<CCSWrapper> lockMgr(m_CritSec, TRUE);
  70. m_bThreadActive = val;
  71. }
  72. //
  73. // Accessor method
  74. //
  75. HANDLE CNtProcessMonitor::Get_ShutdownEvent() const
  76. {
  77. return m_hShutdownEvent;
  78. }
  79. //
  80. // Accessor method
  81. //
  82. HANDLE CNtProcessMonitor::Get_ProcessEvent() const
  83. {
  84. return m_hProcessEvent;
  85. }
  86. //
  87. // Activate / Stop the thread which gets the notification from the 
  88. // device driver
  89. //
  90. void CNtProcessMonitor::SetActive(BOOL bVal)
  91. {
  92. if (m_pDriverCtl)
  93. {
  94. if (bVal)
  95. {
  96. if (!Get_ThreadActive())
  97. {
  98. // Terminal Services W2K/XP: The name can have a "Global" 
  99. // prefix to explicitly create the object in the global 
  100. // or session name space.
  101. char szDriverName[MAX_PATH];
  102. if ( IsWindowsNT4() )
  103. strcpy(szDriverName, "\\.\NTProcDrv");
  104. else
  105. strcpy(szDriverName, "\\.\Global\NTProcDrv");
  106. // Try opening the device driver
  107. m_hDriver = CreateFile(
  108. szDriverName,
  109. GENERIC_READ | GENERIC_WRITE, 
  110. FILE_SHARE_READ | FILE_SHARE_WRITE,
  111. 0,                     // Default security
  112. OPEN_EXISTING,
  113. FILE_FLAG_OVERLAPPED,  // Perform asynchronous I/O
  114. 0);                    // No template
  115.         
  116. if(INVALID_HANDLE_VALUE == m_hDriver)
  117. return;
  118.     
  119. m_hShutdownEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
  120. // Attach to KM-created event handle
  121. m_hProcessEvent = ::OpenEvent(
  122. SYNCHRONIZE, FALSE, "NTProcDrvProcessEvent");
  123. _beginthreadex(
  124. (void *)NULL,
  125. (unsigned)0,
  126. (PTHREAD_START)CNtProcessMonitor::ThreadFunc,
  127. (PVOID)this,
  128. (unsigned)0,
  129. (unsigned *)&m_dwThreadId
  130. );
  131. } // if
  132. else
  133. {
  134. if (Get_ThreadActive())
  135. {
  136. ::SetEvent(m_hShutdownEvent);
  137. // Give some time to the injector thread to clean up itself
  138. while (Get_ThreadActive())
  139. {
  140. }
  141. ::CloseHandle(m_hShutdownEvent);
  142. ::CloseHandle(m_hProcessEvent);
  143. m_dwThreadId = 0;
  144. if (NULL != m_hDriver)
  145. ::CloseHandle(m_hDriver);
  146. } // if
  147. } // else
  148. } // if
  149. }
  150. //
  151. // Retrieves data from the driver after received notification 
  152. //
  153. void CNtProcessMonitor::RetrieveProcessInfo(
  154. CALLBACK_INFO& callbackInfo,
  155. CALLBACK_INFO& callbackTemp
  156. )
  157. {
  158. OVERLAPPED ov          = { 0 };
  159. BOOL       bReturnCode = FALSE;
  160. DWORD      dwBytesReturned;
  161.     // Create an event handle for async notification from the driver
  162. ov.hEvent = ::CreateEvent(
  163. NULL,  // Default security
  164. TRUE,  // Manual reset
  165. FALSE, // non-signaled state
  166. NULL
  167. ); 
  168. // Get the process info
  169. bReturnCode = ::DeviceIoControl(
  170. m_hDriver,
  171. IOCTL_PROCVIEW_GET_PROCINFO,
  172. 0, 
  173. 0,
  174. &callbackInfo, sizeof(callbackInfo),
  175. &dwBytesReturned,
  176. &ov
  177. );
  178. // Wait here for the event handle to be set, indicating
  179. // that the IOCTL processing is completed.
  180. bReturnCode = ::GetOverlappedResult(
  181. m_hDriver, 
  182. &ov,
  183. &dwBytesReturned, 
  184. TRUE
  185. );
  186. ::CloseHandle(ov.hEvent);
  187. // Pevent getting duplicated events
  188. if((callbackTemp.ParentId  != callbackInfo.ParentId) ||
  189.    (callbackTemp.ProcessId != callbackInfo.ProcessId) ||
  190.    (callbackTemp.bCreate    != callbackInfo.bCreate))
  191. {
  192. if(callbackInfo.bCreate)
  193. // Process creation notification
  194. OnCreateProcess((DWORD)callbackInfo.ProcessId);
  195. else
  196. // Process termination notification
  197. OnTerminateProcess((DWORD)callbackInfo.ProcessId);
  198. } // if
  199. // Store the data for next time
  200. callbackTemp = callbackInfo;
  201. }
  202. //
  203. // The thread function 
  204. //
  205. unsigned __stdcall CNtProcessMonitor::ThreadFunc(void* pvParam)
  206. {
  207. CNtProcessMonitor* me = (CNtProcessMonitor*)pvParam;
  208. CALLBACK_INFO callbackInfo, callbackTemp;
  209. DWORD dwResult; 
  210. HANDLE handles[2] = 
  211. {
  212. me->Get_ShutdownEvent(),
  213. me->Get_ProcessEvent()
  214. };
  215. me->Set_ThreadActive(TRUE);
  216. while (TRUE)
  217. {
  218. dwResult = ::WaitForMultipleObjects(
  219. sizeof(handles)/sizeof(handles[0]), // number of handles in array
  220. &handles[0],                        // object-handle array
  221. FALSE,                              // wait option
  222. INFINITE                            // time-out interval
  223. );
  224. //
  225. // the system shuts down
  226. //
  227. if (handles[dwResult - WAIT_OBJECT_0] == me->Get_ShutdownEvent())
  228. break;
  229. //
  230. // A new process has been just created / or terminated
  231. //
  232. else
  233. me->RetrieveProcessInfo(
  234. callbackInfo, 
  235. callbackTemp
  236. );
  237. } // while
  238. me->Set_ThreadActive( FALSE );
  239. _endthreadex(0);
  240. return 0;
  241. }
  242. //----------------------------End of the file -------------------------------