2

このような構文の質問は嫌いですが、検索しても答えを見つけることができませんでした。これらの変数宣言のそれぞれが何を意味するのかはわかりません。3番目の私の最良の推測は、ラベルチェックポイントのアドレスとページのサイズの逆数の論理積を取り、それをunsigned longとしてキャストし、次にvoidポインターとして再キャストすることでした。コードはここからです: http://nmav.gnutls.org/2011/12/self-modifying-code-using-gcc.html

int (*my_printf) (const char *format, ...);
void (*my_exit) (int);
void *page =
  (void *) ((unsigned long) (&&checkpoint) &
    ~(getpagesize() - 1));

ありがとう!

4

3 に答える 3

0

printf最初の 2 つは、それぞれおよび と互換性のある関数ポインタですexit。たとえば、次のことができます。

my_exit = exit;
my_exit(3);

を呼び出すのと同じexit(3)です。

3番目についてのあなたの推測は正しいです。それは、ページ サイズが常に 2 の累乗になるという事実に依存します。したがって、pagesize-1下位ビットがすべて 1、上位ビットがすべて 0 のバイナリ パターンになります。それを反転すると、それらのビットが逆になります。これは、アドレスが指すページの先頭のアドレスを返すために、アドレスと共にビット マスクとして使用できます。次にpage、 を含むページの先頭に設定しますcheckpoint

于 2013-07-04T01:17:59.840 に答える
0

int (*my_printf) (const char *format, ...);int を返す関数ポインターを宣言し、最初のパラメーターとして ac スタイルの文字列を取り、format パラメーターの後に可変数の引数を指定します。

void (*my_exit) (int);何も返さないが int を取る関数ポインタを宣言します。

void *page = (void *) ((unsigned long) (&&checkpoint) & ~(getpagesize() - 1));checkpointページ サイズから 1 を引いた値でマスクされたポインターのアドレスに相当するジェネリック ポインターを宣言します。

于 2013-07-04T01:18:44.320 に答える