zoukankan      html  css  js  c++  java
  • 使用QueueUserAPC线程注入,

    代码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完成端口没有这个限制。
      
  • 相关阅读:
    jQuery 基本选择器
    JavaScriptif while for switch流程控制 JS函数 内置对象
    JavaScrip基本语法
    数据库 存储引擎 表的操作 数值类型 时间类型 字符串类型 枚举集合 约束
    数据库基础知识 管理员 用户登录授权的操作
    粘包的产生原理 以及如何解决粘包问题
    socket TCP DPT 网络编程
    2018年年终总结
    Android技术分享
    No accelerator found
  • 原文地址:https://www.cnblogs.com/chengxin1982/p/1652398.html
Copyright © 2011-2022 走看看