Не удается выполнить EnumProcessModulesEx и CreateToolhelp32Snapshot - независимо от того, 32-разрядный или 64-разрядный
Редактировать:
Ответ на этот вопрос здесь:
https://stackoverflow.com/a/27317947/996540
Когда вы создаете проект в msvc, опция / DYNAMICBASE теперь включена по умолчанию. Из-за ASLR (рандомизации размещения адресного пространства, начиная с Windows Vista), каждый раз, когда вы запускаете exe, его адрес загрузки является случайным.
Недавно я выполнял работу по внедрению DLL, поэтому я провел некоторые исследования в Google и прочитал несколько проектов. Получить адрес загрузки (базовый адрес) exe очень важно.
Кажется, для этого есть два простых API: EnumProcessModulesEx и CreateToolhelp32Snapshot. Но мне это никогда не удавалось.
Итак, это пример кода:
void TestEnumProcessModulesEx(const char* app)
{
std::cout << "Begin TestEnumProcessModulesEx(" << mybit() << ")" << std::endl;
STARTUPINFOA startupInfo = {0};
startupInfo.cb = sizeof(startupInfo);
PROCESS_INFORMATION processInformation = {0};
if (CreateProcessA(app, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &startupInfo, &processInformation))
{
std::vector<HMODULE> buf(128);
DWORD needed = 0;
for (;;) {
if (EnumProcessModulesEx(processInformation.hProcess, &buf[0], DWORD(buf.size()*sizeof(HMODULE)), &needed, LIST_MODULES_ALL) == FALSE) {
DWORD ec = GetLastError();
std::cout << "GetLastError() = " << ec << std::endl;
break;
}
else if (needed <= buf.size() * sizeof(HMODULE)) {
break;
}
else {
const size_t oldSize = buf.size();
buf.resize(oldSize * 2);
}
}
ResumeThread(processInformation.hThread);
WaitForSingleObject(processInformation.hProcess, INFINITE);
}
std::cout << "End TestEnumProcessModulesEx(" << mybit() << ")" << std::endl;
}
Чтобы уменьшить длину этого Вопроса, полный код, включая тестовый код CreateToolhelp32Snapshot, здесь не указан, но его можно получить по адресу:
https://dl.dropboxusercontent.com/u/235920/enum_proc_mods_sample.7z или жеhttps://www.mediafire.com/?cry3pnra8392099
«Если эта функция вызывается из 32-разрядного приложения, работающего на WOW64, она может перечислять только модули 32-разрядного процесса. Если процесс представляет собой 64-разрядный процесс, эта функция завершается ошибкой, а последний код ошибки - ERROR_PARTIAL_COPY ( 299) «. - из MSDN.
И это сообщение в блоге по этому вопросу:http://winprogger.com/getmodulefilenameex-enumprocessmodulesex-failures-in-wow64/
К сожалению, это не имеет смысла, потому что независимо от того, является ли указанный процесс 32-битным или 64-битным, он терпит неудачу с 299; Независимо от того, является ли вызывающий процесс 32-разрядным или 64-разрядным, он завершается с ошибкой 299.
Это вывод моего образца:
Begin TestEnumProcessModulesEx(32bit)
GetLastError() = 299
hello world 32bit
End TestEnumProcessModulesEx(32bit)
Begin TestEnumProcessModulesEx(32bit)
GetLastError() = 299
hello world 64bit
End TestEnumProcessModulesEx(32bit)
Begin TestEnumProcessModulesEx(64bit)
GetLastError() = 299
hello world 32bit
End TestEnumProcessModulesEx(64bit)
Begin TestEnumProcessModulesEx(64bit)
GetLastError() = 299
hello world 64bit
End TestEnumProcessModulesEx(64bit)
Как видите, любая комбинация не удалась.
Моя ОС - Windows 7 64bit Pro, а мой компилятор - VS2013.
Так что я могу сделать ?