您的位置:首页 > 其它

Hook : APC注入技术

2014-07-21 21:56 295 查看
/*

一: 异步过程调用: 每个线程都有自己的APC队列,往线程APC队列加入APC,在线程 下一次被调用的时候就会执行APC函数

二:注意: 1.APC被添加后,线程不会立即执行APC,只有当线程处于"可变等待状态"时,才会调用

2.以下五个函数能够使线程进入可变等待状态:

   SleepEx

   WaitForSingleObjectEx

   WaitForMultipleObjectsEx

   SignalObjectAndWait

   MsgWaitForMultipleObjectsEx

三:过程1.与远程技术相同,向目标进程写入待注入模块的名称

2.

*/

#define _WIN32_WINNT 0x0400

#include <windows.h>

#include <TlHelp32.h>

#include <Winbase.h>

#include <iostream>

#include <string>

typedef HANDLE (__stdcall *OPENTHREADX) (DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId);

using namespace std;

#pragma comment (lib,"Kernel32.lib")

#define DEF_BUF_SIZE 1024

// 用于存储注入模块DLL的路径全名

char szDllPath[DEF_BUF_SIZE] = {0} ;

// 使用APC机制向指定ID的进程注入模块

BOOL InjectModuleToProcessById ( DWORD dwProcessId )

{

OPENTHREADX OpenThread;

OpenThread=(OPENTHREADX)GetProcAddress(LoadLibrary("kernel32.dll"),"OpenThread");

DWORD dwRet = 0 ;

BOOL bStatus = FALSE ;

LPVOID lpData = NULL ;

UINT uLen = strlen(szDllPath) + 1;

// 打开目标进程

HANDLE hProcess = OpenProcess ( PROCESS_ALL_ACCESS, FALSE, dwProcessId ) ;

if ( hProcess )

{

// 分配空间

lpData = VirtualAllocEx ( hProcess, NULL, uLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE ) ;

if ( lpData )

{

// 写入需要注入的模块路径全名

bStatus = WriteProcessMemory

(hProcess,//由OpenProcess返回的进程句柄。如参数传数据为 INVALID_HANDLE_VALUE 【即-1】目标进程为自身进程

lpData,//要写的内存首地址,再写入之前,此函数将先检查目标地址是否可用,并能容纳待写入的数据。

szDllPath,//指向要写的数据的指针。

uLen,//要写入的字节数。

&dwRet ) ;

}

CloseHandle ( hProcess ) ;

}

if ( bStatus == FALSE )

return FALSE ;

// 创建线程快照

THREADENTRY32 te32 = { sizeof(THREADENTRY32) } ;

HANDLE hThreadSnap = CreateToolhelp32Snapshot (

TH32CS_SNAPTHREAD, //用来指定“快照”中需要返回的对象,可以是TH32CS_SNAPPROCESS等

0 ////一个进程ID号,用来指定要获取哪一个进程的快照,当获取系统进程列表或获取当前进程快照时可以设为0

) ;

if ( hThreadSnap == INVALID_HANDLE_VALUE )

return FALSE ;

bStatus = FALSE ;

// 枚举所有线程

if ( Thread32First ( hThreadSnap, &te32 ) )

{

do{

// 判断是否目标进程中的线程

if ( te32.th32OwnerProcessID == dwProcessId )

{

// 打开线程

HANDLE hThread = OpenThread ( THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID ) ;

if ( hThread )

{

// 向指定线程添加APC

DWORD dwRet = QueueUserAPC (

(PAPCFUNC)LoadLibraryA,//APC函数地址

hThread,//目标线程

(ULONG_PTR)lpData //APC函数参数

);

if ( dwRet > 0 )

bStatus = TRUE ;

CloseHandle ( hThread ) ;

}

}

}while ( Thread32Next ( hThreadSnap, &te32 ) ) ;

}

CloseHandle ( hThreadSnap ) ;

return bStatus;

}

int main()

{

// 取得当前工作目录路径

GetCurrentDirectoryA ( DEF_BUF_SIZE, szDllPath ) ;

// 生成注入模块DLL的路径全名

strcat ( szDllPath, "\\DLLSample.dll" ) ;

DWORD dwProcessId = 0 ;

// 接收用户输入的目标进程ID

while ( cout << "请输入目标进程ID:" && cin >> dwProcessId && dwProcessId > 0 )

{

BOOL bRet = InjectModuleToProcessById ( dwProcessId ) ;

cout << (bRet ? "注入成功!":"注入失败!") << endl ;

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: