В настоящее время я изучаю API Hook с использованием DLL Injector
Я создал собственный DLL Injector, используя C# WPF и C++/CLI
также я создал DLL, которая перехватывает функцию send ws2_32.dll для вызова OutputDebugString и регистрации сообщений в DebugView при каждом вызове функции send.
Ниже приведен исходный код DLL, используемой для перехвата.
Я использовал библиотеку MinHook
Код: Выделить всё
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include
#include
#include
#include
#include
#include "MinHook.h"
#include "pch.h"
#pragma comment(lib, "ws2_32.lib")
// Define the original send function pointer
typedef int (WINAPI* send_t)(SOCKET, const char*, int, int);
send_t fpSend = NULL;
// Hooked send function
int WINAPI HookedSend(SOCKET s, const char* buf, int len, int flags)
{
// Buffer for the log message
TCHAR logMessage[2048]; // Set to a sufficient size
// No need to convert ANSI string to Unicode string
// But convert the ANSI string used for formatting to Unicode string
WCHAR wideBuf[2048];
int wideCharCount = MultiByteToWideChar(CP_ACP, 0, buf, len, NULL, 0);
MultiByteToWideChar(CP_ACP, 0, buf, len, wideBuf, wideCharCount);
wideBuf[wideCharCount] = L'\0'; // Null-terminate
// Format the Unicode string into the log message
_stprintf_s(logMessage, _T("send function is called! 【Buffer: %s】"), wideBuf);
OutputDebugString(logMessage);
return fpSend(s, buf, len, flags); // Call the original send function
}
void InitHooking1()
{
// Initialize MinHook
if (MH_Initialize() != MH_OK)
{
return;
}
// Get the handle to ws2_32.dll
HMODULE hWs2_32 = GetModuleHandle(_T("ws2_32.dll"));
if (hWs2_32 == NULL)
{
return;
}
// Get the address of the send function
void* pSend = (void*)GetProcAddress(hWs2_32, "send");
if (pSend == NULL)
{
return;
}
// Create the hook for the send function
if (MH_CreateHook(pSend, &HookedSend, reinterpret_cast(&fpSend)) != MH_OK)
{
return;
}
// Enable the hook for the send function
if (MH_EnableHook(pSend) != MH_OK)
{
return;
}
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
OutputDebugString(L"DLL injection successful");
DisableThreadLibraryCalls((HMODULE)hinstDLL);
InitHooking1();
}
else if (fdwReason == DLL_PROCESS_DETACH)
{
MH_Uninitialize(); // Cleanup MinHook
}
return TRUE;
}
моя программа чата изначально отображает экран входа в систему
login_window
Скриншот дерева диспетчера задач
и я использовал свой собственный инжектор DLL, чтобы внедрить DLL в программу чата
при входе в систему, функцию отправки ws2_32. dll используется для отправки имени пользователя и пароля на сервер, поэтому журналы корректно отображаются в DebugView.
Журналы, записанные в DebugView
Однако именно здесь начинается проблема. После успешного входа в систему при создании окна чата функционал подцепленной DLL перестает работать корректно
Я продолжаю отправлять сообщения в чат, но OutputDebugString не вызывается
Скриншот дерева диспетчера задач
Вновь созданное окно чата
Похоже, что вновь созданное окно не может правильно использовать подключенную DLL.
Ниже приведен исходный код для перехода с экрана входа в экран чата после успешного входа в программу чата.
Код: Выделить всё
if(serverMessage == "Success")
{
ChattingRoomWindow chattingRomm = new ChattingRoomWindow(usernameBox.Text, client, stream);
Close();
chattingRomm.ShowDialog();
}
Код: Выделить всё
private async void sendMessage()
{
byte[] byteData = Encoding.Default.GetBytes(message.Text);
await client.GetStream().WriteAsync(byteData, 0, byteData.Length);
message.Text = "";
}
Инжектор представляет собой приложение C# WPF с графическим интерфейсом пользователя, но его внутренняя логика работает на C++/CLI.< /p>
Код: Выделить всё
#include "pch.h"
#include "DllInjectorLib.h"
namespace DllInjectorLib {
bool Injector::Inject(String^ processName, String^ dllPath)
{
pin_ptr wProcessName = PtrToStringChars(processName);
pin_ptr wDllPath = PtrToStringChars(dllPath);
DWORD dwPID = 0;
// Wait until the process ID is obtained
while ((dwPID = GetPIDByName(wProcessName)) == 0)
{
System::Threading::Thread::Sleep(1000); // Sleep for 1 second before retrying
}
return Inject(dwPID, wDllPath);
}
bool Injector::Inject(DWORD PID, LPCWSTR DllPath)
{
HANDLE hProcess = NULL;
HANDLE hThread = NULL;
LPVOID pRemoteBuf = NULL;
HMODULE hMod = NULL;
LPTHREAD_START_ROUTINE pThreadProc = NULL;
// Open the target process
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
if (hProcess == NULL)
{
return false;
}
// Allocate memory in the target process for the DLL path
SIZE_T dwBufSize = (wcslen(DllPath) + 1) * sizeof(wchar_t);
pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);
if (pRemoteBuf == NULL)
{
CloseHandle(hProcess);
return false;
}
// Write the DLL path into the allocated memory
if (!WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)DllPath, dwBufSize, NULL))
{
VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);
CloseHandle(hProcess);
return false;
}
// Get the address of LoadLibraryW function from kernel32.dll
hMod = GetModuleHandle(L"kernel32.dll");
pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW");
// Create a remote thread in the target process to load the DLL
hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);
if (hThread == NULL)
{
VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);
CloseHandle(hProcess);
return false;
}
WaitForSingleObject(hThread, INFINITE); // Wait for the thread to finish
// Clean up
CloseHandle(hThread);
VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);
CloseHandle(hProcess);
return true;
}
DWORD Injector::GetPIDByName(LPCWSTR processName)
{
DWORD dwPID = 0;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe;
pe.dwSize = sizeof(PROCESSENTRY32);
// Iterate through the process list to find the process ID
if (Process32First(hSnapshot, &pe))
{
do
{
if (wcscmp(pe.szExeFile, processName) == 0)
{
dwPID = pe.th32ProcessID;
break;
}
} while (Process32Next(hSnapshot, &pe));
}
CloseHandle(hSnapshot);
return dwPID;
}
}
Скриншот дерева диспетчера задач
Однако, как показано на снимке экрана выше, когда процесс создает новое окно, DLL не работает должным образом в этом новом окне.
Мой родной язык не Английский, и я впервые использую Stack Overflow. Надеюсь, мои намерения переданы ясно, и прошу прощения за неловкий английский или непреднамеренную грубость
Подробнее здесь: https://stackoverflow.com/questions/787 ... pplication
Мобильная версия