WinExecを呼び出して.exeを実行すると、戻り値0x21が返されます。
MSDNによると、31(0x1F)より大きい戻り値は関数が成功することを意味します。
0x21の意味はどうして私に他の価値を返さなかったのですか?WinExec 0x21を返すが、正確にはどういう意味ですか?
答えて
あなたはそれが何を意味するかを知ることは有用ではありません。これは実装の詳細です。このバージョンの意味を知っていたとしても、次のバージョンでは意味が変わるかもしれません。プログラマとしては、基本的な実装ではなく、インタフェースに対するプログラミングだけに関心があります。
本当に興味があれば、機能をリバースエンジニアリングする方法をお話します。私のシステムでは、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でに関しては
が返され、私の推測では、おそらく何らかの方法でそれをより便利になり複数の内部文書が存在するということです。
成功以外は、戻り値の意味は定義されていません。おそらく、レガシーアプリケーションがこの特定の価値をうまく利用できるように選ばれたのかもしれません。一つのことは確かです。心配するより重要なことがあります!
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687393(v=vs.85).aspx
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のユーザーアクセスコントロールでよりうまく機能し、使用するのが簡単です。一般的には好ましい方法です。
エラーコードではないため、ダウン投票しました! –
@Frederik:ありがとう、私は間違っていることを上にノートを追加します。 :-) –
うーん、それは良い考えではなかった。それは倒立アトラクタでした。今、それを必要としない高所得者だけがその情報を見ることができます。 –
- 1. Kinesis PUT Limit、正確にはどういう意味ですか?
- 2. 関数が返すのはどういう意味ですか?
- 3. ラムダが返すラムダ:object_listはどういう意味ですか?
- 4. C++テンプレートのインスタンス化、正確にはどういう意味ですか?
- 5. 正確にNSUrlConnection非同期はどういう意味ですか?
- 6. Azure DocumentDbストレージの制限 - 正確にはどういう意味ですか?
- 7. linuxの意味はどういう意味ですか?
- 8. %%はどういう意味ですか?
- 9. class.getProtectionDomainがnullを返すとはどういう意味ですか
- 10. AuthorizationExecuteWithPrivileges()が-1を返すとはどういう意味ですか?
- 11. プログラミング言語が単純であることは、正確にはどういう意味ですか?
- 12. Pythonの正規表現ですが、+ Xはどういう意味ですか?
- 13. "javascript://"とはどういう意味ですか?そのコードには意味:
- 14. OpenCVのVideoCapture :: get(CV_CAP_PROP_FORMAT)が返す数値はどういう意味ですか?
- 15. どういう意味ですか? OR?
- 16. (?i)\\は何ですか?正規表現はどういう意味ですか?
- 17. 終了コンテキストがWaitHandle.WaitOneの意味をどういう意味ですか?
- 18. WsKSendToはSTATUS_INVALID_DEVICE_STATEを返します:それはどういう意味ですか?
- 19. メンバ関数でクラスオブジェクトを返すのはどういう意味ですか?
- 20. UnsafeQueueUserWorkItemと、正確に「呼び出しスタックを伝播しない」とはどういう意味ですか?
- 21. ビュー内の「残りのすべてのプロジェクト」は正確にはどういう意味ですか?
- 22. どういう意味ですか?:意味ですか? Apacheの設定ファイルで
- 23. Googleデータストアの「高度にスケーラブルな」プロパティは、正確にはどういう意味ですか?
- 24. voidメソッドの終了時に返り値はどういう意味ですか?
- 25. ディレクトリ名とは何ですか? 'と '..'という意味で、faDirectoryはどういう意味ですか?
- 26. JavaScriptの字句範囲の概念を正確にはどういう意味ですか?
- 27. "ビットマップロック"とは実際にはどういう意味ですか?
- 28. パンジャブを使うのはどういう意味ですか
- 29. データクラスという用語はどういう意味ですか?
- 30. Pythonプログラムに.pyがどういう意味ですか?
あなたは 'CreateProcess'を使用することはできません任意の理由は? – Konrad
*歴史的には* win16の下では、ヒントを再調整しました。 –