使用QueueUserAPC线程注入,

ExpandedBlockStart.gif 代码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 ;
}

 

ExpandedBlockStart.gif 代码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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值