ライブラリ初期化部分でコマンドパラメータをスキップしたいと思います。ライブラリの初期化部分は次のとおりです。
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_main
rtld_fini
__uClibc_main
答え2
私自身の答えを見つけたかもしれません。
https://stackoverflow.com/questions/36998143/alternative-way-to-obtain-argc-and-argv-of-a-process
__attribute__((constructor)) void stuff(int argc, char **argv)
{
for (int i=0; i<argc; i++) {
printf("%s: argv[%d] = '%s'\n", __FUNCTION__, i, argv[i]);
}
}
もちろん、問題はまだパラメータをスキップすることです。つまり、パラメータを見ることができますが、libパラメータと独自のパラメータが混在していると、main()プログラムは失敗します。