#실행시키는 파일은 dreamhack에 있으며 dreamhack에서 더욱더 자세하게 설명되어있음(https://learn.dreamhack.io/112#9)


#Canary 값은 프로세스가 시작도리 떄 TLS가 전역 변수로 저장되고 각 함수마다 프롤로그와 에필로그에서 이 값을 참조
#fs는 세그먼트 레저스터의 일종으로 리눅스는 프로세스가 시작될떄 fs:0x28에 랜덤 값을 저장한다 => 결과적으로 rax에는 리눅스가 생성한 랜덤값이 생성된다.
1. fs는 TLS를 가리키므로 fs의 값을 알면 TLS의 주소를 알 수 있다(fs의 값은 특정 시스템 콜을 사용해야만 조회하거나 설정 할 수 있다).
   -> fs의 값을 설정할때 호출되는 arch_prctl(int code, unsigned long addr) 시스템 콜에 중단점을 설정한다.
   pwndbg> catch syscall arch_prctl
   pwndbg> run
   pwndbg> c
   pwndbg> c
   init_tls() 안에서 catchpoint에 도달할 때까지 continue 명령어를 실행합니다.
   catchpoint에 도달했을 때, rdi의 값이 0x1002인데 이 값은 ARCH_SET_FS의 상숫값입니다. rsi의 값이 0x7ffff7d7f740이므로, 이 프로세스는 TLS를 0x7ffff7d7f740에 저장할 것이며, fs는 이를 가리키게 될 것입니다.
   
2.TLS의 주소를 알았으므로, gdb의 watch 명령어로 TLS+0x28에 값을 쓸 때 프로세스를 중단시키겠습니다(watch는 특정 주소에 저장된 값이 변경되면 프로세스를 중단시키는 명령어입니다).
   *0x7ffff7d7f740 위에서의 rsi값
   pwndbg> watch *(0x7ffff7d7f740+0x28)
   watchpoint를 설정하고 프로세스를 계속 진행시키면(c) security_init함수에서 프로세스가 멈춥니다.
   여기서 TLS+0x28의 값을 조회하면 0x8ab7f53277873d00이 카나리로 설정된 것을 확인할 수 있습니다.
   pwndbg> x/gx 0x7ffff7d7f740+0x28
   0x7ffff7d7f768:	0x8ab7f53277873d00
   
   실제로 이 값이 main함수에서 사용하는 카나리값인지 확인하기 위해 main함수에 중단점을 설정하고
   pwndbg> b *main
   Breakpoint 3 at 0x555555555169
   
   mov rax,QWORD PTR fs:0x28를 실행하고 rax 값을 확인해보면 security_init에서 설정한 값과 같은 것을 확인할 수 있습니다.
   pwndbg> i r $rax
   rax  0x8ab7f53277873d00	9995727495074626816

+ Recent posts