您的位置:首页 > 其它

利用栈帧改变变量的值及强行插入第三个函数

2017-12-06 17:19 253 查看

利用栈帧 改变另一个变量的值

在之前学习了栈帧结构后,我们可不可以不通过某一个变量名来改变该变量的值?

答案是可以的。代码如下:

#include <stdio.h>
#include <windows.h>
int Myadd(int x,int y)
{
int z=0;
int *p=&x;
p++;
printf("Myadd:%#x\n",*p);
*p=10;
printf("Myadd:%#x\n",*p);
z=x+y;
return z;
}
int main()
{
int a=0xAAAAAAAA;
int b=0XBBBBBBBB;
int c=Myadd(a,b);
printf("you should run here!\n");
printf("result:%d\n",c);
system("pause");
return 0;
}


其实很简单,我们对x取地址,当前指针指向x的地址,令指针下移即可指向b,可以通过指针来改变b变量的值,实际上在这个过程中,我们并没有通过b变量的变量名来改变b的值。

强行插入第三个函数

通过栈帧结构,我们知道函数调用返回时,是要将call命令的下一条指令的地址压入栈中,如果我们通过改写这个地址,是否可以强行跳转至我们想要程序跳转的函数,如果可以,那么该如何返回本身应该执行的函数呢?

下面我们具体说明一下:

#include <stdio.h>
#include <windows.h>
int bug()
{
Sleep(1000);
printf("i am a bug!\n");
Sleep(3000);
system("pause");
}
int Myadd(int x,int y)
{
int z=0;
int *p=&x;
p--;
*p=bug;
z=x+y;
return z;
}
int main()
{
int a=0xAAAAAAAA;
int b=0XBBBBBBBB;
int c=Myadd(a,b);
printf("you should run here!\n");
printf("result:%d\n",c);
system("pause");
return 0;
}


类似于修改变量的例子,我们通过修改指针的位置可以找到之前被压入栈中的main函数的返回地址,并且通过改写改地址(修改为我们要插入函数的地址),使得函数Myadd并没有返回main函数而是跳转至了我们自己写的bug函数。



在实际运行时,我们可以发现程序确实是跳转进了我们的bug函数中,但实际上,程序在结束时是挂掉的,因为我们并没有处理如何从bug函数返回我们的main函数。

我们回想一下刚才我们是强行跳转至第三函数的,是通过修改栈中main函数的返回地址来实现的,但是我们并没有将这个地址保存下来,所以我们从bug函数想要回到main函数,程序也不知道他要回到那里继续执行,所以这个操作必须由我们完成。

#include <stdio.h>
#include <windows.h>
void *main_ret = NULL;
int bug()
{
int first=0;
int *p=&first;
p+=2;
*p=main_ret;

Sleep(1000);
printf("This is bug!\n");
Sleep(3000);

}
int Myadd(int x,int y)
{
int z=0;
int *p=&x;
p--;
printf("begin...Myadd\n");
main_ret=*p;
*p=bug;
z=x+y;
printf("end...Myadd\n");
return z;
}
int main()
{
int a=10;
int b=20;
int c=0;
printf("begin...main\n");

c = Myadd(a, b);
_asm{
sub esp,4
}//平衡栈帧
printf("This is main!\n");
printf("result:%d\n",c);
printf("end...main\n");
system("pause");
return 0;
}




通过这个截图我们可以看到函数调用的过程:

main函数–>Myadd–>bug–>main

调用Myadd函数使用了call指令,而调用bug函数是通过更改地址的方式,但返回时两个函数均使用了ret指令才能返回。

_asm是在c语言中插入汇编代码,令esp-4是为了平衡esp的位置,在我们返回main函数时,通过我们的人为操作,esp相比于正常状态是不平衡的,所以我们通过在c语言中插入一段汇编代码来平衡栈帧。

以上:就是通过栈帧结构来改变变量的值,或者强行改变函数跳转。

因此我们在写程序中,对于调用函数的过程要非常清楚,并且还要函数在调用过程中关心内存的变化、返回值、几个函数跳转的过程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: