0

次のテストコードがあります。

#include <stdio.h>

int main(void)
{
    fprintf(stderr, "This is a test.\n");
    int ret = open("somefile.log", 1);
    fprintf(stderr, "Return value is %d.\n", ret);
    return 0;
}

でコンパイルgcc -m64 test.c -o test

を実行するtruss ./testと、最終的に次の出力が表示されます。

getrlimit(RLIMIT_STACK, 0xFFFFFFFF7FFFE280)     = 0
getpid()                                        = 1984 [1983]
setustack(0xFFFFFFFF7EE002C0)
fstat(2, 0xFFFFFFFF7FFFDAA0)                    = 0
This is a test.
write(2, " T h i s   i s   a   t e".., 16)      = 16
open("somefile.log", O_WRONLY)                  = 3
Return value is write(2, " R e t u r n   v a l u e".., 16)      = 16
3.
write(2, " 3 .\n", 3)                           = 3
_exit(0)

open システム コールをフックし、open の呼び出しが終了する前にコードを実行したいと考えています。これを行うために ptrace を使用することについて読んだことがありますが、このシステム (solaris) には sys/ptrace.h がありません。ptrace() の代わりに /proc デバッグ インターフェイスを使用する必要があると記載されているドキュメントを見ましたが、procfs を使用してやりたいことを行う方法を理解できませんでした。

これが可能かどうか誰にもわかりますか?もしそうなら、どのように?

補足として、LD_PRELOAD トリックを使用して自分の共有ライブラリに open システム コールを実装し、通常の open システム コールのアドレスを見つけるために dlsym を呼び出してみました。これが機能しない理由を 100% 理解することはできませんでしたが、呼び出しがインライン化されており、アドレス テーブルを使用してこれらの関数を検索していないことに関連しているようです。ただし、どうにかtrussして open() の呼び出しを検出できます。

これはその試みのための私のコードでした:

cat wrap_open.c

#define _GNU_SOURCE

#include <dlfcn.h>
#include <stdio.h>

static int (*next_open) (const char *path, int oflag, /* mode_t mode */) = NULL;

int open(const char *path, int oflag)
{
    char *msg;

    if(next_open == NULL) {

            fprintf(stderr, "wrapping open\n");

            next_open = dlsym(RTLD_NEXT, "open");

            if((msg = dlerror()) != NULL) {
                    fprintf(stderr, "open: dlopen failed: %s\n", msg);
            } else {
                    fprintf(stderr, "open: wrapping done\n");
            }

    }

    fprintf(stderr, "open: opening %s\n", msg);
    fflush(stderr);

    return next_open(path, oflag);
}

でコンパイル でgcc -fPIC -shared -Wl,-soname,libwrap_open.so.1 -ldl -o libwrap_open.so.1.0 実行LD_PRELOAD_32=./libwrap_open.so.1.0 ./test

ここでは、共有ライブラリからの出力は得られません。通常のプログラム出力のみ。

ヘルプやポインタをいただければ幸いです。前もって感謝します。

4

1 に答える 1