DLL注入进程技术

本文介绍了一种通过DLL注入实现进程间通信的技术。该技术利用LoadLibrary函数和CreateRemoteThread API来实现在目标进程中加载DLL。文章提供了完整的示例代码,并讨论了如何在DLL中实现多线程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

DLL注入进程技术
2010-11-24 23:48

DLL注入其他进程技术
阅读本篇文章,需要有《线程注入其他进程技术》基础。
DLL注入技术才具有强大的功能和使用性,同时简单易用,因为DLL中可以实现复杂的功能和很多的技术。

 

 

技术要点:
1、宿主进程调用LoadLibrary,就可以完成DLL的远程注入。可以通过CreateRemoteThread将LoadLibrary作为宿主进程的一个线程来启动,就可以完成“控制目标进程调用LoadLibrary”的工作。

2、标准DLL中DllMain,是DLL执行的入口;使用MFC的DLL中InitInstance,是DLL执行的入口,但是没有消息循环。

 注意:
 a、如果是需要多线程,只能使用有DLLMain的标准DLL。因为使用MFC的DLL,在InitInstance中启动新的线程,会在启动线程的地方阻塞不继续执行。即说,使用带MFC的DLL只能单线程作业。
 b、如果需要使用多线程和MFC。可以在标准DLL中先启动线程,再调用使用MFC的DLL。


实现步骤
1、将DLL的地址拷贝到宿主进程地址空间中

2、通过CreateRemoteThread将LoadLibrary作为宿主进程的一个线程来启动

 

 

可以正确运行的示例代码(拷贝后直接可以使用):
应用程序文件内容:
// #pragma once


#include <windows.h>
#include <TlHelp32.h>
#include <iostream>
#include <time.h>


// 提升进程访问权限
bool enableDebugPriv()
{
 HANDLE hToken;
 LUID sedebugnameValue;
 TOKEN_PRIVILEGES tkp;

 if ( !OpenProcessToken( GetCurrentProcess(),
 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)
 )
 {
 return false;
 }

 if( !LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue) )
 {
 CloseHandle(hToken);
 return false;
 }

 tkp.PrivilegeCount = 1;
 tkp.Privileges[0].Luid = sedebugnameValue;
 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

 if( !AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL) )
 {
 CloseHandle(hToken);
 return false;
 }

 return true;
}


// 根据进程名称得到进程ID,如果有多个运行实例的话,返回第一个枚举到的进程的ID
DWORD processNameToId(LPCTSTR lpszProcessName)
{
 HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

 PROCESSENTRY32 pe;
 pe.dwSize = sizeof(PROCESSENTRY32);

 if( !Process32First(hSnapshot, &pe) )
 {
 MessageBox( NULL,
 "The frist entry of the process list has not been copyied to the buffer",
 "Notice",
 MB_ICONINFORMATION | MB_OK
 );
 return 0;
 }

 while( Process32Next(hSnapshot, &pe) )
 {
 if( !strcmp(lpszProcessName, pe.szExeFile) )
 {
 return pe.th32ProcessID;
 }
 }

 return 0;
}


int main(int argc, char* argv[])
{
 // 定义线程体的大小
 const DWORD dwThreadSize = 5 * 1024;
 DWORD dwWriteBytes;

 // 提升进程访问权限
 enableDebugPriv();

 // 等待输入进程名称,注意大小写匹配
 std::cout << "Please input the name of target process !" << std::endl;
 char szExeName[MAX_PATH] = { 0 };
 std::cin >> szExeName;

 DWORD dwProcessId = processNameToId(szExeName);
 if( dwProcessId == 0 )
 {
 MessageBox( NULL,
 "The target process have not been found !",
 "Notice",
 MB_ICONINFORMATION | MB_OK
 );
 return -1;
 }


 // 根据进程ID得到进程句柄
 HANDLE hTargetProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
 if( !hTargetProcess )
 {
 MessageBox( NULL,
 "Open target process failed !",
 "Notice",
 MB_ICONINFORMATION | MB_OK
 );
 return 0;
 }


 // 在宿主进程中为线程体开辟一块存储区域
 // 在这里需要注意MEM_COMMIT内存非配类型以及PAGE_EXECUTE_READWRITE内存保护类型
 // 其具体含义请参考MSDN中关于VirtualAllocEx函数的说明。
 void* pRemoteThread = VirtualAllocEx( hTargetProcess,
 0,
 dwThreadSize,
 MEM_COMMIT , PAGE_EXECUTE_READWRITE);
 if( !pRemoteThread )
 {
 MessageBox( NULL,
 "Alloc memory in target process failed !",
 "notice",
 MB_ICONINFORMATION | MB_OK
 );
 return 0;
 }

 // 设置需要注入的DLL名称
 char szDll[256];
 memset(szDll, 0, 256);
 strcpy(szDll, "E://mydll.dll");
 // 拷贝注入DLL内容到宿主空间
 if( !WriteProcessMemory( hTargetProcess,
 pRemoteThread,
 (LPVOID)szDll,
 dwThreadSize,
 0) )
 {
 MessageBox( NULL,
 "Write data to target process failed !",
 "Notice",
 MB_ICONINFORMATION | MB_OK
 );
 return 0;
 }


 LPVOID pFunc = LoadLibraryA;
 //在宿主进程中创建线程
 HANDLE hRemoteThread = CreateRemoteThread( hTargetProcess,
 NULL,
 0,
 (LPTHREAD_START_ROUTINE)pFunc,
 pRemoteThread,
 0,
 &dwWriteBytes);
 if( !hRemoteThread )
 {
 MessageBox( NULL,
 "Create remote thread failed !",
 "Notice",
 MB_ICONINFORMATION | MB_OK
 );
 return 0;
 }
 // 等待LoadLibraryA加载完毕
 WaitForSingleObject(hRemoteThread, INFINITE );
 VirtualFreeEx(hTargetProcess, pRemoteThread, dwThreadSize, MEM_COMMIT);

 CloseHandle( hRemoteThread );
 CloseHandle( hTargetProcess );

 return 0;
}

 

 

实验的标准DLL文件:
// mydll.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
DWORD WINAPI MyThreadProc1( LPVOID pParam );
DWORD WINAPI MyThreadProc2( LPVOID pParam );

 

BOOL APIENTRY DllMain( HANDLE hModule,
 DWORD ul_reason_for_call,
 LPVOID lpReserved
 )
{
 switch ( ul_reason_for_call )
 {
 case DLL_PROCESS_ATTACH:
 {
 MessageBox( NULL, "DLL已进入目标进程。", "信息", MB_ICONINFORMATION );

 DWORD dwThreadId;
 HANDLE myThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MyThreadProc1, NULL, 0, &dwThreadId);

 HANDLE myThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MyThreadProc2, NULL, 0, &dwThreadId);
 break;
 }
 case DLL_PROCESS_DETACH:
 {
 MessageBox( NULL, "DLL已从目标进程卸载。", "信息", MB_ICONINFORMATION );
 break;
 }
 }

 return TRUE;
}

 

DWORD WINAPI MyThreadProc1( LPVOID pParam )
{
 MessageBox( NULL, "DLL已进入线程1。", "信息", MB_ICONINFORMATION );
 return 0;
}


DWORD WINAPI MyThreadProc2( LPVOID pParam )
{
 MessageBox( NULL, "DLL已进入线程2。", "信息", MB_ICONINFORMATION );
 while(1)
 {
 MessageBox( NULL, "我还活着!", "线程2", MB_ICONINFORMATION );
 Sleep(10000);
 }

 return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值