2013-12-18 6 views
0

공유 라이브러리를 사용하는 실행중인 프로세스가 있습니다.공유 라이브러리 다시 매핑

공유 라이브러리를 다른 가상 주소로 다시 매핑하고 이전 가상 주소를 munmap하는 방법이 있습니까? 프로세스 주소를 새 공유 객체 주소로 업데이트하고 계속 실행 하시겠습니까?

+1

'mmap()'에 올바른 옵션이 주어지면 라이브러리의 새로운 복사본을 매핑 할 수는 있지만, 해석되지 않고 text/data/etc로 분리 된 파일의 매핑 일뿐입니다. 로더 또는'dlopen()'과 같은 섹션이 제공합니다. 'dlopen()'은 기존 사본을 돌려 줄 것입니다. 그것은 가능하다면 프로세스에 치명적일 수 있기 때문에 기존 복사본의 매핑을 해제하는 것이 가능하지 않을 가능성이 높습니다 ... – twalberg

답변

1

프로세스가 실행 중일 때가 아니라 준비가되어 있지 않은 경우입니다. 공유 라이브러리 코드는 한 가지이며, 공유 라이브러리 내의 데이터 구조는 다른 것입니다. 라이브러리 내의 정적으로 정의 된 데이터 구조에 대한 포인터는 프로세스의 어느 위치 에나있을 수 있으며 변경할 방법이 없습니다.

이제 프로그램을 작성하려고하면 너무 어려워서는 안됩니다. 공유 라이브러리에 정적 종속성이 없으면 dlopen()을 사용하여 열고 dlsym()으로 함수를 가져옵니다. 프로세스가 SIGUSR1과 같은 시그널을 잡아 내고 시그널 핸들러에서 (더 좋은 점은 시그널 핸들러가 호출 할 때 설정하는 플래그를 탐지하는 메인 루프의 안전한 지점에서) 오래된 라이브러리를 버리고 새 라이브러리를로드 한 다음 그에 따라 기호.

+0

다음을 수행하고 라이브러리를 매핑 해제하고 매핑 한 다음 자식을 포크하는 부모가 있어야합니다. 자식이 다시 매핑 된 라이브러리를 사용할 것입니다. 어떻게하면 모든 심볼을 해석하여 자식이 올바르게 실행될 수 있습니까? 모든 심볼에 대해 dlsym을 호출해야합니까? –

0

공유 라이브러리가 실행되고 있지 않다는 것을 알고 있다면 (즉, 호출 스택에없는 경우) 상당히 쉽게 처리 할 수 ​​있습니다. 라이브러리를 dlclose() 한 후 다시 dlopen()하십시오. 라이브러리 핸들이 필요한 경우 직접 dlopen() 한 다음 두 번 닫을 수 있습니다. refcount가 0이 될 것이고 라이브러리가 매핑되지 않을 것입니다 (처음로드 된 라이브러리가 어떤 식 으로든 특별한 경우를 제외하고는). 공유 라이브러리에 대한 링크 시간 의존성을 피할 수 있다면 (ELF 생성자 함수에서 dlopen을 호출하기 만하면) 확실히 작동 할 것입니다.

수동으로 새 라이브러리를로드하는 경우 (로드 주소를 선택할 수있게하려는 경우) PLT 항목을 직접 덮어 쓸 수 있습니다. 나는 매우 비슷한 것을하는 도구를 썼다. https://github.com/dwks/asyncsafe. 해상도 함수를 다시 가리 키도록 모든 PLT 항목을 덮어 쓰면 지연 기호로드가 자동으로 다시 발생합니다. 또는 직접 해결할 수도 있습니다.

블라인드 ROP 학술 공격 (http://www.scs.stanford.edu/~abelay/pdf/bittau:brop.pdf)에 대해 알고 계실 것입니다. 당신이 제안하고있는 것을 수행하는이 공격에 대한 몇 가지 방어책이 있습니다.