완료됨
PLT & GOT 실습 gdb 동작이 알려진 순서와 다른것 같습니다. 이유를 모르겠습니다. ㅠ

첫번 째 PLT GOT 동작 순서는 PLT ( puts@plt) -> GOT -> PLT (<puts@plt+6>) -> _dl_runtime_resolve_xsavec 이잖아요.

그래서 gdb로 따라가 보니
► 0x4003f0 puts@plt jmp qword ptr [rip + 0x200c22] <GLOBAL_OFFSET_TABLE+24>

0x4003f6 <puts@plt+6> push 0
0x4003fb <puts@plt+11> jmp 0x4003e0 <0x4003e0>

0x4003e0 push qword ptr [rip + 0x200c22] <GLOBAL_OFFSET_TABLE+8>
0x4003e6 jmp qword ptr [rip + 0x200c24] <_dl_runtime_resolve_xsavec>

0x7ffff7dea8f0 <_dl_runtime_resolve_xsavec> push rbx

입니다.
si와 ni를 통해 따라가면 순서대로
0x4003f0 puts@plt jmp qword ptr [rip + 0x200c22]
0x4003f6 <puts@plt+6> push 0
0x4003fb <puts@plt+11> jmp 0x4003e0
0x4003e0 push qword ptr [rip + 0x200c22]
0x4003e6 jmp qword ptr [rip + 0x200c24]
0x7ffff7dea8f0 <_dl_runtime_resolve_xsavec> push rbx

로 실행이 됩니다.

그러나
pwndbg> got
GOT protection: Partial RELRO | GOT functions: 1
[0x601018] puts@GLIBC_2.2.5 -> 0x4003f6 (puts@plt+6)
를 보면 puts@plt+6 주소(0x4003f6)는 got 0x601018에 들어있어야 하는데 막상
0x4003f0 puts@plt jmp qword ptr [rip + 0x200c22]
에서 점프할 곳의 주소 qword ptr [rip + 0x200c22] 값이 got엔트리값 [0x601018]이 아닌
0x601012나옵니다. (아래 명령어로 확인시)
pwndbg> x/gx $rip
0x4003f0 puts@plt: 0x006800200c2225ff
pwndbg> x/gx $rip + 0x200c22
0x601012: 0x03f600007ffff7de

여기에는 당연히 0x601018에 들어있는 puts@plt+6(0x4003f6
) 주소가 안들어 있고요.
pwndbg> x/gx 0x601018
0x601018: 0x00000000004003f6
그래서 0x601012: 0x03f600007ffff7de 주소 값을 확인해 보면
pwndbg> x/gx 0x03f600007ffff7de
0x3f600007ffff7de: Cannot access memory at address 0x3f600007ffff7de
이라고 나옵니다. 내부적으로 0x601012거쳐서 0x601018 로 이동하고 이안의 값 puts@plt+6(0x4003f6)으로 점프하나요?

마찬가지로
0x4003e0 push qword ptr [rip + 0x200c22] <GLOBAL_OFFSET_TABLE+8>
► 0x4003e6 jmp qword ptr [rip + 0x200c24] <_dl_runtime_resolve_xsavec>

0x7ffff7dea8f0 <_dl_runtime_resolve_xsavec> push rbx

0x4003e6: jmp QWORD PTR [rip+0x200c24] # 0x601010
$rip 는 0x4003e6이나 x/x $rip+0x200c24 주소는 0x601010 이 아닌 0x60100a 입니다. 역시나 내부 적인 과정을 통해 0x601010까지 점프하게 되는 것인지요?

명령어를 제대로 쓰지 못해서 그런것인지 .. 혹시 아시는 분 계실지요..ㅠㅠ

#시스템_해킹 #배경지식 #라이브러리 #링크 #plt #got
작성자 정보
더 깊이 있는 답변이 필요할 때
드림핵 팀과 멘토에게 직접 문의해 보세요!
답변 3
kimht
공부벌레
kimht
공부벌레

GDB에서 RIP는 다음에 실행할 명령어를 가리킵니다.

jmp qword ptr [rip + 0x200c22]

따라서 위 명령어의 기계어는 6바이트 크기를 가지므로 x/gx $rip + 0x200c22 대신 x/gx $rip + 6 + 0x200c22로 확인해야 합니다.

2023.07.05. 10:53
kimht
공부벌레
kimht
공부벌레

jmp qword ptr [rip + 0x200c22]는 기계어로 \xFF\x25\x22\x0C\x20\x00 입니다.

일반적으로 Reduced Instruction Set Computer (RISC)인 MIPS나 ARM에서는 명령어 크기가 일정하지만,

Complex Instruction Set Computer (CISC)인 x86-64 아키텍처에서는 명령어 크기가 반드시 64비트가 아닐 수 있습니다.


GDB에서 RIP가 가리키는 곳 즉 화살표로 표시되는 곳은 다음에 실행할 명령어를 가리키고 있는 것입니다!

si 명령어를 실행하면 그제서야 기존에 화살표가 가리키고 있던 명령어를 실행합니다.

2023.07.05. 13:31
avatar
bincat
세계수
avatar
bincat
세계수

네 그게 이상한 점인데 제 gdb에서는 RIP가 가리키는 곳 즉 화살표로 표시되는 곳은 현재 실행 중인 명령어 이고RIP에도 그 주소가 저장되어 있습니다. *RIP 0x4003f0 (puts@plt) ◂— jmp qword ptr [rip + 0x200c22] ───────────────────────────────────────────[ DISASM / x86-64 / set emulate on ]─────────────────────────────────────────── ► 0x4003f0 <puts@plt> jmp qword ptr [rip + 0x200c22] <_GLOBAL_OFFSET_TABLE_+24> 0x4003f6 <puts@plt+6> push 0 이렇게요.. 0x4003f0 <puts@plt> 를 실행 중일때 rip를 보면 0x4003f0 값이 나오는데요 화살표가 0x4003f0을 가리키며 실행 중일 때 rip는 왜 다음 명령어인 0x4003f6를 가리키지 않는 것일까요?
라는 위 대댓글에 답변을 드리려는데 줄바꿈이 불편해서 여기에 씁니다.

  1. 일단 '현재 실행 중인 명령어'라는 표현이 gdb에서는 부적합할 수 있습니다. (부적합하기보다는, 어휘에 따라서 상황 이해를 어렵게 할 수 있습니다.)
    0x4003f0 puts@plt jmp qword ptr [rip + 0x200c22] 가 만약 실행 중인 명령어라면, gdb는 어디에서 멈춰있는걸까요?
    보다 쉽게 생각하기 위해서 0x4003f0 mov rax, rdx 와 같이 생각하기 쉬운 친구로 바꿔봐도 괜찮습니다.
    $rip --> 0x4003f0 mov rax, rdx 라면, 지금 gdb로 보고있는 프로그램은 뭘 하고 있을까요? rdx의 값을.. 천천히.. rax에.. 복사하는 중일까요? 아니면 이전 명령어를 "실행 중" 일까요..?

특수한 상황을 제외하면 유저 입장에서 각 인스트럭션은 'atomic' 하다고 봐도 무방합니다.
따라서 우리가 ni, si 등을 통해 다음 인스트럭션을 '실행하도록' 명령을 주는게 아니면 "실행 중인" 명령어는 없는 것과 같습니다.

2023.07.05. 14:22