Edit:
The answer of this question is here:
https://stackoverflow.com/a/27317947/996540
When you create a project in msvc, the option /DYNAMICBASE is default enabled now. Because of ASLR(Address space layout randomization, since Windows Vista), everytime you run an exe, it's load address is random.
I am doing the DLL injection job recently, so I did some research into it on google, and have read some projects. Get the load address (base address) of an exe is important.
It seems there're two simple APIs to do this: EnumProcessModulesEx and CreateToolhelp32Snapshot. But I never succeeded.
So this is the code sample:
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;
}
To reduce the length of this Question, the complete code - including the CreateToolhelp32Snapshot's test code - is not listed here, but you can get it from:
https://dl.dropboxusercontent.com/u/235920/enum_proc_mods_sample.7z or https://www.mediafire.com/?cry3pnra8392099
"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)." - from MSDN.
And this is a blog post about this question: http://winprogger.com/getmodulefilenameex-enumprocessmodulesex-failures-in-wow64/
Unfortunately, this does not make sence, because whatever the specified process is 32bit or 64bit, it fails with 299; whatever the caller process is 32-bit or 64bit, it fails with 299.
This is the output of my sample:
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)
As you see, any combination is failed.
My OS is Windows 7 64bit pro and my compiler is VS2013.
So, what can I do ?