what is __libc_start_main_ret

__libc_start_main_ret 뭔가 이름만 들어도 알것같이 생겼다. 그렇다. 우리가 흔히 많이 Leak하는 main함수의 RA 주소를 익스플로잇 언어로 다음과 같이 말한다.

Shell
    mov     rbx, QWORD PTR [rip+0x????????]   ; 내부 테이블/포인터 로드
    mov     rsi, QWORD PTR [rsp+0x08]         ; rsi = argv
    mov     edi, DWORD PTR [rsp+0x14]         ; edi = argc
    mov     rdx, QWORD PTR [rbx]              ; rdx = envp (혹은 관련 포인터)
    mov     rcx, QWORD PTR [rsp+0x10]         ; (플랫폼별 보조 인자)
    mov     r8,  QWORD PTR [rsp+0x28]         ; (필요 시)
    mov     r9,  QWORD PTR [rsp+0x30]         ; (필요 시)
    mov     rax, QWORD PTR [rsp+0x18]         ; rax = main의 주소

    call    rax                                ; **** 여기서 main() 호출 ****

    mov     edi, eax             ; exit의 1번 인자 = main의 반환값 `__libc_start_main_ret`
    call    exit@plt                           ; exit(result) -> atexit/소멸자 처리
    hlt                                        ; (여기 도달하면 비정상, 원래는 미복귀)

pwntools에서

Shell
 __libc_start_main_ret_offset = libc_e.libc_start_main_return 

다음으로 쉽게 구할수 있다.