• DLL远程线程注入技术


    文章目录

    DLL注入

    DLL注入:简而言之就是将一个不属于某进程的DLL文件加载到该进程当中。

    Dll注入初衷是给第三方的应用程序进行一个功能的扩展

    API作用
    OpenProcess打开远程进程
    VirtualAllocEx在远程进程中申请内存空间
    WriteProcessMemory写入数据到远程进程
    CreateRemoteThread创建远程线程
    Loadlibrary加载模块
    WaitForSingleObject等待信号
    VirtualFreeEx释放远程进程内存空间
    CloseHandle关闭句柄

    常用API:

    OpenProcess : 根据进程ID,打开进程句柄

    HANDLE OpenProcess(
      [in] DWORD dwDesiredAccess,	//对此进程打开的权限
      [in] BOOL  bInheritHandle,	//是否继承
      [in] DWORD dwProcessId		//进程ID
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5

    VirtualAllocEx:在指定的进程中分配虚拟内存空间

    LPVOID VirtualAllocEx(
      [in]           HANDLE hProcess,	//进程句柄
      [in, optional] LPVOID lpAddress,	//分配的虚拟地址的起始地址,NULL则默认
      [in]           SIZE_T dwSize,		//分配的虚拟内存大小
      [in]           DWORD  flAllocationType,	//分配的类型,预定/提交状态
      [in]           DWORD  flProtect	//分配的内存的属性  可读/可写 ...
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    WriteProcessMemory: 往指定的进程写入内存

    BOOL WriteProcessMemory(
      [in]  HANDLE  hProcess,	//进程句柄
      [in]  LPVOID  lpBaseAddress,	//指向指定进程中写入数据的基地址的指针,说白了就是你刚刚分配的虚拟内存的地址
      [in]  LPCVOID lpBuffer,//要写入的数据缓冲区的指针
      [in]  SIZE_T  nSize,	//要写入的数据的大小
      [out] SIZE_T  *lpNumberOfBytesWritten//接收传输到目标的字节数
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    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//接收线程标识符
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    VirtualFreeEx : 释放开辟的虚拟内存

    BOOL VirtualFreeEx(
      [in] HANDLE hProcess,	//进程句柄
      [in] LPVOID lpAddress,//开辟的虚拟内存的地址
      [in] SIZE_T dwSize,//大小
      [in] DWORD  dwFreeType//释放类型
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Main

    1. 打开指定的进程句柄。
    DWORD ProId = 4424;
    //打开进程句柄
    HANDLE ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProId);
    
    • 1
    • 2
    • 3
    1. 为这个进程开辟虚拟内存
    //申请远程虚拟内存
    LPVOID Alloc=VirtualAllocEx(ProcessHandle,
    	NULL,
    	nlen,
    	MEM_RESERVE | MEM_COMMIT,
    	PAGE_READWRITE
    	);
    if (!Alloc)
    {
    	printf("申请远程内存失败!  %d\n", GetLastError());
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1. 往指定的进程中写入此虚拟内存的数据
    //写入内存
    SIZE_T realsize = 0;	
    WriteProcessMemory(ProcessHandle,
    	Alloc,
    	"MyDll.dll",
    	nlen,
    	&realsize);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. 开辟进程的远程线程,并等待线程句柄处于有信号状态。
    //3. 创建远程线程
    HANDLE MyHandle =  CreateRemoteThread(
    	ProcessHandle,
    	NULL,
    	NULL,
    	(LPTHREAD_START_ROUTINE)LoadLibraryA,
    	Alloc,	//传入线程的变量,加载内存空间
    	NULL,
    	NULL
    );
    WaitForSingleObject(MyHandle, -1);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    1. 释放句柄及虚拟内存
    printf("LastError:%d\n", GetLastError());
    VirtualFreeEx(ProcessHandle, (char*)Alloc, NULL, MEM_RELEASE);
    CloseHandle(ProcessHandle);
    CloseHandle(MyHandle);
    
    • 1
    • 2
    • 3
    • 4

    完整代码:

    #include 
    #include 
    
    int main()
    {
    	DWORD nlen = strlen("MyDll.dll") + 1;
    	DWORD ProId = 4424;
    	//打开进程句柄
    	HANDLE ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProId);
    
    	//申请远程虚拟内存
    	LPVOID Alloc=VirtualAllocEx(ProcessHandle,
    		NULL,
    		nlen,
    		MEM_RESERVE | MEM_COMMIT,
    		PAGE_READWRITE
    		);
    	if (!Alloc)
    	{
    		printf("申请远程内存失败!  %d\n", GetLastError());
    		system("pause");
    		return 0;
    	}
    	//写入内存
    	SIZE_T realsize = 0;	
    	WriteProcessMemory(ProcessHandle,
    		Alloc,
    		"MyDll.dll",
    		nlen,
    		&realsize);
    	//3. 创建远程线程
    	HANDLE MyHandle =  CreateRemoteThread(
    		ProcessHandle,
    		NULL,
    		NULL,
    		(LPTHREAD_START_ROUTINE)LoadLibraryA,
    		Alloc,	//传入线程的变量,加载内存空间
    		NULL,
    		NULL
    	);
    	WaitForSingleObject(MyHandle, -1);
    	printf("LastError:%d\n", GetLastError());
    	VirtualFreeEx(ProcessHandle, (char*)Alloc, NULL, MEM_RELEASE);
    	CloseHandle(ProcessHandle);
    	CloseHandle(MyHandle);
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    DLL

    我们让它弹出一个框。

    设置DLL文件项目的属性为 DLL动态库类型:
    在这里插入图片描述

    #include 
    #include
    
    
    BOOL WINAPI DllMain(DWORD Reason, LPVOID Param)
    {
    	if (Reason == DLL_THREAD_ATTACH)
    	{
    		MessageBoxA(NULL, "DLL注入成功!", "提示", MB_OK);
    	}
    	return TRUE;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    基于Python pygame简易版斗兽棋小游戏源代码
    java基于springboot在线学习教育网站管理系统附代码段
    浮点数(小数)在计算机中如何用二进制存储?
    大学生静态HTML网页源码——佛山旅游景点介绍网页代码 家乡旅游网页制作模板 web前端期末大作业
    Ignition in New Version
    754、到达终点数字
    【附源码】计算机毕业设计SSM社区老人健康服务跟踪系统
    uniapp公共新闻模块components案例
    linux shell脚本语法和makefile总结
    深入剖析Buddy 内存管理机制(上)
  • 原文地址:https://blog.csdn.net/jj6666djdbbd/article/details/127793396