char xxx[]="XXXXXXX";
int main ()
{
int *ret;
ret=(int *)&ret+2; //这个用法是什么意思?
(*ret)=(int)xxx; //前面怎么是括号 然后有赋值号。。。。
return 0;
}
这个好像是把xxx当作函数调用。在哪里调用的啊?
谢谢大家
15 个解决方案
#1
友情帮顶吧
#2
看不出这段代码的用途
等小牛出现
等小牛出现
#3
楼主ret是个野指针.运行时会出错.代码有点绕.
#include<stdio.h>
#include<stdlib.h>
char xxx[]="XXXXXXX";
int main ()
{
int *ret, *p;
//ret=(int *)&ret+2; //这个用法是什么意思?
ret = (int *)malloc(sizeof(3));
p = ret;
p = (int *)&p + 2; /*和下面注释行没区别*/
//p = p + 2;
//(*ret)=(int)xxx; //前面怎么是括号 然后有赋值号。。。。
*ret = (int)xxx; //去掉括号就是了
printf("*ret=%d\n", *ret);
free(ret);
return 0;
}
#4
&ret 取ret的地址,也就是一个指向指针的指针
(int *)&ret
把这个指向ret的指针转换成一个int指针
(int*)&ret + 2 把这个指针向后移2个单位(2个int)
ret = (int*)&ret + 2 再把这个指针赋值给ret
*ret 然后对这个指针解除引用 也就是一个指向int的指针了
(int)xxx 这里写错了吧 应该是 (int *)xxx 吧,把字符指针转换成 int指针
(*ret)=(int*)xxx 赋值给前面的*ret指针
(int *)&ret
把这个指向ret的指针转换成一个int指针
(int*)&ret + 2 把这个指针向后移2个单位(2个int)
ret = (int*)&ret + 2 再把这个指针赋值给ret
*ret 然后对这个指针解除引用 也就是一个指向int的指针了
(int)xxx 这里写错了吧 应该是 (int *)xxx 吧,把字符指针转换成 int指针
(*ret)=(int*)xxx 赋值给前面的*ret指针
#5
呵呵,对了,ret是指向什么地方呢?
#6
我理解错了。。。
检讨,看3L
囧。。
检讨,看3L
囧。。
#7
3楼正解
#8
lz的代码实际上修改存储在栈中eip的值,进入main函数时,main函数的参数入栈,然后eip入栈,然后程序跳转到main函数对应的汇编指令的处,执行main函数对应的汇编指令,一般来讲进入函数体一般会保存ebp指针,即第一条汇编指令是push ebp;,然后会下调esp指针为函数内局部非静态变量分配空间。
上述代码基于一个假设:为局部变量分配栈上的空间和保存ebp的空间是紧挨着的,基于上述假设:
ret=(int *)&ret+1;是获取栈保存ebp的空间起始地址
ret=(int *)&ret+2;是获取栈保存eip值的空间起始地址
(*ret)=(int)xxx;修改eip的值
而ret=(int *)&ret+2是栈保存eip值的空间起始地址假设可能在vc6.0这样编译器可能成立,像vs2005+的版本基本上不会成立的
上述代码基于一个假设:为局部变量分配栈上的空间和保存ebp的空间是紧挨着的,基于上述假设:
ret=(int *)&ret+1;是获取栈保存ebp的空间起始地址
ret=(int *)&ret+2;是获取栈保存eip值的空间起始地址
(*ret)=(int)xxx;修改eip的值
而ret=(int *)&ret+2是栈保存eip值的空间起始地址假设可能在vc6.0这样编译器可能成立,像vs2005+的版本基本上不会成立的
#10
*ret = (int)xxx; //*ret是个整型左值,可以给它赋整数,参见《C和指针》
很好,C我已经忘得差不多了,真正开始Thinking in C++
#11
#include <stdio.h>
#include <stdlib.h>
void HelloWorld()
{
printf("Hello World!\n");
system("Pause");
exit(0);
}
int main()
{
int arData[1] = {0};
arData[2] = (int)HelloWorld;
printf("not print\n");
return 0;
}
原理和lz代码一样,code:block 8.02能通过,估计vc6.0差不多,vs2005+的版本够呛~~~
#12
这个是指针?
还没学完..
还没学完..
#13
谢谢大家。。虽然不太明白。。。
#14
你的代码好象是16位的吧。32位下你看看我的这个就明白了,其实就是利用修改堆栈内容来让main的ret指令退出不正确,推出到另一个函数中。
#include <stdio.h>
void v();
int main ()
{
int *ret;
ret=(int *)&ret+4; //这个用法是什么意思?
(*ret)=(int)v; //前面怎么是括号 然后有赋值号。。。。
return 0;
}
void v(){
printf("hello world!!!");
}
#include <stdio.h>
void v();
int main ()
{
int *ret;
ret=(int *)&ret+4; //这个用法是什么意思?
(*ret)=(int)v; //前面怎么是括号 然后有赋值号。。。。
return 0;
}
void v(){
printf("hello world!!!");
}
#15
上面的代码有问题,退出没处理好。
这是完整版:
这是完整版:
#include <stdio.h>
void v();
int oldexit;
int main ()
{
int *ret;
ret=(int *)&ret+4; //这个用法是什么意思?
oldexit = *ret;
(*ret)=(int)v; //前面怎么是括号 然后有赋值号。。。。
*(ret+1) = oldexit;
return 0;
}
void v(){
printf("hello world!!!");
}
#1
友情帮顶吧
#2
看不出这段代码的用途
等小牛出现
等小牛出现
#3
楼主ret是个野指针.运行时会出错.代码有点绕.
#include<stdio.h>
#include<stdlib.h>
char xxx[]="XXXXXXX";
int main ()
{
int *ret, *p;
//ret=(int *)&ret+2; //这个用法是什么意思?
ret = (int *)malloc(sizeof(3));
p = ret;
p = (int *)&p + 2; /*和下面注释行没区别*/
//p = p + 2;
//(*ret)=(int)xxx; //前面怎么是括号 然后有赋值号。。。。
*ret = (int)xxx; //去掉括号就是了
printf("*ret=%d\n", *ret);
free(ret);
return 0;
}
#4
&ret 取ret的地址,也就是一个指向指针的指针
(int *)&ret
把这个指向ret的指针转换成一个int指针
(int*)&ret + 2 把这个指针向后移2个单位(2个int)
ret = (int*)&ret + 2 再把这个指针赋值给ret
*ret 然后对这个指针解除引用 也就是一个指向int的指针了
(int)xxx 这里写错了吧 应该是 (int *)xxx 吧,把字符指针转换成 int指针
(*ret)=(int*)xxx 赋值给前面的*ret指针
(int *)&ret
把这个指向ret的指针转换成一个int指针
(int*)&ret + 2 把这个指针向后移2个单位(2个int)
ret = (int*)&ret + 2 再把这个指针赋值给ret
*ret 然后对这个指针解除引用 也就是一个指向int的指针了
(int)xxx 这里写错了吧 应该是 (int *)xxx 吧,把字符指针转换成 int指针
(*ret)=(int*)xxx 赋值给前面的*ret指针
#5
呵呵,对了,ret是指向什么地方呢?
#6
我理解错了。。。
检讨,看3L
囧。。
检讨,看3L
囧。。
#7
3楼正解
#8
lz的代码实际上修改存储在栈中eip的值,进入main函数时,main函数的参数入栈,然后eip入栈,然后程序跳转到main函数对应的汇编指令的处,执行main函数对应的汇编指令,一般来讲进入函数体一般会保存ebp指针,即第一条汇编指令是push ebp;,然后会下调esp指针为函数内局部非静态变量分配空间。
上述代码基于一个假设:为局部变量分配栈上的空间和保存ebp的空间是紧挨着的,基于上述假设:
ret=(int *)&ret+1;是获取栈保存ebp的空间起始地址
ret=(int *)&ret+2;是获取栈保存eip值的空间起始地址
(*ret)=(int)xxx;修改eip的值
而ret=(int *)&ret+2是栈保存eip值的空间起始地址假设可能在vc6.0这样编译器可能成立,像vs2005+的版本基本上不会成立的
上述代码基于一个假设:为局部变量分配栈上的空间和保存ebp的空间是紧挨着的,基于上述假设:
ret=(int *)&ret+1;是获取栈保存ebp的空间起始地址
ret=(int *)&ret+2;是获取栈保存eip值的空间起始地址
(*ret)=(int)xxx;修改eip的值
而ret=(int *)&ret+2是栈保存eip值的空间起始地址假设可能在vc6.0这样编译器可能成立,像vs2005+的版本基本上不会成立的
#9
#10
*ret = (int)xxx; //*ret是个整型左值,可以给它赋整数,参见《C和指针》
很好,C我已经忘得差不多了,真正开始Thinking in C++
#11
#include <stdio.h>
#include <stdlib.h>
void HelloWorld()
{
printf("Hello World!\n");
system("Pause");
exit(0);
}
int main()
{
int arData[1] = {0};
arData[2] = (int)HelloWorld;
printf("not print\n");
return 0;
}
原理和lz代码一样,code:block 8.02能通过,估计vc6.0差不多,vs2005+的版本够呛~~~
#12
这个是指针?
还没学完..
还没学完..
#13
谢谢大家。。虽然不太明白。。。
#14
你的代码好象是16位的吧。32位下你看看我的这个就明白了,其实就是利用修改堆栈内容来让main的ret指令退出不正确,推出到另一个函数中。
#include <stdio.h>
void v();
int main ()
{
int *ret;
ret=(int *)&ret+4; //这个用法是什么意思?
(*ret)=(int)v; //前面怎么是括号 然后有赋值号。。。。
return 0;
}
void v(){
printf("hello world!!!");
}
#include <stdio.h>
void v();
int main ()
{
int *ret;
ret=(int *)&ret+4; //这个用法是什么意思?
(*ret)=(int)v; //前面怎么是括号 然后有赋值号。。。。
return 0;
}
void v(){
printf("hello world!!!");
}
#15
上面的代码有问题,退出没处理好。
这是完整版:
这是完整版:
#include <stdio.h>
void v();
int oldexit;
int main ()
{
int *ret;
ret=(int *)&ret+4; //这个用法是什么意思?
oldexit = *ret;
(*ret)=(int)v; //前面怎么是括号 然后有赋值号。。。。
*(ret+1) = oldexit;
return 0;
}
void v(){
printf("hello world!!!");
}