代码1

#define _WIN32_WINNT 0x0400
#define WIN32_LEAN_AND_MEAN   // 从 Windows 头中排除极少使用的资料

#include <iostream>
#include <windows.h>
#include <Winbase.h>
using namespace std;

DWORD  WINAPI WorkThread(LPVOID pParam)
{
    HANDLE Event = (HANDLE)pParam;
    for(;;)
    {
        DWORD dwRet = WaitForSingleObjectEx(Event, INFINITE, TRUE);
        if(dwRet == WAIT_OBJECT_0)
            break;
        else 
            if(dwRet == WAIT_IO_COMPLETION)
                printf("WAIT_IO_COMPLETION\n");
            
            return 0;
    }
}

VOID  WINAPI APCProc(LPVOID dwParam)
{
    printf("%s", (PVOID)dwParam);
}

void TestAPC(BOOL bFast)
{
    
    HANDLE QuitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    HANDLE hThread = CreateThread(NULL,
        0,
        WorkThread,
        (LPVOID)QuitEvent,
        0,
        NULL);
    
    
    Sleep(100); // Wait for WorkThread initialized.
    
    
    for(int i=5; i>0; i--)
    {    
        QueueUserAPC((PAPCFUNC)APCProc, hThread, (DWORD)(PVOID)"APC here\n");
        if(!bFast)
            Sleep(1000);
    }
    
    
    SetEvent(QuitEvent);
    
    WaitForSingleObject(hThread, INFINITE);
    
    CloseHandle(hThread);    
}

int main()
{
    TestAPC(true);
    return 0;
}

代码2

#define _WIN32_WINNT 0x0400
#define WIN32_LEAN_AND_MEAN   // 从 Windows 头中排除极少使用的资料

#include <windows.h>
#include <Tlhelp32.h>
#include <stdio.h>
#include <stdlib.h>

typedef HANDLE (CALLBACK *OPENTHREAD) (DWORD dwFlag, BOOL bUnknow, DWORD dwThreadId); 
typedef   unsigned   long      ULONG_PTR;

typedef struct _TIDLIST 
{
    DWORD dwTid ;
    _TIDLIST *pNext ;
}TIDLIST;

DWORD EnumThread(HANDLE hProcess, TIDLIST *pThreadIdList)
{
    TIDLIST *pCurrentTid = pThreadIdList ;
    HANDLE hThread;
    const char szInjectModName[] = "c:\\sysnap.dll" ;
    DWORD dwLen = strlen(szInjectModName) ;
    HMODULE hDll = GetModuleHandle("Kernel32.dll"); 
    
    PVOID param = VirtualAllocEx(hProcess, \
        NULL, dwLen, MEM_COMMIT | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE) ;
    
    if (param != NULL)
    {
        DWORD dwRet ;
        if (WriteProcessMemory(hProcess, param, (LPVOID)szInjectModName, dwLen, &dwRet))
        {
            
            while (pCurrentTid)
            {
                OPENTHREAD lpfnOpenThread = (OPENTHREAD)::GetProcAddress(hDll, "OpenThread"); 
                hThread = lpfnOpenThread(THREAD_ALL_ACCESS,FALSE,pCurrentTid->dwTid);
                if (hThread != NULL)
                {
                    //
                    // 注入DLL到指定进程
                    //
                    QueueUserAPC((PAPCFUNC)LoadLibraryA, hThread, (ULONG_PTR)param) ;
                }
                
                printf("TID:%d\n", pCurrentTid->dwTid) ;
                pCurrentTid = pCurrentTid->pNext ;
            }
        }
    }
    return 0 ;
}

DWORD GetProcID(const char *szProcessName)
{
    PROCESSENTRY32 pe32 = {0} ;
    pe32.dwSize = sizeof(PROCESSENTRY32);
    
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) ;
    
    if (hSnapshot == INVALID_HANDLE_VALUE)
    {
        return 0xFFFFFFFF ;
    }
    
    if (!Process32First(hSnapshot, &pe32))
    {
        return 0xFFFFFFFF ;
    }
    
    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 0xFFFFFFFF ;
    
}

TIDLIST* InsertTid(TIDLIST *pdwTidListHead, DWORD dwTid)
{
    TIDLIST *pCurrent = NULL ;
    TIDLIST *pNewMember = NULL ;
    
    if (pdwTidListHead == NULL)
    {
        return NULL ;
    }
    pCurrent = pdwTidListHead ;
    
    while (pCurrent != NULL)
    {
        
        if (pCurrent->pNext == NULL)
        {
            //
            // 定位到链表最后一个元素
            //
            pNewMember = (TIDLIST *)malloc(sizeof(TIDLIST)) ;
            
            if (pNewMember != NULL)
            {
                pNewMember->dwTid = dwTid ;
                pNewMember->pNext = NULL ;
                pCurrent->pNext = pNewMember ;
                return pNewMember ;
            }
            else
            {
                return NULL ;
            }
        }
        pCurrent = pCurrent->pNext ;
    }
    
    return NULL ;
}

int EnumThreadID(DWORD dwPID, TIDLIST *pdwTidList)
{
    int i = 0 ;
    
    THREADENTRY32 te32 = {0} ;
    te32.dwSize= sizeof(THREADENTRY32) ;
    
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,dwPID) ;
    
    if(hSnapshot != INVALID_HANDLE_VALUE)
    {
        if(Thread32First(hSnapshot,&te32)) 
        {
            do
            {
                if(te32.th32OwnerProcessID==dwPID) 
                {
                    if (pdwTidList->dwTid == 0)
                    {
                        pdwTidList->dwTid = te32.th32ThreadID ;
                    }
                    else
                    {
                        if (NULL == InsertTid(pdwTidList, te32.th32ThreadID))
                        {
                            printf("插入失败!\n") ;
                            return 0 ;
                        }
                    }
                    
                } 
            }while(Thread32Next(hSnapshot,&te32));
        }
    }
    return 1 ;
}

void RemoveTid(TIDLIST *pdwTidListHead)
{
    TIDLIST *pCurrent = NULL ;
    TIDLIST *pNext = NULL ;
    
    
    if (pdwTidListHead == NULL)
    {
        return;
    }
    pCurrent = pdwTidListHead ;
    
    while (pCurrent != NULL)
    {
        
        pNext = pCurrent->pNext;
        free(pCurrent);
        pCurrent = pNext;
    }
    
}
int main(int argc, char* argv[])
{
    TIDLIST *pTidHead = (TIDLIST *)malloc(sizeof(TIDLIST)) ;
    
    if (pTidHead == NULL)
    {
        return 1 ;
    }

RtlZeroMemory(pTidHead, sizeof(TIDLIST)) ;
    
    DWORD dwPID = 0 ;
    
    if ((dwPID = GetProcID("explorer.exe")) == 0xFFFFFFFF)
    {
        printf("进程ID获取失败!\n") ;
        return 1 ;
    }
    
    //
    // 枚举线程ID
    //
    EnumThreadID(dwPID, pTidHead) ;
    
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID) ;
    
    if (hProcess == NULL)
    {
        return 1 ;
    }
    EnumThread(hProcess, pTidHead) ;
    
    CloseHandle(hProcess);
    
    RemoveTid(pTidHead);
    
    return 0;
}

Alertable IO(告警IO)提供了更有效的异步通知形式。ReadFileEx / WriteFileEx在发出IO请求的同时,提供一个回调函数(APC过程),当IO请求完成后,一旦线程进入可告警状态,回调函数将会执行。
   以下五个函数能够使线程进入告警状态:
   SleepEx
   WaitForSingleObjectEx
   WaitForMultipleObjectsEx
   SignalObjectAndWait
   MsgWaitForMultipleObjectsEx
   线程进入告警状态时,内核将会检查线程的APC队列,如果队列中有APC,将会按FIFO方式依次执行。如果队列为空,线程将会挂起等待事件对象。以后的某个时刻,一旦APC进入队列,线程将会被唤醒执行APC,同时等待函数返回WAIT_IO_COMPLETION。
   QueueUserAPC可以用来人为投递APC,只要目标线程处于告警状态时,APC就能够得到执行。
   使用告警IO的主要缺点是发出IO请求的线程也必须是处理结果的线程,如果一个线程退出时还有未完成的IO请求,那么应用程序将永远丢失IO完成通知。然而以后我们将会看到IO完成端口没有这个限制。
  

转载于:https://www.cnblogs.com/chengxin1982/archive/2010/01/20/1652398.html

使用QueueUserAPC线程注入,相关推荐

  1. 远程线程注入引出的问题

    一.远程线程注入基本原理 远程线程注入--相信对Windows底层编程和系统安全熟悉的人并不陌生,其主要核心在于一个Windows API函数CreateRemoteThread,通过它可以在另外一个 ...

  2. windows-CODE注入(远程线程注入)

    远程线程注入(先简单说,下面会详细说) 今天整理下代码注入(远程线程注入),所谓代码注入,可以简单的理解为是在指定内进程里申请一块内存,然后把我们自己的执行代码和一些变量拷贝进去(通常是以启线程的方式 ...

  3. DLL 远程线程注入

    远程线程注入 首先 , 这里讲和为注入 , 通俗讲 , 就是把自己的东西强加给别人 也就是在 其他程序的运行的内存空间里面 插入自己的代码 这里提到的远程线程注入 这个算是很常用,也算是用的比较多的一 ...

  4. 【超级鼠标键盘锁】之远线程注入winlogon.exe进程屏蔽Ctrl+Alt+Del、Win+L

    通过上一节对winlogon.exe进程的调试,得到了其处理Ctrl+Alt+Del和Win+L按键的关键代码位置偏移,并阐述了如何对指令进行修改,从而达到屏蔽这两个按键. 本节采用远线程注入技术进行 ...

  5. 基于应用层自身反远程线程注入的研究

    基于应用层自身反远程线程注入的研究 现状:目前所有已知的反远程注入方式:r0层hook 句柄的获取,返回失败,让应用层注入者拿不到目标进程的句柄,如hook ntopenprocess ntdubli ...

  6. WinAPI【远程注入】利用远程线程注入DLLDelphi版

    { WinAPI[远程注入]利用远程线程注入DLLDelphi版} (okwary) 小叹的学习园地 ( SDK文档里是这样描述的:进程是一个正在运行的程序,它拥有自己的地址空间,拥有自己的 ...

  7. DLL注入_远程线程注入

    什么是线程注入? 线程注入,是通过开启远程线程的方式,将DLL加载到目标宿主进程中的常用方式. 什么是动态链接库? 首先Windows中链接库分为两种:动态链接库DLL.静态链接库LIB. ① 静态链 ...

  8. 内核线程注入(x64)

    阅读BlackBone源码从里面扣出来的关于内核线程注入方法的使用. 经过自己修改后做成的Demo,功能主要通过Ring0层驱动Attach到目标进程(目标进程可以是32位进程也可以是64位进程,使用 ...

  9. Win10_X64远线程注入dll(非CreateRemoteThread)

    谈到远线程注入,首先肯定会想到使用CreateRemoteThread,但这个API无法对系统进程进行注入,而且根据我个人的验证发现这个函数在win10下也无法正常将dll注入进记事本进程(淦!).好 ...

最新文章

  1. java怎么自动提示关键词_Eclipse 实现关键字自动补全功能
  2. windows下php7.1安装redis扩展以及redis测试使用全过程
  3. 适用于System Center 2016所需前期准备工作
  4. android 中的常用组件
  5. 开源php面板,宝塔面板nginx安装终于搞定了
  6. php accesscontrolalloworigin,设置Access-Control-Allow-Origin实现跨域访问
  7. 飞畅科技-工业交换机防雷知识总结
  8. php自动加载原理,php中的自动加载类机制原理
  9. 简单易用线上引流测试工具:GoReplay
  10. 【转】python开发大全、系列文章、精品教程
  11. 夜间模式(模仿喜马拉雅FM)
  12. GDB 调试 ---转 比较全的东东
  13. The BIG Talk 2015 :创新金融和智能城市
  14. asp.net 页面引入外部JS 在IE6下延迟加载报错,IE7+均没问题
  15. Visual Studio安装及无法打开包括文件: “crtdbg.h”问题解决
  16. UVALive - 4487 HDU3234 UVA12232 【带权并查集】 非常好的一道题!!!
  17. RFB-Net论文代码映射
  18. Linux操作文档——分析和排查系统故障(日志)
  19. 佳博/芯桦打票机对接(含USB和网口)
  20. 二维动态数组空间分配 c语言,科学网—C语言中动态二维数组的使用和分配 - 王一哲的博文...

热门文章

  1. 嵌入式面试知识点总结 -- ARM篇
  2. RTSP再学习 -- Hi3516A RTSP实例 分析
  3. C语言再学习 -- 关键字struct(转)
  4. Android Realm相关操作
  5. Android系统启动-init篇
  6. Android 大牛开发者博客列表
  7. JZOJ 5932. 【NOIP2018模拟10.27】情报中心
  8. java基础知识大全,java 基础知识点汇总
  9. C语言中最常用标准库
  10. 中班科学计算机,幼儿园中班科学课件:《照镜子》