我想将我的dll注入64位应用程序,并且我已经尝试了使用QueueUserAPC在给定链接中解释的逻辑。我收到每个 API 的成功消息,但是当我在进程资源管理器中看到时,我无法看到进程中的 dll。 以下是我的代码:
bool FindProcess(PCWSTR exeName, DWORD& pid, vector<DWORD>& tids) {
auto hSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, 0);
if (hSnapshot == INVALID_HANDLE_VALUE)
return false;
pid = 0;
PROCESSENTRY32 pe = { sizeof(pe) };
if (::Process32First(hSnapshot, &pe)) {
do {
if (_wcsicmp(pe.szExeFile, exeName) == 0) {
pid = pe.th32ProcessID;
THREADENTRY32 te = { sizeof(te) };
if (::Thread32First(hSnapshot, &te)) {
do {
if (te.th32OwnerProcessID == pid) {
tids.push_back(te.th32ThreadID);
}
} while (::Thread32Next(hSnapshot, &te));
}
break;
}
} while (::Process32Next(hSnapshot, &pe));
}
::CloseHandle(hSnapshot);
return pid > 0 && !tids.empty();}
void main(){
DWORD pid;
vector<DWORD> tids;
if (FindProcess(L"DataGrid.exe", pid, tids))
{
printf("OpenProcessn");
HANDLE hProcess = ::OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pid);
printf("VirtualAllocExn");
auto p = ::VirtualAllocEx(hProcess, nullptr, 1 << 12, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
wchar_t buffer[] = L"C:\Users\sbhuma\Documents\Visual Studio 2015\Projects\GalaxyHook\Debug\GalaxyHook.dll";
printf("WriteProcessMemoryn");
::WriteProcessMemory(hProcess, p, buffer, sizeof(buffer), nullptr);
for (const auto& tid : tids)
{
printf("OpenThreadn");
HANDLE hThread = ::OpenThread(THREAD_SET_CONTEXT, FALSE, tid);
if (hThread)
{
printf("GetProcAddressn");
DWORD word = ::QueueUserAPC((PAPCFUNC)::GetProcAddress(GetModuleHandle(L"kernel32"), "LoadLibraryW"), hThread, (ULONG_PTR)p);
if (word)
{
printf("insdie ifn");
}
printf("End of IFn");
}
}
printf("VirtualFreeExn");
::VirtualFreeEx(hProcess, p, 0, MEM_RELEASE | MEM_DECOMMIT);
}}
与将 dll 注入 64 位应用程序相关的任何帮助都是有帮助的,因为我是这个主题的新手。
问候
索米亚。
首先,确保您将注入器应用程序构建为 64 位。
一个可能的原因是您过早释放缓冲区。队列用户APC不等待;它将呼叫排队并立即返回。可能是您的注入器进程结束运行该for
循环,调用VirtualFreeEx
,然后您的目标进程收到 APC,尝试加载您的 DLL,但那时名称缓冲区已经释放,因此 LoadLibrary 失败。要进行验证,请注释掉对VirtualFreeEx的调用。如果您的 DLL 加载正常,修复内存泄漏的一种方法是使用命名事件,在对 QueueUserAPC() 进行任何调用之前在注入器应用程序中CreateEvent
,OpenEvent
,SetEvent
和CloseHandle
您正在注入的 DLL 的 DllMain(DLL_PROCESS_ATTACH),WaitForSingleObject
在VirtualFreeEx
之前在注入器应用程序中,我建议使用超时等待,CloseHandle
在最后。作为副作用,您的注射器应用程序将能够找出并在某处报告注射是否成功。
另一个可能的原因是您的目标应用永远不会进入可警报状态。并非所有应用程序都使用APC,有多种替代方法可以在Windows中实现异步内容。因此,并非所有应用程序都调用这些SleepEx/WaitForMultipleObjectsEx函数。此类应用程序将永远不会收到该APC。如果是这种情况,您应该使用另一种 DLL 注入方法。DataGrid.exe名称提示目标应用可能是 GUI 应用。可以EnumWindows
或FindWindow
查找其顶级窗口,GetWindowThreadProcessId
获取拥有该窗口的线程 ID,SetWindowsHookEx
将 DLL 注入目标进程。