(메모리 보호 기법) PIE
symbol 없을 때나 PIE가 걸려있을 때 디버깅
Entry point + offset
으로 bp 걸면 되는데, offset은 IDA로 알아내고, Entry point는 0x00에 bp걸고 실행한 다음
- 첫 번째
call
에서 리턴되는 값($rax
)이 Enrty point - 또는 그냥
info file
Entry point == start
함수의 시작 지점 start
는 첫 번째 arg
로 main
의 func ptr을 넘기면서 \_\_libc\_start_main
을 호출하므로, call
직전에 넘어가는 arg
가 main
이다.
Position-Independent Executables
바이너리에 PIE를 설정하려면 컴파일 시 다음 옵션을 준다.
1
gcc -fPIE -pie pie\_test.c -o pie -lpictest -L.
1
2
$ file pie
pie: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=70990b73da080686c4d70b5183dfda697f6b8cbd, not stripped
1
2
$ file no\_pie
no\_pie: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=e9a5d685c5a869428e583975e9bf9de035b3c7fe, not stripped
file
명령어로 확인해보면, PIE가 걸려있는 경우 실행 파일이어도 shared object
로 출력된다.
실행하기 전 main disas
no_pie’s main
1
2
3
4
5
6
7
8
9
0x00000000004006dd <+0>: push rbp
0x00000000004006de <+1>: mov rbp,rsp
0x00000000004006e1 <+4>: mov eax,0x0
0x00000000004006e6 <+9>: call 0x4005e0 <picTest@plt>
0x00000000004006eb <+14>: mov edi,0x400784
0x00000000004006f0 <+19>: call 0x4005b0 <puts@plt>
0x00000000004006f5 <+24>: mov eax,0x0
0x00000000004006fa <+29>: pop rbp
0x00000000004006fb <+30>: ret
pie’s main
1
2
3
4
5
6
7
8
9
0x0000000000000815 <+0>: push rbp
0x0000000000000816 <+1>: mov rbp,rsp
0x0000000000000819 <+4>: mov eax,0x0
0x000000000000081e <+9>: call 0x6e0 <picTest@plt>
0x0000000000000823 <+14>: lea rdi,[rip+0x9a] # 0x8c4
0x000000000000082a <+21>: call 0x6b0 <puts@plt>
0x000000000000082f <+26>: mov eax,0x0
0x0000000000000834 <+31>: pop rbp
0x0000000000000835 <+32>: ret
PIE가 걸려있는 경우 이렇게 모든 주소를 상대 주소, offset으로 접근한다. 뿐만 아니라 0x400000
에 mapping되는 일반적인 바이너리와 달리 Image Base가 고정되어있지 않다. mapping 위치를 정해놓지 않는게 PIE니까. no_pie
의 경우 실행하면 저 주소 그대로 적재되지만, pie
는 실행하면 그 때 Image Base가 결정되어 그 위치에 적재된다.
실행 후 main disas
no_pie’s main
1
2
3
4
0x4006dd <main>: push rbp
0x4006de <main+1>: mov rbp,rsp
=> 0x4006e1 <main+4>: mov eax,0x0
0x4006e6 <main+9>: call 0x4005e0 <picTest@plt>
pie’s main
1
2
3
4
5
6
7
0x555555554815 <main>: push rbp
0x555555554816 <main+1>: mov rbp,rsp
=> 0x555555554819 <main+4>: mov eax,0x0
0x55555555481e <main+9>: call 0x5555555546e0 <picTest@plt>
0x555555554823 <main+14>: lea rdi,[rip+0x9a] # 0x5555555548c4
0x55555555482a <main+21>: call 0x5555555546b0 <puts@plt>
0x55555555482f <main+26>: mov eax,0x0
This post is licensed under CC BY 4.0 by the author.