返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++ DLL注入怎么实现
  • 215
分享到

C++ DLL注入怎么实现

2023-06-29 02:06:08 215人浏览 薄情痞子
摘要

这篇文章主要介绍“c++ DLL注入怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C++ DLL注入怎么实现”文章能帮助大家解决问题。先上源码:#include 

这篇文章主要介绍“c++ DLL注入怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C++ DLL注入怎么实现”文章能帮助大家解决问题。

先上源码:

#include "Inject_Main.h"#include "resource.h"#include <windows.h>#include <TlHelp32.h>#include <string>#include <TCHAR.H>using namespace std;/// <summary>/// 通过进程名称获取该进程句柄/// </summary>/// <param name="processName"></param>/// <returns>成功返回 DWord,失败返回 0</returns>DWORD GetProcessByName(CONST TCHAR* processName) {    // 获取到整个系统的进程    HANDLE processALL = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);    // 定义一个容器,该容器用来接收,进程信息    PROCESSENTRY32W processInfo = { 0 };    processInfo.dwSize = sizeof(PROCESSENTRY32W);    // 根据进程名称,循环判断是否是指定的进程    do    {        if (_tcscmp(processInfo.szExeFile, processName) == 0)        {            // 释放进程快照,防止内存泄露            CloseHandle(processALL);            // 如果是返回指定进程句柄            return processInfo.th42ProcessID;        }        // 一个迭代函数    } while (Process32Next(processALL, &processInfo));    // 释放进程快照,防止内存泄露    CloseHandle(processALL);    return 0;}/// <summary>/// 获取指定 DLL 的内存地址/// </summary>/// <param name="pid"></param>/// <param name="moduleName"></param>/// <returns></returns>HMODULE GetProceSSModuleHandle(DWORD pid, CONST TCHAR* moduleName) {    MODULEENTRY32 moduleEntry;    HANDLE handle = NULL;    handle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);    if (!handle) {        CloseHandle(handle);        return NULL;    }    ZeroMemory(&moduleEntry, sizeof(MODULEENTRY32));    moduleEntry.dwSize = sizeof(MODULEENTRY32);    if (!Module32First(handle, &moduleEntry)) {        CloseHandle(handle);        return NULL;    }    do {        if (_tcscmp(moduleEntry.szModule, moduleName) == 0) {            // 释放进程快照,防止内存泄露            CloseHandle(handle);            return moduleEntry.hModule;        }    } while (Module32Next(handle, &moduleEntry));    CloseHandle(handle);    return 0;}/// <summary>/// 把指定DLL注入到指定进程中/// </summary>/// <param name="processName">processName 进程名称</param>/// <param name="dllPath">dllPath dll路径</param>void InjectDll(const wchar_t* processName, const char* dllPath) {    // 获取指定进程的句柄    DWORD dword = GetProcessByName(processName);    if (dword == 0)    {        MessageBox(NULL, TEXT("没有找到指定进程"), TEXT("错误"), 0);        return;    }    // 打开指定进程    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dword);    if (hProcess == NULL)    {        MessageBox(NULL, TEXT("指定进程打开失败"), TEXT("错误"), 0);        return;    }        LPVOID DLLAddress = VirtualAllocEx(hProcess, NULL, strlen(dllPath), MEM_COMMIT, PAGE_READWRITE);        if (WriteProcessMemory(hProcess, DLLAddress, dllPath, strlen(dllPath), NULL) == 0)    {        MessageBox(NULL, TEXT("路径写入失败"), TEXT("错误"), 0);        return;    }    // 获取 Kernel32.dll 这个模块    HMODULE k32 = GetModuleHandle(TEXT("Kernel32.dll"));    // 在 Kernel32.dll 模块中找到 LoadLibrary 这个函数的内存地址    LPVOID loadADD = GetProcAddress(k32, "LoadLibraryA");        HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)loadADD, DLLAddress, 0, NULL);    // 释放指定的模块    CloseHandle(hThread);    CloseHandle(hProcess);}/// <summary>/// 把指定进程中的DLL卸载掉/// </summary>/// <param name="processName"></param>/// <param name="dllPath"></param>void UnInjectDll(const wchar_t* processName) {    // 通过进程名称获取该进程句柄    DWORD dword = GetProcessByName(processName);    if (dword == 0)    {        MessageBox(NULL, TEXT("没有找到指定进程"), TEXT("错误"), 0);        return;    }    // 获取指定进程中指定模块的内存地址    HMODULE hmodule = GetProcessModuleHandle(dword, L"WX_Read_Write.dll");    // 打开指定进程    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dword);    if (hProcess == NULL)    {        MessageBox(NULL, TEXT("指定进程打开失败"), TEXT("错误"), 0);        return;    }    // 获取 Kernel32.dll 这个模块    HMODULE k32 = GetModuleHandle(TEXT("Kernel32.dll"));    // 在 Kernel32.dll 模块中找到 LoadLibrary 这个函数的内存地址    LPVOID loadADD = GetProcAddress(k32, "FreeLibrary");    HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)loadADD, (LPVOID)hmodule, 0, NULL);    // 释放指定的模块    CloseHandle(hThread);    CloseHandle(hProcess);}/// <summary>/// /// </summary>/// <param name="hwndDlg"></param>/// <param name="uMsg"></param>/// <param name="wParam"></param>/// <param name="lParam"></param>/// <returns></returns>INT_PTR CALLBACK dialogProc(_In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam){    wchar_t processName[100] = L"WeChat.exe";    char dllPath[400] = { "C://Users//qiaoas//documents//visual studio 2015//Projects//ConsoleApplication1//Debug//WX_Read_Write.dll" };    switch (uMsg)    {    case WM_INITDIALOG:        break;    case WM_CLOSE:        EndDialog(hwndDlg, 0); // 关闭窗体        break;    case WM_COMMAND:                if (wParam == Btn_Inject_DLL)        {            if (sizeof(processName) == 0)            {                MessageBox(NULL, TEXT("进程名称不能为空"), TEXT("错误"), 0);            }            if (sizeof(dllPath) == 0)            {                MessageBox(NULL, TEXT("DLL路径不能为空"), TEXT("错误"), 0);            }            InjectDll(processName, dllPath); // 注入DLL        }        if (wParam == Btn_unInject_DLL)        {            UnInjectDll(processName); // 卸载DLL        }        break;    default:        break;    }    return FALSE;}/// <summary>/// 初始化/// </summary>/// <param name="hInstance"></param>/// <param name="hPrevInstance"></param>/// <param name="lpCmdLine"></param>/// <param name="nCmdShow"></param>/// <returns></returns>int apiENTRY wWinMain(_In_ HINSTANCE hInstance,    _In_opt_ HINSTANCE hPrevInstance,    _In_ LPWSTR    lpCmdLine,    _In_ int       nCmdShow){    DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, &dialogProc);    return 0;}

初学C++,代码可能有些地方写的不够好,但是注入卸载是完全没问题的。

注入逻辑解释:

使用CreateRemoteThread 函数可以为目标进程创建一个新的线程

在一个进程为另一个进程创建的线程就是远程线程。

使用 LoadLibrary 函数把指定的DLL加载到进程中

因此就可以在创建远程线程的同时调用 LoadLibrary 函数,把指定的DLL加载到目标进程中。

为什么创建远程线程的时候调用 LoadLibrary 函数就能把 DLL 注入到目标进程中?

  • LoadLibrary  函数是 Kernel32.dll 中的一个成员

  • Kernel32.dll 这个DLL是创建进程必须的一个DLL,并且所有进程在内存中指向的 Kernel32.dll 是同一个地址

  • 所以只要获取到当前进程中 LoadLibrary 函数的地址就够了

为什么要在目标进程中开辟一块内存,再把DLL路径写入到块内存中?

  • LoadLibrary 函数需要一个参数,就是DLL的路径

  • 把当前进程中的一个地址传到另一个进程中,鬼知道另一个进程获取这个地址中的数据时,读取到的是否是我们想要的。

  • 因此需要把DLL的路径直接写入到目标进程中。

  • VirtualAllocEx 函数,在目标进程中开辟一块空间,用来存放DLL路径

  • WriteProcessMemory 函数,把DLL的路径写入进去

  • GetModuleHandle 获取 Kernel32.dll 模块

  • GetProcAddress 获取 LoadLibraryA 函数在内存中的地址

  • CreateRemoteThread 创建远程线程,并调用 LoadLibraryA 函数

LoadLibraryLoadLibraryALoadLibraryW 这三者的区别。

LoadLibrary 是一个宏,可以根据字符集的不同,自动决定是使用 LoadLibraryA 还是 LoadLibraryW

LoadLibrary 宏定义的源码:

WINBASEAPI_Ret_maybenull_HMODULEWINAPILoadLibraryA(    _In_ LPCSTR lpLibFileName    );WINBASEAPI_Ret_maybenull_HMODULEWINAPILoadLibraryW(    _In_ LPCWSTR lpLibFileName    );#ifdef UNICODE#define LoadLibrary  LoadLibraryW#else#define LoadLibrary  LoadLibraryA#endif // !UNICODE

卸载逻辑:

使用 CreateRemoteThread 函数创建一个远程线程

调用 FreeLibrary 函数,卸载DLL

FreeLibrary 函数在 Kernel32.dll 模块中,逻辑同上

FreeLibrary 函数需要 DLL 的内存地址

遍历进程快照可以获取到指定模块的内存地址

卸载和注入的思路都是一样的

确认DLL是否注入到目标进程中:

方式一:使用 procexp

C++ DLL注入怎么实现

方式二:Cheat Engine

C++ DLL注入怎么实现

C++ DLL注入怎么实现

C++ DLL注入怎么实现

确认 Kernel32.dll 中的 FreeLibrary 和 LoadLibraryA 在多个进程中是否指向同一块内存地址:

C++ DLL注入怎么实现

可以通过CE查看多个进程中  Kernel32.dll 的内存地址是否相同

再通过  Kernel32.dll 中函数的内存地址,确认 FreeLibrary 和 LoadLibraryA 这两个函数

关于“C++ DLL注入怎么实现”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网其他教程频道,小编每天都会为大家更新不同的知识点。

--结束END--

本文标题: C++ DLL注入怎么实现

本文链接: https://lsjlt.com/news/321998.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++ DLL注入怎么实现
    这篇文章主要介绍“C++ DLL注入怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C++ DLL注入怎么实现”文章能帮助大家解决问题。先上源码:#include ...
    99+
    2023-06-29
  • C++ DLL注入工具(完整源码)
    先上源码: #include "Inject_Main.h" #include "resource.h" #include <Windows.h> #include &l...
    99+
    2024-04-02
  • C#生成带注释的dll并引用实现
    目录一. 编写.cs文件二. 生成XML文件注释三. 打开MSBuild Command Prompt for VS2015生成dll文件四. 使用另一个项目引用...
    99+
    2024-04-02
  • HTML注入怎么实现
    本篇内容介绍了“HTML注入怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!什么是HTMLHTML称为超文本标记语言,是一种标识性的语...
    99+
    2023-06-17
  • 怎么实现SQL注入
    今天就跟大家聊聊有关怎么实现SQL注入,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。什么是SQL注入SQL注入是指通过构建特殊的输入篡改原来的SQL语句达到攻击者所需的操作。Sql ...
    99+
    2023-06-15
  • c#中怎么使用easyhook实现钩子注入
    在 C# 中,你可以使用 EasyHook 库来实现钩子注入。EasyHook 是一个开源的库,用于在 Windows 平台上实现用...
    99+
    2023-10-24
    c# easyhook
  • C#(.Net)将非托管dll嵌入exe中的实现
    目录托管dll与非托管dll下载与安装添加Dll调用编译托管dll与非托管dll 托管dll实际上是指C#编写的dll,可以直接右键“引用”导入 而大部分情况下,我们需要引用C++写...
    99+
    2024-04-02
  • C#怎么生成带注释的dll并引用
    本篇内容主要讲解“C#怎么生成带注释的dll并引用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C#怎么生成带注释的dll并引用”吧!一. 编写.cs文件注:要想编译dll中注释可用,则代码中的...
    99+
    2023-06-29
  • SQL注入之盲注怎么实现
    这篇文章主要介绍“SQL注入之盲注怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“SQL注入之盲注怎么实现”文章能帮助大家解决问题。sql注入——盲注1.回顾...
    99+
    2024-04-02
  • c#怎么添加dll
    c# 中添加 dll 的方法有:使用项目引用:在解决方案资源管理器中,右键单击项目并选择“添加”>“引用”,然后导航到 dll 文件并单击“添加”按钮。使用 dllimport:导...
    99+
    2024-05-14
    c#
  • 怎么实现SQL注入Trick
    这期内容当中小编将会给大家带来有关怎么实现SQL注入Trick,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。between and 操作符代替比较符操作符 BETWEEN...
    99+
    2024-04-02
  • c++ 如何实现线程注入
    目录简单编写DLL文件:x86 实现远程线程注入:x64 实现远程线程注入:实现普通消息钩子注入:实现全局消息钩子注入:APC应用层异步注入:ZwCreateThreadEx强力注入...
    99+
    2024-04-02
  • c#调用c++的DLL的实现方法
    目录1.采用托管的方式进行调用,就和正常调用c#的dll一样2.非托管的方式进行调用C#是托管型代码,创建的对象会自动回收。C++是非托管型代码,创建的对象需要手动回收(有时不手动回...
    99+
    2024-04-02
  • 在C#程序中注入恶意DLL的方法详解
    目录一、背景二、实现原理1. 基本思路2. 案例演示3. 自定义注入三:总结一、背景 前段时间在训练营上课的时候就有朋友提到一个问题,为什么 Windbg 附加到 C# 程序后,程序...
    99+
    2024-04-02
  • Angular依赖注入怎么实现
    今天小编给大家分享一下Angular依赖注入怎么实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解...
    99+
    2024-04-02
  • python依赖注入怎么实现
    在Python中实现依赖注入有多种方法,下面介绍两种常用的实现方式:1. 使用第三方库:可以使用流行的依赖注入框架,例如Dagger...
    99+
    2023-08-30
    python
  • golang依赖注入怎么实现
    在Go语言中实现依赖注入可以使用两种常见的方式:构造函数注入和接口注入。1. 构造函数注入:构造函数注入是通过在结构体中定义一个包含...
    99+
    2023-09-17
    golang
  • Node+mysql怎么实现SQL注入
    这篇文章主要介绍“Node+mysql怎么实现SQL注入”,在日常操作中,相信很多人在Node+mysql怎么实现SQL注入问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Node+mysql怎么实现SQL注入...
    99+
    2023-07-04
  • Visual C#怎么编写DLL
    本篇内容主要讲解“Visual C#怎么编写DLL”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Visual C#怎么编写DLL”吧!一、引言串行通讯口作为计算机与外部串行设备进行数据传输的重要...
    99+
    2023-06-17
  • c#怎么编译成dll
    如何在 c# 中编译成 dll:创建一个新的类库项目。添加您要编译的代码。在生成菜单中选择“配置管理器”,并选中“dll”复选框。生成解决方案以编译 dll。 如何在 C# 中编译成 ...
    99+
    2024-04-04
    c#
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作