4
dlopen()을 사용하여 여러 공유 객체/동적 라이브러리를로드하는 프로그램이 있다고 가정합니다. 전역 객체 (예 : 정적 멤버 변수)에 대한 포인터가 주어지면 포인터가 라이브러리의 경계에 할당되었는지 확인할 수 있습니까?포인터를 생성하는 동적 라이브러리를 결정하는 방법은 무엇입니까?
dlopen()을 사용하여 여러 공유 객체/동적 라이브러리를로드하는 프로그램이 있다고 가정합니다. 전역 객체 (예 : 정적 멤버 변수)에 대한 포인터가 주어지면 포인터가 라이브러리의 경계에 할당되었는지 확인할 수 있습니까?포인터를 생성하는 동적 라이브러리를 결정하는 방법은 무엇입니까?
/proc/self/maps
파일로 프로세스 맵을 구문 분석하고 포인터 주소가 바운드 된 곳을 확인하면 전역 변수가 .data
또는 .bss
세그먼트에 위치합니다.
예 라이브러리 lib.c
:
static int object;
int *
dummy(void)
{
return &object;
}
test.c
, 단순화를 위해 처리되지 오류 :
#include <stdio.h>
#include <dlfcn.h>
#include <unistd.h>
#include <inttypes.h>
#include <assert.h>
#include <linux/limits.h>
static void which_library(void *p);
int
main(int argc, char **argv)
{
void *handle;
void *object;
handle = dlopen("./lib.so", RTLD_NOW);
assert(handle);
object = ((int *(*)(void)) dlsym(handle, "dummy"))();
which_library(object);
dlclose(handle);
return 0;
}
static void
which_library(void *p)
{
FILE *maps;
char buffer[49+PATH_MAX+1];
maps = fopen("/proc/self/maps", "r");
assert(maps);
while(fgets(buffer, sizeof(buffer) - 1, maps)) {
char path[PATH_MAX+1];
uintptr_t starts;
uintptr_t ends;
sscanf(buffer, "%" PRIxPTR "-%" PRIxPTR " %*s %*x %*x:%*x %*d %s", &starts, &ends, path);
if((uintptr_t)p >= starts && (uintptr_t)p < ends) {
printf("%p => %s\n", p, path);
break;
}
}
fclose(maps);
}
테스트 :
$ gcc -Wall -shared lib.c -o lib.so
$ gcc -Wall test.c -ldl
$ ./a.out
0xb779f5f8 => /home/barakat/Desktop/lib.so
$
그건 천재 야! 인사하라. – CommanderHK
사용 디버거는 프로그램을 통해 단계로 볼 수있는 코드가 그것을 할당합니까? – deviantfan
내가 생각할 수있는 유일한 방법은 각 라이브러리가 다른 할당 자 (malloc & free)를 사용하는지 확인하는 것입니다. 심볼 테이블 (dlopen)에 액세스하여 구조를 알 수 있다면 malloc에 대해 가져온 심볼을 패치하여 전용 함수를 가리킬 수 있습니다. – didierc
@sashoalm 질문에 리눅스 용 – simonc