• APC(异步过程调用)

1)当EXE里某个线程执行到SleepEx()或者WaitForSingleObjectEx()时(此时该线程处于可警惕状态),系统就会产生一个软中断。
       2)当线程再次被唤醒时,此线程会首先执行APC队列中的被注册的函数。
       3)利用QueueUserAPC()这个API可以在软中断时向线程的APC队列插入一个函数指针,如果我b们插入的是Loadlirary()执行函数的话,就能达到注入DLL的目的。

  • APC注入DLL流程

    a根据进程ID得到进程句柄

    b枚举进程的线程

    c在目标进程中申请内存(用来储存动态库的绝对地址)

    d调用WriteProcessMemory在申请的内存处写入动态库地址

    e调用QueueUserAPC为每个线程提交APC到APC队列

  • 代码实现
    // InjectByAPC.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"#define _WIN32_WINNT 0x0400
    #define WIN32_LEAN_AND_MEAN   // 从 Windows 头中排除极少使用的资料
    #include<Windows.h>
    #include <iostream>
    #include <Tlhelp32.h>
    using namespace std;typedef struct _THREADID_LIST_
    {DWORD ThreadID;_THREADID_LIST_ *pNext;
    }THREADIDLIST,*PTHREADIDLIST;
    DWORD GetProcessID(const TCHAR* szProcessName);
    PTHREADIDLIST InsertTid(PTHREADIDLIST ThreadIDList, DWORD ThreadId);
    int EnumThreadID(DWORD ProcessID, PTHREADIDLIST ThreadIDList);
    DWORD EnumThread(HANDLE ProcessHandle, PTHREADIDLIST ThreadIDList);int main()
    {PTHREADIDLIST ThreadIDList = (PTHREADIDLIST)malloc(sizeof(THREADIDLIST));if (ThreadIDList == NULL){return 0;}RtlZeroMemory(ThreadIDList, sizeof(THREADIDLIST));DWORD ProcessID = 0;if ((ProcessID = GetProcessID("explorer.exe")) == 0xFFFFFFFF){printf("进程ID获取失败!\n");return 0;}EnumThreadID(ProcessID, ThreadIDList);HANDLE ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);if (ProcessHandle == NULL){return 0;}EnumThread(ProcessHandle, ThreadIDList);getchar();getchar();return 0;
    }DWORD GetProcessID(const TCHAR* szProcessName)
    {PROCESSENTRY32 pe32 = { 0 };pe32.dwSize = sizeof(PROCESSENTRY32);HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (hSnapshot == INVALID_HANDLE_VALUE){return -1;}if (!Process32First(hSnapshot, &pe32)){return -1;}do{if (!_strnicmp(szProcessName, pe32.szExeFile, strlen(szProcessName))){printf("%s的PID是:%d\n", pe32.szExeFile, pe32.th32ProcessID);return pe32.th32ProcessID;}} while (Process32Next(hSnapshot, &pe32));return -1;
    }
    // 枚举线程ID
    int EnumThreadID(DWORD ProcessID, PTHREADIDLIST ThreadIDList)
    {int i = 0;THREADENTRY32 te32 = { 0 };te32.dwSize = sizeof(THREADENTRY32);HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, ProcessID);if (hSnapshot != INVALID_HANDLE_VALUE){if (Thread32First(hSnapshot, &te32)){do{if (te32.th32OwnerProcessID == ProcessID){if (ThreadIDList->ThreadID == 0){ThreadIDList->ThreadID = te32.th32ThreadID;}else{if (NULL == InsertTid(ThreadIDList, te32.th32ThreadID)){printf("插入失败!\n");return 0;}}}} while (Thread32Next(hSnapshot, &te32));}}return 1;
    }
    PTHREADIDLIST InsertTid(PTHREADIDLIST ThreadIDList, DWORD ThreadId)
    {PTHREADIDLIST pCurrent = NULL;PTHREADIDLIST pNewMember = NULL;if (ThreadIDList == NULL){return NULL;}pCurrent = ThreadIDList;while (pCurrent != NULL){if (pCurrent->pNext == NULL){//// 定位到链表最后一个元素//
                pNewMember = (PTHREADIDLIST )malloc(sizeof(THREADIDLIST));if (pNewMember != NULL){pNewMember->ThreadID = ThreadId;pNewMember->pNext = NULL;pCurrent->pNext = pNewMember;return pNewMember;}else{return NULL;}}pCurrent = pCurrent->pNext;}return NULL;
    }DWORD EnumThread(HANDLE ProcessHandle, PTHREADIDLIST ThreadIDList)
    {//默认第一个?PTHREADIDLIST CurrentThreadID = ThreadIDList;const char szInjectModName[] = "J:\\注入\\InjectByAPC\\x64\\Debug\\DLL.dll";DWORD Length = strlen(szInjectModName);PVOID Address = VirtualAllocEx(ProcessHandle,NULL, Length, MEM_COMMIT | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE);if (Address != NULL){SIZE_T ReturnLength;////将动态库的地址写进去//
            if (WriteProcessMemory(ProcessHandle, Address, (LPVOID)szInjectModName, Length, &ReturnLength)){while (CurrentThreadID){HANDLE ThreadHandle = OpenThread(THREAD_ALL_ACCESS, FALSE, CurrentThreadID->ThreadID);if (ThreadHandle != NULL){//// 注入DLL到指定进程//Address LoadLibraryA 参数//
                        QueueUserAPC((PAPCFUNC)LoadLibraryA, ThreadHandle, (ULONG_PTR)Address);}printf("TID:%d\n", CurrentThreadID->ThreadID);CurrentThreadID = CurrentThreadID->pNext;}}}return 0;
    }

转载于:https://www.cnblogs.com/banchen/p/6682804.html

动态库注入--APC注入相关推荐

  1. DLL注入-APC注入

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

  2. 【Android 逆向】Android 进程注入工具开发 ( 远程进程注入动态库文件操作 | 注入动态库 加载 业务动态库 | 业务动态库启动 | pthread_create 线程开发 )

    文章目录 前言 一.加载 libnattive.so 动态库 二. libnattive.so 动态库启动 三. pthread_create 线程开发 四. 线程执行函数 前言 libbridge. ...

  3. 【Android 逆向】Android 进程代码注入原理 ( 注入本质 | 静态注入和动态注入 | 静态注入两种方式 | 修改动态库重打包 | 修改 /data/app/xx/libs 动态库 )

    文章目录 一.注入本质 二.静态注入和动态注入 三.静态注入两种方式 ( 修改动态库重打包 | 修改 /data/app/packageName/libs/ 下的动态库 ) 一.注入本质 进程注入本质 ...

  4. 【Android 逆向】函数拦截实例 ( 函数拦截流程 | ① 定位动态库及函数位置 )

    文章目录 一.函数拦截流程 二.定位动态库及函数位置 一.函数拦截流程 函数拦截流程 : 定位动态库及函数位置 : 获取该动态库在内存中的位置 , 以便于 查找函数位置 ; 插桩 : 在函数的入口处插 ...

  5. 【Android 逆向】Android 进程注入工具开发 ( 远程进程 注入动态库 文件操作 | Android 进程读取文件所需的权限 | fopen 打开文件标志位 | 验证文件权限 )

    文章目录 前言 一.Android 进程读取文件所需的权限 二.fopen 打开文件标志位 三.验证文件权限 前言 一.Android 进程读取文件所需的权限 通过 注入工具 , 将 libbridg ...

  6. 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 注入工具收尾操作 | 关闭注入的动态库 | 恢复寄存器 | 脱离远程调试附着 )

    文章目录 一.dlclose 函数简介 二.关闭注入的 libbridge.so 动态库 三.恢复寄存器 四.脱离远程调试附着 一.dlclose 函数简介 dlclose 函数的作用是 卸载一个 指 ...

  7. 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 获取注入的 libbridge.so 动态库中的 load 函数地址 并 通过 远程调用 执行该函数 )

    文章目录 一.dlsym 函数简介 二.获取 目标进程 linker 中的 dlsym 函数地址 三.远程调用 目标进程 linker 中的 dlsym 函数 获取 注入的 libbridge.so ...

  8. 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 远程调用 目标进程中 libc.so 动态库中的 mmap 函数 三 | 等待远程函数执行完毕 | 寄存器获取返回值 )

    文章目录 前言 一.等待远程进程 mmap 函数执行完毕 二.从寄存器中获取进程返回值 三.博客资源 前言 前置博客 : [Android 逆向]Android 进程注入工具开发 ( 注入代码分析 | ...

  9. 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 远程调用 目标进程中 libc.so 动态库中的 mmap 函数 二 | 准备参数 | 远程调用 mmap 函数 )

    文章目录 一.准备 mmap 函数的参数 二.mmap 函数远程调用 一.准备 mmap 函数的参数 上一篇博客 [Android 逆向]Android 进程注入工具开发 ( 注入代码分析 | 远程调 ...

最新文章

  1. ob_start ob_end_clean的用法 fetch
  2. 恢复mysql数据库详细图解_binlog恢复mysql数据库超详细步骤
  3. c语言订餐管理系统报告,用c语言编程小型的订餐管理系统,谁会啊?
  4. 高性能mysql整理
  5. 【spring boot】新建项目,实现HelloWorld
  6. 分页offset格式_Thinkphp5 原生sql分页操作
  7. 记一次TCP连接异常故障解决
  8. vsphere6.0实验拓扑-虚拟机版
  9. VSCode插件开发全攻略
  10. 移动通信原理学习笔记之一
  11. matlab 反复激活无效——许可证到期
  12. 两万字的CAPL语法基础,一篇文章带你入门
  13. Rust学习:13.1_返回值和错误处理之panic 深入剖析
  14. 要闻君说: 百度云喜提信息安全首证;紫光展锐携5G芯片进击2019MWC;OPPO首发5G手机惊艳亮相……...
  15. 受了点小伤,心情怎么就变坏了呢?
  16. 使用PHP实现密保卡功能
  17. 两阶段市场投标策略。 电力市场程序。 日前日内竞价 提出了日前电力市场和实时电力市场下充电站的投标策略
  18. HR不得不知的Excel技能——模板篇
  19. 【SSL】2128可可摘苹果
  20. 利用eda函数对文本数据进行增强

热门文章

  1. 解析 | 如何从频域的角度解释CNN(卷积神经网络)?
  2. 腾讯开源最大规模多标签图像数据集,刷新行业数据集基准
  3. linux中波浪号代表什么_建筑电气施工图纸中BV、ZRBLV和TC、SC符号代表什么?
  4. 用字典存储学生成绩查询_中考用分数评价学生音体美成绩未尝不是好事
  5. IDEA Docker 插件安装
  6. abp mysql .net core_ABP .Net Core Entity Framework迁移使用MySql数据库
  7. java volatile实例_Java的Volatile实例用法及讲解
  8. [BZOJ3238][AHOI2013]差异 [后缀数组+单调栈]
  9. webpack gulp grunt 简单介绍
  10. Swift - 推送之本地推送(UILocalNotification)添加Button的点击事件