我是靠谱客的博主 霸气小蜜蜂,最近开发中收集的这篇文章主要介绍C++远程注入dll的通俗理解及易错点,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

远程注入大致可分为8步

01给自己提权

                int DebugPrivilege =EnableDebugPrivilege(SE_DEBUG_NAME);

02获取目标窗口句柄

               CWnd* hWnd = FindWindow(L"Notepad", NULL);

03获取目标窗口ID

               GetWindowThreadProcessId(hWnd->m_hWnd, &Win_ID);

04获取目标进程句柄

               HANDLE hWnd_Pro = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Win_ID);

05在目标进程内申请内存空间

              LPVOID lpAddr = VirtualAllocEx(hWnd_Pro, NULL, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

6.拼接出dll的绝对路径,而这个绝对路径是给第8步loadLibrary的地址

               要点一:GetCurrentDirectory获取到的是当前路径,***必须***提前把需要注入的dll手动复制过来

                               因为debug的时候这里是没有dll的,写错地址是最常出现的错误
               要点二:loadLibrary需要2字节的LPCWSTR类型,我们这里也要把一个字节的char*改为LPCWSTR
                              获取到的szBuf已经是LPCWSTR类型了,添加dll名称时,每个char后面多加一个''就变成LPCWSTR的结构了
                              比如DDDDDD,char类型是44 44 44 44 44 44,LPCWSTR类型是44 00 44 00 44 00 44 00 44 00 44 00

                        char szBuf[MAX_PATH] = { NULL };
                        DWORD Len_Path=GetCurrentDirectory(sizeof(szBuf), LPWSTR(szBuf));
                        char* dll_name = "\helper2.dll";//这里填需要注入的dll路径名称
                        int aaaa = strlen(dll_name);
                        for (int i = Len_Path*2; i < (Len_Path + aaaa) * 2; i = i + 1) {
                            if (i % 2 == 0) {
                                szBuf[i] = dll_name[(i - (Len_Path * 2)) / 2];
                            }
                            else {
                                szBuf[i] = '';
                            }
                        }

07使用WriteProcessMemory把地址写入目标进程的内存空间。

                       BOOL bRet = WriteProcessMemory(hWnd_Pro, lpAddr, szBuf, MAX_PATH, NULL);

                        第一个参数: 进程的句柄, 可以用第4步OpenProcess返回的句柄
                        第二个参数 : 写入的内存地址起点,可以用第5步VirtualAllocEx申请空间返回的起始点
                        第三个参数 : 需要写入的内容的指针
                        第四个参数 : 需要写入的内容的长度
                        第五个参数 : NULL即可*/

               

08在目标进程内创建远程线程

                            HANDLE hThreadHandle = CreateRemoteThread(hWnd_Pro, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibrary, lpAddr, 0, NULL);
                            *****************************************************************************************
                            要点一:你必须先知道目标进程是32还是64!!!!64位编译dll和本体才能注入64位程序,32同理。
                            要点二:CreateRemoteThread就是在目标进程中创建线程,这里重点是第四和第五个参数
                                         同时可以执行loadLibrary函数(由第四个参数找到并执行),并传入dll路径(由第五个参数找到并传递)
                                         第四个参数是loadLibrary的函数指针,第五个参数是上面5,6步写入的宽字符串

                                       (2字节的LPCWSTR类型,loadLibrary的参数类型)
                                         从原理上看就是  参数四(参数五)——LoadLibrary(L"D:ABC.dll")
                            要点三:win7之后的系统必须有第1步的提权过程后才能在目标进程中远程调用loadlibrary
                            *****************************************************************************************
                            CreateRemoteThread讲解:
                            第一个参数: 进程的句柄, 可以用第4步OpenProcess返回的句柄
                            第二个参数: 安全属性,句柄可否继承,不需要给NULL
                            第三个参数: 栈的大小,给0则默认
                            第四个参数: *****找到loadLibrary函数并执行*****
                            第五个参数: *****向loadLibrary传入一个参数*****
                            写入远程进程内存的dll路径,而dll路径一旦启动,则会执行自己的代码(核心,一定掌握)
                            第六个参数: 创建的标志,默认给0
                            第七个参数: 线程的ID,不需要知道,给NULL*/

其中比较麻烦的是后面三步

//提升进程权限
int EnableDebugPrivilege(const LPTSTR name)
{
    HANDLE token;
    TOKEN_PRIVILEGES tp;
    //打开进程令牌环   
    if (!OpenProcessToken(GetCurrentProcess(),
        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token))
    {
        std::cout << "open process token error!n";
        return 0;
    }
    //获得进程本地唯一ID   
    LUID luid;
    if (!LookupPrivilegeValue(NULL, name, &luid))
    {
        std::cout << "lookup privilege value error!n";
        return 0;
    }
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    tp.Privileges[0].Luid = luid;
    //调整进程权限   
    if (!AdjustTokenPrivileges(token, 0, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL))
    {
        std::cout << "adjust token privilege error!n";
        return 0;
    }
    return 1;
}

//整体的注入代码

int DebugPrivilege =EnableDebugPrivilege(SE_DEBUG_NAME);//01给自己提权
    if (DebugPrivilege) {
        CWnd* hWnd = FindWindow(L"Notepad", NULL);//02获取目标窗口句柄
        if (hWnd) {
            DWORD Win_ID = 0;
            GetWindowThreadProcessId(hWnd->m_hWnd, &Win_ID);//03获取目标窗口ID
            if (Win_ID) {
                HANDLE hWnd_Pro = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Win_ID);//04获取目标进程句柄
                if (hWnd_Pro) {
                    LPVOID lpAddr = VirtualAllocEx(hWnd_Pro, NULL, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);//05在目标进程内申请内存空间
                    if (lpAddr)
                    {
                        /*6.拼接出dll的绝对路径,而这个绝对路径是给第8步loadLibrary的地址
                        ************************************************************************************
                        要点一:GetCurrentDirectory获取到的是当前路径,***必须***提前把需要注入的dll手动复制过来,因为debug的时候这里是没有dll的
                        要点二:loadLibrary需要2字节的LPCWSTR类型,我们这里也要把一个字节的char*改为LPCWSTR
                            获取到的szBuf已经是LPCWSTR类型了,添加dll名称时,每个char后面多加一个''就变成LPCWSTR的结构了
                            比如DDDDDD,char类型是44 44 44 44 44 44,LPCWSTR类型是44 00 44 00 44 00 44 00 44 00 44 00
                        ************************************************************************************/
                        
                        char szBuf[MAX_PATH] = { NULL };
                        DWORD Len_Path=GetCurrentDirectory(sizeof(szBuf), LPWSTR(szBuf));
                        char* dll_name = "\helper2.dll";//这里填需要注入的dll路径名称
                        int aaaa = strlen(dll_name);
                        for (int i = Len_Path*2; i < (Len_Path + aaaa) * 2; i = i + 1) {
                            if (i % 2 == 0) {
                                szBuf[i] = dll_name[(i - (Len_Path * 2)) / 2];
                            }
                            else {
                                szBuf[i] = '';
                            }
                        }
                        /*07使用WriteProcessMemory把地址写入目标进程的内存空间。
                        第一个参数: 进程的句柄, 可以用第4步OpenProcess返回的句柄
                        第二个参数 : 写入的内存地址起点,可以用第5步VirtualAllocEx申请空间返回的起始点
                        第三个参数 : 需要写入的内容的指针
                        第四个参数 : 需要写入的内容的长度
                        第五个参数 : NULL即可*/
                        BOOL bRet = WriteProcessMemory(hWnd_Pro, lpAddr, szBuf, MAX_PATH, NULL);
                        if (bRet)
                        {
                            /*08在目标进程内创建远程线程
                            *****************************************************************************************
                            要点一:你必须先知道目标进程是32还是64!!!!64位编译dll和本体才能注入64位程序,32同理。
                            要点二:CreateRemoteThread就是在目标进程中创建线程,这里重点是第四和第五个参数
                                同时可以执行loadLibrary函数(由第四个参数找到并执行),并传入dll路径(由第五个参数找到并传递)
                                第四个参数是loadLibrary的函数指针,第五个参数是上面5,6步写入的宽字符串(2字节的LPCWSTR类型,loadLibrary的参数类型)
                                从原理上看就是  参数四(参数五)——LoadLibrary(L"D:ABC.dll")
                            要点三:win7之后的系统必须有第1步的提权过程后才能在目标进程中远程调用loadlibrary
                            *****************************************************************************************
                            CreateRemoteThread讲解:
                            第一个参数: 进程的句柄, 可以用第4步OpenProcess返回的句柄
                            第二个参数: 安全属性,句柄可否继承,不需要给NULL
                            第三个参数: 栈的大小,给0则默认
                            第四个参数: *****找到loadLibrary函数并执行*****
                            第五个参数: *****向loadLibrary传入一个参数*****
                            写入远程进程内存的dll路径,而dll路径一旦启动,则会执行自己的代码(核心,一定掌握)
                            第六个参数: 创建的标志,默认给0
                            第七个参数: 线程的ID,不需要知道,给NULL*/
                            HANDLE hThreadHandle = CreateRemoteThread(hWnd_Pro, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibrary, lpAddr, 0, NULL);
                            if (hThreadHandle) {
                                MessageBox(L"dll注入完成");
                            }
                            else {
                                DWORD aa = GetLastError();
                                MessageBox(L"远程线程开辟失败");
                            }
                        }
                        else {
                            MessageBox(L"目标进程写入dll内容失败");
                        }
                    }
                    else {
                        MessageBox(L"进程空间申请失败");
                    }
                }
                else {
                    MessageBox(L"进程句柄获取失败");
                }
            }
            else {
                MessageBox(L"窗口ID获取失败");
            }
        }
        else {
            MessageBox(L"窗口句柄获取失败");
        }
    }
    else {
        MessageBox(L"提权失败");
    }

最后

以上就是霸气小蜜蜂为你收集整理的C++远程注入dll的通俗理解及易错点的全部内容,希望文章能够帮你解决C++远程注入dll的通俗理解及易错点所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(60)

评论列表共有 0 条评论

立即
投稿
返回
顶部