[转载]Dll注入技术之APC注入

转自:黑客反病毒

APC注入的原理是利用当线程被唤醒时APC中的注册函数会被执行的机制,并以此去执行我们的DLL加载代码,进而完成DLL注入的目的,其具体流程如下:     1)当EXE里某个线程执行到SleepEx()或者WaitForSingleObjectEx()时,系统就会产生一个软中断。     2)当线程再次被唤醒时,此线程会首先执行APC队列中的被注册的函数。     3)利用QueueUserAPC()这个API可以在软中断时向线程的APC队列插入一个函数指针,如果我们插入的是Loadlibrary()执行函数的话,就能达到注入DLL的目的。
1.编写测试文件     新建MFC工程,添加按钮控件,双击写代码如下所示:

void CMfcTextApcInjectDlg::OnBnClickedSleepex()
{
    // TODO: 在此添加控件通知处理程序代码
    SleepEx(5000,TRUE);
}

这里我们需要注意一下SleepEx中第二个参数为TRUE,查下msdn,上面写到: bAlertable [in] If this parameter is FALSE, the function does not return until the time-out period has elapsed. If an I/O completion callback occurs, the function does not return and the I/O completion function is not executed. If an APC is queued tothe thread, the function does not return and the APC function is not executed.

大概意思是说当第二个参数为FALSE,APC是不被执行的,从此可以认为APC注入的使用条件还是有很大约束的。

.编写APC注入程序     由于我们需要时使用LoadLibrary()函数完成注入,因此需要为其先准备好必要的参数,需要我们可以通过在远程进程中申请空间的方式写入LoadLibrary()函数所需要的参数(也就是DLL的路径)。关键代码如下所示:

    //打开远程进程
    handle = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessId);
    if (handle)
    {
        //在远程进程申请空间
        lpData = VirtualAllocEx(handle,
            NULL,
            1024,
            MEM_COMMIT,
            PAGE_EXECUTE_READWRITE);

        if (lpData)
        {
            //在远程进程申请空间中写入待注入DLL的路径
            bRet = WriteProcessMemory(handle,
                lpData,
                (LPVOID)sDllName,
                1024,&dwRet);
        }
        //关闭句柄
        CloseHandle(handle);
}

当我们准备好用于注入DLL的LoadLibrary()函数后,接下来需要使用QueueUserAPC()函数将此函数插入到软中断线程的APC队列中。但是由于QueueUserAPC()函数的第三个参数是线程ID,因此我们需要根据现有进程ID,并通过遍历对比得到线程ID,具体API如下表所示:

CreateToolhelp32Snapshot   创建线程快照  
Thread32First   得到第一个线程快照  
Thread32Next   循环下一个线程快照  

关键代码如下所示:

    THREADENTRY32 te = {0};
    te.dwSize = 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
                    dwRet = QueueUserAPC(
                        (PAPCFUNC)LoadLibrary,
                        handleThread,
                        (ULONG_PTR)lpData);
                    if (dwRet > 0)
                    {
                        bStat = TRUE;
                    }
                    //关闭句柄
                    CloseHandle(handleThread);
                }
            }
            //循环下一个线程
        } while (Thread32Next(handleSnap,&te));
    }
CloseHandle(handleSnap);

3.MFC工程设置和提升权限     经过以上两步的操作,我们已经准备好APC注入的关键代码,现在我们需要将自己的程序提升权限以方便注入操作(另,动态MFC库编译有可能造成注入失败)。主要代码如下:

int CApcInjectDll::EnablePrivilege(bool isStart)
{
    //1. 得到令牌句柄
    HANDLE  hToken = NULL;      //令牌句柄
    if (!::OpenProcessToken( GetCurrentProcess(),
        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_READ,
        &hToken))
    {
        return FALSE;
    }

    //2. 得到特权值
    LUID    luid = {0};         //特权值
    if (!::LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
    {
        return FALSE;
    }

    //3. 提升令牌句柄权限
    TOKEN_PRIVILEGES tp = {0};  //令牌新权限
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    tp.Privileges[0].Attributes = isStart ? SE_PRIVILEGE_ENABLED : 0;

    if (!::AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL))
    {
        return FALSE;
    }

    //4. 关闭令牌句柄
    ::CloseHandle(hToken);
    return 0;
}
       

4.测试注入效果     点击待注入的EXE进行SleepEx,这时EXE的窗口是不可以移动的,因为只有一个线程,处于SleepEx的挂起状态,然后进行注入,我们此时会发现处于挂起状态的进程窗口突然可以移动了,这是因为进程在挂起状态等待时,如果有APC队列就会退出等待并执行APC队列中的函数,然后程序继续运行。

APC注入因为受目标进程使用API的条件而受限,并且处于等待的线程被注入后会立即返回,也有可能造成线程的运行错误,所以应用起来不是很通用。

时间: 2024-12-23 13:09:09

[转载]Dll注入技术之APC注入的相关文章

[转载]Dll注入技术之ComRes注入

转自:黑客反病毒 DLL注入技术之ComRes注入     ComRes注入的原理是利用Windows 系统中C:\WINDOWS\system32目录下的ComRes.dll这个文件,当待注入EXE如果使用CoCreateInstance()这个API时,COM服务器会加载ComRes.dll到EXE中,我们利用这个加载过程,移花接木的把ComRes.dll替换掉,并在伪造的ComRes.dll,然后利用LoadLibrary()将事先准备好的DLL加载到目标的EXE中. 1.编写测试文件  

注入理解之APC注入

近期学习做了一个各种注入的MFC程序,把一些心得和体会每天分享一些 APC(Asynchronous procedure call)异步程序调用,在NT中,有两种类型的APCs:用户模式和内核模式.用户APCs运行在用户模式下目标线程当前上下文中,并且需要从目标线程得到许可来运行.特别是,用户模式的APCs需要目标线程处在alertable等待状态才能被成功的调度执行.通过调用下面任意一个函数,都可以让线程进入这种状态.这些函数是:KeWaitForSingleObject, KeWaitFor

注入技术--万能密码注入

[实验目的] 1)理解[万能密码]的原理 2)学习[万能密码]的使用 [实验原理] 用户进行用户名和密码验证时,网站需要查询数据库.查询数据库就是执行SQL语句.针对此BBS论坛,当用户登录时,后台执行的数据库查询操作(SQL语句)是[Select user_id,user_type,email From usersWhere user_id='用户名' And password='密码'].由于网站后台在进行数据库查询的时候没有对单引号进行过滤,当输入用户名[admin]和万能密码[2'or'

注入技术--数字型注入

[实验目的] 1)理解SQL注入的原理 2)学习SQL注入的过程 [实验原理] 所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令.具体来说,它是利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句.比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的,

[转载]Dll注入技术之注册表注入

转自:黑客反病毒论坛 DLL注入技术之REG注入    DLL注入技术指的是将一个DLL文件强行加载到EXE文件中,并成为EXE文件中的一部分,这样做的目的在于方便我们通过这个DLL读写EXE文件内存数据,(例如 HOOK EXE文件中的API),或以被注入EXE的身份去执行一些操作等等.     REG注入原理是利用在Windows 系统中,当REG以下键值中存在有DLL文件路径时,会跟随EXE文件的启动加载这个DLL文件路径中的DLL文件.当如果遇到有多个DLL文件时,需要用逗号或者空格隔开

[转载]Dll注入技术之劫持进程创建注入

转自:黑客反病毒 DLL注入技术之劫持进程创建注入 劫持进程创建注入原理是利用Windows系统中CreateProcess()这个API创建一个进程,并将第6个参数设为CREATE_SUSPENDED,进而创建一个挂起状态的进程,利用这个进程状态进行远程线程注入DLL,然后用ResumeThread()函数恢复进程.1.创建挂起的进程     下面是创建一个挂起的计算器程序进程的主要代码: STARTUPINFO si = {0}; si.cb = sizeof si; si.dwFlags

[转载]Dll注入技术之远程线程注入

转自:黑客反病毒 DLL注入技术之远线程注入 DLL注入技术指的是将一个DLL文件强行加载到EXE文件中,并成为EXE文件中的一部分,这样做的目的在于方便我们通过这个DLL读写EXE文件内存数据,(例如 HOOK EXE文件中的API),或以被注入EXE的身份去执行一些操作等等.     远线程注入原理是利用Windows 系统中CreateRemoteThread()这个API,其中第4个参数是准备运行的线程,我们可以将LoadLibrary()填入其中,这样就可以执行远程进程中的LoadLi

[转载]Dll注入技术之依赖可信进程注入

转自:黑客反病毒 DLL注入技术之依赖可信进程注入 依赖可信进程注入原理是利用Windows 系统中Services.exe这个权限较高的进程,首先将a.dll远线程注入到Services.exe中,再利用a.dll将b.dll远线程注入到待注入进程中.具体过程如下图所示: 这里提供一个小技巧,当注入到Services.exe里的DLL时,想在做完事情后悄无声息的将自己释放掉,在Windows 中有这样的一个API函数FreeLibraryAndExitThread(),它可以把自己卸载掉并且退

[转载]Dll注入技术之消息钩子

转自:黑客反病毒 DLL注入技术之消息钩子注入 消息钩子注入原理是利用Windows 系统中SetWindowsHookEx()这个API,他可以拦截目标进程的消息到指定的DLL中导出的函数,利用这个特性,我们可以将DLL注入到指定进程中.主要流程如下图所示 1.准备阶段     需要编写一个DLL,并且显式导出MyMessageProc()函数,主要代码如下: LRESULT WINAPI MyMessageProc(int code,WPARAM wParam,LPARAM lParam)