netredirect.cpp
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:18k
源码类别:

外挂编程

开发平台:

Windows_Unix

  1. /*
  2.  * This DLL is "injected" into the RO client's address space.
  3.  * Once injected, we intercept all network traffic and redirect
  4.  * some of it to Kore.
  5.  */
  6. #include <stdio.h>
  7. #include "common.h"
  8. #include <string>
  9. #include <string.h>
  10. using namespace std;
  11. MyRecvProc OriginalRecvProc = (MyRecvProc) recv;
  12. MySendProc OriginalSendProc = (MySendProc) send;
  13. MyRecvFromProc OriginalRecvFromProc = (MyRecvFromProc) recvfrom;
  14. MySendToProc OriginalSendToProc = (MySendToProc) sendto;
  15. MyConnectProc OriginalConnectProc = (MyConnectProc) connect;
  16. MySelectProc OriginalSelectProc = (MySelectProc) select;
  17. MyWSARecvProc OriginalWSARecvProc = (MyWSARecvProc) WSARecv;
  18. MyWSARecvFromProc OriginalWSARecvFromProc = (MyWSARecvFromProc) WSARecvFrom;
  19. MyWSASendProc OriginalWSASendProc = (MyWSASendProc) WSASend;
  20. MyWSASendToProc OriginalWSASendToProc = (MyWSASendToProc) WSASendTo;
  21. MyWSAAsyncSelectProc OriginalWSAAsyncSelectProc = (MyWSAAsyncSelectProc) WSAAsyncSelect;
  22. MyGetProcAddressProc OriginalGetProcAddressProc = (MyGetProcAddressProc) GetProcAddress;
  23. bool enableDebug = false;
  24. // Connection to the X-Kore server that Kore created
  25. static SOCKET koreClient = INVALID_SOCKET;
  26. static bool koreClientIsAlive = false;
  27. static CRITICAL_SECTION CS_koreClientIsAlive;
  28. static bool dataAvailableFromKore = false;
  29. static bool dataAvailableFromKore2 = false;
  30. static CRITICAL_SECTION CS_dataAvailableFromKore;
  31. static SOCKET roServer = INVALID_SOCKET;
  32. static CRITICAL_SECTION CS_ro;
  33. static CRITICAL_SECTION CS_rosend;
  34. static CRITICAL_SECTION CS_send;
  35. static string roSendBuf(""); // Data to send to the RO client
  36. static string xkoreSendBuf(""); // Data to send to the X-Kore server
  37. #define SLEEP_TIME 10
  38. // Process a packet that the X-Kore server sent us
  39. static void
  40. processPacket (Packet *packet)
  41. {
  42. switch (packet->ID) {
  43. case 'S': // Send a packet to the RO server
  44. EnterCriticalSection (&CS_ro);
  45. if (roServer != INVALID_SOCKET && isConnected (roServer))
  46. OriginalSendProc (roServer, packet->data, packet->len, 0);
  47. LeaveCriticalSection (&CS_ro);
  48. break;
  49. case 'R': // Fool the RO client into thinking that we got a packet from the RO server
  50. // We copy the data in this packet into a string
  51. // Next time the RO client calls recv(), this packet will be returned, along with
  52. // whatever data the RO server sent
  53. EnterCriticalSection (&CS_rosend);
  54. roSendBuf.append (packet->data, packet->len);
  55. LeaveCriticalSection (&CS_rosend);
  56. dataAvailableFromKore2 = true;
  57. break;
  58. case 'K': default: // Keep-alive
  59. break;
  60. }
  61. }
  62. // Handles the connection between the RO client (this process) and the X-Kore server
  63. // Note that this function is run in a thread and never exits
  64. static void
  65. koreConnectionMain ()
  66. {
  67. #define BUF_SIZE 1024 * 32
  68. //#define TIMEOUT 10000
  69. #define TIMEOUT 600000
  70. #define PING_INTERVAL 5000
  71. #define RECONNECT_INTERVAL 3000
  72. char buf[BUF_SIZE + 1];
  73. char pingPacket[3];
  74. unsigned short pingPacketLength = 0;
  75. DWORD koreClientTimeout, koreClientPingTimeout, reconnectTimeout;
  76. string koreClientRecvBuf;
  77. debug ("Thread startedn");
  78. koreClientTimeout = GetTickCount ();
  79. koreClientPingTimeout = GetTickCount ();
  80. reconnectTimeout = 0;
  81. memcpy (pingPacket, "K", 1);
  82. memcpy (pingPacket + 1, &pingPacketLength, 2);
  83. while (1) {
  84. bool isAlive;
  85. bool isAliveChanged = false;
  86. // Attempt to connect to the X-Kore server if necessary
  87. EnterCriticalSection (&CS_koreClientIsAlive);
  88. koreClientIsAlive = koreClient != INVALID_SOCKET;
  89. isAlive = koreClientIsAlive; // keep a local copy of that variable so we don't have to enter critical sections over and over
  90. LeaveCriticalSection (&CS_koreClientIsAlive);
  91. if ((!isAlive || !isConnected (koreClient) || GetTickCount () - koreClientTimeout > TIMEOUT)
  92.   && GetTickCount () - reconnectTimeout > RECONNECT_INTERVAL) {
  93. debug ("Connecting to X-Kore server...n");
  94. if (koreClient != INVALID_SOCKET)
  95. closesocket (koreClient);
  96. koreClient = createSocket (XKORE_SERVER_PORT);
  97. isAlive = koreClient != INVALID_SOCKET;
  98. isAliveChanged = true;
  99. if (!isAlive)
  100. debug ("Failedn");
  101. else
  102. koreClientTimeout = GetTickCount ();
  103. reconnectTimeout = GetTickCount ();
  104. }
  105. // Receive data from the X-Kore server
  106. if (isAlive) {
  107. int ret;
  108. ret = readSocket (koreClient, buf, BUF_SIZE);
  109. if (ret == SF_CLOSED) {
  110. // Connection closed
  111. debug ("X-Kore server exitedn");
  112. closesocket (koreClient);
  113. koreClient = INVALID_SOCKET;
  114. isAlive = false;
  115. isAliveChanged = true;
  116. } else if (ret > 0) {
  117. // Data available
  118. Packet *packet;
  119. int next = 0;
  120. koreClientRecvBuf.append (buf, ret);
  121. while ((packet = unpackPacket (koreClientRecvBuf.c_str (), koreClientRecvBuf.size (), next))) {
  122. // Packet is complete
  123. processPacket (packet);
  124. free (packet);
  125. koreClientRecvBuf.erase (0, next);
  126. }
  127. if (dataAvailableFromKore2) {
  128. EnterCriticalSection (&CS_dataAvailableFromKore);
  129. dataAvailableFromKore = true;
  130. LeaveCriticalSection (&CS_dataAvailableFromKore);
  131. }
  132. // Update timeout
  133. koreClientTimeout = GetTickCount ();
  134. }
  135. }
  136. // Check whether we have data to send to the X-Kore server
  137. // This data originates from the RO client and is supposed to go to the real RO server
  138. EnterCriticalSection (&CS_send);
  139. if (xkoreSendBuf.size ()) {
  140. if (isAlive) {
  141. OriginalSendProc (koreClient, (char *) xkoreSendBuf.c_str (), xkoreSendBuf.size (), 0);
  142. } else {
  143. Packet *packet;
  144. int next;
  145. // Kore is not running; send it to the RO server instead,
  146. // if this packet is supposed to go to the RO server ('S')
  147. // Ignore packets that are meant for Kore ('R')
  148. EnterCriticalSection (&CS_ro);
  149. while ((packet = unpackPacket (xkoreSendBuf.c_str (), xkoreSendBuf.size (), next))) {
  150. if (packet->ID == 'S')
  151. OriginalSendProc (roServer, (char *) packet->data, packet->len, 0);
  152. free (packet);
  153. xkoreSendBuf.erase (0, next);
  154. }
  155. LeaveCriticalSection (&CS_ro);
  156. }
  157. xkoreSendBuf.erase ();
  158. }
  159. LeaveCriticalSection (&CS_send);
  160. // Ping the X-Kore server to keep the connection alive
  161. if (koreClientIsAlive && GetTickCount () - koreClientPingTimeout > PING_INTERVAL) {
  162. OriginalSendProc (koreClient, pingPacket, 3, 0);
  163. koreClientPingTimeout = GetTickCount ();
  164. }
  165. if (isAliveChanged) {
  166. EnterCriticalSection (&CS_koreClientIsAlive);
  167. koreClientIsAlive = isAlive;
  168. LeaveCriticalSection (&CS_koreClientIsAlive);
  169. }
  170. Sleep (SLEEP_TIME);
  171. }
  172. }
  173. /*********** Faked functions ************/
  174. int WINAPI
  175. MyWSASend (SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
  176. {
  177. return OriginalWSASendProc(s,lpBuffers,dwBufferCount,lpNumberOfBytesSent,dwFlags,lpOverlapped,lpCompletionRoutine);
  178. }
  179. int WINAPI
  180. MyWSASendTo (SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, struct sockaddr* lpTo, int iToLen, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) {
  181. return OriginalWSASendToProc(s,lpBuffers,dwBufferCount,lpNumberOfBytesSent,dwFlags,lpTo,iToLen,lpOverlapped,lpCompletionRoutine);
  182. }
  183. int WINAPI
  184. MyWSARecv (SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
  185. {
  186. return OriginalWSARecvProc(s,lpBuffers,dwBufferCount,lpNumberOfBytesRecvd,lpFlags,lpOverlapped,lpCompletionRoutine);
  187. }
  188. int WINAPI
  189. MyWSARecvFrom (SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, struct sockaddr* lpFrom, LPINT lpFromlen, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
  190. {
  191. return OriginalWSARecvFromProc(s,lpBuffers,dwBufferCount,lpNumberOfBytesRecvd,lpFlags,lpFrom,lpFromlen,lpOverlapped,lpCompletionRoutine);
  192. }
  193. int WINAPI
  194. MySelect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout)
  195. {
  196. EnterCriticalSection (&CS_dataAvailableFromKore);
  197. if (dataAvailableFromKore) {
  198. dataAvailableFromKore = false;
  199. LeaveCriticalSection (&CS_dataAvailableFromKore);
  200. return 1;
  201. }
  202. LeaveCriticalSection (&CS_dataAvailableFromKore);
  203. return OriginalSelectProc(nfds, readfds, writefds, exceptfds, timeout);
  204. }
  205. int WINAPI
  206. MySend (SOCKET s, char* buf, int len, int flags)
  207. {
  208. int ret;
  209. // See if the socket to the RO server is still alive, and make
  210. // sure WSAGetLastError() returns the right error if something's wrong
  211. EnterCriticalSection (&CS_ro);
  212. roServer = s;
  213. LeaveCriticalSection (&CS_ro);
  214. ret = OriginalSendProc (s, buf, 0, flags);
  215. if (ret != SOCKET_ERROR & len > 0) {
  216. bool isAlive;
  217. // Is Kore running?
  218. EnterCriticalSection (&CS_koreClientIsAlive);
  219. isAlive = koreClientIsAlive;
  220. LeaveCriticalSection (&CS_koreClientIsAlive);
  221. if (isAlive) {
  222. // Don't send this packet to the RO server; send it to the X-Kore server instead
  223. char *newbuf = (char *) malloc (len + 3);
  224. unsigned short sLen = (unsigned short) len;
  225. memcpy (newbuf, "S", 1);
  226. memcpy (newbuf + 1, &sLen, 2);
  227. memcpy (newbuf + 3, buf, len);
  228. // We put this packet in a string, and let the X-Kore client thread send it
  229. EnterCriticalSection (&CS_send);
  230. xkoreSendBuf.append (newbuf, len + 3);
  231. LeaveCriticalSection (&CS_send);
  232. free (newbuf);
  233. return len;
  234. } else {
  235. // Send packet directly to the RO server
  236. ret = OriginalSendProc (s, buf, len, flags);
  237. return ret;
  238. }
  239. } else
  240. return ret;
  241. }
  242. int WINAPI
  243. MySendTo (SOCKET s, char* buf, int len, int flags, struct sockaddr* to, int tolen)
  244. {
  245. return OriginalSendToProc(s,buf,len,flags, to, tolen);
  246. }
  247. int WINAPI
  248. MyRecv (SOCKET s, char* buf, int len, int flags)
  249. {
  250. int ret = 0;
  251. int ret2 = 0;
  252. EnterCriticalSection (&CS_ro);
  253. roServer = s;
  254. LeaveCriticalSection (&CS_ro);
  255. // Is Kore running?
  256. EnterCriticalSection (&CS_koreClientIsAlive);
  257. bool isAlive = koreClientIsAlive;
  258. LeaveCriticalSection (&CS_koreClientIsAlive);
  259. if (isAlive) {
  260. // Data that the RO server sent
  261. if (dataWaiting(s)) {
  262. // Grab data
  263. ret2 = OriginalRecvProc(s, buf, len, flags);
  264. if (ret2 != SOCKET_ERROR && ret2 > 0) {
  265. // Redirect it to Kore
  266. char *newbuf = (char *) malloc (ret2 + 3);
  267. unsigned short sLen = (unsigned short) ret2;
  268. memcpy (newbuf, "R", 1);
  269. memcpy (newbuf + 1, &sLen, 2);
  270. memcpy (newbuf + 3, buf, ret2);
  271. EnterCriticalSection(&CS_send);
  272. xkoreSendBuf.append (newbuf, ret2 + 3);
  273. LeaveCriticalSection(&CS_send);
  274. free (newbuf);
  275. } else if (ret2 == 0 || (ret2 == SOCKET_ERROR && WSAGetLastError () != WSAEWOULDBLOCK)) {
  276. // Connection with RO server closed
  277. EnterCriticalSection(&CS_ro);
  278. roServer = INVALID_SOCKET;
  279. LeaveCriticalSection(&CS_ro);
  280. }
  281. }
  282. // Pass data from Kore to RO Client
  283. EnterCriticalSection (&CS_rosend);
  284. int roSendBufsize = roSendBuf.size();
  285. if (roSendBufsize) {
  286. ret = roSendBufsize < len? roSendBufsize : len;
  287. memcpy (buf, (char *) roSendBuf.c_str (), ret);
  288. roSendBuf.erase (0, ret);
  289. } else {
  290. WSASetLastError (WSAEWOULDBLOCK);
  291. ret = SOCKET_ERROR;
  292. }
  293. LeaveCriticalSection (&CS_rosend);
  294. } else {
  295. EnterCriticalSection (&CS_rosend);
  296. int roSendBufsize = roSendBuf.size();
  297. LeaveCriticalSection (&CS_rosend);
  298. if (roSendBufsize) {
  299. // Flush out anything left thats kore->ROclient
  300. ret = roSendBufsize < len? roSendBufsize : len;
  301. EnterCriticalSection (&CS_rosend);
  302. memcpy (buf, (char *) roSendBuf.c_str(), ret);
  303. roSendBuf.erase(0, ret);
  304. LeaveCriticalSection (&CS_rosend);
  305. } else {
  306. ret2 = OriginalRecvProc(s, buf, len, flags);
  307. if (ret2 == 0 || (ret2 == SOCKET_ERROR && WSAGetLastError () != WSAEWOULDBLOCK)) {
  308. EnterCriticalSection(&CS_ro);
  309. roServer = INVALID_SOCKET;
  310. LeaveCriticalSection(&CS_ro);
  311. }
  312. ret = ret2;
  313. }
  314. }
  315. return ret;
  316. }
  317. int WINAPI
  318. MyRecvFrom (SOCKET s, char* buf, int len, int flags, struct sockaddr* from, int *fromlen)
  319. {
  320. return OriginalRecvFromProc(s,buf,len,flags,from,fromlen);
  321. }
  322. int WINAPI
  323. MyConnect (SOCKET s, struct sockaddr* name, int namelen)
  324. {
  325. EnterCriticalSection (&CS_ro);
  326. roServer = s;
  327. LeaveCriticalSection (&CS_ro);
  328. return OriginalConnectProc(s, name, namelen);
  329. }
  330. int WINAPI
  331. MyWSAAsyncSelect (SOCKET s, HWND hWnd, unsigned int wMsg, long lEvent)
  332. {
  333. EnterCriticalSection (&CS_ro);
  334. roServer = s;
  335. LeaveCriticalSection (&CS_ro);
  336. OriginalWSAAsyncSelectProc(s,hWnd,wMsg,lEvent);
  337. return 0;
  338. }
  339. FARPROC WINAPI
  340. MyGetProcAddress (HMODULE hModule, LPCSTR lpProcName)
  341. {
  342. FARPROC ret = OriginalGetProcAddressProc (hModule, lpProcName);
  343. HMODULE WS2_32 = LoadLibrary ("WS2_32.DLL");
  344. if (hModule == WS2_32) {
  345. if (stricmp (lpProcName, "WSASend") == 0) {
  346. OriginalWSASendProc = (MyWSASendProc) ret;
  347. ret = (FARPROC) MyWSASend;
  348. } else if (stricmp (lpProcName, "WSASendTo") == 0) {
  349. OriginalWSASendToProc = (MyWSASendToProc) ret;
  350. ret = (FARPROC) MyWSASendTo;
  351. } else if (stricmp (lpProcName, "WSARecv") == 0) {
  352. OriginalWSARecvProc = (MyWSARecvProc) ret;
  353. ret = (FARPROC) MyWSARecv;
  354. } else if (stricmp (lpProcName, "WSARecvFrom") == 0) {
  355. OriginalWSARecvFromProc = (MyWSARecvFromProc) ret;
  356. ret = (FARPROC) MyWSARecvFrom;
  357. } else if (stricmp (lpProcName, "send") == 0) {
  358. OriginalSendProc = (MySendProc) ret;
  359. ret = (FARPROC) MySend;
  360. } else if (stricmp (lpProcName, "sendto") == 0) {
  361. OriginalSendToProc = (MySendToProc) ret;
  362. ret = (FARPROC) MySendTo;
  363. } else if (stricmp (lpProcName, "recv") == 0) {
  364. OriginalRecvProc = (MyRecvProc) ret;
  365. ret = (FARPROC) MyRecv;
  366. } else if (stricmp (lpProcName, "recvfrom") == 0) {
  367. OriginalRecvFromProc = (MyRecvFromProc) ret;
  368. ret = (FARPROC) MyRecvFrom;
  369. } else if (stricmp (lpProcName, "connect") == 0) {
  370. OriginalConnectProc = (MyConnectProc) ret;
  371. ret = (FARPROC) MyConnect;
  372. } else if (stricmp (lpProcName, "WSAAsyncSelect") == 0) {
  373. OriginalWSAAsyncSelectProc = (MyWSAAsyncSelectProc) ret;
  374. ret = (FARPROC) MyWSAAsyncSelect;
  375. }
  376. }
  377.   return ret;
  378. }
  379. /************************************************/
  380. static void
  381. DoHookProcs ()
  382. {
  383. // Read the comment for HookImportedFunction() in utils-netredirect.cpp
  384. // about what's going on here
  385. OriginalWSASendProc = (MyWSASendProc)
  386. HookImportedFunction( GetModuleHandle(0), "WS2_32.DLL", "WSASend", (PROC)MyWSASend);
  387. OriginalWSASendToProc = (MyWSASendToProc)
  388. HookImportedFunction( GetModuleHandle(0), "WS2_32.DLL", "WSASendTo", (PROC)MyWSASendTo);
  389. OriginalWSARecvProc = (MyWSARecvProc)
  390. HookImportedFunction( GetModuleHandle(0), "WS2_32.DLL", "WSARecv", (PROC)MyWSARecv);
  391. OriginalWSARecvFromProc = (MyWSARecvFromProc)
  392. HookImportedFunction( GetModuleHandle(0), "WS2_32.DLL", "WSARecvFrom", (PROC)MyWSARecvFrom);
  393. OriginalSendProc = (MySendProc)
  394. HookImportedFunction( GetModuleHandle(0), "WS2_32.DLL", "send", (PROC)MySend);
  395. OriginalSendToProc = (MySendToProc)
  396. HookImportedFunction( GetModuleHandle(0), "WS2_32.DLL", "sendto", (PROC)MySendTo);
  397. OriginalRecvProc = (MyRecvProc)
  398. HookImportedFunction( GetModuleHandle(0), "WS2_32.DLL", "recv", (PROC)MyRecv);
  399. OriginalRecvFromProc = (MyRecvFromProc)
  400. HookImportedFunction( GetModuleHandle(0), "WS2_32.DLL", "recvfrom", (PROC)MyRecvFrom);
  401. OriginalConnectProc = (MyConnectProc)
  402. HookImportedFunction( GetModuleHandle(0), "WS2_32.DLL", "connect", (PROC)MyConnect);
  403. OriginalSelectProc = (MySelectProc)
  404. HookImportedFunction( GetModuleHandle(0), "WS2_32.DLL", "select", (PROC)MySelect);
  405. OriginalWSAAsyncSelectProc = (MyWSAAsyncSelectProc)
  406. HookImportedFunction( GetModuleHandle(0), "WS2_32.DLL", "WSAAsyncSelect", (PROC)MyWSAAsyncSelect);
  407. OriginalGetProcAddressProc = (MyGetProcAddressProc)
  408. HookImportedFunction( GetModuleHandle(0), "KERNEL32.DLL", "GetProcAddress", (PROC)MyGetProcAddress);
  409. }
  410. static void
  411. init ()
  412. {
  413. WSAData WSAData;
  414. ULONG threadID;
  415. WSAStartup (MAKEWORD (2,2),&WSAData);
  416. InitializeCriticalSection (&CS_koreClientIsAlive);
  417. InitializeCriticalSection (&CS_dataAvailableFromKore);
  418. InitializeCriticalSection (&CS_ro);
  419. InitializeCriticalSection (&CS_send);
  420. InitializeCriticalSection (&CS_rosend);
  421. debugInit ();
  422. debug ("Hooking functions...n");
  423. DoHookProcs ();
  424. debug ("Creating thread...n");
  425. CreateThread (0, 0, (LPTHREAD_START_ROUTINE) koreConnectionMain, 0, 0, &threadID);
  426. debug ("Thread createdn");
  427. }
  428. /********* DLL injection support for Win9x *********/
  429. //#define TESTING_INJECT9x
  430. static int isNT = 0;
  431. static int started = 0;
  432. static HINSTANCE hDll = 0;
  433. static HHOOK hookID = 0;
  434. static int
  435. start ()
  436. {
  437. init ();
  438. return 0;
  439. }
  440. // This function is called when we're injected into another process
  441. static LRESULT WINAPI
  442. hookProc (int code, WPARAM wParam, LPARAM lParam)
  443. {
  444. if (!started) {
  445. char lib[MAX_PATH];
  446. ULONG threadID;
  447. started = 1;
  448. GetModuleFileName (hDll, lib, MAX_PATH);
  449. if (LoadLibrary (lib))
  450. UnhookWindowsHookEx (hookID);
  451. // For some reason RO crashes if I call init() here.
  452. // Calling it in a thread seems to fix the problem.
  453. // (but won't we get race conditions??)
  454. CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) start, NULL, 0, &threadID);
  455. }
  456. return CallNextHookEx (hookID, code, wParam, lParam);
  457. }
  458. // Inject this DLL into the process that owns window hwnd
  459. extern "C" int WINAPI __declspec(dllexport)
  460. injectSelf (HWND hwnd)
  461. {
  462. int idHook;
  463. if (isNT)
  464. idHook = WH_CALLWNDPROC;
  465. else
  466. idHook = WH_GETMESSAGE;
  467. hookID = SetWindowsHookEx (idHook, (HOOKPROC) hookProc, hDll,
  468. GetWindowThreadProcessId (hwnd, NULL));
  469. if (hookID == NULL)
  470. return 0;
  471. SendMessage (hwnd, WM_USER + 10, 0, 1);
  472. return 1;
  473. }
  474. /***************************************************/
  475. extern "C" BOOL APIENTRY
  476. DllMain (HINSTANCE hInstance, DWORD dwReason, LPVOID _Reserved)
  477. {
  478. switch (dwReason) {
  479. case DLL_PROCESS_ATTACH:
  480. hDll = hInstance;
  481. // Check whether debugging should be enabled
  482. HKEY key;
  483. DWORD type, size;
  484. BYTE val[1024];
  485. size = sizeof (val) - 1;
  486. val[0] = '';
  487. RegOpenKey (HKEY_CURRENT_USER,
  488. "Software\Kore",
  489. &key);
  490. RegQueryValueEx (key,
  491. "DebugNetRedirect",
  492. NULL,
  493. &type,
  494. val,
  495. &size);
  496. RegCloseKey (key);
  497. enableDebug = val[0] == '1';
  498. #ifndef TESTING_INJECT9x
  499. OSVERSIONINFO version;
  500. version.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
  501. GetVersionEx (&version);
  502. isNT = version.dwPlatformId == VER_PLATFORM_WIN32_NT;
  503. // If we're injected on Win9x, then init() must
  504. // be called from a different function (see above).
  505. // This is because Kore LoadLibrary() this dll when on Win9x.
  506. if (isNT)
  507. init ();
  508. #endif
  509. break;
  510. default:
  511. break;
  512. }
  513. return true;
  514. }