라이브러리에서 명령 매개변수를 건너뛰어야 함

라이브러리에서 명령 매개변수를 건너뛰어야 함

라이브러리 초기화 부분에서 명령 매개변수를 건너뛰고 싶습니다. 라이브러리의 초기화 부분은 다음과 같습니다.

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

답변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() 프로그램이 실패합니다.

관련 정보