如何将程序执行跳转到C中的特定地址?

时间:2011-11-16 20:11:20

标签: c++ c

我希望程序跳转到内存中的特定地址并继续从该地址执行。我考虑过使用goto,但我没有标签而只是内存中的地址。

无需担心从跳转地址返回。

编辑:使用GCC编译器

8 个答案:

答案 0 :(得分:24)

内联汇编可能是最简单,最“优雅”的解决方案,尽管这样做非常不寻常,除非您正在编写调试器或一些专门的内省系统。

另一种选择可能是声明一个指向void函数(void (*foo)(void))的指针,然后将指针设置为包含你的地址,然后调用它:

void (*foo)(void) = 0x12345678;
foo();

由于编译器认为你正在进行子程序调用,因此堆栈上会有东西被推送,但由于你不关心返回,这可能会有效。

答案 1 :(得分:15)

gcc有一个允许跳转到任意地址的扩展名:

void *ptr = (void *)0x1234567;  // a random memory address
goto *ptr;                      // jump there -- probably crash

这与使用设置为固定值的函数指针几乎相同,但实际上它将使用跳转指令而不是调用指令(因此堆栈不会被修改)

答案 2 :(得分:8)

#include <stdio.h>
#include <stdlib.h>

void go(unsigned int addr) {
  (&addr)[-1] = addr;
}

int sub() {
  static int i;
  if(i++ < 10) printf("Hello %d\n", i);
  else exit(0);
  go((unsigned int)sub);
}

int main() {
  sub();
}

当然,这会调用未定义的行为,与平台有关,假定代码地址与int等大小相同,等等。

答案 3 :(得分:3)

看起来应该是这样的:

unsigned long address=0x80; 

void (*func_ptr)(void) = (void (*)(void))address;
func_ptr();

然而,这不是一个非常安全的操作,跳转到某个未知地址可能会导致崩溃!

答案 4 :(得分:2)

由于问题有一个C ++标记,这里是一个 C ++ 调用一个带有签名的函数的例子,如main() - int main(int argc, char* argv[])

int main(int argc, char* argv[])
{
    auto funcAddr = 0x12345678; //or use &main...
    auto result = reinterpret_cast<int (*)(int, char**)>(funcAddr)(argc, argv);
}

答案 5 :(得分:0)

您是否可以控制要跳转到的地址的代码?这是C还是C ++?

我犹豫地建议setjmp() / longjmp()如果你正在使用C并且可以运行setjmp(),你需要跳回去。话虽这么说,你必须非常小心这些。

对于C ++,请参阅以下有关longjmp()快捷方式异常处理和析构函数析构函数的讨论。这会让我更加犹豫,建议在C ++中使用它。

C++: Safe to use longjmp and setjmp?

答案 6 :(得分:0)

我建议使用此代码:

asm(
"LDR R0,=0x0a0000\n\t" /* Or 0x0a0000 for the base Addr. */
"LDR R0, [R0, #4]\n\t" /* Vector+4 for PC */
"BX R0"
);

答案 7 :(得分:0)

这是我用于引导程序加载程序(MSP430AFE253,Compiler = gcc,CodeCompeserStudio);

#define API_RESET_VECT 0xFBFE
#define JUMP_TO_APP()  {((void (*)()) (*(uint16_t*)API_RESET_VECT)) ();}