Windows注入与拦截(1) — DLL注入的基本原理「建议收藏」

Windows注入与拦截(1) — DLL注入的基本原理「建议收藏」一.DLL注入技术的用途从前面的《Windows内存体系》系列文章中我们可以知道,在Windows系统中,每个进程都有自己私有的地址空间。当我们用指针来引用内存的时候,指针的值表示的是进程自己的地址空间的一个虚拟的内存地址。进程不能通过指针来引用其他进程地址空间的内存。因此,如果一个进程有缺陷会导致其引用和覆盖随机地址处的内存,那么这个缺陷的影响就会不会扩散到其他的进程。独立的地址空间有…

大家好,又见面了,我是你们的朋友全栈君。

一. DLL注入技术的用途

从前面的《Windows内存体系》系列文章中我们可以知道,在Windows系统中,每个进程都有自己私有的地址空间。当我们用指针来引用内存的时候,指针的值表示的是进程自己的地址空间的一个虚拟的内存地址。进程不能通过指针来引用其他进程地址空间的内存。因此,如果一个进程有缺陷会导致其引用和覆盖随机地址处的内存,那么这个缺陷的影响就会不会扩散到其他的进程。

独立的地址空间有利于系统的稳定性。但很多时候我们还是需要跨越进程的边界来访问另一个进程地址空间,比如:

  • 我们要从另一个进程创建的窗口来派生子类窗口。比如附着在windows资源管理器上的一些小插件等。
  • 我们需要假借其他进程之名做某些事情。
  • 我们需要获取其他进程的更多详细信息,如加载了哪些dll等。
  • 我们需要对其他进程的某些操作进程拦截。
  • 干一些羞羞的事情…

为了满足上面的这些需求,我们可以使用DLL注入的技术,将我们自己开发的dll注入到另一个进程的地址空间中,让dll中的代码在该进程的地址空间中执行,那么我们就可以在那个中进程为所欲为了。

二. 什么样的DLL可以被注入?

理论上任何DLL都可以被注入到其他进程之中,但是大多数情况下,我们注入到其他进程之中是为了实现某些功能、做某些事情的,所以我们需要在我们的DLL被注入之后,DLL中的功能代码能够被调用执行。

我们知道DLL被首次载入到进程中时,会收到DLL_PROCESS_ATTACH的通知,即调用DllMain函数,并且参数fdwReason的值被设为DLL_PROCESS_ATTACH。我们可以在收到DLL_PROCESS_ATTACH通知时开始我们的业务逻辑。

下面是一个最简单的dll的源码,在被注入成功后(即收到DLL_PROCESS_ATTACH通知时)弹出消息提示框:

BOOL APIENTRY DllMain(HMODULE hModule, DWORD fdwReason, LPVOID lpReserved ) {
    switch(fdwReason) {
        case DLL_PROCESS_ATTACH:
        {
            MessageBox(NULL, TEXT("我已经被注入啦"), TEXT("信息"), MB_ICONINFORMATION);
            break;
        }
        case DLL_THREAD_ATTACH:
        {
            break;
        }
        case DLL_THREAD_DETACH:
        {
            break;
        }
        case DLL_PROCESS_DETACH:
        {
            break;
        }
    }
    return TRUE;
}

但是,如果DLL_PROCESS_ATTACH通知处理过程中的操作被挂起(如消息提示框)或者被阻塞(如用户创建了一个消息循环),这样就会导致目标进程中的LoadLibrary(Ex)函数一直无法返回(dll都是通过LoadLibrary(Ex)函数来加载的),所以我们一般会在DLL_PROCESS_ATTACH通知处理过程中创建一个子线程,将业务逻辑放置到该子线程中执行,代码如下:

#include <windows.h>
#include <tchar.h>
#include <process.h>

unsigned int __stdcall PluginProc(LPVOID pArg) {
    MessageBox(NULL, TEXT("我已经被注入啦"), TEXT("信息"), MB_OK | MB_ICONASTERISK);
    return 0;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD  fdwReason, LPVOID lpReserved) {
    HANDLE hThread = NULL;

    switch(fdwReason) {
        case DLL_PROCESS_ATTACH:
        {
            hThread = (HANDLE)_beginthreadex(NULL, 0, PluginProc, NULL, 0, NULL);

            if (hThread) {
                CloseHandle(hThread); // 关闭句柄,防止句柄泄漏
            }
            break;
        }
        case DLL_THREAD_ATTACH:
        {
            break;
        }
        case DLL_THREAD_DETACH:
        {
            break;
        }
        case DLL_PROCESS_DETACH:
        {
            break;
        }
    }
    return TRUE;
}

另外,当DLL被从目标进程卸载时,DLL会收到DLL_PROCESS_DETACH通知,我们需要在该通知的处理过程中做好最后的善后工作,防止资源泄漏、程序崩溃等问题出现。

本文介绍了“什么样的DLL可以被用来注入”,后面的文章会着重介绍如何通过不同的方式将DLL注入到目标进程。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/145368.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 网约技师APP详细设计说明书「建议收藏」

    网约技师APP详细设计说明书「建议收藏」目录1引言31.1编写目的31.2背景31.3定义31.4参考资料42程序系统的结构43登录程序Login()设计说明53.1程序描述53.2功能63.3性能63.4输人项63.5输出项73.6算法73.7流程逻辑73.8接口83.9存储分配83.10注释设计

  • layout_gravity和gravity的用法

    layout_gravity和gravity的用法也谈layout_gravity和gravity的用法相信对于Android的初学者来说,大家都曾经被layout里这两个极其相似的属性迷惑过。简单使用一下搜索工具,我们就不难找到下面这样的答案:layout_gravity表示组件自身在父组件中的位置gravity            表示组件的子组件在组件中的位置看似很简单嘛~)貌似大伙瞅一眼就明白了。

  • 项目范围管理:项目范围管理的概念是什么_项目范围管理规划案例

    项目范围管理:项目范围管理的概念是什么_项目范围管理规划案例项目范围管理包括确保项目做且只做所需的全部工作,以成功完成项目的各个过程。 项目范围管理关注的焦点是:什么是包括在项目之内的,什么是不包括在项目之内的,即为项目工作明确划定边界。 对项目范围管理和控制的有效性,是衡量项目是否达到成功的一个必要标准,项目范围的管理不仅仅是项目整体管理的一个主要部分,同时在项目中不断地重申项目工作范围,有利于项目不偏离轨道,是项目中实施控制管理的一个主要手段。 项目范围是项目其他各方面管理的基础。如果范围都弄不清楚,成本、进度和质量等就无从谈起。确认项目范围对项目管理有如

  • RabbitMQ流控-FLow Control

    RabbitMQ流控-FLow Control当Connection发布消息的速度太快,队列无法跟上(消费速度低于生产速度),RabbitMQ会降低Connection的速度,无需配置。流控的Connection可以在rabbitmqctl、管理UI和HTTPAPI响应中显示flow状态。这意味着连接每秒要经历多次阻塞和解除阻塞,以便将消息传入的速度保持在服务器其他部分(例如,将这些消息路由到的队列)能够处理的速度。一般来说,处于流…

  • 浏览器下载文件名乱码_ie浏览器下载文件名字是乱码

    浏览器下载文件名乱码_ie浏览器下载文件名字是乱码FireFox下载时文件名乱码问题解决

  • lucene2.4.1的TokenStream

    lucene2.4.1的TokenStream[code="java"]importjava.io.IOException;importorg.apache.lucene.analysis.Token;importorg.apache.lucene.index.Payload;/***TokenStream用来分析文字流,按一定的规则罗列token,在lucene有字节流是即将要索引的文本,或者查询的关键字。…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号