一、远程线程注入的原理

  1、其基础是在 Windows 系统中,每个 .exe 文件在双击打开时都会加载 kernel32.dll 这个系统模块,该模块中有一个 LoadLibrary() 函数,可以将DLL文件加载到自身进程中。

  2、这样,就可以用 CreateRemoteThread() 函数创建一个远程线程,让目标进程调用LoadLibrary() 来加载我们自己写的DLL 。CreateRemoteThread() 有这几个参数比较关键:A:想要注入的进程的句柄,这里可以通过OpenProcess()得到; B:想要运行的函数,本例中当然是 LoadLibrary() 啦; C: 所运行函数的参数,本例中是自己写的DLL的存放路径。

  3、那么,怎么让 LoadLibrary() 找到自己写的DLL的存放路径呢?这就需要在内存中开辟一块空间,把路径写入进去。这要先用 VirtualAllocEx()开辟一块空间,然后用WriteProcessMemory() 函数把DLL路径写进去。

  4、小结:总的来说,就是:先在目标进程的内存空间里开辟一块新地方,往新地方里面写入DLL的路径,再创建远程线程找到LoadLibrary() 函数,并在刚才开辟的新地方中读取DLL路径,进而加载我们自己写的DLL。

二、代码实现(含详细注释)

 #include <iostream>
#include "stdlib.h"
#include <tchar.h>
#include <Windows.h> bool Inject(DWORD dwId, WCHAR* szPath)//参数1:目标进程PID 参数2:DLL路径
{
//一、在目标进程中申请一个空间 /*
【1.1 获取目标进程句柄】
参数1:想要拥有的进程权限(本例为所有能获得的权限)
参数2:表示所得到的进程句柄是否可以被继承
参数3:被打开进程的PID
返回值:指定进程的句柄
*/
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwId); /*
【1.2 在目标进程的内存里开辟空间】
参数1:目标进程句柄
参数2:保留页面的内存地址,一般用NULL自动分配
参数3:欲分配的内存大小,字节单位
参数4:MEM_COMMIT:为特定的页面区域分配内存中或磁盘的页面文件中的物理存储
参数5:PAGE_READWRITE 区域可被应用程序读写
返回值:执行成功就返回分配内存的首地址,不成功就是NULL
*/
LPVOID pRemoteAddress = VirtualAllocEx(
hProcess,
NULL,
,
MEM_COMMIT,
PAGE_READWRITE
); //二、 把dll的路径写入到目标进程的内存空间中 DWORD dwWriteSize = ;
/*
【写一段数据到刚才给指定进程所开辟的内存空间里】
参数1:OpenProcess返回的进程句柄
参数2:准备写入的内存首地址
参数3:指向要写的数据的指针(准备写入的东西)
参数4:要写入的字节数(东西的长度+0/)
参数5: 返回值。返回实际写入的字节
*/
WriteProcessMemory(hProcess,pRemoteAddress, szPath, wcslen(szPath) * + , &dwWriteSize); //三、 创建一个远程线程,让目标进程调用LoadLibrary /*
参数1:该远程线程所属进程的进程句柄
参数2:一个指向 SECURITY_ATTRIBUTES 结构的指针, 该结构指定了线程的安全属性
参数3:线程栈初始大小,以字节为单位,如果该值设为0,那么使用系统默认大小
参数4:在远程进程的地址空间中,该线程的线程函数的起始地址(也就是这个线程具体要干的活儿)
参数5:传给线程函数的参数(刚才在内存里开辟的空间里面写入的东西)
参数6:控制线程创建的标志。0(NULL)表示该线程在创建后立即运行
参数7:指向接收线程标识符的变量的指针。如果此参数为NULL,则不返回线程标识符
返回值:如果函数成功,则返回值是新线程的句柄。如果函数失败,则返回值为NULL
*/
HANDLE hThread = CreateRemoteThread(
hProcess,
NULL,
,
(LPTHREAD_START_ROUTINE)LoadLibrary,
pRemoteAddress,
NULL,
NULL
);
WaitForSingleObject(hThread, -); //当句柄所指的线程有信号的时候,才会返回 /*
四、 【释放申请的虚拟内存空间】
参数1:目标进程的句柄。该句柄必须拥有 PROCESS_VM_OPERATION 权限
参数2:指向要释放的虚拟内存空间首地址的指针
参数3:虚拟内存空间的字节数
参数4:MEM_DECOMMIT仅标示内存空间不可用,内存页还将存在。
MEM_RELEASE这种方式很彻底,完全回收。
*/
VirtualFreeEx(hProcess, pRemoteAddress, , MEM_DECOMMIT);
return ;
} int _tmain(int argc, _TCHAR * argv[])
{
wchar_t wStr[] = L"E:\\inject.dll";
DWORD dwId = ; //参数1:(NULL
//参数2:目标窗口的标题
//返回值:目标窗口的句柄
HWND hCalc = FindWindow(NULL, L"微信");
printf("目标窗口的句柄为:%d\n", hCalc); DWORD dwPid = ; //参数1:目标进程的窗口句柄
//参数2:把目标进程的PID存放进去
DWORD dwRub = GetWindowThreadProcessId(hCalc, &dwPid);
printf("目标窗口的进程PID为:%d\n", dwPid); //参数1:目标进程的PID
//参数2:想要注入DLL的路径
Inject(dwPid, wStr); return ;
}

执行之后,DLL就注入到了PC版的微信进程。且该DLL中含有一个弹窗代码,也出现在了PC版微信的界面之上。

附:测试用的DLL代码

 #include <windows.h>

 DWORD WINAPI runBot(LPVOID lpParam) {
// 此处可以写具体的bot代码
return ;
} BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBoxA(NULL, "DLL Attached!\n", "Game Hacking", MB_OK | MB_TOPMOST);
CreateThread(NULL, , &runBot, NULL, , NULL);
break;
}
return TRUE;
}

(以上例程均在 Windows 10 系统,VisualStudio 2019 环境中编译通过)

详细解读:远程线程注入DLL到PC版微信的更多相关文章

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

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

  2. 远程线程注入DLL

    远程线程注入 0x00 前言 远程线程注入是一种经典的DLL注入技术.其实就是指一个新进程中另一个进程中创建线程的技术. 0x01 介绍 1.远程线程注入原理 画了一个图大致理解了下远程线程注入dll ...

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

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

  4. 微信 电脑版 HOOK(WeChat PC Hook)- 远程线程注入dll原理

    Windows加载dll的特性 1.Windows系统中,每个exe软件运行的时候,会加载系统模块kernel32.dll 2.所有加载进exe软件的系统模块kernel32.dll,内存地址都是一样 ...

  5. CreateRemoteThread远程线程注入Dll与Hook

    CreateRemoteThread虽然很容易被检测到,但是在有些场合还是挺有用的.每次想用的时候总想着去找以前的代码,现在在这里记录一下. CreateRemoteThread远程注入 DWORD ...

  6. 【windows核心编程】使用远程线程注入DLL

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

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

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

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

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

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

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

随机推荐

  1. Python与数据库[0] -> 数据库概述

    数据库概述 / Database Overview 1 关于SQL / About SQL 构化查询语言(Structured Query Language)简称SQL,是一种特殊目的的编程语言,是一 ...

  2. Linux下将MySQL服务添加到服务器的系统服务中

    Linux下将MySQL服务添加到服务器的系统服务中 Linux环境下将MySQL服务添加到服务器的系统服务中 1.了解MySQL程序路径 MySQL数据目录: /home/mysql/dataMyS ...

  3. Android文件操作工具类(转)

    Android文件操作工具类(转)  2014/4/3 18:13:35  孤独的旅行家  博客园 这个工具类包含Android应用开发最基本的几个文件操作方法,也是我第一次发博客与大家分享自己写的东 ...

  4. Jenkins的安装方法(Windows/Linux)

    前提:要确定本机全部安装了JDK 一.先说官方的安装方式 打开网址:https://wiki.jenkins-ci.org/display/JENKINS/Installing+Jenkins,会留意 ...

  5. IOS调用WCF提供的服务方法,但是方法的参数是WCF那边自定义的对象,这样有办法调用么,如果可以IOS应该怎么传参呢?请问有了解的么,

    最近做一个项目后端使用WCF接收Android手机拍照并带其它参数保存到服务器里:刚好把最近学习的WCF利用上,本以为是个比较简单的功能应该很好实现,没想到其中碰到不少问题,在网上搜索很久一直没有想到 ...

  6. Android笔试总结

    1.请谈一下Android系统的架构.答:Android系统采用了分层架构,从高层到低层分别是应用程序层.应用程序框架层.系统运行库层和linux核心层. 2.谈谈android大众常用的五种布局.答 ...

  7. .net开发常用的第三方开发组件

    转自:http://www.cnblogs.com/damsoft/p/6100323.html .net开发常用的第三方组件: 1.RSS.NET.dll: RSS.NET是一款操作RSS feed ...

  8. [iOS 高级] iOS远程推送与本地推送大致流程

    本地推送: UILocalNotification *notification=[[UILocalNotification alloc] init]; if (notification!=nil) { ...

  9. linux /etc/hosts 配置问题

    在java code中获取本机IP的程序如下: import java.net.InetAddress; public class Test { public static void main(Str ...

  10. Java的位运算

    左移位操作 左移位运算的符号为[<<],左移位运算符左面的操作元称作被移位数,右面的操作数称作移位量. 左移位运算是双目运算符,操作元必须是整型类型的数据,其移动过程是:[a <&l ...