|
分享源码
界面截图: |
|
是否带模块: |
- |
备注说明: |
- |
最近要搞这个,所以,弄了个C++实现了下调用64位dll,前提是这个64位dll函数公开啊,不公开的用其他大神的模块或者工具,汇编啥的整不来。
这个设计主要涉及两个组件:32位的 Bridge32.dll 和 64位的 Helper64.exe。让我们逐步分析这个调用过程:
初始化阶段:
当 Bridge32.dll 被加载时(通常是在 DLL_PROCESS_ATTACH),它会启动 Helper64.exe。
Helper64.exe 启动后会创建一个命名管道,等待来自 Bridge32.dll 的连接。
调用过程:
当 32位应用程序调用 Bridge32.dll 中的 CallFunction 时,以下步骤会发生:
a. Bridge32.dll 连接到 Helper64.exe 创建的命名管道。
b. Bridge32.dll 将调用信息(DLL名称、函数名、参数)通过管道发送给 Helper64.exe。
c. Helper64.exe 接收这些信息,然后动态加载指定的 64位 DLL。
d. Helper64.exe 使用 GetProcAddress 获取指定函数的地址。
e. Helper64.exe 调用该函数,并获取返回值。
f. Helper64.exe 将返回值通过管道发送回 Bridge32.dll。
g. Bridge32.dll 接收结果并返回给调用它的 32位应用程序。
通信机制:
使用命名管道进行 32位和 64位进程间的通信。
命名管道允许双向通信,适合请求-响应模型。
4. 动态加载:
Helper64.exe 使用 LoadLibrary 动态加载 64位 DLL。
使用 GetProcAddress 获取函数地址,允许调用未在编译时链接的函数。
[C++] 纯文本查看 复制代码 #include <windows.h>
#include <string>
#include <sstream>
#include <map>
#define PIPE_NAME "\\\\.\\pipe\\UniversalBridge64Pipe"
#define SHUTDOWN_EVENT_NAME "Global\\Helper64ShutdownEvent"
typedef int(__stdcall* GENERICFUNCTION)();
std::map<std::string, HMODULE> loadedDlls;
HMODULE LoadDLL(const std::string& dllName) {
if (loadedDlls.find(dllName) == loadedDlls.end()) {
HMODULE hDll = LoadLibraryA(dllName.c_str());
if (hDll) {
loadedDlls[dllName] = hDll;
}
return hDll;
}
return loadedDlls[dllName];
}
std::string CallFunction(const std::string& dllName, const std::string& funcName, const std::string& args) {
HMODULE hDll = LoadDLL(dllName);
if (!hDll) {
return "ERROR: Failed to load DLL";
}
FARPROC func = GetProcAddress(hDll, funcName.c_str());
if (!func) {
return "ERROR: Failed to find function";
}
if (funcName == "GetNetworkAdapterInfo") {
typedef const char* (__stdcall* GetNetworkAdapterInfoFunc)(int);
GetNetworkAdapterInfoFunc getNetworkAdapterInfo = reinterpret_cast<GetNetworkAdapterInfoFunc>(func);
int index = std::stoi(args);
const char* result = getNetworkAdapterInfo(index);
return result ? result : "ERROR: Null result";
}
else if (funcName == "GetActiveNetworkAdapterInfo") {
typedef const char* (__stdcall* GetActiveNetworkAdapterInfoFunc)();
GetActiveNetworkAdapterInfoFunc getActiveNetworkAdapterInfo = reinterpret_cast<GetActiveNetworkAdapterInfoFunc>(func);
const char* result = getActiveNetworkAdapterInfo();
return result ? result : "ERROR: Null result";
}
else {
int result = reinterpret_cast<int(*)()>(func)();
return std::to_string(result);
}
}
DWORD WINAPI MonitorParentProcess(LPVOID lpParam) {
const char* parentProcessIdStr = static_cast<const char*>(lpParam);
DWORD parentProcessId = strtoul(parentProcessIdStr, NULL, 10);
HANDLE hParentProcess = OpenProcess(SYNCHRONIZE, FALSE, parentProcessId);
if (hParentProcess == NULL) {
return 1;
}
WaitForSingleObject(hParentProcess, INFINITE);
CloseHandle(hParentProcess);
HANDLE hShutdownEvent = OpenEventA(EVENT_MODIFY_STATE, FALSE, SHUTDOWN_EVENT_NAME);
if (hShutdownEvent != NULL) {
SetEvent(hShutdownEvent);
CloseHandle(hShutdownEvent);
}
return 0;
}
DWORD WINAPI ClientHandler(LPVOID lpParam) {
HANDLE hPipe = (HANDLE)lpParam;
char buffer[1024];
DWORD bytesRead;
if (ReadFile(hPipe, buffer, sizeof(buffer), &bytesRead, NULL)) {
buffer[bytesRead] = '\0';
std::string input(buffer);
std::istringstream iss(input);
std::string dllName, funcName, args;
std::getline(iss, dllName, '|');
std::getline(iss, funcName, '|');
std::getline(iss, args);
std::string result = CallFunction(dllName, funcName, args);
DWORD bytesWritten;
WriteFile(hPipe, result.c_str(), static_cast<DWORD>(result.length()), &bytesWritten, NULL);
FlushFileBuffers(hPipe);
}
CloseHandle(hPipe);
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
if (__argc <= 1) {
return 1;
}
const char* parentProcessIdStr = __argv[1];
HANDLE hMonitorThread = CreateThread(NULL, 0, MonitorParentProcess, (LPVOID)parentProcessIdStr, 0, NULL);
if (hMonitorThread == NULL) {
return 1;
}
HANDLE hShutdownEvent = CreateEventA(NULL, TRUE, FALSE, SHUTDOWN_EVENT_NAME);
if (hShutdownEvent == NULL) {
return 1;
}
while (true) {
HANDLE hPipe = CreateNamedPipeA(
PIPE_NAME,
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
1024,
1024,
0,
NULL
);
if (hPipe == INVALID_HANDLE_VALUE) {
Sleep(1000);
continue;
}
HANDLE waitHandles[2] = { hShutdownEvent, hPipe };
DWORD waitResult = WaitForMultipleObjects(2, waitHandles, FALSE, INFINITE);
if (waitResult == WAIT_OBJECT_0) {
CloseHandle(hPipe);
break;
}
if (waitResult == WAIT_OBJECT_0 + 1) {
BOOL connected = ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
if (connected) {
HANDLE hThread = CreateThread(NULL, 0, ClientHandler, (LPVOID)hPipe, 0, NULL);
if (hThread == NULL) {
CloseHandle(hPipe);
}
else {
CloseHandle(hThread);
}
}
else {
CloseHandle(hPipe);
}
}
}
CloseHandle(hShutdownEvent);
WaitForSingleObject(hMonitorThread, INFINITE);
CloseHandle(hMonitorThread);
for (auto& dll : loadedDlls) {
FreeLibrary(dll.second);
}
return 0;
} [C++] 纯文本查看 复制代码 #include <windows.h>
#include <string>
#include <thread>
#include <chrono>
#define PIPE_NAME "\\\\.\\pipe\\UniversalBridge64Pipe"
#define SHUTDOWN_EVENT_NAME "Global\\Helper64ShutdownEvent"
HANDLE g_hHelper = NULL;
void StartHelper() {
STARTUPINFOA si = { sizeof(si) };
PROCESS_INFORMATION pi;
DWORD parentProcessId = GetCurrentProcessId();
std::string parentProcessIdStr = std::to_string(parentProcessId);
std::string cmdLine = "Helper64.exe " + parentProcessIdStr;
if (CreateProcessA(NULL, const_cast<char*>(cmdLine.c_str()), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
CloseHandle(pi.hThread);
g_hHelper = pi.hProcess;
}
}
bool EnsureHelperRunning() {
if (g_hHelper == NULL || WaitForSingleObject(g_hHelper, 0) == WAIT_OBJECT_0) {
StartHelper();
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
return g_hHelper != NULL;
}
extern "C" __declspec(dllexport) const char* __stdcall CallFunction(const char* dllName, const char* funcName, const char* params)
{
static char resultBuffer[1024] = { 0 };
for (int retry = 0; retry < 3; retry++) {
if (!EnsureHelperRunning()) {
strcpy_s(resultBuffer, "ERROR: Helper not running");
return resultBuffer;
}
HANDLE hPipe = CreateFileA(PIPE_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hPipe == INVALID_HANDLE_VALUE) {
if (retry == 2) {
strcpy_s(resultBuffer, "ERROR: Failed to connect to pipe after 3 attempts");
return resultBuffer;
}
Sleep(100);
continue;
}
std::string message = std::string(dllName) + "|" + funcName + "|" + (params ? params : "");
DWORD bytesWritten;
if (!WriteFile(hPipe, message.c_str(), static_cast<DWORD>(message.length()), &bytesWritten, NULL) || bytesWritten != message.length()) {
CloseHandle(hPipe);
if (retry == 2) {
strcpy_s(resultBuffer, "ERROR: Failed to write to pipe after 3 attempts");
return resultBuffer;
}
continue;
}
DWORD bytesRead;
if (!ReadFile(hPipe, resultBuffer, sizeof(resultBuffer) - 1, &bytesRead, NULL)) {
CloseHandle(hPipe);
if (retry == 2) {
strcpy_s(resultBuffer, "ERROR: Failed to read from pipe after 3 attempts");
return resultBuffer;
}
continue;
}
resultBuffer[bytesRead] = '\0';
CloseHandle(hPipe);
return resultBuffer;
}
strcpy_s(resultBuffer, "ERROR: Unexpected failure in CallFunction");
return resultBuffer;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
EnsureHelperRunning();
break;
case DLL_PROCESS_DETACH:
if (g_hHelper) {
HANDLE hShutdownEvent = OpenEventA(EVENT_MODIFY_STATE, FALSE, SHUTDOWN_EVENT_NAME);
if (hShutdownEvent != NULL) {
SetEvent(hShutdownEvent);
CloseHandle(hShutdownEvent);
}
WaitForSingleObject(g_hHelper, 5000);
TerminateProcess(g_hHelper, 0);
CloseHandle(g_hHelper);
}
break;
}
return TRUE;
} |
评分
-
查看全部评分
本帖被以下淘专辑推荐:
- · 鱼木|主题: 1573, 订阅: 154
- · 收藏|主题: 230, 订阅: 6
|