前一段时间在论坛看到讨论关于“栈上改变值参的方法”的问题和方法,觉得十分有趣,自己也小试了一下。
原问题类似如下:
#include
int test(int a)
{
//请写段代码,让main中打印的a的值前后不等。如第一个printf打印a=100,第二个printf打印a=200
}
int main()
{
int a = 100;
printf("a=%d\n",a);
test(a);
printf("a=%d\n",a);
system("pause");
return 0;
}
关于linux下gcc的写法这里就不说了,好多大牛都给出了详细解释,这里俺又做了vc80下的测试。可以说是几经痛苦的调试呵呵,才发现这个幻数53,主要是对编译器,反汇编不熟悉。代码如下
#include
#define MAGIC_NUMBER 53
int test(int a)
{
//请写段代码,让main中打印的a的值前后不等。如第一个printf打印a=100,第二个printf打印a=200
*(&a + MAGIC_NUMBER ) = 200;
}
int main()
{
int a = 100;
printf("a=%d\n",a);
test(a);
printf("a=%d\n",a);
system("pause");
return 0;
}
推广一下,对于多个参数,可以这样写
#include
#define MAGIC_NUMBER 53
int test(int a,int v)
{
int b = 500;
*(&a + MAGIC_NUMBER + sizeof(int)) = 200;
*(&v + MAGIC_NUMBER ) = 200;
}
int main()
{
int a = 100;
int v = 0;
printf("a=%d\n",a);
printf("a=%d\n",a);
test(a,0);
printf("a=%d\n",a);
printf("v=%d\n",v);
system("pause");
return 0;
}
这样打印出的a,v,满足了要求。您没看错吧?这句test(a,0);是不是有问题啊?我没有传v进去啊!本来纯属我的笔误,可是运行出来v的的确确是200!晕倒ing...
看来结果正确纯属侥幸,并没有找到原理,再试一下
#include
#define MAGIC_NUMBER 53
int test(int a,int v)
{
int b = 500;
*(&a + MAGIC_NUMBER + sizeof(int)) = 200;
*(&v + MAGIC_NUMBER ) = 200;
}
int main()
{
int a = 100;
int c = 0;
int v = 0;
test(a,v);
printf("a=%d\n",a);
printf("v=%d\n",v);
system("pause");
return 0;
}
结果v是符合要求了,而a则不正确,这下可以看出来了,由于c的引入,改变了a,c的内存位置。而相邻的两个变量地址之差值为3.所以还是可以算的。再来!
#include
#define MAGIC_NUMBER 53
#define STEP 3
int test(int a,int v)
{
//int b = 500;
*(&a + MAGIC_NUMBER + 4*STEP + 1) = 200; //从a到v共4个int(含v)
*(&v + MAGIC_NUMBER ) = 200;
}
int main()
{
int a = 100;
int c = 10;
int d;
int f;
int v = 0;
test(a,v);
printf("a=%d\n",a);
printf("v=%d\n",v);
system("pause");
return 0;
}
这个规律不明显,再改造一下,改用v的地址
#include
#define MAGIC_NUMBER 53
#define STEP 3
int test(int a,int v)
{
//int b = 500;
*(&v + MAGIC_NUMBER + 4*STEP) = 200;//从a到v共4个int(含v)
*(&v + MAGIC_NUMBER ) = 200;
}
int main()
{
int a = 100;
int c = 10;
int d;
int f;
int v = 0;
test(a,v);
printf("a=%d\n",a);
printf("v=%d\n",v);
system("pause");
return 0;
}
这次一定程度上满足了要求,但是必须记得变量之间的跨度,而且v的位置很关键,再试试其他数据类型
#include
#define MAGIC_NUMBER 53
//#define STEP 3
int test(int a,int step)
{
//int b = 500;
*(&step + MAGIC_NUMBER + step) = 200;//a
}
int main()
{
int a = 100;
int b;
double dd;
double ddd;
int step = 2*(sizeof(int) -1) + 2* sizeof(double) /2;
test(a,step);
printf("a=%d\n",a);
system("pause");
return 0;
}
也可以计算出。
阅读(1124) | 评论(0) | 转发(0) |