When call WinExec to run a .exe, I get return value 0x21.
According to MSDN, a return value greater than 31 (0x1F) means function succeeds.
But what does it mean of 0x21, Why it didn’t return other value to me?
When call WinExec to run a .exe, I get return value 0x21. According to
Share
It is not useful for you to know what it means. That is an implementation detail. Even if you knew what it meant for this version, the meaning might change in the next version. As a programmer, you are concerned only with programming against the interface, not the underlying implementation.
However, if you are really interested, I will take you through the approach I would take to reverse engineer the function. On my system,
WinExecis disassembled to this:The call convention used under Win32 is
stdcallwhich mandates return values be held inEAX. In the case ofWinExec, there is only one exit from the function (0x764F2D2F). Tracing back from there, EAX is set by (at least when the return is 0x21):Tracing back further,
ESIitself is set fromPOP ESIwhich pops the top of the stack intoESI. The value of this is dependent on what was previously pushed on the stack. In the case of 0x21, this happens at:Immediately afterwards, a JMP is made to the
POP ESI. How we got to thePUSH 21is interesting only from after theCreateProcesscall.To see how the path will take you to the
PUSH 21, observe different branches. The first occurs as:This is saying if
CreateProcessreturned 0, callWin-Core-ErrorHandling. The return values are then set differently (0x2, 0x3 and 0xB are all possible return values ifCreateProcessfailed).The next branch is a lot less obvious to reverse engineer:
What it does is read a memory address which probably contains a function pointer (we know this because the result of the read is called later on). This
JEsimply indicates whether or not to make this call at all. Regardless of whether the call is made, the next step is to callZwClose(twice). Finally 0x21 is returned.So one simple way of looking at it is that when
CreateProcesssucceeds, 0x21 is returned, otherwise 0x2, 0x3 or 0xB are returned. This is not to say these are the only return values. For example, 0x0 can also be returned from the branch at0x764F2C53(in this case, ESI is not used in the same way at all). There are a few more possible return values but I will leave those for you to look into yourself.What I’ve shown you is how to do a very shallow analysis of
WinExecspecifically for the 0x21 return. If you want to find out more, you need to poke around more in-depth and try to understand from a higher level what is going on. You’ll be able to find out a lot more just by breakpointing the function and stepping through it (this way you can observe data values).One other way is to look at the Wine source, where someone has already done all the hard work for you:
33d is 0x21 so this actually just confirms the fruits of our earlier analysis.
In regards to the reason 0x21 is returned, my guess is that perhaps there exists more internal documentation which makes it more useful in some way.