逆向工程核心原理 Chapter23 | DLL注入

2024-09-02 22:36

本文主要是介绍逆向工程核心原理 Chapter23 | DLL注入,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前面学的只是简单的Hook,现在正式开始DLL注入的学习。

0x01 DLL注入概念

DLL注入指的是向运行中的其它进程强制插入特点的DLL文件。

从技术细节上来说,DLL注入就是命令其它进程自行调用LoadLibrary() API,加载用户指定的DLL文件

概念示意图:在这里插入图片描述

很关键的一个点:

加载到notepad.exe进程的myhack.dll具有对notepad.exe进程内存合法的访问权限!

那我们就可以"为所欲为"了。

这里还涉及到一个点:

DLL被加载到进程后会自动运行DllMain()函数,用户可以把待执行的代码放在DllMain()函数内。

类似Java反序列化构造恶意类的静态方法,或者是LD_PRELOAD绕过disable_function的那个__attribute__

在这里插入图片描述

0x02 DLL注入实现——CreateRemoteThread

核心代码:

在这里插入图片描述

核心思路:

  • OpenProcess:获取目标进程句柄
  • VitrualAllocEx:在目标进程内存中分配对应大小的内存
  • WriteProcessMemory:将待注入的dll路径写入上一步分配的内存中
  • GetModuleHandleW + GetProcAddress:获取LoadLibrary()API的地址
  • CreateRemoteThread:传入LoadLibrary()API地址和dll路径地址,调用LoadLibrary("myhack.dll"),触发DllMain函数执行。

这里有几个点得注意下。

注意点

CreateRemoteThread

HANDLE CreateRemoteThread([in]  HANDLE                 hProcess,[in]  LPSECURITY_ATTRIBUTES  lpThreadAttributes,[in]  SIZE_T                 dwStackSize,[in]  LPTHREAD_START_ROUTINE lpStartAddress,[in]  LPVOID                 lpParameter,[in]  DWORD                  dwCreationFlags,[out] LPDWORD                lpThreadId
);

我们这里关注两个参数:lpStartAddresslpParameter

在这里插入图片描述

这也是为什么我们要获得LoadLibrary()API的地址,以及将myhack.dll路径字符串写入目标进程的内存。

kernel32.dll

这里我们LoadLibrary()这些都是在我们当前进程获取的,并不是在目标进程notepad.exe

可以这么做的原因(也是这种DLL注入能成功的原因):

在这里插入图片描述

ThreadProc && LoadLibrary

这个也是很有趣的点。

在这里插入图片描述

两者接收的参数是类似的,所以完全可以将LoadLibray传为ThreadProc参数,把LoadLibrary的参数lpFileName传为lpParameter


下面开始手写一下代码。

代码编写

dll

这里编写用到了一个小技巧:

我们可以实现另一个函数,然后DllMain用CreateThread来调用。(避免了DllMain中写大量代码)

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"#include<Windows.h>
#include<urlmon.h>#pragma comment (lib,"Urlmon.lib")
#define URL (L"https://www.runoob.com")
#define FILENAME (L"C:\\Users\\Administrator\\Desktop\\down.html")DWORD WINAPI down(LPVOID lpParam) {HRESULT hResult = URLDownloadToFileW(NULL, URL, FILENAME, 0, NULL);if (hResult == S_OK) {OutputDebugString(L"下载成功!\n");}else {OutputDebugString(L"下载失败!\n");return 1;}return 0;
}BOOL APIENTRY DllMain( HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved)
{switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:MessageBoxA(NULL, "DLL Injected!\n", "REVERSING", MB_OK);HANDLE hThread = CreateThread(NULL, 0, &down, NULL, 0, NULL);CloseHandle(hThread);break;}return TRUE;
}

main

#include<Windows.h>
#include<stdio.h>
#include<stdlib.h>
#include<tchar.h>
#include<iostream>
using namespace std;void Inject(DWORD dwPid, WCHAR* szPath) {DWORD dwBufSize = (DWORD)(wcslen(szPath) + 1) * sizeof(WCHAR);// 1. OpenProcess()HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);// 2. VitrualAllocEx()LPVOID pRemoteAddress = VirtualAllocEx(hProcess,NULL,dwBufSize,MEM_COMMIT,PAGE_READWRITE);// 3. WriteProcessMemory()WriteProcessMemory(hProcess, pRemoteAddress, szPath, dwBufSize, NULL);// 4. GET LoadLibraryWHMODULE hK32 = GetModuleHandle(L"kernel32.dll");LPVOID pLW = GetProcAddress(hK32,"LoadLibraryW");cout << "loadAdd:" << pLW << "\n";// 5. CreateRemoteThread()HANDLE hThread = CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)pLW,pRemoteAddress,0,NULL);if (!hThread){printf("CreateRemoteThread Failed");}WaitForSingleObject(hThread, -1);VirtualFreeEx(hProcess, pRemoteAddress, dwBufSize, MEM_DECOMMIT);
}
int _tmain(int argc, _TCHAR* argv[]) {wchar_t wStr[] = L"C:\\Users\\Administrator\\Desktop\\逆向练习\\DLL Injection\\dll\\Dll1\\x64\\Debug\\Dll1.dll";DWORD dwPid = 0;HWND hNotepad = FindWindowA("Notepad", NULL); // 首字母大写。。// get PIDDWORD dwRub = GetWindowThreadProcessId(hNotepad, &dwPid);printf("目标窗口的进程PID为 : %d\n", dwPid);Inject(dwPid, wStr);system("pause");return 0;
}

效果

在这里插入图片描述

在这里插入图片描述

0x03 DLL注入实现——AppInit_DLLs

这种在渗透中可以留后门。

原理

在这里插入图片描述

dll编写

若当前加载自己的进程为"notepad.exe",则以隐藏模式运行IE,连接指定网站。

这里就不按教程的写法了,而是直接把先前的dll修改一下,加一个notepad.exe的判断

dll:

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"#include<Windows.h>
#include<urlmon.h>
#include<tchar.h>#pragma comment (lib,"Urlmon.lib")
#define URL (L"https://www.runoob.com")
#define FILENAME (L"C:\\Users\\Administrator\\Desktop\\down2.html")
#define TARGET_PROC (L"notepad.exe")DWORD WINAPI down(LPVOID lpParam) {HRESULT hResult = URLDownloadToFileW(NULL, URL, FILENAME, 0, NULL);if (hResult == S_OK) {OutputDebugString(L"下载成功!\n");}else {OutputDebugString(L"下载失败!\n");return 1;}return 0;
}BOOL APIENTRY DllMain(HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved
)
{TCHAR szPath[MAX_PATH] = { 0 };TCHAR *p = NULL;switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:if (!GetModuleFileName(NULL, szPath, MAX_PATH))break;if (!(p = _tcsrchr(szPath, '\\')))break;if (_tcsicmp(p + 1, TARGET_PROC))break;HANDLE hThread = CreateThread(NULL, 0, &down, NULL, 0, NULL);CloseHandle(hThread);break;}return TRUE;
}

编译后放在C:/Users/Administrator/Desktop/Dll2.dll

编辑注册表

然后编辑注册表。(记得先导出备份)

编辑AppInit_Dlls

在这里插入图片描述

再修改LoadAppInit_Dlls注册表项的值为1.在这里插入图片描述

重启。

然后用ProcessMonitor看,随便找个调用了User32.dll的进程:

在这里插入图片描述

可以看到我们自己的Dll2.dll已经加载了。

那我们尝试运行notepad.exe

在这里插入图片描述

成功。

当然,实战中这种必会被杀软杀掉。。所以只是当个技巧知识点掌握一下。

总结

共勉!

在这里插入图片描述

这篇关于逆向工程核心原理 Chapter23 | DLL注入的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1131257

相关文章

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

hdu4407(容斥原理)

题意:给一串数字1,2,......n,两个操作:1、修改第k个数字,2、查询区间[l,r]中与n互质的数之和。 解题思路:咱一看,像线段树,但是如果用线段树做,那么每个区间一定要记录所有的素因子,这样会超内存。然后我就做不来了。后来看了题解,原来是用容斥原理来做的。还记得这道题目吗?求区间[1,r]中与p互质的数的个数,如果不会的话就先去做那题吧。现在这题是求区间[l,r]中与n互质的数的和

hdu4407容斥原理

题意: 有一个元素为 1~n 的数列{An},有2种操作(1000次): 1、求某段区间 [a,b] 中与 p 互质的数的和。 2、将数列中某个位置元素的值改变。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.Inpu

hdu4059容斥原理

求1-n中与n互质的数的4次方之和 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWrit

【LabVIEW学习篇 - 21】:DLL与API的调用

文章目录 DLL与API调用DLLAPIDLL的调用 DLL与API调用 LabVIEW虽然已经足够强大,但不同的语言在不同领域都有着自己的优势,为了强强联合,LabVIEW提供了强大的外部程序接口能力,包括DLL、CIN(C语言接口)、ActiveX、.NET、MATLAB等等。通过DLL可以使用户很方便地调用C、C++、C#、VB等编程语言写的程序以及windows自带的大

PostgreSQL核心功能特性与使用领域及场景分析

PostgreSQL有什么优点? 开源和免费 PostgreSQL是一个开源的数据库管理系统,可以免费使用和修改。这降低了企业的成本,并为开发者提供了一个活跃的社区和丰富的资源。 高度兼容 PostgreSQL支持多种操作系统(如Linux、Windows、macOS等)和编程语言(如C、C++、Java、Python、Ruby等),并提供了多种接口(如JDBC、ODBC、ADO.NET等

Jenkins构建Maven聚合工程,指定构建子模块

一、设置单独编译构建子模块 配置: 1、Root POM指向父pom.xml 2、Goals and options指定构建模块的参数: mvn -pl project1/project1-son -am clean package 单独构建project1-son项目以及它所依赖的其它项目。 说明: mvn clean package -pl 父级模块名/子模块名 -am参数

寻迹模块TCRT5000的应用原理和功能实现(基于STM32)

目录 概述 1 认识TCRT5000 1.1 模块介绍 1.2 电气特性 2 系统应用 2.1 系统架构 2.2 STM32Cube创建工程 3 功能实现 3.1 代码实现 3.2 源代码文件 4 功能测试 4.1 检测黑线状态 4.2 未检测黑线状态 概述 本文主要介绍TCRT5000模块的使用原理,包括该模块的硬件实现方式,电路实现原理,还使用STM32类