我最近在课堂上了解了函数指针,我想知道是否可以将函数指针分配给程序分配的内存块,用汇编命令(操作码的十六进制值)填充该内存块,然后调用使用功能指针的内存块.
I learned about function pointers recently in class and I was wondering if you could assign a function pointer to a block of memory allocated by a program, fill the memory block with assembly commands (hex values of op codes), then call the memory block using the function pointer.
我对函数指针了解不多,但是我猜想您无法在内存中的任何位置分配它们,它们需要指向一个函数.如果是这样,如何在内存中创建要调用的函数?那有可能吗?
I don't know much about function pointers, but I'm guessing you can't assign them wherever you want in memory, they need to point to a function. If that's true, how can you create a function in memory to be called? Is that even possible?
这是我输入的一些代码来显示此概念.我使用了各种操作码值来查看是否有任何效果,并且0x90(NOP)有时没有破坏它(但是其他时候也有),并且0xC3(ret)总是破坏了它.
Here's some code I typed up to show the concept. I used various opcode values to see if anything would work, and 0x90 (NOP) did not break it sometimes (but it did other times), and 0xC3 (ret) always broke it.
#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
your asm_commands[] should probably be unsigned char (or uint8_t) - as is, you'll be copying 3 NUL/0 characters as well as the 0x90
某些操作系统只是不允许您在使用malloc()分配的内存中执行指令-它们将改为SIGSEGV或类似内容-旨在防止某些类型的堆栈溢出和其他黑客行为
some Operating Systems will just not let you execute instructions in memory you've allocated with malloc() - they'll SIGSEGV or similar instead - that's intended to prevent certain types of stack overflow and other hackery
我建议您编写一个实际的函数void f() { },并查看使用g++ -S或编译器提供的任何内容为它生成的操作码,因为您可能需要做的事情不只是0xC3才能返回正确(例如弹出某些寄存器)
I suggest you write an actual function void f() { } and see what opcodes are generated for it, using g++ -S or whatever your compiler offers, as you might need to do something more than just 0xC3 to return properly (e.g. pop certain registers)
- 如果从实际C ++函数中克隆"指令以使您开始使用经过调整的asm函数,也请警惕与位置相关的代码...您不能只复制函数中的数据和代码地址,因为它们将不会t在分配的区域内.位置独立代码(PIC)使用相对寻址操作码来避免这种情况...这就是您需要编写的内容.
更多推荐
在内存中创建函数
发布评论