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.
www.jamo123.com
实现步骤托福答案
www.lefeng123.com
1、将DLL的地址拷贝到宿主进程地址空间中
2、通过CreateRemoteThread将LoadLibrary作为宿主进程的一个线程来启动
可以正确运行的示例代码(拷贝后直接可以使用):
应用程序文件内容:
//
#pragma once
#include
<windows.h>
#include
#include
#include
//
提升进程访问权限
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
);
相关文章
- 11-02vc++进程注入钩子DLL通用模块开源
- 11-02一步一步实现使用vs2010调试被注入的dll
- 11-02C++学习之DLL注入
- 11-02CreateRemoteThread方式实现进程注入
- 11-02c++实现dll注入其它进程
- 11-02DLL进程注入之CreateRemoteThread()
- 11-02C++编写DLL动态链接库的步骤与实现方法
- 11-02C++实现第三方资源释放与载入过程(以DLL为例)
- 11-02C# 嵌入dll 动软代码生成器基础使用 系统缓存全解析 .NET开发中的事务处理大比拼 C#之数据类型学习 【基于EF Core的Code First模式的DotNetCore快速开发框架】完成对DB First代码生成的支持 基于EF Core的Code First模式的DotNetCore快速开发框架 【懒人有道】在asp.net core中实现程序集注入
- 11-02C/C++ 实现常用的线程注入