2

我讨厌问这样的语法问题,但我无法通过搜索找到答案。我不确定每个变量声明的含义。我对第 3 个的最佳猜测是,它采用标签检查点地址的逻辑和以及页面大小的倒数,将其转换为无符号长整数,然后将其重新转换为 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

5

my_printf是返回 int 的函数的指针,它接受 char 指针参数和其他变量列表。

my_exit是指向没有返回值的函数的指针,采用一个 int 参数。

page是指向某个未指定类型的指针。它被分配了一个不应该编译的表达式的值,因为&&它是一个二元运算符并且没有左操作数,并且一元地址是没有意义的。该& ~(getpagesize() - 1)位掩盖了可能是地址的低位位,然后该地址将指向页面的开头。

一元&&是一个 GNU C 扩展,它采用(goto)标签的地址,所以这个结构基本上得到了包含该标签的代码页的开始地址。这是非常特定于编译器和操作系统的东西,并不是 C 语言的一部分。

于 2013-07-04T01:23:06.053 回答
0

前两个是分别与printf和兼容的函数指针exit。例如,您可以这样做:

my_exit = exit;
my_exit(3);

它相当于调用exit(3).

你对第三个的猜测是正确的。这取决于页面大小始终是 2 的幂的事实。因此,pagesize-1将具有低位全为 1,高位全为 0 的二进制模式。反转它会反转这些位。这可以用作带有地址的位掩码,以返回地址指向的页面的开头地址。然后它设置page到包含checkpoint.

于 2013-07-04T01:17:59.840 回答
0

int (*my_printf) (const char *format, ...);声明一个返回 int 的函数指针,并将 ac 样式字符串作为第一个参数,在格式参数之后具有可变数量的参数。

void (*my_exit) (int);声明一个不返回任何内容但采用 int 的函数指针。

void *page = (void *) ((unsigned long) (&&checkpoint) & ~(getpagesize() - 1));声明一个通用指针,该指针等效于checkpoint用页大小减一屏蔽的指针的地址。

于 2013-07-04T01:18:44.320 回答