Hacking/Pwnable
[Mitigation] PIE | Position Independent Executable
min_zu
2025. 5. 12. 23:28
728x90
반응형
PIE : Position-Independent Executable
무작위 주소에 매필되도 실행 가능한 실행 파일을 의미함
즉, 코드 영역이 무작위 주소에 배치되는 바이너리
- ASLR이 코드 영역에 적용되는 것
- ALSR이 적용되지 않으면, PIE도 적용되지 않음
PIC
Position-Independent Code
리눅스에는 ELF, 공유 오브젝트(Shared Object, so) 두 가지가 존재함
그 중 공유 오브젝트는 재배치(Relocation)이 가능하도록 설계되어있음
재배치가 가능하다는 것은, 메모리의 어느 주소에 코드가 배치되어도 코드의 의미가 훼손되지 않음을 의미한다.
이러한 코드를 PIC라고 함
push rbp
mov rbp,rsp
mov rax,QWORD PTR [rip+0x200b3e] # 0x601030 <data> (NO-PIC)
mov rax,QWORD PTR [rip+0x2009ab] # 0x201010 <data> (PIC)
mov rsi,rax
mov edi,0x4005a1 (NO-PIC)
lea rdi,[rip+0xa2] # 0x711 (PIC)
mov eax,0x0
call 0x4003f0 <printf@plt> (NO-PIC)
call 0x530 <printf@plt> (PIC)
mov eax,0x0
pop rbp
ret
PIC가 적용되어 있는 코드들은 상대 주소로 작동하게 된다.
따라서 어디에 매핑되어도 코드를 실행할 수 있는 것이다.
PIE
PIC가 적용되어 있는 무작위 주소에 매핑되어도 실행 가능한 실행 파일을 의미한다.
ASLR이 도입되면서 실행 파일도 무작위 주소에 매핑될 수 있도록 하여 원래 재배치가 가능했던 공유 오브젝트를 실행 파일로 사용하고자 함
Window DLL
Call 명령과 DLL 로딩
- Window의 DLL은 CALL E8 (상대주소 기반 근거리 호출)을 사용함
- 이 방식은 DLL이 메모리에 어디에 로딩되든 CALL명령의 내부 상대 주소는 수정 없이 그대로 동작함
코드의 재배치 (relocation)없이도 실행 가능하여 효율적
전역 변수와 주소 재배치
- DLL 내부 전역 변수들은 문자열, 가상 함수 테이블 등의 주소(포인터)를 포함할 수 있음
- DLL이 로드되는 실제 주소는 매번 다를 수 있기 때문에
- 동적 로더가 이 포인터 값을 재계산하여 전역 변수에 저장함
- 이 과정에서 해당 메모리 페이지는 Copy on write 처리됨 -> 다른 프로세스와 공유 불가
- 반면 코드 자체나 포인터가 없는 전역 변수는 그대로 공유 가능함
Vista 이전 이후
이전 : 커널이 직접 재배치하면서 재배치된 DLL도 프로세스 간 공유 가능
이후 : DLL 충돌 방지 방식으로 DLL이 고정된 주소에 로드 되어야함 -> DLL은 프로세스마다 별도로 복사됨
728x90
반응형