How to find the entry point(or base address) of a

2019-03-06 22:33发布

问题:

Because of ASLR(Address space layout randomization, since Windows Vista), the base address of an exe is random, so it can't be found in PE file anymore.

In Visual C++ now the /DYNAMICBASE option is default enabled, so the base address of an exe is random - everytime the loader loads it, it happens.

After did some research on google, I am trying to use this pattern, But it doesn't work.

Please have a look at this simple code sample:

#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);
    }
}

My OS is Windows 7 64bit pro, my compiler is VS2013, this is a 32bit console program, and the UseCase01.exe is also a 32bit console program too.

EnumProcessModulesEx always fails, the error code returned by GetLastError() is 299, MSDN says what about this error code: ERROR_PARTIAL_COPY, "Only part of a ReadProcessMemory or WriteProcessMemory request was completed."

About this error code, on the EnumProcessModules's page of MSDN, "If this function is called from a 32-bit application running on WOW64, it can only enumerate the modules of a 32-bit process. If the process is a 64-bit process, this function fails and the last error code is ERROR_PARTIAL_COPY (299)."

But I am sure my program is 32bit, And, I tested on 64bit program, it fails with error 299 too, so it doesn't make sence.

"The handle returned by the CreateProcess function has PROCESS_ALL_ACCESS access to the process object." - from MSDN, so it can't be a access rights problem ?

Then I try to use CreateToolhelp32Snapshot, it fails with error code 299 too, both 32bit and 64bit.

I just can't figure it out.

My goal is find the entry point of the sub-process in a safe way, whatever it's 32bit or 64bit process.

I found this is the "deepest" answer about this question: http://winprogger.com/getmodulefilenameex-enumprocessmodulesex-failures-in-wow64/

Unfortunately, 64bit program will fails too, not only for Wow64, so it doesn't make sence.

If this is infeasible, what is the good way (find base address or entry point of a suspended sub-process)?

回答1:

You are creating the process suspended. While the key kernel data structures will be created, no modules will be loaded (that would involve executing code in module entry points (dllmain)).

Thus the error makes sense: the data structures to track modules loaded will be empty, and quite possibly not allocated at all.



回答2:

On all Windows operating systems (32/64bit):

DWORD ImageBaseAddress = ((LPDWORD)PEB)[2]