このバイナリ変換は、通常トレースベースであることがわかります。関数の境界を得ることができないからですか?バイナリコードに関数ラベルがありますか?バイナリコードで関数境界を見つける方法
答えて
これには簡単な答えはありません。 ret
命令を検索することはできますが、関数の途中から戻ることができるので、関数境界であるとは限りません。
mov ebp, esp
のようなものを検索する
はある程度動作しますが、再び、それは保証ません。
いくつかのコンパイラ(特にインテルコンパイラー)は、
トレースベースどういう意味...関数が終了した後に分岐したブロックを移動し、関数に戻ってジャンプしますか?あなたの質問に対する本質的な答えはいいえです。機械語には機能ラベルがありません。おそらく、それぞれのコンパイラ固有のパターンがあり、実行可能な形式を使用して、コード内のパブリック関数へのエントリポイントを見つけることもできます。しかし、最近のコンパイラでは、マシンコードレベルで関数の概念をぼかすプログラム全体の最適化を行うことができます。
C関数の開始アドレスと終了アドレスを見つける通常の方法は、メモリマップを出力し、関数の開始をスキャンすることです。多くのコンパイラはメモリマップに関数の長さを指定します。
一部のコンパイラでは、特定のアドレスに関数を割り当てるために、#pragma
または前処理キーワードを提供するものがあります。
申し訳ありませんが、C言語では機能の開始アドレスのみが提供されています。その長さではありません。
すべての機能の開始アドレスを知っていれば、長さを得るのは簡単ですよね? – dalibocai
いいえ、C言語は機能長を取得するための機能を提供していません。マップファイルとリンカ命令ファイルを参照する必要があります。リンカが関数を連続して配置する必要はなく、同じ空間に配置する必要もありません。 1つの機能はSRAMにあり、もう1つの機能はROMにあります。 –
LLVMバイナリコードから機能ラベル情報を取得するのは簡単です。マシンコードに機能ラベル情報が含まれていないのはなぜですか? – dalibocai
しかし、これはLLVMではありません。完全にコンパイルされたバイナリです。 (少なくともそれは私が仮定しているものです...) – Mysticial