함수 호출 스택 프레임에서 메모리 보호를 위한 카나리(Canary)
지난 3월 26일에 운영체제 스터디 중 함수 호출 스택 프레임을 살펴보는 발표가 있었습니다.
당시에 이해가 되지 않고 넘어간 질문이 있었는데, 유투브를 우연히 보다가 해답을 알게 되었네요..!
스택 프레임에서 변수 메모리 값 앞 뒤에 cc cc cc cc 4바이트로 넣어져 있는 걸 확인할 수 있습니다.
어셈블리어 코드에서도 MOV eax, CCCCCC , mov eax, dword ptr ss:[ebp+8] , mov eax, dword ptr ss:[ebp-8] 으로 넣어주는 걸 확인할 수 있습니다.
이를 '카나리(Canary)', '카나리 비트' 라고 합니다.
메모리 보호를 위한 값이라고 하는데요,
해당 값이 '오버 플로우' 또는 '언더 플로우'로 수정이 되면 손상되었다고 판단한다고 합니다.
이를 판단하는 (어셈블리어)코드가 컴파일 단계에서 추가합니다.
$ gcc -S -fverbose-asm -O2 main.c -fstack-protector-all
.section __TEXT,__text,regular,pure_instructions
.build_version macos, 14, 0 sdk_version 14, 2
.globl _main ; -- Begin function main
.p2align 2
_main: ; @main
.cfi_startproc
; %bb.0:
sub sp, sp, #32
.cfi_def_cfa_offset 32
stp x29, x30, [sp, #16] ; 16-byte Folded Spill
add x29, sp, #16
.cfi_def_cfa w29, 16
.cfi_offset w30, -8
.cfi_offset w29, -16
Lloh0:
adrp x8, ___stack_chk_guard@GOTPAGE
Lloh1:
ldr x8, [x8, ___stack_chk_guard@GOTPAGEOFF]
Lloh2:
ldr x8, [x8]
str x8, [sp, #8]
mov w8, #8265
movk w8, #28001, lsl #16
str w8, [sp, #4]
add x0, sp, #4
bl _puts
ldr x8, [sp, #8]
Lloh3:
adrp x9, ___stack_chk_guard@GOTPAGE
Lloh4:
ldr x9, [x9, ___stack_chk_guard@GOTPAGEOFF]
Lloh5:
ldr x9, [x9]
cmp x9, x8
b.ne LBB0_2
; %bb.1:
mov w0, #0
ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
add sp, sp, #32
ret
LBB0_2:
bl ___stack_chk_fail
.loh AdrpLdrGotLdr Lloh3, Lloh4, Lloh5
.loh AdrpLdrGotLdr Lloh0, Lloh1, Lloh2
.cfi_endproc
; -- End function
.subsections_via_symbols
Visual Studio 에서 기본 런타임 검사 옵션을, 기본값(사용 안함) 으로 설정하거나
gcc 옵션으로 -fno-stack-protector 옵션을 주면 기능을 끌 수 있습니다.
( -fstack-protector-all 은 메모리 보호 기법 사용 )
< 출처 >
1. (Youtube) 널널한개발자 C언어 예제 실행결과 맞히기 문제 해설 : https://www.youtube.com/watch?v=nr5IZDg1fXY&ab_channel=널널한개발자TV
-> 시간 11분 50초 부터 설명 시작
- 스택 프레임 동작 원리
- 메모리 값과 자료형의 관계
- 문자열을 읽는 방식 (아스키)
- 카나리와 기본 런타임 검사(SSP, Stack Smashing Protector)
- 디버그 모드와 릴리즈 모드의 차이 (컴파일러 최적화로 인한 사용하지 않는 메모리 할당 제거)
2. (Wiki) Buffer overflow protection : https://en.wikipedia.org/wiki/Buffer_overflow_protection
3. (Blog) 메모리 보호기법 - SSP(Stack Smashing Protector) : https://pmandocom.tistory.com/82