2016-08-08 10 views
3

私は非常に時折アセンブリのユーザーです。だから私は対処しなければならない小さなコードをデコードするために、より専門的な人の助けが必要です。x64 JMP命令のアセンブリーデコード

0000: 48 ff 25 61 57 07 00 rex.W jmp QWORD PTR [rip+0x75761]  # 0x75768 
0007: cc      int3 

これはrip+0x75761に保持された8バイト/ 64ビット・アドレスにメモリ間接ジャンプが絶対アドレスにジャンプターゲットは、右、0007 + 0x75761 = 0x75768あるからロードされていますか?

+2

はい、REX.Wは冗長です。 – harold

+0

ありがとう!残念なことに、このコードは、user32.dll関数の1つについて、顧客のx64 Windows 10インストールにあります。それは標準的なMSのコードではないので、どのようにコードがそこに着いたか分かりません。だから私はそれのための調整をしなければならない。 – user118708

+0

これは64ビットのマシンコードですか? 32ビットコードとして逆アセンブルされた場合、 '0x48'バイトは' dec'または 'inc'になります。 ( 'dec eax'と思う)。 –

答えて

2

これは、Microsoftコンパイラによって生成されるように、x86-64上の標準的なテールコールシーケンスです。

はい、あなたが言ったように、それは64ビットメモリアドレス0x75768への間接的なジャンプです。このコードが実行される時点で、ripは7に等しいので、rip + 0x75761 == 0x7 + 0x75761 == 0x75768です。コードは無条件に制御をアドレス0x75768の命令に転送します。

次のint 3は、ただのパディングですが、レンガの壁としても機能します。実行は前の命令の無条件分岐のためにこの点に達するべきではありません。そうであれば、CPUは "ブレーク"割り込みであるため、トラップします。

REX.Wのプレフィックスは、技術的には正しくありませんが、あなたが考えるかもしれない理由ではありません。いくぶん驚くべきことに、レジスタを介した間接的なジャンプがx86-64上で使用される場合、スタック巻き戻しが成功するためにはWindowsにREX.W接頭辞が必要です。スタック巻き戻しコードはこれを信号として内部的に使用します。 Ross Ridgeは、Windows x64でREX接頭辞のJMP命令の目的についてan excellent answerと書いています。

この場合、これはIP相対オペランドで間接的にジャンプするためですが、コンパイラが明らかにそれを放出しているためです。これを処理するためのロジックは、おそらくそれほど複雑ではなく、たぶん一貫性のためにこのコードを生成します。あるいは、スタックアンワインディングコードがどのように実装されているかについては、公式の文書が完全には網羅されていないかもしれません余分なREX.W接頭辞には実質的な不利益がないので、申し訳ありませんよりも安全です。

+0

REX.Wは、Windows 10周年更新でMicrosoftからWIn32 APIに追加されました。オプションであっても、それは今後のOSの一部です。 – user118708

+0

私はあなたが言っていることを理解しているとは思わない、@ユーザー。アセンブリopcodeをAPIにどのように追加しますか? Windows 10に同梱されているコードでこのエンコーディングが使用されているとしたら、確かにそうです。 64ビットWindowsのすべてのバージョンは、常に持っています。 Windows 10 Anniversary Editionの32ビット版を含む、32ビット版のWindows版はありません。そして、それが「オプション」である理由は、IP相対エンコーディングのために実際には必要でないためです。間接的なエンコーディングにのみ必要です。これはWindows 10では変更されていません。スタックの巻き戻しは同じように機能します。 –

+0

ハングアップ、それは相対的なジャンプではありません。これは、RIP相対アドレッシングモードを使用して64ビットの絶対ポインタをロードしています。それは、間接指定のないテールコールとして 'REX.W = 1 jmp rel32'と大きく異なっています。 –