Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7720795
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 1, 20262026-06-01T03:45:38+00:00 2026-06-01T03:45:38+00:00

When call WinExec to run a .exe, I get return value 0x21. According to

  • 0

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?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-01T03:45:39+00:00Added an answer on June 1, 2026 at 3:45 am

    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, WinExec is disassembled to this:

    764F2C21 > 8BFF             MOV EDI,EDI
    764F2C23   55               PUSH EBP
    764F2C24   8BEC             MOV EBP,ESP
    764F2C26   81EC 80000000    SUB ESP,80
    764F2C2C   53               PUSH EBX
    764F2C2D   8B5D 0C          MOV EBX,DWORD PTR SS:[EBP+C]
    764F2C30   56               PUSH ESI
    764F2C31   57               PUSH EDI
    764F2C32   33FF             XOR EDI,EDI
    764F2C34   47               INC EDI
    764F2C35   33F6             XOR ESI,ESI
    764F2C37   85DB             TEST EBX,EBX
    764F2C39   79 4F            JNS SHORT kernel32.764F2C8A
    764F2C3B   8D45 FC          LEA EAX,DWORD PTR SS:[EBP-4]
    764F2C3E   50               PUSH EAX
    764F2C3F   56               PUSH ESI
    764F2C40   57               PUSH EDI
    764F2C41   8D45 C8          LEA EAX,DWORD PTR SS:[EBP-38]
    764F2C44   50               PUSH EAX
    764F2C45   C745 FC 20000000 MOV DWORD PTR SS:[EBP-4],20
    764F2C4C   E8 90BE0200      CALL <JMP.&API-MS-Win-Core-ProcessThread>
    764F2C51   85C0             TEST EAX,EAX
    764F2C53   0F84 D2000000    JE kernel32.764F2D2B
    764F2C59   56               PUSH ESI
    764F2C5A   56               PUSH ESI
    764F2C5B   6A 04            PUSH 4
    764F2C5D   8D45 F8          LEA EAX,DWORD PTR SS:[EBP-8]
    764F2C60   50               PUSH EAX
    764F2C61   68 01000600      PUSH 60001
    764F2C66   56               PUSH ESI
    764F2C67   8D45 C8          LEA EAX,DWORD PTR SS:[EBP-38]
    764F2C6A   50               PUSH EAX
    764F2C6B   C745 0C 00000800 MOV DWORD PTR SS:[EBP+C],80000
    764F2C72   897D F8          MOV DWORD PTR SS:[EBP-8],EDI
    764F2C75   E8 5CBE0200      CALL <JMP.&API-MS-Win-Core-ProcessThread>
    764F2C7A   85C0             TEST EAX,EAX
    764F2C7C   0F84 95000000    JE kernel32.764F2D17
    764F2C82   8D45 C8          LEA EAX,DWORD PTR SS:[EBP-38]
    764F2C85   8945 C4          MOV DWORD PTR SS:[EBP-3C],EAX
    764F2C88   EB 03            JMP SHORT kernel32.764F2C8D
    764F2C8A   8975 0C          MOV DWORD PTR SS:[EBP+C],ESI
    764F2C8D   6A 44            PUSH 44
    764F2C8F   8D45 80          LEA EAX,DWORD PTR SS:[EBP-80]
    764F2C92   56               PUSH ESI
    764F2C93   50               PUSH EAX
    764F2C94   E8 B5E9F7FF      CALL <JMP.&ntdll.memset>
    764F2C99   83C4 0C          ADD ESP,0C
    764F2C9C   33C0             XOR EAX,EAX
    764F2C9E   3975 0C          CMP DWORD PTR SS:[EBP+C],ESI
    764F2CA1   897D AC          MOV DWORD PTR SS:[EBP-54],EDI
    764F2CA4   0F95C0           SETNE AL
    764F2CA7   66:895D B0       MOV WORD PTR SS:[EBP-50],BX
    764F2CAB   8D0485 44000000  LEA EAX,DWORD PTR DS:[EAX*4+44]
    764F2CB2   8945 80          MOV DWORD PTR SS:[EBP-80],EAX
    764F2CB5   8D45 E8          LEA EAX,DWORD PTR SS:[EBP-18]
    764F2CB8   50               PUSH EAX
    764F2CB9   8D45 80          LEA EAX,DWORD PTR SS:[EBP-80]
    764F2CBC   50               PUSH EAX
    764F2CBD   56               PUSH ESI
    764F2CBE   56               PUSH ESI
    764F2CBF   FF75 0C          PUSH DWORD PTR SS:[EBP+C]
    764F2CC2   56               PUSH ESI
    764F2CC3   56               PUSH ESI
    764F2CC4   56               PUSH ESI
    764F2CC5   FF75 08          PUSH DWORD PTR SS:[EBP+8]
    764F2CC8   56               PUSH ESI
    764F2CC9   E8 A4E3F7FF      CALL kernel32.CreateProcessA
    764F2CCE   85C0             TEST EAX,EAX
    764F2CD0   74 27            JE SHORT kernel32.764F2CF9
    764F2CD2   A1 3C005476      MOV EAX,DWORD PTR DS:[7654003C]
    764F2CD7   3BC6             CMP EAX,ESI
    764F2CD9   74 0A            JE SHORT kernel32.764F2CE5
    764F2CDB   68 30750000      PUSH 7530
    764F2CE0   FF75 E8          PUSH DWORD PTR SS:[EBP-18]
    764F2CE3   FFD0             CALL EAX
    764F2CE5   FF75 E8          PUSH DWORD PTR SS:[EBP-18]
    764F2CE8   8B35 A0054776    MOV ESI,DWORD PTR DS:[<&ntdll.NtClose>]  ; ntdll.ZwClose
    764F2CEE   FFD6             CALL ESI
    764F2CF0   FF75 EC          PUSH DWORD PTR SS:[EBP-14]
    764F2CF3   FFD6             CALL ESI
    764F2CF5   6A 21            PUSH 21
    764F2CF7   EB 1D            JMP SHORT kernel32.764F2D16
    764F2CF9   E8 C9E4F7FF      CALL <JMP.&API-MS-Win-Core-ErrorHandling>
    764F2CFE   48               DEC EAX
    764F2CFF   48               DEC EAX
    764F2D00   74 12            JE SHORT kernel32.764F2D14
    764F2D02   48               DEC EAX
    764F2D03   74 0B            JE SHORT kernel32.764F2D10
    764F2D05   2D BE000000      SUB EAX,0BE
    764F2D0A   75 0B            JNZ SHORT kernel32.764F2D17
    764F2D0C   6A 0B            PUSH 0B
    764F2D0E   EB 06            JMP SHORT kernel32.764F2D16
    764F2D10   6A 03            PUSH 3
    764F2D12   EB 02            JMP SHORT kernel32.764F2D16
    764F2D14   6A 02            PUSH 2
    764F2D16   5E               POP ESI
    764F2D17   F745 0C 00000800 TEST DWORD PTR SS:[EBP+C],80000
    764F2D1E   74 09            JE SHORT kernel32.764F2D29
    764F2D20   8D45 C8          LEA EAX,DWORD PTR SS:[EBP-38]
    764F2D23   50               PUSH EAX
    764F2D24   E8 A2BD0200      CALL <JMP.&API-MS-Win-Core-ProcessThread>
    764F2D29   8BC6             MOV EAX,ESI
    764F2D2B   5F               POP EDI
    764F2D2C   5E               POP ESI
    764F2D2D   5B               POP EBX
    764F2D2E   C9               LEAVE
    764F2D2F   C2 0800          RETN 8
    

    The call convention used under Win32 is stdcall which mandates return values be held in EAX. In the case of WinExec, there is only one exit from the function (0x764F2D2F). Tracing back from there, EAX is set by (at least when the return is 0x21):

    764F2D29   8BC6             MOV EAX,ESI
    

    Tracing back further, ESI itself is set from POP ESI which pops the top of the stack into ESI. The value of this is dependent on what was previously pushed on the stack. In the case of 0x21, this happens at:

    764F2CF5   6A 21            PUSH 21
    

    Immediately afterwards, a JMP is made to the POP ESI. How we got to the PUSH 21 is interesting only from after the CreateProcess call.

    764F2CC9    E8 A4E3F7FF     CALL kernel32.CreateProcessA
    764F2CCE    85C0            TEST EAX,EAX
    764F2CD0    74 27           JE SHORT kernel32.764F2CF9
    764F2CD2    A1 3C005476     MOV EAX,DWORD PTR DS:[7654003C]
    764F2CD7    3BC6            CMP EAX,ESI
    764F2CD9    74 0A           JE SHORT kernel32.764F2CE5
    764F2CDB    68 30750000     PUSH 7530
    764F2CE0    FF75 E8         PUSH DWORD PTR SS:[EBP-18]
    764F2CE3    FFD0            CALL EAX
    764F2CE5    FF75 E8         PUSH DWORD PTR SS:[EBP-18]
    764F2CE8    8B35 A0054776   MOV ESI,DWORD PTR DS:[<&ntdll.NtClose>]  ; ntdll.ZwClose
    764F2CEE    FFD6            CALL ESI
    764F2CF0    FF75 EC         PUSH DWORD PTR SS:[EBP-14]
    764F2CF3    FFD6            CALL ESI
    764F2CF5    6A 21           PUSH 21
    

    To see how the path will take you to the PUSH 21, observe different branches. The first occurs as:

    764F2CD0   74 27            JE SHORT kernel32.764F2CF9
    

    This is saying if CreateProcess returned 0, call Win-Core-ErrorHandling. The return values are then set differently (0x2, 0x3 and 0xB are all possible return values if CreateProcess failed).

    The next branch is a lot less obvious to reverse engineer:

    764F2CD9   74 0A            JE SHORT kernel32.764F2CE5
    

    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 JE simply indicates whether or not to make this call at all. Regardless of whether the call is made, the next step is to call ZwClose (twice). Finally 0x21 is returned.

    So one simple way of looking at it is that when CreateProcess succeeds, 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 at 0x764F2C53 (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 WinExec specifically 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:

    UINT WINAPI WinExec( LPCSTR lpCmdLine, UINT nCmdShow )
    {
        PROCESS_INFORMATION info;
        STARTUPINFOA startup;
        char *cmdline;
        UINT ret;
    
        memset( &startup, 0, sizeof(startup) );
        startup.cb = sizeof(startup);
        startup.dwFlags = STARTF_USESHOWWINDOW;
        startup.wShowWindow = nCmdShow;
    
        /* cmdline needs to be writable for CreateProcess */
        if (!(cmdline = HeapAlloc( GetProcessHeap(), 0, strlen(lpCmdLine)+1 ))) return 0;
        strcpy( cmdline, lpCmdLine );
    
         if (CreateProcessA( NULL, cmdline, NULL, NULL, FALSE,
                            0, NULL, NULL, &startup, &info ))
        {
            /* Give 30 seconds to the app to come up */
            if (wait_input_idle( info.hProcess, 30000 ) == WAIT_FAILED)
                WARN("WaitForInputIdle failed: Error %d\n", GetLastError() );
            ret = 33;
            /* Close off the handles */
            CloseHandle( info.hThread );
            CloseHandle( info.hProcess );
        }
        else if ((ret = GetLastError()) >= 32)
        {
            FIXME("Strange error set by CreateProcess: %d\n", ret );
            ret = 11;
        }
        HeapFree( GetProcessHeap(), 0, cmdline );
        return ret;
    }
    

    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.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I call my JavaScript function. Why do I sometimes get the error 'myFunction is
I call a javascript function from a textbox by using OnKeyPress=clickSearchButton() Here is my
I call the following function with a mouseover event but it's not working. My
I call an ajax enabled wcf service method , <script type=text/javascript> function GetEmployee() {
Call to a member function save() on a non-object in .../views/manufacturer/tmpl/edit.php line 24 which
Call like: mAsyncRunner.request(me, params,new AsyncFacebookRunner.RequestListener() returns me all info for user /according to permisions/.
The call to n.sort(sortNo) doesn't specify any parameters for the function sortNo (which defines
I call a template like this from my view: return render_to_response('mytemplate.html', context_instance=RequestContext(request)) I'm trying
Function call: $trdata .= $this->table_td($tddata, 1, $td); Function: public function table_td($data = '', $parameters
Smarty {call} built-in function is able to call a template function defined by the

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.