DebugInject(dll)

原理:
用到调试器附加的原理实现注入。

    bRet = CreateProcess(NULL,
        m_strExePath.GetBuffer(0),
        NULL,
        NULL,
        FALSE,
        DEBUG_ONLY_THIS_PROCESS,
        NULL,
        NULL,
        &si,
        &pi);

// DebugInject.h

#pragma once
#include "afxwin.h"

// DebugInject 对话框

class DebugInject : public CDialogEx
{
    DECLARE_DYNAMIC(DebugInject)

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

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

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

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

};

// DebugInject.cpp

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

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

//结构必须字节对齐!  
#pragma pack(1)  
typedef struct _INJECT_CODE
{
    BYTE  byMOV_EAX;          //mov eax, addr szDllpath
    DWORD dwMOV_EAX_VALUE;
    BYTE  byPUSH_EAX;         //push eax
    BYTE  byMOV_ECX;          //mov ecx, LoadLibrary
    DWORD dwMOV_ECX_VALUE;
    WORD  wCALL_ECX;          //call ecx
    BYTE  byINT3;             //int 3
    CHAR  szDllPath[MAX_PATH];
}INJECT_CODE, *PINJECT_CODE;
#pragma pack()
// DebugInject 对话框

IMPLEMENT_DYNAMIC(DebugInject, CDialogEx)

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

}

DebugInject::~DebugInject()
{
}

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

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

// DebugInject 消息处理程序

void DebugInject::OnBnClickedInject()
{
    // TODO:  在此添加控件通知处理程序代码
    BOOL bRet;
    DWORD dwProcessId = 0;
    LPVOID lpBaseAddress = NULL;
    HANDLE hThread = NULL;
    HANDLE hProcess = NULL;
    DEBUG_EVENT dbgEvent = { 0 };
    CONTEXT ctxOld = { CONTEXT_FULL };
    CONTEXT ctxNew = { CONTEXT_FULL };
    INJECT_CODE ic = { 0 };
    STARTUPINFO si = { sizeof(si) };
    PROCESS_INFORMATION pi = { 0 };
    HMODULE hDll = NULL;
    BOOL bIsSystemBp = TRUE;
    DWORD dwOldEip = 0;
    bRet = CreateProcess(NULL,
        m_strExePath.GetBuffer(0),
        NULL,
        NULL,
        FALSE,
        DEBUG_ONLY_THIS_PROCESS,
        NULL,
        NULL,
        &si,
        &pi);
    if (!bRet)
    {
        MessageBox("CreateProcess 失败");
        return;
    }

    //防止被调试进程和调试器一起关闭
    bRet = DebugSetProcessKillOnExit(FALSE);

    while (WaitForDebugEvent(&dbgEvent, INFINITE))
    {
        switch (dbgEvent.dwDebugEventCode)
        {
        case CREATE_PROCESS_DEBUG_EVENT:
            hProcess = dbgEvent.u.CreateProcessInfo.hProcess;
            hThread = dbgEvent.u.CreateProcessInfo.hThread;

            //分配内存,填充注入指令  
            lpBaseAddress = VirtualAllocEx(hProcess,
                NULL,
                sizeof(INJECT_CODE),
                MEM_COMMIT | MEM_RESERVE,
                PAGE_EXECUTE_READWRITE);
            if (NULL == lpBaseAddress)
            {
                MessageBox("VirtualAllocEx 失败");
                return;
            }

            //给ShellCode结构体赋值
            ic.byMOV_EAX = 0xB8;
            ic.dwMOV_EAX_VALUE = (DWORD)lpBaseAddress + offsetof(INJECT_CODE, szDllPath);
            ic.byPUSH_EAX = 0x50;
            ic.byMOV_ECX = 0xB9;
            ic.dwMOV_ECX_VALUE = (DWORD)&LoadLibrary;
            ic.wCALL_ECX = 0xD1FF;
            ic.byINT3 = 0xCC;
            memcpy(ic.szDllPath, m_strDllPath.GetBuffer(0), m_strDllPath.GetLength());

            //写入ShellCode
            bRet = WriteProcessMemory(hProcess, lpBaseAddress, &ic, sizeof(ic), NULL);
            if (!bRet)
            {
                MessageBox("WriteProcessMemory 失败");
                return;
            }

            //获取当前线程上下文
            bRet = GetThreadContext(hThread, &ctxOld);
            if (!bRet)
            {
                MessageBox("GetThreadContext 失败");
                return;
            }

            ctxNew = ctxOld;

#ifdef _WIN64
            ctxNew.Rip = (DWORD)lpBaseAddress;
            dwOldEip = ctxNew.Rip;
#else 
            ctxNew.Eip = (DWORD)lpBaseAddress;
            dwOldEip = ctxNew.Eip;
#endif

            bRet = SetThreadContext(hThread, &ctxNew);
            if (!bRet)
            {
                MessageBox("SetThreadContext 失败");
                return;
            }

            break;
        case EXCEPTION_DEBUG_EVENT:
            if (dbgEvent.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT)
            {
                //屏蔽掉系统断点
                if (bIsSystemBp)
                {
                    bIsSystemBp = FALSE;
                    break;
                }

                //释放内存
                bRet = VirtualFreeEx(hProcess,
                    lpBaseAddress,
                    0,
                    MEM_RELEASE
                    );

                if (!bRet)
                {
                    MessageBox("VirtualFreeEx 失败");
                    return;
                }

                //恢复到程序创建时的EIP
                bRet = SetThreadContext(hThread, &ctxOld);
                if (!bRet)
                {
                    MessageBox("SetThreadContext 失败");
                    return;
                }

                bRet = ContinueDebugEvent(dbgEvent.dwProcessId, dbgEvent.dwThreadId, DBG_CONTINUE);
                if (!bRet)
                {
                    MessageBox("ContinueDebugEvent 失败!!");
                    return;
                }
                //退出本进程,让被调试程序跑起来
                //ExitProcess(0);
                return;

            }
            break;
        }

        bRet = ContinueDebugEvent(dbgEvent.dwProcessId, dbgEvent.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
        if (!bRet)
        {
            MessageBox("ContinueDebugEvent 失败!!");
            return;
        }
    }
}

void DebugInject::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 DebugInject::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);
}

猜你喜欢

转载自blog.51cto.com/haidragon/2306918
dll