Discussion:
CreateProcess suspended followed by an EnumProcessModules - no result ?
(too old to reply)
R.Wieser
2017-09-23 18:58:27 UTC
Permalink
Hello all,

Not as much as a problem, but something that is nagging me because I have no
idea what happens:

I've used CreateProcess with the CREATE_SUSPENDED flag to load a small test
program. Pretty-much directly after that I'm calling EnumProcessModules on
the handle returned in the proces-info record to see which modules are
(already) there.

The odd thing (to me) is, I get nothing, zilch, nada. The thing is that I
expected it to *at least* return the just-loaded process ...

And by the way, when I allow the process to run (using ResumeProcess) and
again call EnumProcessModules I get the process itself, as well as ntdll and
kernel32. In other words, the call and my usage of it works. :-)

Again, not really a problem, just something thats nagging me and I hope
someone can explain it to me.

Regards,
Rudy Wieser
Ant
2017-09-23 20:52:19 UTC
Permalink
Post by R.Wieser
Not as much as a problem, but something that is nagging me because I have no
I've used CreateProcess with the CREATE_SUSPENDED flag to load a small test
program. Pretty-much directly after that I'm calling EnumProcessModules on
the handle returned in the proces-info record to see which modules are
(already) there.
The odd thing (to me) is, I get nothing, zilch, nada. The thing is that I
expected it to *at least* return the just-loaded process ...
The memory footprint of a newly created suspended process is very small.
I strongly suspect that the loader has not yet determined which modules
are needed and the structure which holds this info is not yet set up.
Post by R.Wieser
And by the way, when I allow the process to run (using ResumeProcess) and
again call EnumProcessModules I get the process itself, as well as ntdll and
kernel32. In other words, the call and my usage of it works. :-)
As you would expect when the process has been fully initialised.
R.Wieser
2017-09-24 06:16:50 UTC
Permalink
Ant,
Post by Ant
The memory footprint of a newly created suspended process is very small.
I strongly suspect that the loader has not yet determined which modules
are needed and the structure which holds this info is not yet set up.
If you mean with "modules" the DLLs, than I agree with you. But why is the
process module (the program itself) not visible. I just loaded it !

Regards,
Rudy Wieser
Post by Ant
Post by R.Wieser
Not as much as a problem, but something that is nagging me because I have no
I've used CreateProcess with the CREATE_SUSPENDED flag to load a small test
program. Pretty-much directly after that I'm calling EnumProcessModules on
the handle returned in the proces-info record to see which modules are
(already) there.
The odd thing (to me) is, I get nothing, zilch, nada. The thing is that I
expected it to *at least* return the just-loaded process ...
The memory footprint of a newly created suspended process is very small.
I strongly suspect that the loader has not yet determined which modules
are needed and the structure which holds this info is not yet set up.
Post by R.Wieser
And by the way, when I allow the process to run (using ResumeProcess) and
again call EnumProcessModules I get the process itself, as well as ntdll and
kernel32. In other words, the call and my usage of it works. :-)
As you would expect when the process has been fully initialised.
Ant
2017-09-24 12:14:15 UTC
Permalink
Post by R.Wieser
Ant,
Post by Ant
The memory footprint of a newly created suspended process is very small.
I strongly suspect that the loader has not yet determined which modules
are needed and the structure which holds this info is not yet set up.
If you mean with "modules" the DLLs, than I agree with you. But why is the
process module (the program itself) not visible. I just loaded it !
I had a look at EnumProcessModules and it gets all it needs from:
PEB -> Ldr -> InMemoryOrderModuleList (where PEB is the Process
Environment Block). The InMemoryOrderModuleList includes the process
module as well as the others. EnumProcessModules does not look
elsewhere for the process name so if the PEB_LDR_DATA structure in the
PEB has not been filled in you'll get nothing.
R.Wieser
2017-09-24 12:37:12 UTC
Permalink
Ant,
so if the PEB_LDR_DATA structure in the PEB has not been
filled in you'll get nothing.
Well, although that is rather logical, it also explains nothing. Somehow
it looks like loading the process in a suspended mode stops quite a bit of
the OSes work from being done. Causing, as you might have noticed, a
rather illogical situation.

And another thing: Today I tried the rather, according to google common,
method to inject a(nother) DLL into the process, and to my amazement it
worked. Why to my amazement ? Well, the process is suspended and has
none of its DLLs loaded. And the injection method depends on the LoadLibrary
function being available in the target process ...

Although a check revealed that after calling CreateRemoteThread all where
loaded, and the processes IAT resolved. Yep, MS on its best I guess. :-)

Regards,
Rudy Wieser
Post by R.Wieser
Ant,
Post by Ant
The memory footprint of a newly created suspended process is very small.
I strongly suspect that the loader has not yet determined which modules
are needed and the structure which holds this info is not yet set up.
If you mean with "modules" the DLLs, than I agree with you. But why is the
process module (the program itself) not visible. I just loaded it !
PEB -> Ldr -> InMemoryOrderModuleList (where PEB is the Process
Environment Block). The InMemoryOrderModuleList includes the process
module as well as the others. EnumProcessModules does not look
elsewhere for the process name so if the PEB_LDR_DATA structure in the
PEB has not been filled in you'll get nothing.
Ant
2017-09-24 14:44:29 UTC
Permalink
Post by R.Wieser
Ant,
so if the PEB_LDR_DATA structure in the PEB has not been
filled in you'll get nothing.
Well, although that is rather logical, it also explains nothing. Somehow
it looks like loading the process in a suspended mode stops quite a bit of
the OSes work from being done. Causing, as you might have noticed, a
rather illogical situation.
Yep. I stepped through EnumProcessModules on a new suspended process
and indeed the PEB_LDR_DATA structure is null. In my version of
psapi.dll it actually tries to use that null pointer + the small
offset to InMemoryOrderModuleList so fails anyway!
Post by R.Wieser
And another thing: Today I tried the rather, according to google common,
method to inject a(nother) DLL into the process, and to my amazement it
worked. Why to my amazement ? Well, the process is suspended and has
none of its DLLs loaded. And the injection method depends on the LoadLibrary
function being available in the target process ...
Although a check revealed that after calling CreateRemoteThread all where
loaded, and the processes IAT resolved.
Doing certain things seem to force further initialisation. When I
looked at the process with Sysinternals Process Explorer There were no
DLLs or handles listed. Then when I clicked the "Threads" tab on the
Properties dialog I got an error message about the process failing to
initialize properly. On returning to view the DLLs I find the names
of the process, ntdll and kernel32 now listed although not all the
DLLs required had been loaded (the process was cmd.exe).
Post by R.Wieser
Yep, MS on its best I guess. :-)
Not very good, is it?!
R.Wieser
2017-09-24 17:24:18 UTC
Permalink
Ant,
Post by Ant
Yep. I stepped through EnumProcessModules on a new suspended
process and indeed the PEB_LDR_DATA structure is null. In my
version of psapi.dll it actually tries to use that null pointer + the
small
offset to InMemoryOrderModuleList so fails anyway!
Wowsers. I guess that means we should consider ourselves lucky that trying
to use EnumProcessModules on a suspended-created process does not simply
crash ...
Post by Ant
Doing certain things seem to force further initialisation.
Yep, seems it to be doing that. I experimented a bit, and calling a Sleep
for a single tick caused the same effect. Now if I want to do some IAT
patching (for which I was actually doing all the testing-and-trying to be
honest) I do not need to write my own IAT resolver/DLL loader (with all the
dependencies ofcourse) (something I was already considering :-) )

But I wonder if MS tried to do some kind of injection themselves long ago,
and went for a hack instead of actually trying to solving the problem --
maybe having added a flag to CreateProcess which would indicate a request
for IAT resolving, and thus DLL loading.
Post by Ant
Post by R.Wieser
Yep, MS on its best I guess. :-)
Not very good, is it?!
Well, Windows is a *big* program, and several version are encumbered with
lots of backward compatibility, possibly making it impossible to apply the
*best* solution, or see lots of older programs crash-and-burn.

But yes, I sometimes get the feeling they aren't all that good ... :-( :-)

Shortly ago I asked a question about how I could check if a filepath was
actually pointing to a file (and not to a device, pipe, and all sorts of
other stuff). When doing testing I fould that calling GetFileAttributes
on a named pipe caused the server-sides ConnectedNamedPipe to actually
respond as if a connection was requested. Not quite expected.

A question though: which program do you use to track-and-trace/single-step
Windows programs ? I never had much use for them, but in cases like these
(working with a static program/setup I mean) such a tool does seems to be
handy to have.

Regards,
Rudy Wieser
Post by Ant
Post by R.Wieser
Ant,
so if the PEB_LDR_DATA structure in the PEB has not been
filled in you'll get nothing.
Well, although that is rather logical, it also explains nothing.
Somehow
it looks like loading the process in a suspended mode stops quite a bit of
the OSes work from being done. Causing, as you might have noticed, a
rather illogical situation.
Yep. I stepped through EnumProcessModules on a new suspended process
and indeed the PEB_LDR_DATA structure is null. In my version of
psapi.dll it actually tries to use that null pointer + the small
offset to InMemoryOrderModuleList so fails anyway!
Post by R.Wieser
And another thing: Today I tried the rather, according to google common,
method to inject a(nother) DLL into the process, and to my amazement it
worked. Why to my amazement ? Well, the process is suspended and has
none of its DLLs loaded. And the injection method depends on the LoadLibrary
function being available in the target process ...
Although a check revealed that after calling CreateRemoteThread all where
loaded, and the processes IAT resolved.
Doing certain things seem to force further initialisation. When I
looked at the process with Sysinternals Process Explorer There were no
DLLs or handles listed. Then when I clicked the "Threads" tab on the
Properties dialog I got an error message about the process failing to
initialize properly. On returning to view the DLLs I find the names
of the process, ntdll and kernel32 now listed although not all the
DLLs required had been loaded (the process was cmd.exe).
Post by R.Wieser
Yep, MS on its best I guess. :-)
Not very good, is it?!
Ant
2017-09-24 21:07:26 UTC
Permalink
Post by R.Wieser
Ant,
Post by Ant
Yep. I stepped through EnumProcessModules on a new suspended
process and indeed the PEB_LDR_DATA structure is null. In my
version of psapi.dll it actually tries to use that null pointer + the
small offset to InMemoryOrderModuleList so fails anyway!
Wowsers. I guess that means we should consider ourselves lucky that trying
to use EnumProcessModules on a suspended-created process does not simply
crash ...
That's what I thought. I was really surprised to see no check.
Post by R.Wieser
Post by Ant
Doing certain things seem to force further initialisation.
Yep, seems it to be doing that. I experimented a bit, and calling a Sleep
for a single tick caused the same effect.
Not sure I understand that. How do you call Sleep on/in a suspended
process?
Post by R.Wieser
A question though: which program do you use to track-and-trace/single-step
Windows programs ? I never had much use for them, but in cases like these
(working with a static program/setup I mean) such a tool does seems to be
handy to have.
I use Ollydbg (http://www.ollydbg.de/). It's a very good debugger. I
prefer v1.1 but v2.1 is able to decode some newer machine instructions.
The 64bit version is still in development.
R.Wieser
2017-09-25 06:35:04 UTC
Permalink
Ant,
Post by Ant
Not sure I understand that. How do you call Sleep on/in a
suspended process?
I honestly have no idea. At first I also wondered how calling LoadLibrary
in a dll that does not exist in a suspended process could work. But it
does.

But now you're mentioning it, CreatRemoteThread also has a "create
suspended" flag. Maybe the remote and local processes are handled
differently ? Your guess is as good as mine I'm afraid.
Post by Ant
Post by R.Wieser
A question though: which program do you use to
track-and-trace/single-step
Windows programs ?
I use Ollydbg
Thanks. I've heard that name before. I'm going to get me a look.

Regards,
Rudy Wieser
Post by Ant
Post by R.Wieser
Ant,
Post by Ant
Yep. I stepped through EnumProcessModules on a new suspended
process and indeed the PEB_LDR_DATA structure is null. In my
version of psapi.dll it actually tries to use that null pointer + the
small offset to InMemoryOrderModuleList so fails anyway!
Wowsers. I guess that means we should consider ourselves lucky that trying
to use EnumProcessModules on a suspended-created process does not simply
crash ...
That's what I thought. I was really surprised to see no check.
Post by R.Wieser
Post by Ant
Doing certain things seem to force further initialisation.
Yep, seems it to be doing that. I experimented a bit, and calling a Sleep
for a single tick caused the same effect.
Not sure I understand that. How do you call Sleep on/in a suspended
process?
Post by R.Wieser
A question though: which program do you use to
track-and-trace/single-step
Windows programs ? I never had much use for them, but in cases like these
(working with a static program/setup I mean) such a tool does seems to be
handy to have.
I use Ollydbg (http://www.ollydbg.de/). It's a very good debugger. I
prefer v1.1 but v2.1 is able to decode some newer machine instructions.
The 64bit version is still in development.
R.Wieser
2017-09-25 06:58:36 UTC
Permalink
Ant,
Post by R.Wieser
Post by Ant
Not sure I understand that. How do you call Sleep on/in a
suspended process?
I honestly have no idea. At first I also wondered how calling LoadLibrary
in a dll that does not exist in a suspended process could work. But it
does.
Ehrm ... after hitting the "send" button I realized I should maybe extend a
bit on that "but it does" ...

With that I ment that the IAT gets resolved and the DLLs are loaded.
However, a WaitForSingleObject on the remote thread times out, which seems
to indicate that the Sleep 1 isn't actually running.

But again some oddity there: I replaced the call to Sleep with one to an
injected dummy procedure (containing a MOV EAX,1234 and a RET 4), and there
the WaitForSingleObject returned an OK result (zero). The IAT is still
resolved and the DLLs are loaded.

As result a "what would happen when I do *this* ?" I added a Beep into the
dummy procedure. The WaitForSingleObject timed out again ... How is it
that a LoadLibrary (which also calls all sorts of other functions)
succeedes, where my dummy procedure calling a simple Sleep or Beep doesn't ?
Questions, questions ... :-)

Regards,
Rudy Wieser
R.Wieser
2017-09-25 08:17:06 UTC
Permalink
Hey Ant,

My brain wasn't quite engaged this morning ...
Post by R.Wieser
As result a "what would happen when I do *this* ?" I added a Beep into the
dummy procedure. The WaitForSingleObject timed out again ...
That 'Beep' call ofcourse pointed at a trampoline indirect jump inside the
*current* procedure. When I realized that and after having figured out what
to use instead it worked, with WaitForSingleObject returning an OK (zero).

So, "questions, questions" minus one. :-)

Regards,
Rudy Wieser
Ant
2017-09-25 11:16:48 UTC
Permalink
Post by R.Wieser
Ant,
Post by R.Wieser
Post by Ant
Not sure I understand that. How do you call Sleep on/in a
suspended process?
I honestly have no idea. At first I also wondered how calling LoadLibrary
in a dll that does not exist in a suspended process could work. But it
does.
Ehrm ... after hitting the "send" button I realized I should maybe extend a
bit on that "but it does" ...
It's ok, I meant by what mechanism do you call Sleep but, of course,
you had already mentioned CreatRemoteThread so I should have realised
that was it.
Post by R.Wieser
With that I ment that the IAT gets resolved and the DLLs are loaded.
However, a WaitForSingleObject on the remote thread times out, which seems
to indicate that the Sleep 1 isn't actually running.
But again some oddity there: I replaced the call to Sleep with one to an
injected dummy procedure (containing a MOV EAX,1234 and a RET 4), and there
the WaitForSingleObject returned an OK result (zero). The IAT is still
resolved and the DLLs are loaded.
Another thing is that by making the DLLs load the system will be
calling their DllMain function. A program might have its own DLL that
does most of the work and a lot of it could be done in DllMain. So by
calling CreatRemoteThread on a suspended process you may cause some
of that program to run. Perhaps this is why the DLLs are not loaded
when you create a suspended process.
Post by R.Wieser
Questions, questions ... :-)
Indeed, and having a running thread in a suspended process does not
seem right at all.
R.Wieser
2017-09-25 15:32:04 UTC
Permalink
Ant,
Post by Ant
It's ok, I meant by what mechanism do you call Sleep but, of
course, you had already mentioned CreatRemoteThread so I
should have realised that was it.
In another, later message you can read how I also tried to call a function
from within some injected code, and how I was caught out by the mechanism a
program normally uses to call functions residing in DLLs.

Today I tried several ways to emulate something like it for an injected
procedure (and failed -- didn't find relative data access addressing), which
made me remember what hoops I had to jump thru when I did some
memory-patching of a loaded executable. It also made me realize why
injecting a DLL is the preferred method: its adresses get resolved "for
free".

Regards,
Rudy Wieser
Post by Ant
Post by R.Wieser
Ant,
Post by R.Wieser
Post by Ant
Not sure I understand that. How do you call Sleep on/in a
suspended process?
I honestly have no idea. At first I also wondered how calling LoadLibrary
in a dll that does not exist in a suspended process could work. But it
does.
Ehrm ... after hitting the "send" button I realized I should maybe extend a
bit on that "but it does" ...
It's ok, I meant by what mechanism do you call Sleep but, of course,
you had already mentioned CreatRemoteThread so I should have realised
that was it.
Post by R.Wieser
With that I ment that the IAT gets resolved and the DLLs are loaded.
However, a WaitForSingleObject on the remote thread times out, which seems
to indicate that the Sleep 1 isn't actually running.
But again some oddity there: I replaced the call to Sleep with one to an
injected dummy procedure (containing a MOV EAX,1234 and a RET 4), and there
the WaitForSingleObject returned an OK result (zero). The IAT is still
resolved and the DLLs are loaded.
Another thing is that by making the DLLs load the system will be
calling their DllMain function. A program might have its own DLL that
does most of the work and a lot of it could be done in DllMain. So by
calling CreatRemoteThread on a suspended process you may cause some
of that program to run. Perhaps this is why the DLLs are not loaded
when you create a suspended process.
Post by R.Wieser
Questions, questions ... :-)
Indeed, and having a running thread in a suspended process does not
seem right at all.
Udo Steinbach
2017-09-24 08:23:55 UTC
Permalink
Try a search on https://blogs.msdn.microsoft.com/oldnewthing/ ,
he explained more than one time about Modules, loading DLLs, starting
Processes.
--
Fahrradverkehr in Deutschland: http://radwege.udoline.de/
GPG: A245 F153 0636 6E34 E2F3 E1EB 817A B14D 3E7E 482E
R.Wieser
2017-09-24 08:26:27 UTC
Permalink
Udo,

Thanks, will do.

Regards,
Rudy Wieser
Post by Udo Steinbach
Try a search on https://blogs.msdn.microsoft.com/oldnewthing/ ,
he explained more than one time about Modules, loading DLLs, starting
Processes.
--
Fahrradverkehr in Deutschland: http://radwege.udoline.de/
GPG: A245 F153 0636 6E34 E2F3 E1EB 817A B14D 3E7E 482E
Loading...