안녕하세요. 해당 문제에서 _dl_rtld_lock_recursive
함수 포인터가 가리키는 주소를 아래의 코드를 통해서 overwrite 하는 것이 가능합니다.
printf("addr: ");
scanf("%ld", &addr);
printf("value: ");
scanf("%ld", &value);
*(long *)addr = value;
그래서 결론적으로 _dl_rtld_lock_recursive
함수가 가리키는 주소에 libc.symbols['system']
값을 넣게 되는데요.
그렇다면 원래 _dl_rtld_lock_recursive
-> _dl_rtld_default_lock
-> system 함수의 주소
로 저장되는 것이 맞을텐데,
만약 이렇다면 _dl_rtld_lock_recursive
함수 포인터를 실행하면 system
함수가 실행되는 것이 아니라, system 함수가 존재하는 주소를 instruction으로 실행하기 때문에 실제로 system 함수가 실행되지 않는 것이 아닌가요..?
제가 함수포인터 동작에 대해 잘못 이해하고 있는 부분이 있다면 설명주시면 정말 감사드리겠습니다.
함수와 함수 포인터를 혼용해 사용하고 계신 것 같습니다. 함수 포인터란 함수의 주소를 들고 있는 포인터이며 _dl_rtld_lock_recursive
은 함수가 아닌 함수 포인터입니다.
함수 포인터 타입인 _dl_rtld_lock_recursive
변수가 system()
의 주소를 들고 있다면 이후 _dl_rtld_lock_recursive()
실행 시 system()
을 실행한 것과 동일할 것입니다. C로 표현하면 아래와 같은 상황입니다.
function_pointer _dl_rtld_lock_recursive = system; // _dl_rtld_lock_recursive에 system주소 저장
_dl_rtld_lock_recursive() // _dl_rtld_lock_recursive 호출, 즉 system()이 실행됨
따라서 system()
함수가 실행되게 됩니다.
"그렇다면 원래 _dl_rtld_lock_recursive -> _dl_rtld_default_lock -> system 함수의 주소"부분은 질문을 명확하게 이해하지 못해서 조금 더 자세하게 설명해주시면 답변드리겠습니다!