2017-11-19 1 views
1

내가 다음 함수에 대한 호출에 의해 초기화됩니다 공유 라이브러리가 :Segfault가 PLT 코드입니다. 어떤 아이디어?

extern "C" { 

int pa__init(pa_module *m) { 
    m->userdata = new PAModule(m); 
    return 0; 
} 

} // extern "C" 

그것은 (주소가 컴파일 시간 오프셋입니다)이 컴파일됩니다를 :

0000000000064717 <pa__init>: 
    [...] 
    64726:  bf 40 00 00 00   mov $0x40,%edi 

    6472b:  e8 e0 cb ff ff   callq 61310 <operator new(unsigned long)@plt> 

    64730:  48 89 c3    mov %rax,%rbx 
    64733:  48 8b 45 d8    mov -0x28(%rbp),%rax 
    64737:  48 89 c6    mov %rax,%rsi 
    6473a:  48 89 df    mov %rbx,%rdi 
    6473d:  e8 2e e1 ff ff   callq 62870 <PAModule::PAModule(pa_module*)@plt> 
    [...] 

이것은 분해하다 나는 도서관 및이 방법 GE를로드하고 때

0000000000061310 <operator new(unsigned long)@plt>: 
    61310:  ff 25 a2 c1 66 00  jmpq *0x66c1a2(%rip)  # 6cd4b8 <operator new(unsigned long)@@Base+0x57f708> 
    61316:  68 94 02 00 00   pushq $0x294 
    6131b:  e9 a0 d6 ff ff   jmpq 5e9c0 <.plt> 

: 컴파일시 PLT 기능의 61310 오프셋

컴파일시 GOT의 값이 오프셋
#0 0x0000000000061316 in ??() 
#1 0x00007fd9faae9730 in pa__init (m=0x55f1a750d850) at pa_module.cpp:24 
[...] 

6cd4b8 (런타임시에 이전 예 : 전화 TS, 내가 컴파일시 세그먼트 폴트가 61310 오프셋 얻을 0x7fced7ffa4b8)는

0x7fced7ffa4b8: 0x00061316 

입니다. 프로세서가 해당 위치로 점프를 시도합니다. 그러나 이것은 여전히 ​​컴파일 타임 오프셋 (유효하지 않은 메모리를 가리킴)이므로 프로그램 segfaults가되는 이유입니다.

내 라이브러리를로드 할 때 GOT의 항목이 재배치되지 않는 이유는 무엇입니까?

대단히 감사합니다!

+0

'0x0000000000061316'은'push' 직접 명령입니다. 그것은 스택 오버 플로우 나'rsp'가 어딘가에 가짜를 가리키고있는 경우에만 segfault해야합니다. ** 발신자가 스택을 깰 수 있었습니까? 예 : 매우 큰 로컬 배열 또는 alloca? ** RIP가 실제로'push' 명령을 가리키고 있는지 확인할 수 있습니까? 백 트레이스에서 느린 동적 연결 중에 실제로 segfault가 발생하는 것처럼 보이지 않습니다. –

+0

즉 스택 포인터가 가리키는 메모리를 읽을 수 있는지 gcc로 확인하십시오. 'x $ rsp'를 사용하여 그 주소에서 덤프를 시작하십시오. –

+0

실제로 코드를 단계별로 살펴보면'61310' 행에만 도달합니다. 이 시점에서 모든 레지스터가 유효합니다. 다음 단계에서는 이미 segfault가 발생합니다. 또한 점프는'0x7fced7ffa4b8'로 끝납니다. 나는이 기억 장소에 GOT를 질문에 추가했다. –

답변

1

내 라이브러리에 정의되지 않은 기호가있는 것으로 나타났습니다.

이렇게하면 동적 연결 로더가 GOT를 성공적으로 업데이트하지 못하게되고 컴파일 시간 오프셋이 메모리에 유지됩니다. 런타임에 이러한 주소는 유효하지 않으므로 segfault가 발생합니다.

관련 문제