내가 다음 함수에 대한 호출에 의해 초기화됩니다 공유 라이브러리가 :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
오프셋
#0 0x0000000000061316 in ??()
#1 0x00007fd9faae9730 in pa__init (m=0x55f1a750d850) at pa_module.cpp:24
[...]
6cd4b8
(런타임시에 이전 예 : 전화 TS, 내가 컴파일시 세그먼트 폴트가 61310
오프셋 얻을 0x7fced7ffa4b8
)는
0x7fced7ffa4b8: 0x00061316
입니다. 프로세서가 해당 위치로 점프를 시도합니다. 그러나 이것은 여전히 컴파일 타임 오프셋 (유효하지 않은 메모리를 가리킴)이므로 프로그램 segfaults가되는 이유입니다.
내 라이브러리를로드 할 때 GOT의 항목이 재배치되지 않는 이유는 무엇입니까?
대단히 감사합니다!
'0x0000000000061316'은'push' 직접 명령입니다. 그것은 스택 오버 플로우 나'rsp'가 어딘가에 가짜를 가리키고있는 경우에만 segfault해야합니다. ** 발신자가 스택을 깰 수 있었습니까? 예 : 매우 큰 로컬 배열 또는 alloca? ** RIP가 실제로'push' 명령을 가리키고 있는지 확인할 수 있습니까? 백 트레이스에서 느린 동적 연결 중에 실제로 segfault가 발생하는 것처럼 보이지 않습니다. –
즉 스택 포인터가 가리키는 메모리를 읽을 수 있는지 gcc로 확인하십시오. 'x $ rsp'를 사용하여 그 주소에서 덤프를 시작하십시오. –
실제로 코드를 단계별로 살펴보면'61310' 행에만 도달합니다. 이 시점에서 모든 레지스터가 유효합니다. 다음 단계에서는 이미 segfault가 발생합니다. 또한 점프는'0x7fced7ffa4b8'로 끝납니다. 나는이 기억 장소에 GOT를 질문에 추가했다. –