请问这段代码是什么意思?

时间:2020-12-06 21:14:36

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指针


#5


呵呵,对了,ret是指向什么地方呢?

#6


我理解错了。。。

检讨,看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+的版本基本上不会成立的

#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!!!");
}

#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指针


#5


呵呵,对了,ret是指向什么地方呢?

#6


我理解错了。。。

检讨,看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+的版本基本上不会成立的

#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!!!");
}

#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!!!");
}