PLT & GOT 실습 따라하는데 아주 다르게 나옵니다. 살려 주십시오

got.c 코드는 아래 처럼 강의와 똑같이 했습니다.

// Name: got.c
// Compile: gcc -o got got.c
#include <stdio.h>
int main() {
  puts("Resolving address of 'puts'.");
  puts("Get address from GOT");
}

컴파일도 별다른 옵션을 주지 않고
gcc -o got got.c
로 했습니다.

다음은 gdb입니다.
gdb-peda$ start

gdb-peda$ disass main
Dump of assembler code for function main:
=> 0x0000555555555149 <+0>: endbr64
0x000055555555514d <+4>: push rbp
0x000055555555514e <+5>: mov rbp,rsp
0x0000555555555151 <+8>: lea rdi,[rip+0xeac] # 0x555555556004
0x0000555555555158 <+15>: call 0x555555555050 puts@plt
0x000055555555515d <+20>: lea rdi,[rip+0xebd] # 0x555555556021
0x0000555555555164 <+27>: call 0x555555555050 puts@plt
0x0000555555555169 <+32>: mov eax,0x0
0x000055555555516e <+37>: pop rbp
0x000055555555516f <+38>: ret
End of assembler dump.
gdb-peda$ b *main+15
gdb-peda$ c

0x55555555514d <main+4>: push rbp
0x55555555514e <main+5>: mov rbp,rsp
0x555555555151 <main+8>: lea rdi,[rip+0xeac] # 0x555555556004
=> 0x555555555158 <main+15>: call 0x555555555050 puts@plt
0x55555555515d <main+20>: lea rdi,[rip+0xebd] # 0x555555556021
0x555555555164 <main+27>: call 0x555555555050 puts@plt
0x555555555169 <main+32>: mov eax,0x0
0x55555555516e <main+37>: pop rbp

gdb-peda$ si
0x555555555040 __cxa_finalize@plt: endbr64
0x555555555044 <__cxa_finalize@plt+4>: bnd jmp QWORD PTR [rip+0x2fad] # 0x555555557ff8
0x55555555504b <__cxa_finalize@plt+11>: nop DWORD PTR [rax+rax1+0x0]
=> 0x555555555050 puts@plt: endbr64
0x555555555054 <puts@plt+4>: bnd jmp QWORD PTR [rip+0x2f75] # 0x555555557fd0 puts@got.plt
0x55555555505b <puts@plt+11>: nop DWORD PTR [rax+rax
1+0x0]
0x555555555060 <_start>: endbr64
0x555555555064 <_start+4>: xor ebp,ebp

gdb-peda$ ni

0x555555555044 <__cxa_finalize@plt+4>: bnd jmp QWORD PTR [rip+0x2fad] # 0x555555557ff8
0x55555555504b <__cxa_finalize@plt+11>: nop DWORD PTR [rax+rax1+0x0]
0x555555555050 puts@plt: endbr64
=> 0x555555555054 <puts@plt+4>: bnd jmp QWORD PTR [rip+0x2f75] # 0x555555557fd0 puts@got.plt
0x55555555505b <puts@plt+11>: nop DWORD PTR [rax+rax
1+0x0]
0x555555555060 <_start>: endbr64
0x555555555064 <_start+4>: xor ebp,ebp
0x555555555066 <_start+6>: mov r9,rdx

puts 함수 첫번째 호출이지만 밑줄로 안 보내고 다른 곳으로 날려버립니다.

gdb-peda$ ni

0x7ffff7e4f40f <_IO_new_popen+143>: jmp 0x7ffff7e4f3e4 <_IO_new_popen+100>
0x7ffff7e4f411: nop WORD PTR cs:[rax+rax1+0x0]
0x7ffff7e4f41b: nop DWORD PTR [rax+rax
1+0x0]
=> 0x7ffff7e4f420 <__GI__IO_puts>: endbr64
0x7ffff7e4f424 <__GI__IO_puts+4>: push r14
0x7ffff7e4f426 <__GI__IO_puts+6>: push r13
0x7ffff7e4f428 <__GI__IO_puts+8>: push r12
0x7ffff7e4f42a <__GI__IO_puts+10>: mov r12,rdi

###그럼 갑자기 __GI__IO_puts라는 함수(?) 가 시작됩니다.
gdb-peda$ disass __GI__IO_put 해보면 다음과 같습니다.
0x00007ffff7e4f420 <+0>: endbr64
0x00007ffff7e4f424 <+4>: push r14
0x00007ffff7e4f426 <+6>: push r13
=> 0x00007ffff7e4f428 <+8>: push r12
0x00007ffff7e4f42a <+10>: mov r12,rdi
0x00007ffff7e4f42d <+13>: push rbp
0x00007ffff7e4f42e <+14>: push rbx
0x00007ffff7e4f42f <+15>: call 0x7ffff7ded460 *ABS*+0x9f630@plt
0x00007ffff7e4f434 <+20>: mov r13,QWORD PTR [rip+0x167b0d] # 0x7ffff7fb6f48
0x00007ffff7e4f43b <+27>: mov rbx,rax
0x00007ffff7e4f43e <+30>: mov rbp,QWORD PTR [r13+0x0]
0x00007ffff7e4f442 <+34>: mov edx,DWORD PTR [rbp+0x0]
0x00007ffff7e4f445 <+37>: and edx,0x8000
0x00007ffff7e4f44b <+43>: jne 0x7ffff7e4f4b0 <__GI__IO_puts+144>
0x00007ffff7e4f44d <+45>: mov r8,QWORD PTR [rbp+0x88]
0x00007ffff7e4f454 <+52>: mov r14,QWORD PTR fs:0x10
0x00007ffff7e4f45d <+61>: cmp QWORD PTR [r8+0x8],r14
0x00007ffff7e4f461 <+65>: je 0x7ffff7e4f570 <__GI__IO_puts+336>
0x00007ffff7e4f467 <+71>: mov eax,DWORD PTR fs:0x18
0x00007ffff7e4f46f <+79>: test eax,eax
0x00007ffff7e4f471 <+81>: jne 0x7ffff7e4f5b0 <__GI__IO_puts+400>
0x00007ffff7e4f477 <+87>: mov edx,0x1
0x00007ffff7e4f47c <+92>: cmpxchg DWORD PTR [r8],edx
0x00007ffff7e4f480 <+96>: mov r8,QWORD PTR [rbp+0x88]
0x00007ffff7e4f487 <+103>: mov rdi,QWORD PTR [r13+0x0]
0x00007ffff7e4f48b <+107>: mov QWORD PTR [r8+0x8],r14
0x00007ffff7e4f48f <+111>: mov eax,DWORD PTR [rdi+0xc0]
0x00007ffff7e4f495 <+117>: add DWORD PTR [r8+0x4],0x1
0x00007ffff7e4f49a <+122>: test eax,eax
0x00007ffff7e4f49c <+124>: je 0x7ffff7e4f4bd <__GI__IO_puts+157>
0x00007ffff7e4f49e <+126>: cmp eax,0xffffffff
0x00007ffff7e4f4a1 <+129>: je 0x7ffff7e4f4c7 <__GI__IO_puts+167>
0x00007ffff7e4f4a3 <+131>: mov r8d,0xffffffff
0x00007ffff7e4f4a9 <+137>: jmp 0x7ffff7e4f52f <__GI__IO_puts+271>
0x00007ffff7e4f4ae <+142>: xchg ax,ax
0x00007ffff7e4f4b0 <+144>: mov rdi,rbp
0x00007ffff7e4f4b3 <+147>: mov eax,DWORD PTR [rdi+0xc0]
0x00007ffff7e4f4b9 <+153>: test eax,eax
0x00007ffff7e4f4bb <+155>: jne 0x7ffff7e4f49e <__GI__IO_puts+126>
0x00007ffff7e4f4bd <+157>: mov DWORD PTR [rdi+0xc0],0xffffffff
0x00007ffff7e4f4c7 <+167>: mov r14,QWORD PTR [rdi+0xd8]
0x00007ffff7e4f4ce <+174>: lea rdx,[rip+0x1643cb] # 0x7ffff7fb38a0 <_IO_helper_jumps>
0x00007ffff7e4f4d5 <+181>: lea rax,[rip+0x16512c] # 0x7ffff7fb4608
0x00007ffff7e4f4dc <+188>: sub rax,rdx
0x00007ffff7e4f4df <+191>: mov rcx,r14
0x00007ffff7e4f4e2 <+194>: sub rcx,rdx
0x00007ffff7e4f4e5 <+197>: cmp rax,rcx
0x00007ffff7e4f4e8 <+200>: jbe 0x7ffff7e4f580 <__GI__IO_puts+352>
0x00007ffff7e4f4ee <+206>: mov rdx,rbx
0x00007ffff7e4f4f1 <+209>: mov rsi,r12
0x00007ffff7e4f4f4 <+212>: call QWORD PTR [r14+0x38]
0x00007ffff7e4f4f8 <+216>: cmp rbx,rax
0x00007ffff7e4f4fb <+219>: jne 0x7ffff7e4f4a3 <__GI__IO_puts+131>
0x00007ffff7e4f4fd <+221>: mov rdi,QWORD PTR [r13+0x0]
0x00007ffff7e4f501 <+225>: mov rax,QWORD PTR [rdi+0x28]
0x00007ffff7e4f505 <+229>: cmp rax,QWORD PTR [rdi+0x30]
0x00007ffff7e4f509 <+233>: jae 0x7ffff7e4f590 <__GI__IO_puts+368>
0x00007ffff7e4f50f <+239>: lea rdx,[rax+0x1]
0x00007ffff7e4f513 <+243>: mov QWORD PTR [rdi+0x28],rdx
0x00007ffff7e4f517 <+247>: mov BYTE PTR [rax],0xa
0x00007ffff7e4f51a <+250>: add rbx,0x1
0x00007ffff7e4f51e <+254>: mov r8d,0x7fffffff
0x00007ffff7e4f524 <+260>: cmp rbx,0x7fffffff
0x00007ffff7e4f52b <+267>: cmovbe r8,rbx
0x00007ffff7e4f52f <+271>: test DWORD PTR [rbp+0x0],0x8000
0x00007ffff7e4f536 <+278>: jne 0x7ffff7e4f561 <__GI__IO_puts+321>
0x00007ffff7e4f538 <+280>: mov rdi,QWORD PTR [rbp+0x88]
0x00007ffff7e4f53f <+287>: mov eax,DWORD PTR [rdi+0x4]
0x00007ffff7e4f542 <+290>: sub eax,0x1
0x00007ffff7e4f545 <+293>: mov DWORD PTR [rdi+0x4],eax
0x00007ffff7e4f548 <+296>: jne 0x7ffff7e4f561 <__GI__IO_puts+321>
0x00007ffff7e4f54a <+298>: mov QWORD PTR [rdi+0x8],0x0
0x00007ffff7e4f552 <+306>: mov edx,DWORD PTR fs:0x18
0x00007ffff7e4f55a <+314>: test edx,edx
0x00007ffff7e4f55c <+316>: jne 0x7ffff7e4f5d0 <__GI__IO_puts+432>
0x00007ffff7e4f55e <+318>: sub DWORD PTR [rdi],0x1
0x00007ffff7e4f561 <+321>: pop rbx
0x00007ffff7e4f562 <+322>: mov eax,r8d
0x00007ffff7e4f565 <+325>: pop rbp
0x00007ffff7e4f566 <+326>: pop r12
0x00007ffff7e4f568 <+328>: pop r13
0x00007ffff7e4f56a <+330>: pop r14
0x00007ffff7e4f56c <+332>: ret
0x00007ffff7e4f56d <+333>: nop DWORD PTR [rax]
0x00007ffff7e4f570 <+336>: mov rdi,rbp
0x00007ffff7e4f573 <+339>: jmp 0x7ffff7e4f48f <__GI__IO_puts+111>
0x00007ffff7e4f578 <+344>: nop DWORD PTR [rax+rax1+0x0]
0x00007ffff7e4f580 <+352>: call 0x7ffff7e58b60 <_IO_vtable_check>
0x00007ffff7e4f585 <+357>: mov rdi,QWORD PTR [r13+0x0]
0x00007ffff7e4f589 <+361>: jmp 0x7ffff7e4f4ee <__GI__IO_puts+206>
0x00007ffff7e4f58e <+366>: xchg ax,ax
0x00007ffff7e4f590 <+368>: mov esi,0xa
0x00007ffff7e4f595 <+373>: call 0x7ffff7e5c9e0 <__GI___overflow>
0x00007ffff7e4f59a <+378>: cmp eax,0xffffffff
0x00007ffff7e4f59d <+381>: jne 0x7ffff7e4f51a <__GI__IO_puts+250>
0x00007ffff7e4f5a3 <+387>: jmp 0x7ffff7e4f4a3 <__GI__IO_puts+131>
0x00007ffff7e4f5a8 <+392>: nop DWORD PTR [rax+rax
1+0x0]
0x00007ffff7e4f5b0 <+400>: mov ecx,0x1
0x00007ffff7e4f5b5 <+405>: mov eax,edx
0x00007ffff7e4f5b7 <+407>: lock cmpxchg DWORD PTR [r8],ecx
0x00007ffff7e4f5bc <+412>: je 0x7ffff7e4f480 <__GI__IO_puts+96>
0x00007ffff7e4f5c2 <+418>: mov rdi,r8
0x00007ffff7e4f5c5 <+421>: call 0x7ffff7e5f5a0 <__lll_lock_wait_private>
0x00007ffff7e4f5ca <+426>: jmp 0x7ffff7e4f480 <__GI__IO_puts+96>
0x00007ffff7e4f5cf <+431>: nop
0x00007ffff7e4f5d0 <+432>: xchg DWORD PTR [rdi],eax
0x00007ffff7e4f5d2 <+434>: cmp eax,0x1
0x00007ffff7e4f5d5 <+437>: jle 0x7ffff7e4f561 <__GI__IO_puts+321>
0x00007ffff7e4f5d7 <+439>: xor r10d,r10d
0x00007ffff7e4f5da <+442>: mov edx,0x1
0x00007ffff7e4f5df <+447>: mov esi,0x81
0x00007ffff7e4f5e4 <+452>: mov eax,0xca
0x00007ffff7e4f5e9 <+457>: syscall
0x00007ffff7e4f5eb <+459>: jmp 0x7ffff7e4f561 <__GI__IO_puts+321>
0x00007ffff7e4f5f0 <+464>: endbr64
0x00007ffff7e4f5f4 <+468>: mov r8,rax
0x00007ffff7e4f5f7 <+471>: jmp 0x7ffff7dedd5c <__GI__IO_puts.cold>
Address range 0x7ffff7dedd5c to 0x7ffff7deddb3:
0x00007ffff7dedd5c <-399044>: test DWORD PTR [rbp+0x0],0x8000
0x00007ffff7dedd63 <-399037>: jne 0x7ffff7dedd8e <__GI__IO_puts-398994>
0x00007ffff7dedd65 <-399035>: mov rdi,QWORD PTR [rbp+0x88]
0x00007ffff7dedd6c <-399028>: mov eax,DWORD PTR [rdi+0x4]
0x00007ffff7dedd6f <-399025>: sub eax,0x1
0x00007ffff7dedd72 <-399022>: mov DWORD PTR [rdi+0x4],eax
0x00007ffff7dedd75 <-399019>: jne 0x7ffff7dedd8e <__GI__IO_puts-398994>
0x00007ffff7dedd77 <-399017>: mov QWORD PTR [rdi+0x8],0x0
0x00007ffff7dedd7f <-399009>: mov edx,DWORD PTR fs:0x18
0x00007ffff7dedd87 <-399001>: test edx,edx
0x00007ffff7dedd89 <-398999>: jne 0x7ffff7dedd96 <__GI__IO_puts-398986>
0x00007ffff7dedd8b <-398997>: sub DWORD PTR [rdi],0x1
0x00007ffff7dedd8e <-398994>: mov rdi,r8
0x00007ffff7dedd91 <-398991>: call 0x7ffff7def3a0 <_Unwind_Resume>
0x00007ffff7dedd96 <-398986>: xchg DWORD PTR [rdi],eax
0x00007ffff7dedd98 <-398984>: sub eax,0x1
0x00007ffff7dedd9b <-398981>: jle 0x7ffff7dedd8e <__GI__IO_puts-398994>
0x00007ffff7dedd9d <-398979>: xor r10d,r10d
0x00007ffff7dedda0 <-398976>: mov edx,0x1
0x00007ffff7dedda5 <-398971>: mov esi,0x81
0x00007ffff7deddaa <-398966>: mov eax,0xca
0x00007ffff7deddaf <-398961>: syscall
0x00007ffff7deddb1 <-398959>: jmp 0x7ffff7dedd8e <__GI__IO_puts-398994>

계속 넘겨보면

0x7ffff7e4f51e <__GI__IO_puts+254>: mov r8d,0x7fffffff
0x7ffff7e4f524 <__GI__IO_puts+260>: cmp rbx,0x7fffffff
0x7ffff7e4f52b <__GI__IO_puts+267>: cmovbe r8,rbx
=> 0x7ffff7e4f52f <__GI__IO_puts+271>: test DWORD PTR [rbp+0x0],0x8000
0x7ffff7e4f536 <__GI__IO_puts+278>: jne 0x7ffff7e4f561 <__GI__IO_puts+321>
0x7ffff7e4f538 <__GI__IO_puts+280>: mov rdi,QWORD PTR [rbp+0x88]
0x7ffff7e4f53f <__GI__IO_puts+287>: mov eax,DWORD PTR [rdi+0x4]
0x7ffff7e4f542 <__GI__IO_puts+290>: sub eax,0x1

gdb-peda$ n
0x55555555514e <main+5>: mov rbp,rsp
0x555555555151 <main+8>: lea rdi,[rip+0xeac] # 0x555555556004
0x555555555158 <main+15>: call 0x555555555050 puts@plt
=> 0x55555555515d <main+20>: lea rdi,[rip+0xebd] # 0x555555556021
0x555555555164 <main+27>: call 0x555555555050 puts@plt
0x555555555169 <main+32>: mov eax,0x0
0x55555555516e <main+37>: pop rbp
0x55555555516f <main+38>: ret

<__GI__IO_puts+271>에서 메인함수로 넘어옵니다.
그런데 이게 puts 두번째 호출에서도 똑같이 작동합니다.
0x555555555151 <main+8>: lea rdi,[rip+0xeac] # 0x555555556004
0x555555555158 <main+15>: call 0x555555555050 puts@plt
0x55555555515d <main+20>: lea rdi,[rip+0xebd] # 0x555555556021
=> 0x555555555164 <main+27>: call 0x555555555050 puts@plt
0x555555555169 <main+32>: mov eax,0x0
0x55555555516e <main+37>: pop rbp
0x55555555516f <main+38>: ret
0x555555555170 <__libc_csu_init>: endbr64

gdb-peda$ si
0x555555555040 __cxa_finalize@plt: endbr64
0x555555555044 <__cxa_finalize@plt+4>: bnd jmp QWORD PTR [rip+0x2fad] # 0x555555557ff8
0x55555555504b <__cxa_finalize@plt+11>: nop DWORD PTR [rax+rax1+0x0]
=> 0x555555555050 puts@plt: endbr64
0x555555555054 <puts@plt+4>: bnd jmp QWORD PTR [rip+0x2f75] # 0x555555557fd0 puts@got.plt
0x55555555505b <puts@plt+11>: nop DWORD PTR [rax+rax
1+0x0]
0x555555555060 <_start>: endbr64
0x555555555064 <_start+4>: xor ebp,ebp

gdb-peda$ ni

0x555555555044 <__cxa_finalize@plt+4>: bnd jmp QWORD PTR [rip+0x2fad] # 0x555555557ff8
0x55555555504b <__cxa_finalize@plt+11>: nop DWORD PTR [rax+rax1+0x0]
0x555555555050 puts@plt: endbr64
=> 0x555555555054 <puts@plt+4>: bnd jmp QWORD PTR [rip+0x2f75] # 0x555555557fd0 puts@got.plt
0x55555555505b <puts@plt+11>: nop DWORD PTR [rax+rax
1+0x0]
0x555555555060 <_start>: endbr64
0x555555555064 <_start+4>: xor ebp,ebp
0x555555555066 <_start+6>: mov r9,rdx

gdb-peda$ ni
0x7ffff7e4f40f <_IO_new_popen+143>: jmp 0x7ffff7e4f3e4 <_IO_new_popen+100>
0x7ffff7e4f411: nop WORD PTR cs:[rax+rax1+0x0]
0x7ffff7e4f41b: nop DWORD PTR [rax+rax
1+0x0]
=> 0x7ffff7e4f420 <__GI__IO_puts>: endbr64
0x7ffff7e4f424 <__GI__IO_puts+4>: push r14
0x7ffff7e4f426 <__GI__IO_puts+6>: push r13
0x7ffff7e4f428 <__GI__IO_puts+8>: push r12
0x7ffff7e4f42a <__GI__IO_puts+10>: mov r12,rdi

그러고는 첫번쨰 호출이랑 같이 <__GI__IO_puts>로 넘어가서 <__GI__IO_puts+271>에서 메인함수로 넘어옵니다.
gcc 버전을 바꿨을 때도 같은 일이 일어납니다. 뭐가 문제인가요?

#시스템_해킹 #배경지식 #라이브러리 #링크 #plt #got
작성자 정보
답변 4
avatar
wyv3rn
무플 방지 위원회장

아시고싶으신게 무엇인가요? 아무래도 plt와 got에 대한 정의가 제대로 정리되지 않으신 느낌인데... 구글에서 plt got이라고 검색하시면 똑똑하신분들께서 아주 상세하게 분석해놓으신 글들이 많이 나올겁니다 ㅎㅎ 처음에 보면 이게 무슨 말인가 싶겠지만 보시다보면 이해가...

2022.09.17. 01:21
ChAp_cHaP_HACK
강의 수강: 1

요약
이해 안 가는 점

  1. 강의에서는 첫번째 호출에서 got가 plt 바로 다음 줄을 가리켜 plt에서 puts의 위치를 찾는 과정과 그 위치를 got에 등록하는 과정을 거치고 두번째 호출에서는 got가 puts함수를 가르켜 puts 함수가 바로 실행될 수 있음으로 이해했으나 제가 컴퓨터로 돌려봤을때는 puts의 첫번째와 두번째 호출 모두 <__GI__IO_puts>라는 함수로 바로 넘어간다는 것입니다. 강의에서와 달리 dl_runtime_resolve_xsavec라는 함수도 실행된 적 없고 심지어는 <puts>도 실행되지 않습니다.

질문

  1. 왜 이런 차이가 생기는가?
  2. <__GI__IO_puts>는 무엇인가?
  3. 강의와 같은 방법으로 돌아가게 하려면 어떻게 해야하는 가?
2022.09.17. 08:50
ChAp_cHaP_HACK
강의 수강: 1

첫번째 호출에서 si를 이용해도 바로 <__GI__IO_puts>로 넘어가네요... 얘는 어떻게 puts 함수 주소를 알고 있는 것일까요...? ㅠㅠㅠ 컴파일 할 때 특별한 옵션을 줘야하나요?
file 명령어로 살펴봐도 dynamically linked라고 나와있는데... 영문을 모르겠네요
$ file got
got: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=e62a150c7279955b4dbd05222114d2ecc161fa48, for GNU/Linux 3.2.0, not stripped

checksec으로 살펴보면 다음과 같습니다.
$ checksec got
Arch: amd64-64-little
RELRO: Full RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled


0x555555555044 <__cxa_finalize@plt+4>: bnd jmp QWORD PTR [rip+0x2fad] # 0x555555557ff8
0x55555555504b <__cxa_finalize@plt+11>: nop DWORD PTR [rax+rax1+0x0]
0x555555555050 puts@plt: endbr64
=> 0x555555555054 <puts@plt+4>: bnd jmp QWORD PTR [rip+0x2f75] # 0x555555557fd0 puts@got.plt
0x55555555505b <puts@plt+11>: nop DWORD PTR [rax+rax
1+0x0]
0x555555555060 <_start>: endbr64
0x555555555064 <_start+4>: xor ebp,ebp
0x555555555066 <_start+6>: mov r9,rdx

gdb-peda$ si
0x7ffff7e4f40f <_IO_new_popen+143>: jmp 0x7ffff7e4f3e4 <_IO_new_popen+100>
0x7ffff7e4f411: nop WORD PTR cs:[rax+rax1+0x0]
0x7ffff7e4f41b: nop DWORD PTR [rax+rax
1+0x0]
=> 0x7ffff7e4f420 <__GI__IO_puts>: endbr64
0x7ffff7e4f424 <__GI__IO_puts+4>: push r14
0x7ffff7e4f426 <__GI__IO_puts+6>: push r13
0x7ffff7e4f428 <__GI__IO_puts+8>: push r12
0x7ffff7e4f42a <__GI__IO_puts+10>: mov r12,rdi


아니 왜 그런진 모르겠는데 -no-pie 옵션을 주면 main -> puts@plt -> puts@plt 조금 앞의 주소 -> _dl_runtime_resolve_xsave -> __GI__IO_puts -> main 순으로 넘어갑니다...
아니 근데 이건 또 왜 그러죠.. ㅠㅠ

  1. -no-pie 옵션이 도대체 왜 이런 거에 영향을 주는 건가요?
  2. -no-pie 옵션을 안 줬을 때는 어떻게 처음부터 puts 함수의 위치를 알고 있는 건가요?
  3. -no-pie 옵션을 줬을 경우에도 코드를 살펴보면 의문이 생깁니다.
    첫번째 호출일 때
    => 0x401044 <puts@plt+4>: bnd jmp QWORD PTR [rip+0x2fcd] # 0x404018 <puts@got.plt>
    에서는 si하면
    => 0x401030: endbr64
    로 넘어가는데
    두번째 호출일 때는
    => 0x401044 <puts@plt+4>: bnd jmp QWORD PTR [rip+0x2fcd] # 0x404018 <puts@got.plt>
    에서 si 하면
    => 0x7ffff7e4f420 <__GI__IO_puts>: endbr64
    로 넘어갑니다. 같은 bnd jmp QWORD PTR [rip+0x2fcd] 명령인데 왜 둘이 다른 곳으로 넘어가버리는 거죠?
    아니 근데 심지어 rip+0x2fcd를 구해 보면
    gdb-peda$ print $rip+0x2fcd
    $4 = (void (*)()) 0x404011
    입니다...
    그럼..
    jmp하면 0x404011로 넘어가야 하는 거 아닌가요?

수준 낮은 질문 죄송합니다.

2022.09.17. 22:30
avatar
wyv3rn
무플 방지 위원회장

아닙니다 ㅎㅎ 첫 댓글에서 말씀 드렸듯 plt와 got에 대해서 조금 공부해보시면 바로 이해되실 것 같습니다.
아래 링크 참고하시면 좋을 것 같아요 ㅎㅎ
https://bpsecblog.wordpress.com/2016/03/09/about_got_plt_2/

2022.09.18. 00:36
질문에 대한 답을 알고 계신가요?
지식을 나누고 포인트를 획득해보세요.
답변하고 포인트 받기