PHP FFI

PHP FFI

什么是FFI

FFI(Foreign Function Interface),即外部函数接口,是指在一种语言里调用另一种语言代码的技术。PHP的FFI扩展就是一个让你在PHP里调用C代码的技术。在PHP 7.4版本作为扩展。

使用 FFI 调用 C 的函数

首先要启用PHP7.4的ext / ffi,需要注意的是PHP-FFI要求libffi-3以上。

然后,我们需要告诉PHP FFI我们要调用的函数原型是咋样的,这个我们可以使用FFI :: cdef,它的原型是:

public static FFI::cdef ( string $code = "" , string|null $lib = null ) : FFI

Creates a new FFI object.

code: 包含常规 C 语言声明序列(类型、结构、函数、变量等)的字符串。 实际上,这个字符串可能是从 C 头文件复制粘贴的。

lib: 要加载并与定义链接的共享库文件的名称。也就是我们需要的.ll.so文件,它与我们声明字符串是对应的。

example:

// 创建一个FFI对象,加载libc并且导入printf函数
$ffi_print = FFI::cdef(
    "int printf(const char *format, ...);", // C的定义规则
    "libc.so.6");   // 指定libc库

// 调用C的printf函数
$ffi_printf->printf("Hello %s!\n", "world");

// 加载math并且导入pow函数
$ffi_pow = FFI::cdef(
    "double pow(double x, double y);",
    "libboost_math_c99.so.1.66.0");
// 这里调用的是C的pow函数,不是PHP自己的
echo $ffi_pow->pow(2,3),PHP_EOL;

定义变量和数组

当然,FFI也是可以定义变量和数组的。使用FFI::new()创建一个C的数据结构,也就是变量声明,这些变量的内容将保存在cdata属性钟。而数组则直接就可以操作这个函数的返回值。当我们要结束使用的时候,要用FFI::free()来释放变量。

public static FFI::new ( mixed $type [, bool $owned = TRUE [, bool $persistent = FALSE ]] ) : FFI\CData

type: Type是字符串形式的有效C声明,或者是已创建的FFI\ctype的实例。

owned: 是创建自有(即托管)还是非托管数据。 托管数据与返回的 FFI\CData 对象一起存在,并在该对象的最后一个引用被常规 PHP 引用计数或 GC 释放时释放。 当不再需要时,应通过调用 ·FFI::free() 来释放非托管数据。

persistent: 是在系统堆(使用 malloc())还是在 PHP 请求堆(使用 emalloc())上永久分配 C 数据结构。

example:

// 创建一个int变量
$x = FFI::new("int");
var_dump($x->cdata);    // int(0)

// 为变量赋值
$x->cdata = 5;
var_dump($x->cdata);    // int(5)

// 计算变量
$x->cdata +=2;
var_dump($x->cdata);    // int(7)

// 结合上面两个FFI对象操作
echo "pow value:", $ffi_pow->pow($x->cdata,3),PHP_EOL;
// pow value:343
$ffi_printf->printf("Int Pow value is : %f\n", $ffi_pow->pow($x->cdata, 3));
// Int Pow value is : 343.000000

// 创建一个数组
$a = FFI::new("long[1024]");
// 为数组赋值
for ($i = 0; $i < count($a); $i++) {
    $a[$i] = $i;
}
var_dump($a[25]);    // int(25)

$sum = 0;
foreach ($a as $n) {
    $sum += $n;
}
var_dump($sum);    // int(523776)

var_dump(count($a));    // int(1024) 数组长度
var_dump(FFI::sizeof($a));    // int(8192), 内存大小

利用FFI命令执行

使用C的system()函数可命令执行

$ffi = FFI::cdef("int system(const char *command);");
$ffi->system("/readflag >flag.txt");
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇