APC注入APCInject(DLL)

APC注入的原理是利用当线程被唤醒时APC中的注册函数会被执行的机制,并以此去执行我们的DLL加载代码,进而完成DLL注入的目的,其具体流程如下:
1)当EXE里某个线程执行到SleepEx()或者WaitForSingleObjectEx()时,系统就会产生一个软中断(或者是Messagebox弹窗的时候不点OK的时候也能注入)。
2)当线程再次被唤醒时,此线程会首先执行APC队列中的被注册的函数。
3)利用QueueUserAPC()这个API可以在软中断时向线程的APC队列插入一个函数指针,如果我们插入的是Loadlibrary()执行函数的话,就能达到注入DLL的目的。
// APCInject.h


#pragma once

// APCInject 对话框

class APCInject : public CDialogEx
{
    DECLARE_DYNAMIC(APCInject)

public:
    APCInject(CWnd* pParent = NULL);   // 标准构造函数
    virtual ~APCInject();

// 对话框数据
    enum { IDD = IDD_DIALOG5 };

protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

    DECLARE_MESSAGE_MAP()
public:
    CString m_strExePath;
    CString m_strDllPath;
    afx_msg void OnBnClickedButton3();
    afx_msg void OnBnClickedButton4();
    afx_msg void OnBnClickedInject();
};

// APCInject.cpp

// APCInject.cpp : 实现文件
//

#include "stdafx.h"
#include "MyInjectTool.h"
#include "APCInject.h"
#include "afxdialogex.h"

// APCInject 对话框

IMPLEMENT_DYNAMIC(APCInject, CDialogEx)

APCInject::APCInject(CWnd* pParent /*=NULL*/)
    : CDialogEx(APCInject::IDD, pParent)
    , m_strExePath(_T(""))
    , m_strDllPath(_T(""))
{

}

APCInject::~APCInject()
{
}

void APCInject::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Text(pDX, IDC_EDIT1, m_strExePath);
    DDX_Text(pDX, IDC_EDIT2, m_strDllPath);
}

BEGIN_MESSAGE_MAP(APCInject, CDialogEx)
    ON_BN_CLICKED(IDC_BUTTON3, &APCInject::OnBnClickedButton3)
    ON_BN_CLICKED(IDC_BUTTON4, &APCInject::OnBnClickedButton4)
    ON_BN_CLICKED(IDC_INJECT, &APCInject::OnBnClickedInject)
END_MESSAGE_MAP()

// APCInject 消息处理程序

void APCInject::OnBnClickedButton3()
{
    // TODO:  在此添加控件通知处理程序代码
    char szFilter[] = "可执行程序|*.exe";
    CFileDialog fileDlg(TRUE, "exe", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter);
    UpdateData(TRUE);
    if (fileDlg.DoModal() == IDOK)
    {
        m_strExePath = fileDlg.GetPathName();
    }
    UpdateData(FALSE);
}

void APCInject::OnBnClickedButton4()
{
    // TODO:  在此添加控件通知处理程序代码
    char szFilter[] = "动态链接库|*.dll";
    CFileDialog fileDlg(TRUE, "dll", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter);
    UpdateData(TRUE);
    if (fileDlg.DoModal() == IDOK)
    {
        m_strDllPath = fileDlg.GetPathName();
    }
    UpdateData(FALSE);
}

void APCInject::OnBnClickedInject()
{
    // TODO:  在此添加控件通知处理程序代码
    DWORD dwRet = 0;
    PROCESS_INFORMATION pi;
    STARTUPINFO si;
    ZeroMemory(&pi, sizeof(pi));
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(STARTUPINFO);

    //以挂起的方式创建进程
    dwRet = CreateProcess(m_strExePath.GetBuffer(0),
        NULL,
        NULL,
        NULL,
        FALSE,
        CREATE_SUSPENDED,
        NULL,
        NULL,
        &si,
        &pi);

    if (!dwRet)
    {
        MessageBox("CreateProcess失败!!");
        return;
    }

    PVOID lpDllName = VirtualAllocEx(pi.hProcess,
        NULL,
        m_strDllPath.GetLength(),
        MEM_COMMIT,
        PAGE_READWRITE);

    if (lpDllName)
    {
        //将DLL路径写入目标进程空间
        if (WriteProcessMemory(pi.hProcess, lpDllName, m_strDllPath.GetBuffer(0), m_strDllPath.GetLength(), NULL))
        {
            LPVOID nLoadLibrary = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
            //向远程APC队列插入LoadLibraryA
            if (!QueueUserAPC((PAPCFUNC)nLoadLibrary, pi.hThread, (DWORD)lpDllName))
            {
                MessageBox("QueueUserAPC失败!!");
                return;
            }
        }
        else
        {
            MessageBox("WriteProcessMemory失败!!");
            return;
        }
    }

    //恢复主线程
    ResumeThread(pi.hThread);
    MessageBox("APC注入成功");

}

原文地址:http://blog.51cto.com/haidragon/2306937

时间: 2024-10-10 07:17:28

APC注入APCInject(DLL)的相关文章

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

转自:黑客反病毒 APC注入的原理是利用当线程被唤醒时APC中的注册函数会被执行的机制,并以此去执行我们的DLL加载代码,进而完成DLL注入的目的,其具体流程如下:     1)当EXE里某个线程执行到SleepEx()或者WaitForSingleObjectEx()时,系统就会产生一个软中断.     2)当线程再次被唤醒时,此线程会首先执行APC队列中的被注册的函数.     3)利用QueueUserAPC()这个API可以在软中断时向线程的APC队列插入一个函数指针,如果我们插入的是L

QueryUserAPC Ring3下 APC注入

DLL.dll可以自己建,实测在win7 X86 X64, win10 X64下可用 #pragma once /****************************************************************************************************/ /*Ring3下 APC注入提权 TLHelp32枚举线程 vector*/ /***************************************************

注入理解之APC注入

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

奇技淫巧之调试被远程线程注入的DLL

远程线程注入, 这东西大家都懂的, 一般都被大家用来干些小小的坏事情,比如API Hook~~将DLL注入到其它进程并不是难事,问题是这个被注入的DLL不太好调试,调试DLL本来就是个比较头疼的问题,更何况是这种运行在其它进程空间的DLL, 被注入DLL的程序,不崩溃还好,崩溃了,要定位崩溃点,真是够麻烦的. 这几天,无意中发现了一个可以调试这种DLL的方法. 首先,需要准备两样东西: 1.微软的Detours库, 下载地址戳这里: 下载链接 2.打开Detours安装目录下的samples\s

IAT 注入ImportInject(dll)

原理:PE文件中的每一个导入表都代表一个库(dll),所以你添加一个导入表时,当你调用函数时就会去加载相应的DLL而达到注入.写法一: // INTInject.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<Windows.h> #include <exception> #include <iostream> using namespace std; BOOL AddImportTable(

Ring3 APC注入

系统产生一个软中断,当线程再次被唤醒时,此线程会首先执行APC队列中的被注册的函数,利用QueueUserAPC()这个API,并以此去执行我们的DLL加载代码,进而完成DLL注入的目的, 1.根据进程名称得进程ID2.枚举该进程中的线程3.将自己的函数插入到每个线程的APC队列中 1 // APCInject(Ring3).cpp : 定义控制台应用程序的入口点. 2 // 3 4 #include "stdafx.h" 5 #include <windows.h> 6

APC注入(Ring3)

首先简单介绍一下APC队列和Alertable. 看看MSDN上的一段介绍(https://msdn.microsoft.com/en-us/library/ms810047.aspx): The system delivers most user-mode APCs when a thread unwinds from kernel mode back to user mode after an alertable wait. User-mode APCs do not interrupt u

APC注入(Ring3层)

/* 步骤: 1.提权(GrantDebugPrivileges) (1)获得令牌token,OpenThreadToken(),OpenProcessToken () WINADVAPI BOOL WINAPI OpenThreadToken( _In_ HANDLE ThreadHandle, _In_ DWORD DesiredAccess, _In_ BOOL OpenAsSelf, _Outptr_ PHANDLE TokenHandle ); OpenAsSelf参数 [in]  t

线程注入ThreadInject(dll)

原理通过挂起线程(SuspendThread),设置线程(SetThreadContext)上下文中的eip(rip)方式注入.//ThreadInject.h #pragma once // ThreadInject 对话框 class ThreadInject : public CDialogEx { DECLARE_DYNAMIC(ThreadInject) public: ThreadInject(CWnd* pParent = NULL); // 标准构造函数 virtual ~Thr