原理

核心函数

CreateRemoteThread:让在其他进程中创建一个线程变成可能

核心思想

HANDLE WINAPI 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
);
HMODULE
WINAPI
LoadLibraryW(
_In_ LPCWSTR lpLibFileName
);

CreateRemoteThread函数的第四个参数是线程函数,我们可以用LoadLibrary的函数地址作为线程函数地址。

CreateRemoteThread函数的第五个参数是线程函数参数。用要加载的dll路径作为线程函数的参数。

相当于用这个线程函数(LoadLibrary)把参数(dll路径)Load到“被注入的进程”里。

设计的巧合才出现了这一注入方式

代码实现

获取pid

OpenProcess这个函数有个参数是pid,获取pid的方式多种多样,我这里使用的是快照

 1 //根据进程名找对应的pid(快照方式)
2 DWORD _getProcessHandle(LPCTSTR lpProcessName)
3 {
4 DWORD dwRet = 0;
5 HANDLE hSnapShot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6 if (hSnapShot == INVALID_HANDLE_VALUE)
7 {
8 printf("\n获得进程快照失败,返回的GetLastError():%d", ::GetLastError());
9 return dwRet;
10 }
11
12 PROCESSENTRY32 pe32;
13 pe32.dwSize = sizeof(PROCESSENTRY32);
14 ::Process32First(hSnapShot, &pe32);
15 do
16 {
17 if (!lstrcmp(pe32.szExeFile, lpProcessName))
18 {
19 dwRet = pe32.th32ProcessID;
20 break;
21 }
22 } while (::Process32Next(hSnapShot, &pe32));
23 ::CloseHandle(hSnapShot);
24 return dwRet;
25 }

打开进程

hprocess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, _Pid);

在注入进程里申请空间

pAlloc = ::VirtualAllocEx(hprocess,NULL, _SIZE, MEM_COMMIT,PAGE_READWRITE);

因为我们需要找到那个参数(dll路径),在我本来的进程中,dll路径存放的地方和注入进程中dll路径存放的地方不是同一个地方,我们需要跨进程将dll路径写在注入进程中,下面起线程的时候才能找到存放dll路径的字符串

在申请的空间中写入数据

::WriteProcessMemory(hprocess, pAlloc, psDllFillName, _SIZE, NULL);

获得LoadLibraryW的地址

pThreadFunction = ::GetProcAddress(::GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");

由于Windows引入了基址随机化ASLR安全机制,所以导致每次开机启动时系统DLL加载基址都不一样,有些系统dll(kernel,ntdll)的加载地址,允许每次启动基址可以改变,但是启动之后必须固定,也就是说两个不同进程在相互的虚拟内存中,这样的系统dll地址总是一样的。

创建线程在注入进程中

hThread = ::CreateRemoteThread(hprocess, NULL, 0, (LPTHREAD_START_ROUTINE)pThreadFunction, pAlloc,0,NULL);

让这个线程loadlibrary

所有代码

 1 #include <iostream>
2 #include <windows.h>
3 #include <TlHelp32.h>
4 #include "tchar.h"
5
6 //根据进程名找对应的pid(快照方式)
7 DWORD _getProcessHandle(LPCTSTR lpProcessName)
8 {
9 DWORD dwRet = 0;
10 HANDLE hSnapShot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
11 if (hSnapShot == INVALID_HANDLE_VALUE)
12 {
13 printf("\n获得进程快照失败,返回的GetLastError():%d", ::GetLastError());
14 return dwRet;
15 }
16
17 PROCESSENTRY32 pe32;
18 pe32.dwSize = sizeof(PROCESSENTRY32);
19 ::Process32First(hSnapShot, &pe32);
20 do
21 {
22 if (!lstrcmp(pe32.szExeFile, lpProcessName))
23 {
24 dwRet = pe32.th32ProcessID;
25 break;
26 }
27 } while (::Process32Next(hSnapShot, &pe32));
28 ::CloseHandle(hSnapShot);
29 return dwRet;
30 }
31
32
33 //打开一个进程并为其创建一个线程
34 DWORD _InjectThread(DWORD _Pid, LPCWSTR psDllFillName)
35 {
36 //打开进程
37 HANDLE hprocess;
38 HANDLE hThread;
39 DWORD _SIZE = 0;
40 LPVOID pAlloc = NULL;
41 DWORD psDllAddr = 0;
42 FARPROC pThreadFunction;
43 hprocess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, _Pid);
44 //在注入进程中写入Loadlibrary名称
45 _SIZE = (_tcslen(psDllFillName) + 1)* sizeof(TCHAR);
46 pAlloc = ::VirtualAllocEx(hprocess,NULL, _SIZE, MEM_COMMIT,PAGE_READWRITE);
47 if (pAlloc == NULL)
48 {
49 printf("VirtualAllocExERROR");
50 return FALSE;
51 }
52 BOOL x = ::WriteProcessMemory(hprocess, pAlloc, psDllFillName, _SIZE, NULL);
53 if (FALSE == x)
54 {
55 printf("WriteProcessMemoryERROR");
56 return FALSE;
57 }
58 //获得Loadlibrary的地址
59 pThreadFunction = ::GetProcAddress(::GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");
60 //在另一个进程创建一个线程
61 hThread = ::CreateRemoteThread(hprocess, NULL, 0, (LPTHREAD_START_ROUTINE)pThreadFunction, pAlloc,0,NULL);
62 if (hThread == NULL)
63 {
64 printf("CreateRemoteThreadError");
65 return FALSE;
66 }
67 WaitForSingleObject(hThread,-1);
68 GetExitCodeThread(hThread, &psDllAddr);
69 VirtualFreeEx(hprocess, pAlloc, _SIZE, MEM_DECOMMIT);
70 ::CloseHandle(hprocess);
71 return TRUE;
72 }
73 int main()
74 {
75 DWORD PID = _getProcessHandle(L"Test.exe");
76 _InjectThread(PID,L"MessageBox.dll");
77 }

实际上整个过程就是等效于在注入进程中自己LoadLibrary,只不过我们是在其他进程load这个dll

Dll文件

 1 #include "pch.h"
2
3 BOOL APIENTRY DllMain( HMODULE hModule,
4 DWORD ul_reason_for_call,
5 LPVOID lpReserved
6 )
7 {
8 switch (ul_reason_for_call)
9 {
10 case DLL_PROCESS_ATTACH:
11 MessageBox(NULL, L"sucess!!!", L"注入", MB_OK);
12 case DLL_THREAD_ATTACH:
13 MessageBox(NULL, L"sucess!!!", L"注入", MB_OK);
14 case DLL_THREAD_DETACH:
15 case DLL_PROCESS_DETACH:
16 break;
17 }
18 return TRUE;
19 }

测试

一开始没有这个dll

注入后

说明注入成功

dll远线程注入的更多相关文章

  1. 恶意软件开发——突破SESSION 0 隔离的远线程注入

    一.前言 在Windows XP,Windows Server 2003以及更早的版本中,第一个登录的用户以及Windows的所有服务都运行在Session 0上,这样的做法导致用户使用的应用程序可能 ...

  2. 动态加载dll的实现+远线程注入

    1.在目标进程中申请内存 2.向目标进程内存中写入shellcode(没有特征,编码比较麻烦) 3.创建远线程执行shellcode 之前可以看到shellcode很难编写还要去依赖库,去字符串区等等 ...

  3. VB.NET实现32位、64位远线程运行ASM,注入非托管、托管DLL

    这是一个老话题,远线程函数给我们提供了机会在其他进程中启动一个新线程,所以我们可以做很多事情.但事情远远没有结束,如果我们要做的事情非常复杂,那么将面临编写大量的ASM代码,虽然我们可以用VC之类的工 ...

  4. Dll注入技术之远程线程注入

    DLL注入技术之远线程注入 DLL注入技术指的是将一个DLL文件强行加载到EXE文件中,并成为EXE文件中的一部分,这样做的目的在于方便我们通过这个DLL读写EXE文件内存数据,(例如 HOOK EX ...

  5. 远程线程注入dll,突破session 0

    前言 之前已经提到过,远线程注入和内存写入隐藏模块,今天介绍突破session 0的dll注入 其实今天写这个的主要原因就是看到倾旋大佬有篇文章提到:有些反病毒引擎限制从lsass中dump出缓存,可 ...

  6. 远程线程注入DLL突破session 0 隔离

    远程线程注入DLL突破session 0 隔离 0x00 前言 补充上篇的远程线程注入,突破系统SESSION 0 隔离,向系统服务进程中注入DLL. 0x01 介绍 通过CreateRemoteTh ...

  7. 远程线程注入突破SESSION 0

    远程线程注入突破SESSION 0 SESSION 0 隔离 在Windows XP.Windows Server 2003,以及更老版本的Windows操作系统中,服务和应用程序使用相同的会话(Se ...

  8. 安全之路 —— 借助DLL进行远程线程注入实现穿墙与隐藏进程

    简介        大多数后门或病毒要想初步实现隐藏进程,即不被像任务管理器这样典型的RING3级进程管理器找到过于明显的不明进程,其中比较著名的方法就是通过远程线程注入的方法注入将恶意进程的DLL文 ...

  9. 安全之路 —— 无DLL文件实现远程线程注入

    简介         在之前的章节中,笔者曾介绍过有关于远程线程注入的知识,将后门.dll文件注入explorer.exe中实现绕过防火墙反弹后门.但一个.exe文件总要在注入时捎上一个.dll文件着 ...

随机推荐

  1. ESLint All In One

    ESLint All In One ESLint $ yarn add -D eslint .eslintrc.{js,yml,json} 优先级 .eslintrc .eslintrc.js .es ...

  2. lerna

    lerna A tool for managing JavaScript projects with multiple packages. https://lerna.js.org/ https:// ...

  3. github & code owners

    github & code owners https://help.github.com/en/github/creating-cloning-and-archiving-repositori ...

  4. c++ x86_x64挂钩函数 传递寄存器表

    https://github.com/januwA/GameCheat #include "pch.h" #include <iostream> #include &l ...

  5. DeFi里的灰度?每月获得高收益?BGV代币初探

    2020年已经接近了尾声,但是DeFi市场的热闹场面并没有停止,或者说,一直在延续.资本市场不断将大批的资金投入到DeFi市场中,以求在这波热潮中赚得一波又一波红利. 美国时间12月21日,Bacca ...

  6. Echarts制作一张全球疫情图

    一.获取全球疫情数据 1)获取API 使用用友提供的新冠肺炎实时数据,登录注册之后可以免费使用. 2)点击用户信息 这里的AIPCODE,复制并保存,用于后续的使用. 3)API的使用 用友有提供一个 ...

  7. [转]ROS Q&A | How to read LaserScan data

    http://www.theconstructsim.com/read-laserscan-data/ Step 1. Open a project on ROS Development Studio ...

  8. scrapy 运行逻辑

    爬虫的步骤:发送请求获得响应→解析并提取数据→保存数据 我们沿用这个朴素的逻辑去理解scrapy 一.发送请求获得响应 1.爬虫发送请求request到引擎 2.引擎将请求request传递给调度器s ...

  9. JVM基础入门

    内存模型 我理解的jvm: 个人理解的jvm流程: .java反编译为.class文件 经类加载器到上图的内存模型 方法区:存静态 常量区(String在里面) 本地栈区:调本地服务其它库的方法 计数 ...

  10. 微信小程序引入ECharts组件

    首先打开ECharts网页 https://echarts.apache.org/zh/tutorial.html#%E5%9C%A8%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8 ...