【windows核心编程】使用远程线程注入DLL
前言
该技术是指通过在【目标进程】中创建一个【远程线程】来达到注入的目的。
创建的【远程线程】函数为LoadLibrary, 线程函数的参数为DLL名字, 想要做的工作在DLL中编写。
示意图如下:

相关API
1、创建远程线程
//该函数除了第一个参数为目标进程句柄外
//其他参数均和CreateThread一样
HANDLE hThread = CreateRemoteThread(
__in HANDLE hProcess, //目标进程句柄
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in SIZE_T dwStackSize, //线程栈初始预定空间=Max(/STACK, dwStackSize, 初始调拨大小=(dwStackSize == 0? /STACK, dwStackSize)
__in LPTHREAD_START_ROUTINE lpStartAddress, //线程函数
__in_opt LPVOID lpParameter, //线程函数参数
__in DWORD dwCreationFlags, //标志
__out_opt LPDWORD lpThreadId //线程ID
)
失败返回NULL
2、根据进程ID获取进程句柄,并且传入相应权限标志,自定义函数
//根据进程ID获取进程句柄
HANDLE GetProcessHandle(DWORD deProcessID)
{
HANDLE hProcess = OpenProcess(
PROCESS_QUERY_INFORMATION //查询进程句柄
| PROCESS_VM_OPERATION //PROCESS_VM_WRITE + PROCESS_VM_READ + x
| PROCESS_CREATE_THREAD //创建线程
| PROCESS_VM_WRITE, //WriteProcessMemory
FALSE, //不继承
deProcessID //进程句柄
); return hProcess;
}
3、获得LoadLibrary函数地址
由于LoadLibrary是个宏,而非实际的函数,因此需要使用GetProcAddress并传入LoadLibraryW 或 LoadLibraryA来获取真实地址
4、从目标进程申请内存
当把Dll名字作为线程函数LoadLibraryW(A)的参数传给他时,由于此时的线程是运行在其他进程地址空间中的,因此当把本地进程中的字符串指针传给CreateRemoteThread函数时会引起访问违例,因此需要从目标进程地址空间中申请内存,并将本地Dll名字符串写入远程进程,然后使用远程进程中的地址作为CreateRemoteThread函数的参数。
//该函数除了第一个参数为进程句柄外
//其他参数和VirtualAlloc一样
LPVOID WINAPI VirtualAllocEx(
__in HANDLE hProcess, //进程句柄
__in_opt LPVOID lpAddress, //地址,为NULL自动找一个合适的地址
__in SIZE_T dwSize, //内存块大小,单位为字节
__in DWORD flAllocationType, //分配类型,预定或调拨
__in DWORD flProtect //保护属性
);
5、往远程进程中写输入, 即把本地DLL名字字符串 写入 远程进程地址空间中
BOOL WINAPI WriteProcessMemory(
__in HANDLE hProcess, //进程句柄
__in LPVOID lpBaseAddress, //写入地址
__in LPCVOID lpBuffer, //源缓冲区
__in SIZE_T nSize, //缓冲区大小,单位为字节
__out SIZE_T *lpNumberOfBytesWritten //实际写入的字节数
);
No code you say a XX
本demo的作用是将一个DLL注入一个窗口标题为"Endl"的目标进程,该DLL的作用是在DLL_PROCESS_ATTACH中ExitProcess,即强制退出目标进程。
开发进程代码
//根据进程ID获取进程句柄
HANDLE GetProcessHandle(DWORD deProcessID)
{
HANDLE hProcess = OpenProcess(
PROCESS_QUERY_INFORMATION //查询进程句柄
| PROCESS_VM_OPERATION //PROCESS_VM_WRITE + PROCESS_VM_READ + x
| PROCESS_CREATE_THREAD //创建线程
| PROCESS_VM_WRITE, //WriteProcessMemory
FALSE, //不继承
deProcessID //进程句柄
); return hProcess;
} int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwErrCode = ; //获取进程ID
//HWND hWnd = FindWindow(NULL, _T("计算器"));
HWND hWnd = FindWindow(NULL, _T("Endl")); DWORD dwProcessID = ;
GetWindowThreadProcessId(hWnd, &dwProcessID);
HANDLE hDestProcess = GetProcessHandle(dwProcessID);
if(NULL == hDestProcess)
{
cerr<<"打开进程句柄失败"<<endl;
return ;
} //获取KERNER32.DLL 模块句柄
HMODULE hModule = GetModuleHandle(_T("kernel32.dll"));
if(NULL == hModule)
{
cerr<<"获取kernel32.dll句柄失败"<<endl;
return -;
} //线程函数,kernerl32.dll被映射到所有进程内相同的地址
LPTHREAD_START_ROUTINE lpThreadStartRoutine =
(LPTHREAD_START_ROUTINE)GetProcAddress(hModule, "LoadLibraryW");
if(NULL == lpThreadStartRoutine)
{
cerr<<"获取LoadLibraryW地址失败"<<endl;
return -;
} //从目标进程内申请堆内存
LPVOID lpMemory = VirtualAllocEx(
hDestProcess, NULL, MAX_PATH, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if(NULL == lpMemory)
{
cerr<<"申请目标进程内存失败"<<endl;
return -;
} //注入DLL
LPCTSTR lpDLLName = _T("DLLForRemoteThread.dll"); //把DLL名字写入目标进程
BOOL bWriteMemory = WriteProcessMemory(
hDestProcess, lpMemory, lpDLLName, (_tcslen(lpDLLName) + ) * sizeof(lpDLLName[]), NULL); if(FALSE == bWriteMemory)
{
cerr<<"WriteProcessMemory失败"<<endl;
dwErrCode = GetLastError();
VirtualFreeEx(hModule, lpMemory, , MEM_RELEASE | MEM_DECOMMIT);
return -;
} //创建远程线程
HANDLE hThread = CreateRemoteThread(
hDestProcess,
NULL,
,
lpThreadStartRoutine,
lpMemory,
,
NULL);
if (NULL == hThread || INVALID_HANDLE_VALUE == hThread)
{
cerr<<"创建远程线程CreateRomoteThread失败"<<endl;
VirtualFreeEx(hModule, lpMemory, , MEM_RELEASE | MEM_DECOMMIT);
return -;
} VirtualFreeEx(hModule, lpMemory, , MEM_RELEASE | MEM_DECOMMIT); return ;
}
待注入DLL代码
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
#if defined _DEBUG
OutputDebugString(TEXT("\r\n*************DLL_PROCESS_ATTACH*************"));
#endif
ExitProcess();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
} return TRUE;
}
【windows核心编程】使用远程线程注入DLL的更多相关文章
- 【windows核心编程】远程线程DLL注入
15.1 DLL注入 目前公开的DLL注入技巧共有以下几种: 1.注入表注入 2.ComRes注入 3.APC注入 4.消息钩子注入 5.远线程注入 6.依赖可信进程注入 7.劫持进程创建注入 8.输 ...
- 远程线程注入DLL突破session 0 隔离
远程线程注入DLL突破session 0 隔离 0x00 前言 补充上篇的远程线程注入,突破系统SESSION 0 隔离,向系统服务进程中注入DLL. 0x01 介绍 通过CreateRemoteTh ...
- 远程线程注入DLL
远程线程注入 0x00 前言 远程线程注入是一种经典的DLL注入技术.其实就是指一个新进程中另一个进程中创建线程的技术. 0x01 介绍 1.远程线程注入原理 画了一个图大致理解了下远程线程注入dll ...
- 远程线程注入dll,突破session 0
前言 之前已经提到过,远线程注入和内存写入隐藏模块,今天介绍突破session 0的dll注入 其实今天写这个的主要原因就是看到倾旋大佬有篇文章提到:有些反病毒引擎限制从lsass中dump出缓存,可 ...
- 详细解读:远程线程注入DLL到PC版微信
一.远程线程注入的原理 1.其基础是在 Windows 系统中,每个 .exe 文件在双击打开时都会加载 kernel32.dll 这个系统模块,该模块中有一个 LoadLibrary() 函数,可以 ...
- 《windows核心编程系列》十七谈谈dll
DLL全称dynamic linking library.即动态链接库.广泛应用与windows及其他系统中.因此对dll的深刻了解,对计算机软件开发专业人员来说非常重要. windows中所有API ...
- 微信 电脑版 HOOK(WeChat PC Hook)- 远程线程注入dll原理
Windows加载dll的特性 1.Windows系统中,每个exe软件运行的时候,会加载系统模块kernel32.dll 2.所有加载进exe软件的系统模块kernel32.dll,内存地址都是一样 ...
- CreateRemoteThread远程线程注入Dll与Hook
CreateRemoteThread虽然很容易被检测到,但是在有些场合还是挺有用的.每次想用的时候总想着去找以前的代码,现在在这里记录一下. CreateRemoteThread远程注入 DWORD ...
- Windows核心编程 第十九章 DLL基础
第1 9章 D L L基础 这章是介绍基本dll,我就记录一些简单应用,dll的坑点以及扩展后面两章会说,到时候在总结. 自从M i c r o s o f t公司推出第一个版本的Wi n d o w ...
随机推荐
- 【nginx网站性能优化篇(3)】反向代理实现负载均衡
注意,本篇文章为负载均衡的理论篇,后续找个机会推出实战篇.理论篇主要讲述如何配置负载均衡,配置负载均衡不难.难的是真正的实战,比如如何做到多服务器之间的数据共享(session,file等),多cac ...
- SpringMVC学习总结(三)——Controller接口详解(1)
4.12.ParameterizableViewController 参数化视图控制器,不进行功能处理(即静态视图),根据参数的逻辑视图名直接选择需要展示的视图. <bean name=&quo ...
- 卓京---java基础2
2.数据类型 基本类型: 整型: byte字节型 8位(bit) -2^7~2^7-1(-128~127) 0000 0000 short短整型 16位 -2^15~2^15-1(-32768 ...
- C++:对象的初始化和构造函数
对象的初始化和构造函数 构造函数:是一种特殊的成员函数,它主要用于为对象分配空间,进行初始化.构造函数 的名字必须与类名相同,它不要用户来调用,而是在建立对象时自动执行的 形式一: 类名 对象名(实参 ...
- 实例学习Bloom Filter
0. 科普1. 为什么需要Bloom Filter2. 基本原理3. 如何设计Bloom Filter4. 实例操作5. 扩展 0. 科普 Bloom Filter是由Bloom在1970年提出的一种 ...
- 公交wifi运营平台分析
一.前言背景 昨晚下午,老板让看一些车载公交wifi后台管理的一些东西,这个随着移动端设备而兴起的wifi战,慢慢的也会越演越烈. 现在于很多人在外面的时候,进入一家店首先看的不是菜单,而是问一句“你 ...
- NuGet学习笔记
NuGet学习笔记(1)——初识NuGet及快速安装使用 NuGet学习笔记(2)——使用图形化界面打包自己的类库 NuGet学习笔记(3)——搭建属于自己的NuGet服务器
- [POJ3177]Redundant Paths(双连通图,割边,桥,重边)
题目链接:http://poj.org/problem?id=3177 和上一题一样,只是有重边. 如何解决重边的问题? 1. 构造图G时把重边也考虑进来,然后在划分边双连通分量时先把桥删去,再划分 ...
- UVa 1648 (推公式) Business Center
题意: 有一种奇怪的电梯,每次只能向上走u个楼层或者向下走d个楼层 现在有m个这种电梯,求恰好n次能够到达的最小楼层数(必须是正数),最开始默认位于第0层. 分析: 假设电梯向上走x次,则向下走n-x ...
- HDU 3492 (直线与所有线段相交) Segment
题意: 给出n个线段,判断是否存在一条直线使得所有线段在直线上的射影的交非空. 分析: 如果我们找到一条与所有线段相交的直线,然后做一条与该直线垂直的直线,这些线段在直线上的射影就一定包含这个垂足. ...