如何强制C程序打印意外结果?

时间:2012-01-16 14:21:25

标签: c linux

square.c的源代码是:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int square(int *ptr)
{
  int a;
  a = *ptr;
  return a * a;
}

int main(int argc, char **argv)
{
  int a, aa;
  srandom(time(NULL));
  a = random() % 10 + 1;
  aa = square(&a);
  printf("%d\n", aa);
  return 0;
}

编译源代码的命令行是:

gcc square.c -o square

是否可以在Linux中运行square可执行文件,以使打印值为任何整数的平方?

允许运行该程序的任何方法。

4 个答案:

答案 0 :(得分:6)

是。我们可以覆盖printf。

将帖子中的代码写入square.c并使用gcc square.c

进行编译

制作此文件,fakesquare.c

int printf(char *str,int i)
{
    return puts("7");
}

将fakesquare.c编译为共享库:

gcc -fPIC -o libfakesquare.so -shared fakesquare.c

使用预先加载的libfakesquare.so运行square程序:

[15:27:27 0 /tmp] $ LD_PRELOAD=./libfakesqare.so ./a.out
7
[15:29:16 0 /tmp] $ LD_PRELOAD=./libfakesqare.so ./a.out
7
[15:29:16 0 /tmp] $ LD_PRELOAD=./libfakesqare.so ./a.out
7

Witout libfakeshared.so preloaded:

[15:29:40 0 /tmp] $  ./a.out
36
[15:29:41 0 /tmp] $  ./a.out
16
[15:29:42 0 /tmp] $  ./a.out
64

答案 1 :(得分:0)

您的代码唯一的依赖是libc。如果libc未经修改,那么您的代码将始终有效。

如果在运行之前您的程序将失败,则所有可用内存都将耗尽。您始终可以检查ptr!= NULL。

答案 2 :(得分:0)

你可以用这个:

Fastest way to determine if an integer's square root is an integer

他们的代码似乎已经过优化,但无论哪种最简单都应该为你做好准备。

答案 3 :(得分:0)

假设一个标准的C环境,我没有看到为什么在标准平台上失败的原因。如果printf没有做它想做的事情,代码可能会失败,但我可能这不是你要求的。它也可能在一个平台上失败,其中int小到一个字节,一个字节只有6位宽。在这种情况下,你的平方函数可能会计算9 * 9 = 81,这将不适合结果类型int(对于6位字节为0..63)。但在我看来,这是一个非常学术的案例。