DLL Code injection to third party process using QueueUserAPC
I want to inject my dll in to 64 bit application and I have tried the logic explained in the given link using QueueUserAPC. I am getting success message for every API but when I see in ProcessExplorer I am not able to see my dll in the process. Below is my code :
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:UserssbhumaDocumentsVisual Studio 2015ProjectsGalaxyHookDebugGalaxyHook.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);
}}
Any help related to inject the dll in to 64 bit application is helpful as I am new to this topic.
Regards,
Sowmya.
First of all, ensure you're building your injector app as 64 bit.
One possible reason is you're releasing the buffer too early. QueueUserAPC doesn't wait; it enqueues the call and returns immediately. Can be your injector process ends running that for
loop, calls VirtualFreeEx
, then your target process receives the APC, tries to load your DLL but the name buffer is already released by then, so LoadLibrary fails. To verify, comment out the call to VirtualFreeEx. If your DLL will load OK, one way to fix the memory leak is use a named event, CreateEvent
in injector app before any calls to QueueUserAPC(), OpenEvent
, SetEvent
and CloseHandle
in DllMain(DLL_PROCESS_ATTACH) of the DLL you're injecting, WaitForSingleObject
in injector app before VirtualFreeEx
, I recommend using a timeout for the wait, CloseHandle
at the end. As a side effect, your injector app will be able to find out, and report somewhere, whether the injection was successful.
Another possible reason is your target app never enters alertable state. Not all apps use APC, there're multiple alternative methods to implement asynchronous stuff in Windows. So, not all apps ever call these SleepEx / WaitForMultipleObjectsEx functions. Such app will never receive that APC. If that's the case, you should use another method of DLL injection. DataGrid.exe name hints your target app is probably a GUI app. You can EnumWindows
or FindWindow
to find its top-level window, GetWindowThreadProcessId
to get thread ID who owns that window, SetWindowsHookEx
to inject your DLL into the target process.
上一篇: 警告从后台线程调用UIKit