Como encontrar o ponto de entrada (ou endereço base) de um processo - cuide do ASLR

Devido ao ASLR (randomização do layout do espaço de endereço, desde o Windows Vista), o endereço base de um exe é aleatório, portanto, ele não pode mais ser encontrado no arquivo PE.

Agora, no Visual C ++, a opção / DYNAMICBASE está habilitada por padrão, portanto o endereço base de um exe é aleatório - sempre que o carregador o carregar, isso acontece.

Depois de fazer algumas pesquisas no google, estou tentando usar esse padrão, mas não funciona.

Veja este exemplo de código simples:

#include <iostream>

#include <vector>
#include <stdio.h>

#include <windows.h>
#include <psapi.h>

int main()
{
    STARTUPINFOA startupInfo = {0};
    startupInfo.cb = sizeof(startupInfo);
    PROCESS_INFORMATION processInformation = {0};

    if (CreateProcessA("UseCase01.exe", 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 << 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);
    }
}

Meu sistema operacional é o Windows 7 64bit pro, meu compilador é o VS2013, este é um programa de console de 32 bits e o UseCase01.exe também é um programa de console de 32 bits.

EnumProcessModulesEx sempre falha, o código de erro retornado por GetLastError () é 299, o MSDN informa o código de erro: ERROR_PARTIAL_COPY, "Somente parte de uma solicitação ReadProcessMemory ou WriteProcessMemory foi concluída."

Sobre esse código de erro, na página do MSDN do EnumProcessModules, "Se essa função for chamada de um aplicativo de 32 bits em execução no WOW64, ela poderá enumerar apenas os módulos de um processo de 32 bits. Se o processo for de 64 bits , essa função falha e o último código de erro é ERROR_PARTIAL_COPY (299). "

Mas tenho certeza que meu programa é de 32 bits, e eu testei no programa de 64 bits, ele falha com o erro 299 também, por isso não faz sentido.

"O identificador retornado pela função CreateProcess tem acesso PROCESS_ALL_ACCESS ao objeto de processo." - do MSDN, por isso não pode ser um problema de direitos de acesso?

Então eu tento usar o CreateToolhelp32Snapshot, ele também falha com o código de erro 299, ambos de 32 bits e de 64 bits.

Eu simplesmente não consigo entender.

Meu objetivo é encontrar o ponto de entrada do subprocesso de maneira segura, seja qual for o processo de 32 bits ou 64 bits.

Descobri que esta é a resposta "mais profunda" sobre esta pergunta:http://winprogger.com/getmodulefilenameex-enumprocessmodulesex-failures-in-wow64/

Infelizmente, o programa de 64 bits também falhará, não apenas no Wow64, por isso não faz sentido.

Se isso for inviável, qual é o bom caminho (encontre o endereço base ou o ponto de entrada de um subprocesso suspenso)?

questionAnswers(2)

yourAnswerToTheQuestion