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;
}
一: 异步过程调用: 每个线程都有自己的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;
}
相关文章推荐
- Dll注入技术之APC注入
- APC注入技术
- Hook技术之4 在自己的进程中注入一个Dll到别人的进程
- Dll注入技术之APC注入
- Dll注入技术之APC注入
- Android so注入(inject)和Hook技术学习(二)——Got表hook之导入表hook
- 注入Hook技术 -- DLL注入
- Hook技术之4 在自己的进程中注入一个Dll到别人的进程
- DLL注入技术之APC注入
- HOOK -- DLL的远程注入技术详解(1)
- Android so注入(inject)和Hook技术学习(三)——Got表hook之导出表hook
- Android so注入(inject)和Hook技术学习(一)
- Dll注入技术之APC注入
- [转载]Dll注入技术之APC注入
- DLL注入技术之APC注入
- 利用HOOK技术实现DLL远程进程注入
- Dll注入技术之APC注入
- Dll注入技术之APC注入
- 这个是APC注入?
- 技术文章 |【漏洞公告】 CVE-2017-14596:Joomla! LDAP 注入漏洞