ライブラリ内のコマンドパラメータをスキップする必要があります

ライブラリ内のコマンドパラメータをスキップする必要があります

ライブラリ初期化部分でコマンドパラメータをスキップしたいと思います。ライブラリの初期化部分は次のとおりです。

static void pa_init_services (void) __attribute__((constructor (102)));
static void pa_init_services()

IEでは、プログラム内でmain()を呼び出す前に実行されます。私はパラメータを「切り離す」と呼ぶことを達成したいと思います。つまり、パラメータを事前に調べて、パラメータが私のライブラリに属していることを確認してから、そのオプションを私のライブラリに対してのみ解析し、main()がインポートされる前に削除したいと思います。それらをリストから除外してください。クライアントプログラムへの接続に使用される共通ライブラリであるmain()を含むプログラムを制御することはできません。

たとえば、実際にargv POINTERと実際のargcの場所にアクセスできる場合は、単に解析を実行してプロセスをスキップできます。

GTKのドキュメントには、GTKが特定のオプションを解析し、クライアントプログラムがそのオプションを取得する前にスキップするこのプロセスが記載されています。

ベストアンサー1

__libc_start_main()Linux[1]では、ライブラリの関数をオーバーライドできます(関数の周りのラッパー呼び出し)。main()これは複数回行うことができます。

例:

#define _GNU_SOURCE     /* for RTLD_NEXT */
#include <string.h>
#include <unistd.h>
#include <dlfcn.h>
#include <err.h>
#ifdef __UCLIBC__
#define __libc_start_main       __uClibc_main
#endif
#define STR_(s) #s
#define STR(s)  STR_(s)
int __libc_start_main(
        int (*main)(int,char**,char**), int ac, char **av,
        int (*init)(int,char**,char**), void (*fini)(void),
        void (*rtld_fini)(void), void *stack_end)
{
        typeof(__libc_start_main) *real_lsm;
        if(*(void**)&real_lsm = dlsym(RTLD_NEXT, STR(__libc_start_main)))
                return real_lsm(main, ac - 1, av + 1, init, fini, rtld_fini, stack_end);
        else
                errx(1, "BUG: dlsym: %s", dlerror());
}
$ cc -fPIC -shared -Wall -W -Wno-parentheses skip.c -o skip1.so -ldl
$ cc -fPIC -shared -Wall -W -Wno-parentheses skip.c -o skip2.so -ldl
$ LD_PRELOAD="./skip1.so ./skip2.so" /bin/echo a b c d
c d

これは、プログラムをskip1.so別のライブラリに明示的にリンクする場合にも当てはまります。execve()まったく異なるパラメータを使用してまったく異なるプログラムを作成することもできます。

[1]引数は必要muslありませんが、この方法も機能します。 uclibcの対応する関数はです。__libc_start_mainrtld_fini__uClibc_main

おすすめ記事