Не удается выполнить 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.

Так что я могу сделать ?

Ответы на вопрос(1)

Ваш ответ на вопрос