C语言中将绝对地址转换为函数指针以及跳转到内存指定位置处执行
1、方法一
如果要对绝对地址0x200000进行赋值,我们可以用
(unsigned int * ) 0x200000 = 1234;//指针直接指向存储区地址
那么要是想让程序跳转到绝对地址是0x100000去执行,应该怎么做?
*( (void (*)( ))0x100000 ) ( );
首先要将0x100000强制转换成函数指针,即:
(void (*)())0x100000
然后再调用它:
*((void (*)())0x100000)();
用typedef可以看得更直观些:
typedef void(*)() voidFuncPtr;
*((voidFuncPtr)0x100000)();
又如
如果用 C 语言,可以像下列示例代码这样来调用内核:
void (*theKernel)(int zero, int arch, u32 params_addr)
= (void (*)(int, int, u32))KERNEL_RAM_BASE;
……
theKernel(0, ARCH_NUMBER, (u32) kernel_params_start);
KERNEL_RAM_BASE 是内核在系统内存中的第一条指令的地址。
2、方法二
C语言使用函数指针跳转到程序固定地址(0x8000)执行程序的方法
使用函数指针,把一个纯数据强制转换为函数指针类型。
(*(void(*)())0x8000)();
转成汇编就占两条指令.
如果要对绝对地址0x200000进行赋值,我们可以用
(unsigned int * ) 0x200000 = 1234;//指针直接指向存储区地址
那么要是想让程序跳转到绝对地址是0x100000去执行,应该怎么做?
*( (void (*)( ))0x100000 ) ( );
首先要将0x100000强制转换成函数指针,即:
(void (*)())0x100000
然后再调用它:
*((void (*)())0x100000)();
用typedef可以看得更直观些:
typedef void(*)() voidFuncPtr;
*((voidFuncPtr)0x100000)();
又如
如果用 C 语言,可以像下列示例代码这样来调用内核:
void (*theKernel)(int zero, int arch, u32 params_addr)
= (void (*)(int, int, u32))KERNEL_RAM_BASE;
……
theKernel(0, ARCH_NUMBER, (u32) kernel_params_start);
KERNEL_RAM_BASE 是内核在系统内存中的第一条指令的地址。
2、方法二
C语言使用函数指针跳转到程序固定地址(0x8000)执行程序的方法
使用函数指针,把一个纯数据强制转换为函数指针类型。
int main(void) { void (* my_function)(void); //int *my_address = 0x8000; my_function =(void (*)())(0x8000); my_function(); } #include<stdio.h> typedef void (*funcptr)(); //funcptr为无参数,无返回值的函数指针类型 void f(void) //随便一个无参数无返回值函数 { printf("aaa\n"); } int main(void) { //printf("%p", f); //通过此可知道函数f的地址。不同的环境可能会不一样, //我的是0x401530 (*(funcptr) 0x401530)(); //将0x401530强制转换为funcptr类型,并解引用,再 调用,因为funcptr为函数指针类型,所以0x401530被强制转换为函数指针, 也就是说,将地址为0x401530的东西当作函数来看待,而函数 f 的地址正好是 0x401530,所以直接调用函数 f 。 (*(void (*)()) 0x401530)(); return 0; }
如果带参数的呢?
#include <stdio.h> #define my_function(a,b) ((*(void(*)(int ,char ))0x40052d)(a,b)) void ppr(int a,char b) { printf("hello,word!!%d ,%d",a,b); } int main(void) { printf("%p\r\n",ppr); my_function(1,2); }
(*(void(*)())0x8000)();
转成汇编就占两条指令.
- 随机文章
- 热门文章
- 热评文章
- C#图片处理示例(裁剪,缩放,清晰度,水印)
- 安装包制作工具 SetupFactory使用1 详解
- Linux下python2.7安装pip
- STM32 keil mdk启动代码发分析
- ESP8266在Eclipse下设置编译模式(有boot和无boot)
- HTTP请求头详解
- C#实现邮件发送的功能
- 单片机时钟周期,机器周期,指令周期的区别