Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 通过c/c+中的内存地址调用函数+;_C++_C_Function Call_Memory Address - Fatal编程技术网

C++ 通过c/c+中的内存地址调用函数+;

C++ 通过c/c+中的内存地址调用函数+;,c++,c,function-call,memory-address,C++,C,Function Call,Memory Address,已知函数的原型及其在内存中的地址,是否可以从另一个进程或只知道原型和内存地址的某段代码调用此函数?如果可能,如何在代码中处理返回的类型?是-您正在描述函数指针。这里有一个简单的例子 int (*func)(void) = (int (*)(void))0x12345678; int x = func(); 它可能无法在进程之间工作-在大多数操作系统中,进程都不能访问彼此的内存。在现代操作系统中,每个进程都有自己的地址空间,并且地址仅在进程内有效。如果要在其他进程中执行代码,则必须插入共享库或将

已知函数的原型及其在内存中的地址,是否可以从另一个进程或只知道原型和内存地址的某段代码调用此函数?如果可能,如何在代码中处理返回的类型?

是-您正在描述函数指针。这里有一个简单的例子

int (*func)(void) = (int (*)(void))0x12345678;
int x = func();

它可能无法在进程之间工作-在大多数操作系统中,进程都不能访问彼此的内存。

在现代操作系统中,每个进程都有自己的地址空间,并且地址仅在进程内有效。如果要在其他进程中执行代码,则必须插入共享库将程序作为调试器附加

一旦进入另一个程序的地址空间,此代码将调用任意地址的函数:

typedef int func(void);
func* f = (func*)0xdeadbeef;
int i = f();

在大多数操作中,每个进程都有自己的内存,所以您不能

示例代码: a、 c:

#包括
int r(){return 2;}
int main(){
printf(“%p\n”,r);
而(1),;
}
b、 c:

#包括
int main(){
int a,(*b)();
scanf(“%p”和“b”);
a=b();
printf(“%d\n”,a);
返回0;
}

这是一个分段错误。

前面的所有答案都很好,但太长了:

inti=((int(*)(void))0xdeadbeef)();
//=========-->要调用的函数的地址
//============-->要调用的函数的类型
//       =========================     --> ... 我们得到了一份fct的ptr
//      =============================  --> ... 我们称之为函数

当您需要直拨电话时:

((void(*)(void))0x1234)();

这当然是可能的,但也有限制。每个进程都有自己的内存块,其他进程无法干扰。现在,你们会注意到,我写的这是绝对可能的,这是通过DLL注入(或代码注入)


我们可以使用typedef关键字来实现这一点。现在,我看到你把答案标记为“回答”,而且看起来你已经很好了,这只是对任何其他人感兴趣的通知。C++中没有进程。如果需要帮助,您需要指定您的平台。从另一个进程?这是一个非常特殊的情况。你真的需要吗?@ddriver-听起来你想调查进程间通信,而不是函数指针。除非您正在尝试编写调试器,否则在这种情况下,您将面临许多障碍。@ddriver如果您正在谈论从其他进程调用,则确实需要指定平台。在大多数现代操作系统中,一个进程拥有的内存不能被另一个进程任意读取或写入。如果两个进程想要共享一个内存区域,它们必须显式地进行设置。这通常是一件好事,因为它可以防止一个进程中的错误指针或其他错误破坏其他进程,甚至整个操作系统。@Caleb:你想解决什么问题?一般来说,进程如何交互有很多限制,从其他进程调用原始函数是非常困难的,要安全可靠地完成这项工作。试着退一步,向我们解释最终目标是什么,因为现在听起来你走错了方向为什么要强制转换到void()(void)来指定int()(void)?这是非常不合逻辑的,在C++中,你可以访问任何你想要的内存位置,以便更好地或者worse@ddriverC++允许你访问任何虚拟内存位置。然而,许多操作系统为每个进程提供了自己的虚拟内存,因此它们不会相互影响。但是,您可以进行/使用某些特定于操作系统的调用来影响其他进程的内存。@ddriver-不,您不能。您只能访问操作系统允许您访问的内存位置。你的程序所知道的只是它运行的虚拟内存环境,它通常与物理现实几乎没有关系。感谢@R.Martinho的帮助。我甚至不知道这是怎么回事!顺便说一句,在新的操作系统中,无法在其他程序的地址空间中写入内存,这会导致SEGFAULT。但是没有任何东西可以阻止程序读取任何内存位置(因此,OpenSSL中的heartbleed bug非常可怕,因为你可以用它读取内存中的任何东西)。那么,你能解释一下为什么我不能访问其他程序的地址空间,而需要共享库或调试器吗?@TheQuantumPhysicator:因为每个进程都有自己的虚拟内存空间。您的进程“
0xdeadbeef
是您的,而我的进程”是我的。它们位于物理内存的不同地址。@abi仅当计算机有MMU时。如果没有操作系统,计算机甚至可能没有进程……不,它们很棒。另一方面,你的很穷。完全没有解释。这取决于你的操作系统——如果你有操作系统的话。有些计算机没有硬件MMU,因此没有内存障碍,因此即使有操作系统,进程也可以相互写入内存。
#include <stdio.h>

int main() {
int a,(*b)();
scanf("%p",&b);
a=b();
printf("%d\n",a);
return 0;
}
((void(*)(void))0x1234)();