APC注入

APC注入的原理是利用当线程被唤醒时APC中的注册函数会被执行的机制,并以此去执行我们的DLL加载代码,进而完成DLL注入的目的,其具体流程如下:

    1)当EXE里某个线程执行到SleepEx()或者WaitForSingleObjectEx()时,系统就会产生一个软中断(或者是Messagebox弹窗的时候不点OK的时候也能注入)。

    2)当线程再次被唤醒时,此线程会首先执行APC队列中的被注册的函数。

    3)利用QueueUserAPC()这个API可以在软中断时向线程的APC队列插入一个函数指针,如果我们插入的是Loadlibrary()执行函数的话,就能达到注入DLL的目的。

核心函数:

局限:

这种注入方式局限性很明显,一是必须要等待时机,而是当注入成功后,SleepEx或者其他等待函数直接就会跳过当前等待继续往下走,这样可能造成被注入程序的不稳定行,经常导致被注入程序崩溃。

代码:

// LoadExeWin32.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <string>
#include <windows.h>
#include <shlwapi.h>
#include <tlhelp32.h>
#include <winternl.h>
#pragma comment(lib, "shlwapi.lib")
#pragma comment(lib,"ntdll.lib") using namespace std; //根据进程名字获取pid
DWORD GetPidFromName(wstring wsProcessName) {
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE){
return FALSE;
}
PROCESSENTRY32W pe = {sizeof(pe)};
BOOL bOk;
for (bOk = Process32FirstW(hSnapshot, &pe); bOk; bOk = Process32NextW(hSnapshot, &pe)){
wstring wsNowProcName = pe.szExeFile;
if(StrStrI(wsNowProcName.c_str() ,wsProcessName.c_str())!= NULL){
CloseHandle(hSnapshot);
return pe.th32ProcessID;
}
}
CloseHandle(hSnapshot);
return 0;
}
//把wcCacheInDllPath DLL文件注入进程wsProcessName
BOOL Injection_APC(const wstring &wsProcessName ,const WCHAR wcCacheInDllPath[]){
//初始化
DWORD dwProcessId = GetPidFromName(wsProcessName);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessId);
if (!hProcess){
return FALSE;
}
PVOID lpData = VirtualAllocEx(hProcess,
NULL,
1024,
MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
DWORD dwRet;
if (lpData) {
//在远程进程申请空间中写入待注入DLL的路径
WriteProcessMemory(hProcess,
lpData,
(LPVOID)wcCacheInDllPath,
MAX_PATH,&dwRet);
}
CloseHandle(hProcess);
//开始注入
THREADENTRY32 te = {sizeof(THREADENTRY32)};
//得到线程快照
HANDLE handleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD ,0);
if (INVALID_HANDLE_VALUE == handleSnap) {
return FALSE;
}
BOOL bStat = FALSE;
//得到第一个线程
if (Thread32First(handleSnap,&te)){
do { //进行进程ID对比
if (te.th32OwnerProcessID == dwProcessId) {
//得到线程句柄
HANDLE handleThread = OpenThread(THREAD_ALL_ACCESS ,FALSE ,te.th32ThreadID);
if (handleThread) { //向线程插入APC
DWORD dwRet = QueueUserAPC(
(PAPCFUNC)LoadLibraryW,
handleThread,
(ULONG_PTR)lpData);
if (dwRet > 0) {
bStat = TRUE;
}
//关闭句柄
CloseHandle(handleThread);
}
}
//循环下一个线程
} while (Thread32Next(handleSnap,&te));
}
CloseHandle(handleSnap);
return bStat;
}
//Adds a user-mode asynchronous procedure call (APC)
int main(int argc, char* argv[]){
//Sleep(1000*100);
Injection_APC(L"Sleep3M.exe" ,L"M.dll");
return 0;
}

然后写一个测试DLL:

然后再写一个被注入程序:

测试结果:

注入自己的程序成功:

随便尝试了下注入QQ.exe,直接崩溃退出了。

DLL注入-APC注入的更多相关文章

  1. 分析恶意驱动(进程启动apc注入dll)

    一.前言  用IDA也有好些时间了,以前就只会用F5功能玩无壳无保护的裸驱动,感觉太坑了,这两天就开始看网上大牛的逆向. 今天记录一下sudami曾经逆向过的fuck.sys.第一遍自己走的时候漏掉了 ...

  2. Dll注入:Ring3 层 APC注入

    APC,即Asynchronous procedure call,异步程序调用APC注入的原理是:在一个进程中,当一个执行到SleepEx()或者WaitForSingleObjectEx()时,系统 ...

  3. Dll注入技术之APC注入

    APC注入的原理是利用当线程被唤醒时APC中的注册函数会被执行的机制,并以此去执行我们的DLL加载代码,进而完成DLL注入的目的,其具体流程如下:     1)当EXE里某个线程执行到SleepEx( ...

  4. APC注入

    0X01 注入原理 当线程被唤醒时APC中的注册函数会被执行的机制,并依此去调用我们的DLL加载代码,进而完成注入的目的 具体的流程: 1 当EXE里的某个线程执行到sleepEX(),或者waitF ...

  5. 常见注入手法第二讲,APC注入

    常见注入手法第二讲,APC注入 转载注明出处 首先,我们要了解下什么是APC APC 是一个简称,具体名字叫做异步过程调用,我们看下MSDN中的解释,异步过程调用,属于是同步对象中的函数,所以去同步对 ...

  6. 注入理解之APC注入

    近期学习做了一个各种注入的MFC程序,把一些心得和体会每天分享一些 APC(Asynchronous procedure call)异步程序调用,在NT中,有两种类型的APCs:用户模式和内核模式.用 ...

  7. HOOK -- DLL的远程注入技术详解(1)

    DLL的远程注入技术是目前Win32病毒广泛使用的一种技术.使用这种技术的病毒体通常位于一个DLL中,在系统启动的时候,一个EXE程序会将这个DLL加载至某些系统进程(如Explorer.exe)中运 ...

  8. DLL的远程注入技术

    DLL的远程注入技术是目前Win32病毒广泛使用的一种技术.使用这种技术的病毒体通常位于一个DLL中,在系统启动的时候,一个EXE程序会将这个DLL加载至某些系统进程(如Explorer.exe)中运 ...

  9. windows:shellcode 代码远程APC注入和加载

    https://www.cnblogs.com/theseventhson/p/13197776.html  上一章介绍了通用的shellcode加载器,这个加载器自己调用virtualAlloc分配 ...

随机推荐

  1. WeihanLi.Npoi 1.16.0 Release Notes

    WeihanLi.Npoi 1.16.0 Release Notes Intro 最近有网友咨询如何设置单元格样式,在之前的版本中是不支持的,之前主要考虑的是数据,对于导出的样式并没有支持,这个 is ...

  2. 关于PHP的__construct()函数

    1 <?php 2 header("Content-Type:text/html;charset=utf-8");//调整为utf-8编码格式 3 class car 4 { ...

  3. javascript中的Strict模式

    目录 简介 使用Strict mode strict mode的新特性 强制抛出异常 简化变量的使用 简化arguments 让javascript变得更加安全 保留关键字和function的位置 总 ...

  4. 【图像处理】OpenCV+Python图像处理入门教程(五)阈值处理

    这篇随笔介绍使用OpenCV进行图像处理的第五章 阈值处理. 5  阈值处理 阈值是指像素到达某临界值.阈值处理表示像素到达某临界值后,对该像素点进行操作和处理. 例如:设定一幅图像素阈值为200,则 ...

  5. 9、MyBatis教程之多对一处理

    10.多对一处理 多对一的理解: 多个学生对应一个老师 如果对于学生这边,就是一个多对一的现象,即从学生这边关联一个老师! 1.创建数据库 CREATE TABLE `teacher` ( `id` ...

  6. String 的不可变真的是因为 final 吗?

    尽人事,听天命.博主东南大学硕士在读,热爱健身和篮球,乐于分享技术相关的所见所得,关注公众号 @ 飞天小牛肉,第一时间获取文章更新,成长的路上我们一起进步 本文已收录于 「CS-Wiki」Gitee ...

  7. flexbox(弹性盒布局模型),以及适用场景

    一.是什么 Flexible Box 简称 flex,意为"弹性布局",可以简便.完整.响应式地实现各种页面布局 采用Flex布局的元素,称为flex容器container 它的所 ...

  8. DBeaver、Navicat、MySQL高频报错及解决方法,此文持续更新

    目录 第一坑,没有用管理员身份 第二坑,MySQL 服务无法启动 第三坑,报错:ERROR 1045 (28000): Access denied for user 'root'@'localhost ...

  9. 如何快速创建odoo模块,使用脚手架快速创建自己的odoo应用app

    上一篇内容:如何快速搭建自己的ERP系统,4步源码快速安装odoo教程 了解什么是odoo的插件模块 odoo在基础的框架代码之下,可以安装自己的应用程序或者业务逻辑,也可以对原有的模块进行二次修改 ...

  10. Linux 用户和用户组管理(useradd userdel groupadd groupdel)

    Linux 用户和用户组管理 Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统. Linux系统用户账户的 ...