在内存中创建函数
Create function in memory
我最近在课堂上学习了函数指针,我想知道是否可以将函数指针分配给程序分配的内存块,用汇编命令(操作码的十六进制值)填充内存块,然后使用函数指针调用内存块。
我对函数指针了解不多,但我猜你不能把它们分配到内存中任何你想分配的地方,它们需要指向一个函数。如果这是真的,如何在内存中创建一个要调用的函数?这可能吗?
下面是我键入的一些代码来展示这个概念。我使用了各种操作码值来查看是否有任何东西可以工作,0x90(NOP)有时不会破坏它(但其他时候会破坏它),0xC3(ret)总是破坏它
#include <stdlib.h> //for malloc
#include <cstring> //for memcpy
int main() //program entry
{
void(*test)() = NULL; //create function pointer, initialize to NULL
void* hold_address = (void*)malloc(100); //allocate memory, save the address it returns in a dummy pointer
int asm_commands[] = {0x90}; //create array of assembly commands, hex values
memcpy(hold_address, asm_commands, sizeof(asm_commands)); //copy the array into the reserved memory
test = (void(*)())hold_address; //set the function pointer to start of the allocated memory
test(); //call the function, crashes here
return 0; //exit the program
}
几点:
-
您的
asm_commands[]
可能应该是unsigned char
(或uint8_t
)-按原样,您将复制3个NUL/0字符以及0x90
-
一些操作系统不允许您在分配给
malloc()
的内存中执行指令,而是SIGSEGV或类似的指令,这是为了防止某些类型的堆栈溢出和其他黑客 -
我建议您编写一个实际的函数
void f() { }
,并使用g++ -S
或编译器提供的任何操作码来查看为其生成了什么操作码,因为您可能需要做的不仅仅是0xC3
才能正确返回(例如,弹出某些寄存器)- 如果从一个实际的C++函数中"克隆"指令,让你开始使用一个经过调整的asm函数,也要小心位置相关的代码。。。不能只在函数中复制数据和代码地址,因为它们不在mallocated区域中。位置无关代码(PIC)使用相对寻址操作码来避免这种情况。。。这就是你需要写的
您可以按照自己的描述进行操作。但是,使用malloc()
分配的内存可能没有执行代码的权限,具体取决于您的平台。
分配可执行内存的方式因操作系统而异。在Linux上,检查mmap
。在Windows上,请参见VirtualAlloc
。
函数调用比这更复杂。
您必须至少修改基指针。我建议您查看函数调用的disassembly,并尝试模仿它
相关文章:
- 通过构造函数创建的所有对象都具有相同的向量
- 通过构造函数创建一些值并尝试添加到文档中使用 rapidjson 不起作用
- 为 NewObjectA() 函数创建 jvalues 的参数数组时出错 - JNI Invocation API
- 使用带有 ref 参数的成员函数创建线程时出现编译错误
- C++ :: 如何捕获由 void 函数创建的矩阵
- 通过零参数构造函数创建的 glm::mat4 应该包含哪些值?
- 用于基于成员字段或函数创建比较器的快捷方式
- std::使用类成员函数创建线程 - 最佳实践
- 为C++重载函数创建SWIG类型映射
- 使用成员函数创建std::函数不会编译
- 如何为返回特定类型的函数创建 SWIG 类型图
- 为具有多个参数的函数创建 SWIG 类型图的更简单方法?
- 通过另一个宏创建的函数创建所有列表的宏
- std::map<int, A> 运算符 [] 需要使用空构造函数创建 A
- 无法使用 CreateWindowEx 函数创建窗口
- c++ 从成员函数创建新线程并移动对象和整个对象
- 无法使用 c++ 中的类成员函数创建/写入文件
- 使用makeword函数创建错误e0109-表观呼叫的括号前表达式必须具有(指针到 - )函数类型
- 为 OpenMP 函数创建别名 ||部分禁用 openMP
- 稍后使用<Class>调用类构造函数创建 std::vector