If you're *really* creating the process suspended and aren't injecting a thread into it, then that shouldn't be the output you get. Until the first thread runs, the only two images mapped in the address space are ntdll and the main exe, and the PEB_LDR_DATA entries are not yet created.
If you inject a thread into the process (such as by attaching a debugger to it - the debugger breakin thread counts), you will perturb the state of the target.
Using the following:
int
__cdecl
wmain(
int ac,
wchar_t **av
)
{
PROCESS_INFORMATION pi;
STARTUPINFO si;
HANDLE h;
MODULEENTRY32 m;
BOOL success;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
if (!CreateProcess(
L"C:\\Windows\\System32\\Cmd.exe",
0,
0,
0,
FALSE,
CREATE_SUSPENDED | CREATE_NEW_CONSOLE,
0,
0,
&si,
&pi))
return 0;
wprintf(L"Pid: %x\n", pi.dwProcessId);
if ((h = CreateToolhelp32Snapshot(
TH32CS_SNAPMODULE,
pi.dwProcessId)) == INVALID_HANDLE_VALUE)
{
wprintf(L"Error in snapshot: %lu\n", GetLastError());
TerminateProcess(pi.hProcess, 0);
return 0;
}
wprintf(L"Snapshot is %p\n", h);
ZeroMemory(&m, sizeof(m));
m.dwSize = sizeof(m);
for (success = Module32First(h, &m);
success;
success = Module32Next(h, &m))
{
wprintf(L"%p %p %s\n",
m.modBaseAddr,
m.modBaseAddr + m.modBaseSize,
m.szModule);
}
wprintf(L"Last error was %lu\n", GetLastError());
CloseHandle(h);
getc(stdin);
ResumeThread(pi.hThread);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return 0;
}
I get:
Pid: 59c
Error in snapshot: 299
As long as you are running on an nt-based system (i.e. not 9x), you should never get any data back from trying to enum modules like that on an uninitialized process. If you are on an nt-based system, then something is running a thread before you perform the enumeration.
BTW, CreateToolhelp32Snapshot returns INVALID_HANDLE_VALUE and not NULL when it fails.