source

리눅스에서 syscall 기능을 다시 구현(또는 랩)하려면 어떻게 해야 합니까?

manycodes 2023. 11. 2. 21:56
반응형

리눅스에서 syscall 기능을 다시 구현(또는 랩)하려면 어떻게 해야 합니까?

열려 있는() 시스템 호출을 완전히 인계받고 실제 syscall을 랩핑하고 로깅을 수행하려고 합니다.LD_PRELOAD를 사용하여 열린() 진입점을 대신하는 (사용자가 만든) 공유 객체 라이브러리를 로드하는 도 한 방법입니다.

사용자가 만든 open() 루틴은 glibc 함수에 대한 포인터를 가져옵니다.open()타고dlsym()그것을 호출하고, 그것을 호출합니다.

그러나 위에서 제안된 해결책은 동적인 해결책입니다.내가 내 것을 연결하고 싶다고 가정해 보겠습니다.open()정적 포장지제가 어떻게 하죠?메커니즘은 동일하지만 사용자 정의 간에 심볼 충돌이 있을 것으로 추측합니다.open()그리고 libc.open().

같은 목표를 달성하기 위한 다른 기술을 공유해 주시기 바랍니다.

에서 제공하는 랩 기능을 사용할 수 있습니다.ld.부터man ld:

--wrap symbol기호는 래퍼 함수를 사용합니다.에 대한 정의되지 않은 참조symbol로 해결될 것입니다.__wrap_symbol.

에 대한 정의되지 않은 참조__real_symbol로 해결될 것입니다.symbol.

그래서 접두사만 쓰면 됩니다.__wrap_당신의 포장지 기능을 위해.__real_실제 함수를 호출하고 싶을 때.간단한 예는 다음과 같습니다.

malloc_wrapper.c:

#include <stdio.h>
void *__real_malloc (size_t);

/* This function wraps the real malloc */
void * __wrap_malloc (size_t size)
{
    void *lptr = __real_malloc(size);
    printf("Malloc: %lu bytes @%p\n", size, lptr);
    return lptr;
}

시험적용testapp.c:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    free(malloc(1024)); // malloc will resolve to __wrap_malloc
    return 0;
}

그런 다음 응용프로그램을 컴파일합니다.

gcc -c malloc_wrapper.c
gcc -c testapp.c
gcc -Wl,-wrap,malloc testapp.o malloc_wrapper.o -o testapp

결과적인 애플리케이션의 출력은 다음과 같습니다.

$ ./testapp
Malloc: 1024 bytes @0x20d8010

기호는 명령행에 나열하는 순서대로 링커에 의해 해결되므로 표준 라이브러리보다 먼저 라이브러리를 나열하면 정확합니다.gcc의 경우 지정해야 합니다.

gcc <BLAH> -nodefaultlibs <BLAH BLAH> -lYOUR_LIB <OTHER_LIBS>

이렇게 하면 라이브러리가 먼저 검색되고 찾을 수 있습니다.

리눅스 및 GNU libc의 경우 라이브러리에 있는 모든 기능을 가로채고 다시 구현할 수 있도록 라이브러리가 내장되어 있습니다.

ANY libc 함수의 고유 버전을 정의하고 libc 이전에 링크하는 경우(따라서 실행 파일의 일부이거나 link 명령어의 -lc 이전에 링크된 라이브러리 또는 loaded.LD_PRELOADlibc가 동적 링크인 경우 libc 버전 대신 호출됩니다(libc 자체의 다른 함수에서도 호출됨).그런 다음 a를 사용하여 함수를 호출할 수 있습니다.__libc_라이브러리에서 실제 버전을 가져오려면 접두사를 사용합니다(단, 해당 기호를 직접 선언해야 함).예를 들어,

       #include <sys/types.h>
       #include <sys/stat.h>
       #include <fcntl.h>

       extern int __libc_open(const char *pathname, int flags, mode_t mode);

       int open(const char *pathname, int flags, mode_t mode) {
           return __libc_open(pathname, flags, mode);
       }

언급URL : https://stackoverflow.com/questions/3662856/how-do-i-reimplement-or-wrap-a-syscall-function-on-linux

반응형