1

重複の可能性:
AC関数のサイズを取得する方法はありますか?

実行時にac関数のバイトサイズを決定する必要があります。私はMSVCを使用しており、このコンパイラが提供する任意の手法を使用できます。

この質問はよく聞かれますが、「いいえ、できません」と言う人しか見つかりませんでした。それでも、おそらく私は解決策を監督しました。もしそうなら、私を指さしてください。

4

3 に答える 3

4

一般に、ソース コードに関数が表示される順序で、適切な方法でコードを生成します。したがって、サイズは次の関数のアドレスから関数のアドレスを引いたものです。

ただし、それがうまくいかない方法がいくつかあります。最初はインクリメンタル リンク オプションです。値は 5 になります。これは、実際の関数にジャンプする jmp 命令のサイズです。これらのジャンプにより、リンカーはイメージを完全に再リンクせずにコードを置き換えることができます。コードを追加してジャンプ アドレスにパッチを当てるだけです。

もちろん、オプティマイザもあります。インライン化されると、関数のサイズについて意味のある話をすることはできなくなります。__declspec(noinline) が必要です。

それをテストして、コードを完全にコメントして、いつか誰も関数を挿入しないようにすることができます。また、コードを移動するためにこれを行う場合、コンパイラは位置に依存しないコードを生成せず、そのコードに再配置をパッチできないことに注意してください。

于 2012-06-10T19:07:42.460 に答える
1

これは可能であるべきだと思います。どのように進めるかは、必要な結果の精度によって異なります。多少の不正確さが許容できる場合、私の最初の選択はSymEnumSymbols. 指定したフィルターに適合する各シンボルに対して呼び出されるコールバック関数を指定します。コールバック関数には、各シンボルの名前と計算された (推測された) サイズが与えられます。適切なシンボルに到達すると、関数が推測/計算するサイズが得られます (ただし、サイズが 0 であると言う場合もあるため、適切なアイデアを得るためにいくつかのテストを行う必要があることに注意してください)。あなたが望むものに対してどれだけうまくいく可能性が高いか)。

少しテストしたところ、関数の場合、これかなり正確であることがわかりました (これが 0 を返す場合ではないかと少し心配でした)。通常、これを使用するためにデバッグ情報を使用してビルドする必要があることに注意してください (ただし、関心のある関数をエクスポートするだけで十分な場合があります)。

もう 1 つの可能性 (おそらくもっと複雑ですが) を使用#pragma code_segして、関心のある関数を一意のセクション名を持つセクションに配置し、PE ファイルを調べてそのセクションのサイズを見つけます。

于 2012-06-10T20:15:49.450 に答える
1

本当に興味がある場合は、MSVC から .asm にコンパイルしてから、関数の開始ラベルと最後のカスタム ラベルのバイト差を調べ、それらの差を計算してください。:) 通常、コンパイラは関数ラベルの終わりを生成しません...始まりだけです。

関数をメモリに再配置して呼び出す必要がない限り、通常はこれを使用しません。

于 2012-06-10T19:00:42.117 に答える