我已经阅读和谷歌有关右左规则来解码函数指针。
前任:
int (*(*fun_one)(char *,double))[9][20];is:fun_one是指向函数期望(char *,double)的指针,并将指针返回到int.的数组(大小为20)的数组(大小9)。
所以什么是
const char code[] = "\x31\xc0";
int main(){
((void(*)( ))code)();
}“代码是??返回函数返回的指针.?在那之后,外部()如何?”
我对这个完全搞不懂。
发布于 2015-11-10 06:18:38
const char code[] = "\x31\xc0";
int main(){
((void(*)( ))code)();
}这就是它的工作原理。code变量将衰减到第一个元素(\x31)的地址。
然后,该地址将被转换为接受不定参数的函数的地址,而不返回任何内容。
这涵盖了整个((void(*)( ))code)位,到目前为止,您基本上已经构造了指向字符串的函数指针。
然后,()只调用您所指向的函数。
如果这是你瞄准的英特尔CPU,31 c0会反汇编到xor eax, eax上,但我并不指望它在缓冲区的末端运行时会有太多的joy,它很可能会突然崩溃。标记字符串结束的\x00是add指令的第一位,但是对于后面的内容,没有保证。
将ret指令添加到字符串的末尾可能会使其更安全,但您可能必须检查生成的汇编程序代码,以便调用本身,以确定应该使用哪个ret。
发布于 2015-11-10 06:18:45
这不是函数指针声明,而是函数指针转换和调用。
对转换进行一段时间的修饰后,我们有了((sometype)code)() --也就是说,将code转换为某种类型(显然是一个函数指针),然后调用它。
演员里面的类型是什么?我是void (*)()。换句话说,指向一个函数的指针返回void,没有什么特别的(由于C遗留,它实际上可以接受参数,但在本例中却没有)。什么都没有,什么都没有。
在*之后,如果这是一个声明,那么名称就会在哪里,但是由于它是一个强制转换,所以类型是独立的,根本就没有名称。
发布于 2015-11-10 06:26:48
您会感到困惑,因为它不是函数指针声明,而是一个随函数调用的强制转换。
(void (*)()) code 这将code转换为指向一个函数的指针,该函数接受未指定数量的参数,不返回任何内容。
((void (*)()) code) 这是括在括号中的整个表达式;结果是一个函数指针。
(void (*)() code)();这将调用由强制转换点“创建”函数指针所指向的函数。
这实际上是在调用一些用code构造的机器代码--这里省略了其余的代码,但是31 c0是通常的xor eax,eax。
https://stackoverflow.com/questions/33624012
复制相似问题