如何用C++实现 向进程注入dll并传参(也就是程序和dll间通信) 或 不注入dll直接向进程调用汇编代码
注:我用的是VS2019,向x86,32-bit程序注入
向进程注入dll并传参的实现步骤如下:
下面是一个示例代码:
#include <windows.h>
#include <iostream>
using namespace std;
typedef void(*DLL_FUNCTION)(int);
int main()
{
// 加载dll
HMODULE hDll = LoadLibrary("dllname.dll");
if (hDll == NULL)
{
cout << "LoadLibrary failed" << endl;
return -1;
}
// 获取dll中的函数地址
DLL_FUNCTION pFunction = (DLL_FUNCTION)GetProcAddress(hDll, "functionname");
if (pFunction == NULL)
{
cout << "GetProcAddress failed" << endl;
return -1;
}
// 调用dll中的函数,并传递参数
pFunction(123);
// 释放dll
FreeLibrary(hDll);
return 0;
}
不注入dll直接向进程调用汇编代码的实现步骤如下:
向进程注入 DLL 并传参,是一种比较常见的技术,常用于一些系统级工具或者安全软件中,比如 Hook 技术、远程线程注入等。下面给出一个简单的示例,演示如何使用 C++ 实现 DLL 注入并传参的功能。
首先,我们需要一个 DLL 项目,可以使用 Visual Studio 2019 新建一个 DLL 项目,生成一个动态链接库文件,比如 MyInjectDLL.dll。
DLL 中的代码可以比较简单,我们只需要在 DLL 中实现一个导出函数,接收一个字符串参数,然后将该字符串输出到控制台即可,示例代码如下:
#include <Windows.h>
#include <iostream>
extern "C" __declspec(dllexport) void InjectFunction(const char* message)
{
std::cout << "Message from injector: " << message << std::endl;
}
接下来,我们需要编写一个注入器程序,用于将 DLL 注入到指定进程中,并调用 DLL 中的函数,传递参数。注入器程序需要实现以下步骤:
获取目标进程的句柄
在目标进程中分配一段内存,用于存放 DLL 的路径和参数
将 DLL 路径和参数写入到目标进程中分配的内存中
在目标进程中创建一个远程线程,执行 LoadLibrary 函数加载 DLL,并调用 DLL 中的导出函数,传递参数
示例代码如下:
#include <Windows.h>
#include <iostream>
int main()
{
// 获取目标进程的句柄
DWORD pid = 1234; // 目标进程的 PID
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (hProcess == NULL)
{
std::cerr << "Failed to open process." << std::endl;
return 1;
}
// 在目标进程中分配一段内存,用于存放 DLL 的路径和参数
const char* dllPath = "C:\\MyInjectDLL.dll";
const char* message = "Hello, world!";
size_t pathSize = strlen(dllPath) + 1;
size_t messageSize = strlen(message) + 1;
LPVOID mem = VirtualAllocEx(hProcess, NULL, pathSize + messageSize, MEM_COMMIT, PAGE_READWRITE);
if (mem == NULL)
{
std::cerr << "Failed to allocate memory." << std::endl;
CloseHandle(hProcess);
return 1;
}
// 将 DLL 路径和参数写入到目标进程中分配的内存中
LPVOID pathAddr = mem;
LPVOID messageAddr = (char*)mem + pathSize;
WriteProcessMemory(hProcess, pathAddr, dllPath, pathSize, NULL);
WriteProcessMemory(hProcess, messageAddr, message, messageSize, NULL);
// 在目标进程中创建一个远程线程,执行 LoadLibrary 函数加载 DLL,并调用 DLL 中的导出函数,传递参数
HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32.dll"));
LPVOID
不注入dll直接向进程调用汇编代码的实现:
可以通过创建远程线程的方式,将需要执行的汇编代码加载到目标进程的内存空间中,然后再通过远程线程调用的方式执行该代码。
具体实现步骤如下:
1打开目标进程,并获取该进程的句柄。
2在目标进程中申请一块内存空间,用于存放需要执行的汇编代码。
3将需要执行的汇编代码写入到申请的内存空间中。
4创建一个远程线程,在该线程中执行申请的内存空间中的汇编代码。
代码示例:
```c++
#include <windows.h>
#include <iostream>
using namespace std;
// 汇编代码
BYTE shellcode[] = { /* ... */ };
int main()
{
// 获取目标进程的句柄
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (hProcess == NULL)
{
cout << "OpenProcess failed" << endl;
return 1;
}
// 在目标进程中申请内存空间
LPVOID pRemoteShellcode = VirtualAllocEx(hProcess, NULL, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (pRemoteShellcode == NULL)
{
cout << "VirtualAllocEx failed" << endl;
CloseHandle(hProcess);
return 1;
}
// 将汇编代码写入到申请的内存空间中
if (!WriteProcessMemory(hProcess, pRemoteShellcode, shellcode, sizeof(shellcode), NULL))
{
cout << "WriteProcessMemory failed" << endl;
VirtualFreeEx(hProcess, pRemoteShellcode, 0, MEM_RELEASE);
CloseHandle(hProcess);
return 1;
}
// 创建远程线程,在该线程中执行申请的内存空间中的汇编代码
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pRemoteShellcode, NULL, 0, NULL);
if (hThread == NULL)
{
cout << "CreateRemoteThread failed" << endl;
VirtualFreeEx(hProcess, pRemoteShellcode, 0, MEM_RELEASE);
CloseHandle(hProcess);
return 1;
}
// 等待远程线程执行完毕
WaitForSingleObject(hThread, INFINITE);
// 关闭句柄并释放内存
CloseHandle(hThread);
VirtualFreeEx(hProcess, pRemoteShellcode, 0, MEM_RELEASE);
CloseHandle(hProcess);
return 0;
}