레지스터에 대한 기초를 이해하고 난 뒤에 봐야하는 글.
https://wyv3rn.tistory.com/144
1. 서론
각 레지스터들이 데이터 연산 시 어떻게 사용되는지는 위 글과 같이 보았는데,
프로그램 실행 시 레지스터는 과연 무슨 역할을 할까?
2. 함수 호출 규약
함수를 호출할 때 파라미터 즉, 인자를 어떤 방식으로 전달할지 정해놓은 규약이다.
2.1 32 bit 함수 호출 규약
3가지 방식이 있는데, 결국 리눅스에서는 cdecl 방식을 사용하기에 이것만 보자.
* cdecl
C declaration을 이야기하며, 이름과 같이 C 언어가 기원인 호출 규약이다.
호출 방법을 간단히 요약하면, stack에 쌓여있는 값을 참조로 "호출하는 함수에서" 차례로 값을 가져가 함수를 실행한다.
이게 무슨 소리냐 하면,
wyv3rn(1,2,3,4,5) 와 같이 함수를 인자와 함께 호출한다고 가정하자.
그럼 어셈블러 코드는 아래와 같다.
push 5
push 4
push 3
push 2
push 1
call wyv3rn
이를 스택의 입장에서 보면 높은 주소부터 5, 4, 3, 2, 1의 값을 넣어둔 상태로 함수를 call 하는 것이다.
낮은 주소 |
1 |
2 |
3 |
4 |
5 |
높은 주소 |
그럼 호출하는 함수가 알아서 1, 2, 3, 4, 5를 가져가서 인자로 사용한다.
이것이 우리가 32 bit rop 시 call 할 함수의 주소와 인자를 연속적으로 넣어주고 pppr과 같은 register를 신경쓰지 않은 gadget을 사용하는 이유이다.
이런 방식으로 인해 인자가 5개던, 100개던 상관 없이 전달이 가능하다. (아마 최대 수량은 제한이 있을거다.)
* 예제
예제는 아래 링크를 참고하자.
2.2 64 bit 함수 호출 규약
64 bit는 32 bit와 다르게 fastcall이라는 규약을 사용한다.
* fastcall
이는 stdcall 방식과 동일하지만, register를 이용해 일부 인자를 전달하는 방식이다.
stdcall은 또 뭐야? 그냥 무시하고 아래를 보자.
64 bit에는 스택의 값을 바로 참조하지 않고, 6개 인자까지는 register에서 값을 가져와서 사용하고 이후에는 스택에서 값을 가져와 사용한다.
이를 테이블로 만들어보면 아래와 같고,
32 bit와 동일한 함수를 실행시킨다고 가정하면 아래와 같이 값이 삽입되어있어야 한다.
syscall NR | return | arg0 | arg1 | arg2 | arg3 | arg4 | arg5 |
wyv3rn | rax | rdi = 1 | rsi = 2 | rdx = 3 | r10 = 4 | r8 = 5 | r9 |
만일 테이블의 register보다 더 많은 인자가 요구되는 경우 64 bit에 한해
* 예제
예제는 아래를 참고하자.
2022.07.22 - [Wargame/Dreamhack] - basic_rop_x64
3. 참고사항
3.1 syscall table
함수를 호출하기 위해서는 어떤 함수를 호출할지 알아야하는데, 각 함수는 이미 넘버링이 되어있다.
아래 주소를 참고하자.
Chromium OS Docs - Linux System Call Table (googlesource.com)
3.2 ROP(Return Oriented Programming)
결국 위의 내용은 ROP 기법을 이용하기 위한 기본 지식이다. (더불어 어셈블러 코드로 코딩 시 반드시 필요하다)
ROP이란 결국 특정 함수를 인자와 함께 호출한다는 것인데, 한번의 함수 호출을 위해서는 위에서 설명한 정도면 충분하지만, 보통은 여러번의 함수 호출이 필요하며, 32 bit와 64 bit에서 각각 그 방법이 다르다.
아래 예제를 참고하자.
rop — think storage (tistory.com)
'Tips & theory' 카테고리의 다른 글
Return to csu (0) | 2022.09.05 |
---|---|
one gadget 사용법 (0) | 2022.09.05 |
system hacking을 register 기초 (0) | 2022.09.05 |
_IO_FILE_plus의 모든 것. (0) | 2022.08.21 |
FSOP - _IO_flush_all_lockp () (0) | 2022.08.18 |