使用mod_php覆盖在Apache上运行的PHP脚本中的connect()

时间:2015-11-21 12:46:43

标签: php c apache ld-preload mod-php

当通过mod_php启用PHP时,如何在Apache脚本请求中覆盖从PHP脚本中调用的connect()系统调用?

我在 custom-connect.c 中定义了自定义connect()版本:

#define _GNU_SOURCE 1
#include <stdio.h>
#include <arpa/inet.h>
#include <dlfcn.h>

int (*real_connect)(int, const struct sockaddr *, socklen_t);
FILE *f;

void _init (void) {
    const char *err;

    f = fopen("/tmp/connect.log", "a");

    real_connect = dlsym (RTLD_NEXT, "connect");
    if ((err = dlerror()) != NULL) {
        fprintf (f, "dlsym (connect): %s\n", err);
    }
}

int connect(int fd, const struct sockaddr *sk, socklen_t sl) {
    static struct sockaddr_in *sk_in;
    sk_in = (struct sockaddr_in *)sk;

    fprintf(f, "Custom connect: %d %s:%d\n", fd, inet_ntoa(sk_in->sin_addr), ntohs(sk_in->sin_port));

    return real_connect(fd, sk, sl);
}

我用以下代码编译它:

gcc -nostartfiles -fpic -shared custom-connect.c -o custom-connect.so -ldl

我有一个简单的脚本 curl-test.php ,它在内部调用connect():

<?php
$ch = curl_init("http://example.com");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);
curl_close($ch);
echo 'Received length: ' . strlen($data) . "\n";

当我从命令行使用LD_PRELOAD运行我的脚本时:

LD_PRELOAD=./custom-connect.so php curl-test.php

然后它看起来很好,我可以看到我的自定义connect()记录到 /tmp/connect.log

Custom connect: 4 192.168.178.1:53
Custom connect: 4 93.184.216.34:80

看起来它在命令行中工作正常。 但是当我从Apache运行我的脚本并通过mod_php启用PHP时,如何用我自己的版本覆盖connect()?我还应该使用LD_PRELOAD吗?如果是,那么如何配置呢?

0 个答案:

没有答案