2012-03-26 25 views
4

WinExecを呼び出して.exeを実行すると、戻り値0x21が返されます。
MSDNによると、31(0x1F)より大きい戻り値は関数が成功することを意味します。
0x21の意味はどうして私に他の価値を返さなかったのですか?WinExec 0x21を返すが、正確にはどういう意味ですか?

+1

あなたは 'CreateProcess'を使用することはできません任意の理由は? – Konrad

+0

*歴史的には* win16の下では、ヒントを再調整しました。 –

答えて

9

あなたはそれが何を意味するかを知ることは有用ではありません。これは実装の詳細です。このバージョンの意味を知っていたとしても、次のバージョンでは意味が変わるかもしれません。プログラマとしては、基本的な実装ではなく、インタフェースに対するプログラミングだけに関心があります。

本当に興味があれば、機能をリバースエンジニアリングする方法をお話します。私のシステムでは、WinExecはこれに解体さ:Win32で使用

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 

呼び出し規約は、戻り値はEAXで開催さ義務付けstdcallです。 WinExecの場合、関数からの出口は1つだけです(0x764F2D2F)。

764F2D29 8BC6    MOV EAX,ESI 

さらに遡っ、ESI自体がESIにスタックの先頭をポップPOP ESIから設定されている。そこから遡っ、EAXは(リターンは、少なくとも場合0x21で)で設定されています。この値は、以前にスタックにプッシュされた値に依存します。その後すぐに

764F2CF5 6A 21   PUSH 21 

、JMPはPOP ESIに行われます0x21である場合には、これはで起こります。 PUSH 21にどうやって届いたかは、CreateProcessコールの後でしかない。

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 

パスが異なるブランチを観察し、PUSH 21に行くことができますどのように確認してください。これはCreateProcessは0を返した場合、Win-Core-ErrorHandlingを呼び出して言っている

764F2CD0 74 27   JE SHORT kernel32.764F2CF9 

:として最初に発生します。戻り値は、別の方法で設定されます(CreateProcessが失敗した場合は、0x2、0x3および0xBはすべての可能な戻り値です)。

次の分岐がエンジニアを逆にはるかに少ない明白です:

読み取りの結果は、後に呼ばれるので、それは(私たちはこのことを知っている、おそらく関数ポインタが含まれているメモリアドレスを読まれない何
764F2CD9 74 0A   JE SHORT kernel32.764F2CE5 

に)。このJEは、単にこの呼び出しを行うかどうかを示します。コールが行われたかどうかにかかわらず、次のステップはZwClose(2回)に電話することです。最後に0x21が返されます。

だからそれを見ての一つの簡単な方法は、CreateProcessが成功した場合、0x21では、それ以外の場合は0x2の、0x3のを返されたり0xBが返されることです。これが唯一の戻り値であるとは限りません。たとえば、0x0はブランチから0x764F2C53に戻すこともできます(この場合、ESIはまったく同じ方法で使用されません)。戻り値にはいくつかの可能性がありますが、私はそれらをあなた自身の中に見るようにしておきます。私はあなたを示してきたもの

は、具体的には0x21でリターンをWinExecの非常に浅い分析を行う方法です。あなたがもっと知りたいのであれば、もっと深く掘り下げて、何が起きているのかをより高いレベルから理解しようとする必要があります。関数をブレークポイントして実行するだけで、さらに多くの情報を得ることができます(データ値を見ることができるように)。


もう一つの方法は、誰かが既にあなたのためのすべてのハードワークを行っているWine source、見ている:

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が0x21であるので、これは実際に私たちの以前の分析の成果を確認し、 。理由0x21でに関しては

が返され、私の推測では、おそらく何らかの方法でそれをより便利になり複数の内部文書が存在するということです。

+2

マジックナンバー:p – Deanna

+1

面白い、それを通ってくれてありがとう。 – Konrad

+1

それは献身です! –

0

EDIT:OPの結果がエラーコードではありませんので、この答えは間違っています。私は誤ってそれがエラーコードであると言われていると思った。私はまだ以下の実用的な情報が役に立つと思っています。また、間違った仮定が導かれるのを見ておくと便利なこともあるので、私はこの答えを立てます。


Visual Studioをインストールしている場合(フルまたはエディションを発現する)、そして、あなたはあなたを伝えるために FormatMessage API関数を使用し errlookと呼ばれるツールを、持っているもののエラーコードまたは HRESULT値手段。この場合

別のプロセスがファイルの一部をロックしているため、

プロセスがファイルにアクセスできません。

<winerror.h>ファイルを参照することで、同じことを手動で行うことができます。たとえば、Visual StudioのC++ソースファイルに#includeと入力し、右クリックしてヘッダーを開きます。あなたがところで

// 
// MessageId: ERROR_LOCK_VIOLATION 
// 
// MessageText: 
// 
// The process cannot access the file because another process has locked a portion of the file. 
// 
#define ERROR_LOCK_VIOLATION    33L 

ことを見つけた場合、WinExecは単に古い互換機能です。好ましくはShellExecuteまたはCreateProcessを使用します。 ShellExecute機能は、Windows Vistaと7のユーザーアクセスコントロールでよりうまく機能し、使用するのが簡単です。一般的には好ましい方法です。

+0

エラーコードではないため、ダウン投票しました! –

+0

@Frederik:ありがとう、私は間違っていることを上にノートを追加します。 :-) –

+0

うーん、それは良い考えではなかった。それは倒立アトラクタでした。今、それを必要としない高所得者だけがその情報を見ることができます。 –

関連する問題