博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
是否可以通过绝对内存地址进行参数赋值与函数调用---转载
阅读量:5008 次
发布时间:2019-06-12

本文共 2067 字,大约阅读时间需要 6 分钟。

同一个数可以通过不同的方式表达出来,对于函数的访问,变量的赋值除了直接对变量赋值以外,还可以通过绝对内存地址进行参数赋值与函数调用。

(1)       通过地址修改变量的值

int x;

int *p;

printf("%x\n",&x);

p=(int *)0x0012ff60;

*p = 3;

printf("%d\n",x);

程序的输出结果为:

12ff60

3

程序首先输出变量x所在地址为十六进制的0x12ff60(本来应该为8位的十六进制数,高位为0则省略掉),然后定义一个指针变量,让它指向该地址,通过指针变量的值来修改变量x的值。

示例代码:

int *ptr=(int*)0xa4000000; 

*ptr=0xaabb;

printf("%d\n",*ptr);

以上程序会崩溃,因为这样做会给一个指针分配一个随意的地址,很危险,所以这种做法是不允许的。

(2)       通过地址调用函数的执行

#include <iostream>

using namespace std;

typedef void(*FuncPtr)() ;

void  p()

{

       printf("MOP\n");

}    

int main()

{

       void (*ptr)();

       p();

       printf("%x\n",p);

       ptr = (void (*)())0x4110f0;

       ptr();//函数指针执行

       ((void (*)())0x4110f0)();

       ((FuncPtr)0x4110f0)();

       return 0;

}

程序执行结果如下:

MOP

4110f0

MOP

MOP

MOP

首先定义一个ptr的函数指针,第一次通过函数名调用函数,输出Mop,打印函数的入口地址,函数的入口地址为4110f0。然后给函数指针ptr赋地址值为p的入口地址,调用ptr,输出Mop。接着的过程是不通过函数指针直接执行,仍然使用p的入口地址调用,输出为MOP。最后是通过typedef调用的直接执行。

函数名称、代码都是放在代码段的,因为是放在代码段,每次会跳到相同的地方,但参数会压栈,所以函数只根据函数名来获取入口地址,与参数和返回值无关。无论参数和返回值如何不同,函数入口地址都是一个地方。

对以下程序进行分析如下:

#include <stdio.h>

int  p(int a,int b)

{

       return 3;

}  

int main()

{

       printf("%x\n",p);

       int a = p(2,3);

       printf("%d\n",p);

       int b = p(4,5);

       printf("%x\n",p);

       return 0;

}

程序输出结果如下:

411159

4264281

411159

十六进制的411159转换成十进制的值为4264281。程序中打印的p的入口地址,无论p是否调用函数,入口地址都没有改变。

分析如下代码:

#include <stdio.h>

int p(int a,int b)

{

       return ((a>b)?a:b);

int main()

{

       int (*ptr)(int ,int);

       ptr = (int (*)(int,int))0x411159;

       int c = ptr(5,6);

       printf("%d\n",c);

       return 0;

}

程序输出为

6

通过函数指针调用有返回值和参数的函数,不适用函数名,而是用函数入口地址调用。

函数存放在内存的代码区域内,也有地址,一个函数在编译时被分配一个入口地址,将这个入口地址称为函数的指针,函数的地址就是函数的名字。

函数指针不能指向不同类型或是带不同形参的函数。

参考链接:

(<<程序员面试笔试宝典>>官网)

 

方法一:

*(int *)0x6789 = 0x0080; //直接把0x0080赋值给地址为0x6789的单元

int m;
m = *(int *)0x6789;        //从地址为0x6789的单元取值赋给变量m
----------------------------------------------------------------------------

方法二:
int *p, m;
p = (int *)0x6789;
*p = 0x0080;
m = *p;

 

想让程序跳转到绝对地址是0x100000的代码去执行,应该怎么做?

网上有三种答案(本人没有验证):
第一种:  *((void (*)( ))0x100000 ) ( );
第二种:    ((void (*)())0x100000)() 或者 (*((void (*)())0x100000))()
         源地址:
第三种:
typedef  void (*func)(void);
          func f = (func)1000000;    
          f();

转载于:https://www.cnblogs.com/followyourdream/p/3370066.html

你可能感兴趣的文章
矩阵求逆
查看>>
在 Windows 8、Windows 10 桌面模式下的 .NET Framework 程序中,引用 Windows.Runtime 的 API。...
查看>>
2015 8月24号 工作计划与实行
查看>>
MVC AJAX
查看>>
Google Map API V3开发(6) 代码
查看>>
Kafka初入门简单配置与使用
查看>>
第三章Git使用入门
查看>>
Amd,Cmd, Commonjs, ES6 import/export的异同点
查看>>
开源介绍:Google Guava、Google Guice、Joda-Time
查看>>
Nginx IP 白名单设置
查看>>
Java比较两个日期的大小
查看>>
学习总结 java 输入输出流
查看>>
【Spring Boot学习之十二】mybatis3 分页打印sql日志
查看>>
div中莫名出现一些空白..
查看>>
如何在sharepoint2010中配置Google Anlytics 分析服务
查看>>
计算机启动过程(转载)
查看>>
烂笔头@WP 的博文仅供自己学习的备忘录
查看>>
cocos2dx-Lua与Java通讯机制
查看>>
上下文管理器之__enter__和__exit__
查看>>
android3.2以上切屏禁止onCreate()
查看>>