3.1 DLL注入:常规远程线程注入

dll,注入,常规,远程,线程 · 浏览次数 : 17

小编点评

**动态链接库注入技术** 动态链接库注入技术是一种特殊的技术,允许在运行的进程中注入 DLL 动态链接库,从而改变目标进程的行为。 **实现方式** 常见的实现方式包括: * **远程线程注入**:利用 `CreateRemoteThread()` 函数创建一个远线程,并让它在目标进程中执行 DLL 代码。 **核心概念** * 创建进程句柄 * 获取目标进程的内存空间 * 写入 DLL 文件路径到内存中 * 获取 `LoadLibraryA()` 函数的地址 * 创建远线程并启动 * 获取 DLL 代码的入口地址 * 执行 DLL 代码 **代码示例** 以下代码展示了如何使用 `CreateRemoteThreadInjectDll()` 函数在 32 位 DLL 中注入代码: ```c++ #include #include #include #include // 远程线程注入函数 BOOL CreateRemoteThreadInjectDll(DWORD Pid, char* DllName) { HANDLE hProcess = NULL; SIZE_T dwSize = 0; LPVOID pDllAddr = NULL; FARPROC pFuncProcAddr = NULL; // 打开注入进程 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid); if (NULL == hProcess) { return FALSE; } // 获取注入文件的完整路径 dwSize = sizeof(char) + lstrlen(DllName); // 写入 DLL 文件路径到内存中 if (FALSE == WriteProcessMemory(hProcess, pDllAddr, DllName, dwSize, NULL)) { return FALSE; } // 获取 LoadLibraryA() 函数的地址 pFuncProcAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"); if (NULL == pFuncProcAddr) { return FALSE; } // 启动线程注入 HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFuncProcAddr, pDllAddr, 0, NULL); if (NULL == hRemoteThread) { return FALSE; } // 关闭句柄 CloseHandle(hProcess); return TRUE; } ``` **注意** * 动态链接库注入可能存在安全风险,因为攻击者可以注入恶意代码并控制目标进程的行为。 * 仅在信任来源执行 DLL 代码是安全的。

正文

动态链接库注入技术是一种特殊的技术,它允许在运行的进程中注入DLL动态链接库,从而改变目标进程的行为。DLL注入的实现方式有许多,典型的实现方式为远程线程注入,该注入方式的注入原理是利用了Windows系统中提供的CreateRemoteThread()这个API函数,该函数第四个参数是准备运行的线程,我们将LoadLibrary()函数填入其中,这样就可以执行远程进程中的LoadLibrary()函数,进而将我们自己准备的DLL加载到远程进程空间中执行,DLL在被装载后则会自动执行初始化部分。

远程线程注入的实现可以总结为如下流程;

  • 1.OpenProcess 打开进程获取进程句柄
  • 2.VirtualAllocEx 在目标进程申请一块内存
  • 3.WriteProcessMemory 将注入DLL路径写出到内存中
  • 4.GetProcAddress 获得LoadLibraryA函数的内存地址
  • 5.CreateRemoteThread 创建远线程,实现DLL注入

远程注入的核心实现原理是利用了CreateRemoteThread函数,CreateRemoteThread是Windows系统的一个函数,能够在指定的进程上下文中创建一个线程。该函数可以使一个进程在另一个进程中执行任意代码,并返回新线程的句柄。在DLL注入中,我们可以使用该函数在目标进程的上下文中创建一个新线程,从而使我们的DLL代码被加载和运行。该函数的声明如下所示;

HANDLE WINAPI CreateRemoteThread(
  HANDLE                 hProcess,
  LPSECURITY_ATTRIBUTES  lpThreadAttributes,
  SIZE_T                 dwStackSize,
  LPTHREAD_START_ROUTINE lpStartAddress,
  LPVOID                 lpParameter,
  DWORD                  dwCreationFlags,
  LPDWORD                lpThreadId
);

参数说明:

  • hProcess: 目标进程的句柄。
  • lpThreadAttributes: 线程安全描述符,通常为NULL。
  • dwStackSize: 新线程的初始化栈大小,通常为0。
  • lpStartAddress: 线程入口点,指向要在新线程中执行的代码。
  • lpParameter: 传递给线程入口点的参数。
  • dwCreationFlags: 线程创建标志,通常为0。
  • lpThreadId: 如果非NULL,返回新线程的ID号。

在DLL注入中,我们可以使用它来在指定的进程上下文中执行我们的DLL代码,使其被加载和运行。这段代码的实现很容易理解,我们以注入32为DLL为例,代码如下所示;

#include <windows.h>
#include <iostream>
#include <TlHelp32.h>
#include <tchar.h>

// 传入进程名称返回该进程PID
DWORD FindProcessID(LPCTSTR szProcessName)
{
    DWORD dwPID = 0xFFFFFFFF;
    HANDLE hSnapShot = INVALID_HANDLE_VALUE;
    PROCESSENTRY32 pe;
    pe.dwSize = sizeof(PROCESSENTRY32);
    hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
    Process32First(hSnapShot, &pe);
    do
    {
        if (!_tcsicmp(szProcessName, (LPCTSTR)pe.szExeFile))
        {
            dwPID = pe.th32ProcessID;
            break;
        }
    } while (Process32Next(hSnapShot, &pe));
    CloseHandle(hSnapShot);
    return dwPID;
}

// 远程线程注入
BOOL CreateRemoteThreadInjectDll(DWORD Pid, char* DllName)
{
    HANDLE hProcess = NULL;
    SIZE_T dwSize = 0;
    LPVOID pDllAddr = NULL;
    FARPROC pFuncProcAddr = NULL;

    // 打开注入进程
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);
    if (NULL == hProcess)
    {
        return FALSE;
    }

    // 得到注入文件的完整路径
    dwSize = sizeof(char) + lstrlen(DllName);

    // 在对端申请一块内存
    pDllAddr = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
    if (NULL == pDllAddr)
    {
        return FALSE;
    }

    // 将注入文件名写入到内存中
    if (FALSE == WriteProcessMemory(hProcess, pDllAddr, DllName, dwSize, NULL))
    {
        return FALSE;
    }

    // 得到LoadLibraryA()函数的地址
    pFuncProcAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
    if (NULL == pFuncProcAddr)
    {
        return FALSE;
    }

    // 启动线程注入
    HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFuncProcAddr, pDllAddr, 0, NULL);
    if (NULL == hRemoteThread)
    {
        return FALSE;
    }

    // 关闭句柄
    CloseHandle(hProcess);
    return TRUE;
}

int main(int argc, char *argv[])
{
    DWORD pid = FindProcessID("lyshark.exe");
    std::cout << "进程PID: " << pid << std::endl;

    bool flag = CreateRemoteThreadInjectDll(pid, (char *)"d://hook.dll");
    std::cout << "注入状态: " << flag << std::endl;

    return 0;
}

本文作者: 王瑞
本文链接: https://www.lyshark.com/post/82225748.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

与3.1 DLL注入:常规远程线程注入相似的内容:

3.1 DLL注入:常规远程线程注入

动态链接库注入技术是一种特殊的技术,它允许在运行的进程中注入DLL动态链接库,从而改变目标进程的行为。DLL注入的实现方式有许多,典型的实现方式为远程线程注入,该注入方式的注入原理是利用了`Windows`系统中提供的`CreateRemoteThread()`这个API函数,该函数第四个参数是准备运行的线程,我们将`LoadLibrary()`函数填入其中,这样就可以执行远程进程中的`LoadL

3.2 DLL注入:远程APC异步注入

APC(Asynchronous Procedure Call)异步过程调用是一种`Windows`操作系统的核心机制,它允许在进程上下文中执行用户定义的函数,而无需创建线程或等待OS执行完成。该机制适用于一些频繁的、短暂的或非常细微的操作,例如改变线程优先级或通知线程处理任务。在`APC机制`中,当某些事件发生时(例如文件IO,网络IO或定时器触发),这些事件将被操作系统添加到一个`APC队列`

3.3 DLL注入:突破会话0强力注入

Session是`Windows`系统的一个安全特性,该特性引入了针对用户体验提高的安全机制,即拆分Session 0和用户会话,这种拆分`Session 0`和`Session 1`的机制对于提高安全性非常有用,这是因为将桌面服务进程,驱动程序以及其他系统级服务取消了与用户会话的关联,从而限制了攻击者可用的攻击面。由于`DLL`注入在`Session 0`中的注入机制不同于在用户会话中的注入机制

3.4 DLL注入:全局消息钩子注入

SetWindowHookEx 是`Windows`系统的一个函数,可用于让一个应用程序安装全局钩子,但读者需要格外注意该方法安装的钩子会由操作系统注入到所有可执行进程内,虽然该注入方式可以用于绕过游戏保护实现注入,但由于其属于全局注入所以所有的进程都会受到影响,而如果想要解决这个问题,则需要在`DllMain()`也就是动态链接库开头位置进行判断,如果是我们所需操作的进程则执行该DLL模块内的功

[Cmake Qt]找不到文件ui_xx.h的问题?有关Qt工程的问题,看这篇文章就行了。

前言 最近在开发一个组件,但是这个东西是以dll的形式发布的界面库,所以在开发的时候就需要上层调用。 如果你是很懂CMake的话,ui_xx.h的文件目录在 $ 下 然后除了有关这个ui_xx.h,还有一些别的可以简单聊聊的 一、父子工程组织,或者说依赖关系 在使用CMake进行开发的时候,一般可以

4.3 IAT Hook 挂钩技术

IAT(Import Address Table)Hook是一种针对Windows操作系统的API Hooking 技术,用于修改应用程序对动态链接库(DLL)中导入函数的调用。IAT是一个数据结构,其中包含了应用程序在运行时使用的导入函数的地址。IAT Hook的原理是通过修改IAT中的函数指针,将原本要调用的函数指向另一个自定义的函数。这样,在应用程序执行时,当调用被钩子的函数时,实际上会执行

cmake构建32位应用程序

1. 背景介绍 2. 工具介绍 3. 环境搭建 4. MinGW编译器版本 1. 背景介绍 最近需要使用第三方动态库文件G33DDCAPI.dll进行二次开发。由于这个动态库文件生成的时间比较早,且只提供了32位的版本,并没有提供源代码。如果希望利用这个动态库进行开发,有两种解决方法: 编译64位应

3.1 C++ STL 双向队列容器

双向队列容器(Deque)是C++ STL中的一种数据结构,是一种双端队列,允许在容器的两端进行快速插入和删除操作,可以看作是一种动态数组的扩展,支持随机访问,同时提供了高效的在队列头尾插入和删除元素的操作。Deque 双向队列容器与Vector非常相似,它不但可以在数组尾部插入和删除元素,还可以在头部进行插入和删除,队列算法的时间复杂度也是`常数阶O(1)`,队列内部的数据机制和性能与Vecto

3.1 C/C++ 使用字符与指针

C/C++语言是一种通用的编程语言,具有高效、灵活和可移植等特点。C语言主要用于系统编程,如操作系统、编译器、数据库等;C语言是C语言的扩展,增加了面向对象编程的特性,适用于大型软件系统、图形用户界面、嵌入式系统等。C/C++语言具有很高的效率和控制能力,但也需要开发人员自行管理内存等底层资源,对于初学者来说可能会有一定的难度。

umich cv-3-1

UMICH CV Neural Network 对于传统的线性分类器,分类效果并不好,所以这节引入了一个两层的神经网络,来帮助我们进行图像分类 可以看出它的结构十分简单,x作为输入层,经过max(0,W1*x)到达h隐藏层,再经过W2到达s输出层 如果我们对隐藏层的结果进行可视化,我们可以看到如下的