Этот код выполняется в 64-битном приложении. Целевое приложение 32-битное.
Каждый раз, когда я запускаю этот код, CreateToolhelp32Snapshot()
возвращается INVALID_HANDLE_VALUE
а потом GetLastError()
возвращается ERROR_PARTIAL_COPY
, Таким образом, он пропускает цикл и возвращает false.
BOOL HookInjector::InjectIntoProcess(DWORD pID)
{
//Get Handle to Remote Process
HANDLE Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
....
//Check to see if 64-bit or 32-bit application
IsWow64Process(Proc, &isWow64);
size_t szCurProc = sizeof(void*); //returns 8
if (isWow64)
{
__debugbreak();
//Get list of all Modules associated with the Process
HANDLE hProc32Module;
do {
hProc32Module = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE32, pID);
}
while ((hProc32Module == INVALID_HANDLE_VALUE) && (GetLastError() == ERROR_BAD_LENGTH));
if (hProc32Module == INVALID_HANDLE_VALUE) {
__debugbreak();
DWORD err = GetLastError(); //just to see the error code which is 0x12b
return false;
}
//Find the module for Kernel.dll and get the base address of it
MODULEENTRY32 entryModule;
entryModule.dwSize = sizeof(MODULEENTRY32);
BOOL isGetModuleSuccess = Module32First(hProc32Module, &entryModule);
DWORD errEndofList = GetLastError();
BOOL isSuccessful = false;
while (errEndofList != ERROR_NO_MORE_FILES && isGetModuleSuccess)
{
if (_tcscmp(entryModule.szModule, KERNEL32_DLL)){
isSuccessful = true;
break;
}
isGetModuleSuccess = Module32Next(hProc32Module, &entryModule);
errEndofList = GetLastError();
}
if (!isSuccessful)
{
__debugbreak();
CloseHandle(hProc32Module);
return false;
}
//Get handle for Kernel.dll module
hKernel32 = entryModule.hModule;
CloseHandle(hProc32Module);
}
else
{
....
Согласно документация, CreateToolhelp32Snapshot()
только терпит неудачу с ERROR_PARTIAL_COPY
когда CreateToolhelp32Snapshot()
вызывается 32-битным процессом, пытающимся получить доступ к 64-битному процессу:
Если указанный процесс является 64-битным процессом и вызывающий является 32-битным процессом, эта функция завершается ошибкой, и последний код ошибки — ERROR_PARTIAL_COPY (299).
Убедитесь, что ваше приложение действительно скомпилировано для 64-битной системы. TH32CS_SNAPMODULE32
имеет смысл использовать только когда CreateToolhelp32Snapshot()
вызывается в 64-битном процессе:
TH32CS_SNAPMODULE32
0x00000010
Включает все 32-битные модули процесса, указанного в th32ProcessID в снимке при вызове из 64-битного процесса.
Вы также не принимаете во внимание, что GetLastError()
обновляется только при сбое функций API, если не указано иное. Ваши петли предполагают, что GetLastError()
обновляется после каждого вызова API, это просто неверно.
Попробуйте что-то более похожее на это:
BOOL HookInjector::InjectIntoProcess(DWORD pID)
{
//Get Handle to Remote Process
HANDLE Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
....
DWORD dwFlag;
#ifdef _WIN64
//Check if Remote Process is a 32-bit application
BOOL isWow64 = FALSE;
IsWow64Process(Proc, &isWow64);
if (!isWow64) return false;
// TH32CS_SNAPMODULE32 includes 32bit modules when used by a 64bit process...
dwFlag = TH32CS_SNAPMODULE32;
#else
// TH32CS_SNAPMODULE includes 32bit modules when used by a 32bit process...
dwFlag = TH32CS_SNAPMODULE;
#endif
__debugbreak();
//Get list of all Modules associated with the Process
HANDLE hProc32Module;
do {
hProc32Module = CreateToolhelp32Snapshot(dwFlag, pID);
}
while ((hProc32Module == INVALID_HANDLE_VALUE) && (GetLastError() == ERROR_BAD_LENGTH));
if (hProc32Module == INVALID_HANDLE_VALUE) {
__debugbreak();
return false;
}
//Find the module for Kernel.dll and get the base address of it
hKernel32 = NULL;
MODULEENTRY32 entryModule = {0};
entryModule.dwSize = sizeof(MODULEENTRY32);
BOOL isGetModuleSuccess = Module32First(hProc32Module, &entryModule);
while (isGetModuleSuccess) {
if (_tcscmp(entryModule.szModule, KERNEL32_DLL)) {
hKernel32 = entryModule.hModule;
break;
}
isGetModuleSuccess = Module32Next(hProc32Module, &entryModule);
}
if (!hKernel32) {
__debugbreak();
CloseHandle(hProc32Module);
return false;
}
CloseHandle(hProc32Module);
....
}