ポップレジスタがIPポインタを変更する理由

私はいくつかのアセンブリコードで遊んでいた

func:
    pop ax
    ret
main:
    push 0x44
    call func

ipポインタがスタックの最後の項目である0x44を指すことに気付きました。
ROP テクニックを理解するためにそれをやっています。
私はこれを行うときに私はこの動作を理解する必要があります

func:
    ret
main:
   call func

EIPポインタが元のコードを指していても、期待通りに動作します。 では、コードフローを変更するために pop がどのように違うのですか。
pop ax はスタックの最後の値を ax に代入しますか?

3
各命令の機能については、命令セットのリファレンスを参照してください。 TL; DR: call はリターンアドレスをスタックに配置し、 ret はそれを削除します。その前に pop を挿入した場合、もちろんその返信先アドレスは削除され、 ret は次のアイテムを使用しますが、これはおそらく間違いです。
追加された 著者 Jester,
各命令の機能については、命令セットのリファレンスを参照してください。 TL; DR: call はリターンアドレスをスタックに配置し、 ret はそれを削除します。その前に pop を挿入した場合、もちろんその返信先アドレスは削除され、 ret は次のアイテムを使用しますが、これはおそらく間違いです。
追加された 著者 Jester,
次回、あなたが実際にマニュアルを読み込もうとしているのであれば、そのように言って、あなたが理解するのに苦労した部分を引用してください。とにかく、リバースエンジニアリングやROPなどの高度なトピックに進む前に、基本的なことについてもう少し学ぶことをお勧めします。また、デバッガを使用してコードをシングルステップし、それが何をしているのかを確認する方法も学びます。
追加された 著者 Jester,
次回、あなたが実際にマニュアルを読み込もうとしているのであれば、そのように言って、あなたが理解するのに苦労した部分を引用してください。とにかく、リバースエンジニアリングやROPなどの高度なトピックに進む前に、基本的なことについてもう少し学ぶことをお勧めします。また、デバッガを使用してコードをシングルステップし、それが何をしているのかを確認する方法も学びます。
追加された 著者 Jester,
手動で call ret が何をするのか読んでみませんか。
追加された 著者 Ped7g,
call ret もスタックを使用するためです。
追加された 著者 Oliver Charlesworth,
誰かが少なくとも投票してくれる理由が少なくとも私に説明します。
追加された 著者 Ahmed Ezzat,
誰かが少なくとも投票してくれる理由が少なくとも私に説明します。
追加された 著者 Ahmed Ezzat,
@ Ped7g私はすでに試しましたが、私はそれを正しく理解できませんでした..私はまだ初心者です
追加された 著者 Ahmed Ezzat,
@ Ped7g私はすでに試しましたが、私はそれを正しく理解できませんでした..私はまだ初心者です
追加された 著者 Ahmed Ezzat,

4 答え

このコードを理解するには、実際のプログラムの流れを見てみるといいでしょう(コードの順序を逆にし、線形の流れを仮定します)。

main:           ; entry point IP = main
    push 0x44   ; 0x44 on top of stack
    call func   ; PUSH 'next cur IP'(=func) on the stack
func:
    pop ax      ; POP 'next cur IP' from the stack(=this)
    ret         ; return to current stack value (=0x44 = IP) which is probably invalid

これは、現在のIPを取得する次の手法とよく似ています。

命令ポインタ(IP)の現在の値を取得するための命令がないため、次のコードはその値を取得するための便利な回避策です。

    call next   ; call next address
next:
    pop ax      ; POP the current value of the IP (AX=this address)
1
追加された

このコードを理解するには、実際のプログラムの流れを見てみるといいでしょう(コードの順序を逆にし、線形の流れを仮定します)。

main:           ; entry point IP = main
    push 0x44   ; 0x44 on top of stack
    call func   ; PUSH 'next cur IP'(=func) on the stack
func:
    pop ax      ; POP 'next cur IP' from the stack(=this)
    ret         ; return to current stack value (=0x44 = IP) which is probably invalid

これは、現在のIPを取得する次の手法とよく似ています。

命令ポインタ(IP)の現在の値を取得するための命令がないため、次のコードはその値を取得するための便利な回避策です。

    call next   ; call next address
next:
    pop ax      ; POP the current value of the IP (AX=this address)
1
追加された

EIPはレジスタです。スタック上の値は(まだ)EIPではありません。戻りコードまたは ret を実行してEIPにポップするとEIPになる可能性がある値です。

x86が pop eip を綴る方法として ret を考えてください。


push 0x44 を実行すると、EIPレジスタが2、命令の長さ分増えます。

ESP が指しているときに ret を実行してリターンアドレスとして 0x44 を使用すると、EIPは 0x44 。

そして、IPはEIPの下位16ビットです。あなたが本当に低い16ビットを意味しない限り、IPの代わりにEIPを書きなさい。

0
追加された

EIPはレジスタです。スタック上の値は(まだ)EIPではありません。戻りコードまたは ret を実行してEIPにポップするとEIPになる可能性がある値です。

x86が pop eip を綴る方法として ret を考えてください。


push 0x44 を実行すると、EIPレジスタが2、命令の長さ分増えます。

ESP が指しているときに ret を実行してリターンアドレスとして 0x44 を使用すると、EIPは 0x44 。

そして、IPはEIPの下位16ビットです。あなたが本当に低い16ビットを意味しない限り、IPの代わりにEIPを書きなさい。

0
追加された