Hook : APC注入技术

  1. /*  
  2. 一: 异步过程调用: 每个线程都有自己的APC队列,往线程APC队列加入APC,在线程 下一次被调用的时候就会执行APC函数  
  3. 二:注意: 1.APC被添加后,线程不会立即执行APC,只有当线程处于"可变等待状态"时,才会调用   
  4.   
  5.         2.以下五个函数能够使线程进入可变等待状态:  
  6.         SleepEx  
  7.         WaitForSingleObjectEx  
  8.         WaitForMultipleObjectsEx  
  9.         SignalObjectAndWait  
  10.         MsgWaitForMultipleObjectsEx  
  11. 三:过程1.与远程技术相同,向目标进程写入待注入模块的名称  
  12.        2.  
  13.   */  
  14.   
  15.   
  16. #define _WIN32_WINNT 0x0400  
  17. #include <windows.h>  
  18. #include <TlHelp32.h>  
  19. #include <Winbase.h>  
  20. #include <iostream>  
  21. #include <string>  
  22.   
  23.   
  24.   
  25.   
  26. typedef HANDLE (__stdcall *OPENTHREADX) (DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId);  
  27.   
  28.   
  29. using namespace std;  
  30. #pragma comment (lib,"Kernel32.lib")  
  31. #define DEF_BUF_SIZE 1024  
  32.   
  33.   
  34. // 用于存储注入模块DLL的路径全名  
  35. char szDllPath[DEF_BUF_SIZE] = {0} ;  
  36.   
  37.   
  38. // 使用APC机制向指定ID的进程注入模块  
  39. BOOL InjectModuleToProcessById ( DWORD dwProcessId )  
  40. {  
  41. OPENTHREADX OpenThread;  
  42. OpenThread=(OPENTHREADX)GetProcAddress(LoadLibrary("kernel32.dll"),"OpenThread");  
  43. DWORD dwRet = 0 ;  
  44. BOOL bStatus = FALSE ;  
  45. LPVOID lpData = NULL ;  
  46. UINT uLen = strlen(szDllPath) + 1;  
  47. // 打开目标进程  
  48. HANDLE hProcess = OpenProcess ( PROCESS_ALL_ACCESS, FALSE, dwProcessId ) ;  
  49. if ( hProcess )  
  50. {  
  51. // 分配空间  
  52. lpData = VirtualAllocEx ( hProcess, NULL, uLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE ) ;  
  53. if ( lpData )  
  54. {  
  55. // 写入需要注入的模块路径全名  
  56. bStatus = WriteProcessMemory  
  57. (hProcess,//由OpenProcess返回的进程句柄。如参数传数据为 INVALID_HANDLE_VALUE 【即-1】目标进程为自身进程  
  58. lpData,//要写的内存首地址,再写入之前,此函数将先检查目标地址是否可用,并能容纳待写入的数据。  
  59. szDllPath,//指向要写的数据的指针。  
  60. uLen,//要写入的字节数。  
  61. &dwRet ) ;  
  62. }  
  63. CloseHandle ( hProcess ) ;  
  64. }  
  65.   
  66.   
  67. if ( bStatus == FALSE )  
  68. return FALSE ;  
  69.   
  70.   
  71. // 创建线程快照  
  72. THREADENTRY32 te32 = { sizeof(THREADENTRY32) } ;  
  73. HANDLE hThreadSnap = CreateToolhelp32Snapshot (  
  74.                                           TH32CS_SNAPTHREAD, //用来指定“快照”中需要返回的对象,可以是TH32CS_SNAPPROCESS等  
  75.   0 一个进程ID号,用来指定要获取哪一个进程的快照,当获取系统进程列表或获取当前进程快照时可以设为0  
  76.   ) ;  
  77. if ( hThreadSnap == INVALID_HANDLE_VALUE )   
  78. return FALSE ;   
  79.   
  80.   
  81. bStatus = FALSE ;  
  82. // 枚举所有线程  
  83. if ( Thread32First ( hThreadSnap, &te32 ) )  
  84. {  
  85. do{  
  86. // 判断是否目标进程中的线程  
  87. if ( te32.th32OwnerProcessID == dwProcessId )  
  88. {  
  89. // 打开线程  
  90. HANDLE hThread = OpenThread ( THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID ) ;  
  91. if ( hThread )  
  92. {  
  93. // 向指定线程添加APC  
  94. DWORD dwRet = QueueUserAPC (  
  95. (PAPCFUNC)LoadLibraryA,//APC函数地址  
  96. hThread,//目标线程  
  97. (ULONG_PTR)lpData //APC函数参数  
  98. );  
  99.   
  100.   
  101. if ( dwRet > 0 )  
  102. bStatus = TRUE ;  
  103. CloseHandle ( hThread ) ;  
  104. }  
  105. }   
  106.   
  107.   
  108. }while ( Thread32Next ( hThreadSnap, &te32 ) ) ;  
  109. }  
  110.   
  111.   
  112. CloseHandle ( hThreadSnap ) ;  
  113. return bStatus;  
  114. }  
  115.   
  116.   
  117. int main()  
  118. {  
  119. // 取得当前工作目录路径  
  120. GetCurrentDirectoryA ( DEF_BUF_SIZE, szDllPath ) ;  
  121.   
  122.   
  123. // 生成注入模块DLL的路径全名  
  124. strcat ( szDllPath, "\\DLLSample.dll" ) ;  
  125.   
  126.   
  127. DWORD dwProcessId = 0 ;  
  128. // 接收用户输入的目标进程ID  
  129. while ( cout << "请输入目标进程ID:" && cin >> dwProcessId && dwProcessId > 0 )   
  130. {  
  131. BOOL bRet = InjectModuleToProcessById ( dwProcessId ) ;  
  132. cout << (bRet ? "注入成功!":"注入失败!") << endl ;  
  133. }  
  134. return 0;  
  135. }  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值