본문 바로가기
해킹/시스템해킹

시스템해킹 레지스터 쓰임새와 시스템콜

by 맑은청이 2020. 7. 31.
728x90
반응형

https://com24everyday.tistory.com/222

 

시스템해킹 nano 통해 어셈블리코드 실행

vi 을 많이 써봤어도 nano는 써본 적이 없어서 신기했습니다. 단축키 정리는 이 블로그가 좋은 거 같습니다. https://junistory.blogspot.com/2017/08/nano.html nano에디터 소개 및 사용법 Web개발, 웹디자인, 웹..

com24everyday.tistory.com

여기서 볼 수 있었던 다음 코드가 64비트 운영체제에서 어떻게 동작하는지, 레지스터들을 배워보고 알아보고 그 레지스터들이 동작되기 위해 사용되는 시스템 콜에 대해서 알아보겠습니다.  (마지막 줄에 syscalls 이 아닌 syscall을 해야합니다)

https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/x64-architecture

 

x64 Architecture - Windows drivers

x64 Architecture

docs.microsoft.com

위 링크에 들어가면 마이크로소프트에서 64비트 운영체제에 대한 정보가 나와 있습니다.

 

레지스터들은 각자 역할들이 있는데 반드시는 아니지만 지켜주시는 것이 좋습니다. 

 

'rax' - 가장 중요한 레지스터로 시스템 콜의 실질적 번호를 가리키는 번호, 함수 결과값이 담기는 레지스터

'rbx' - base register로 메모리 주소를 지정할 때 사용

'rcx' - 보통 반복문에 사용 

'rdx' - 데이터 레지스터로 연산 수행할 때 rax 와 많이 사용함

 

여기 위 네개의 레지스터를 '데이터 레지스터'라고 합니다.

 

다음 네개는 '포인터 레지스터' 입니다. 이 레지스터들은 특정한 주소를 가리킵니다. 

'rsi' - 메모리를 이동하거나 비교할 때 출발주소을 가리키는데 사용 

'rdi'- 메모리를 이동하거나 비교할 때 목적지 주소를 가리키는데 사용 

'rbp' - 함수 파라미터나 주소를 가리킬 때 사용

'rsp' - 중요, stack의 삽입 및 삭제 명령어에 의해서 변경되는 스택 가장 위를 가리키는 포인터 

 

이런 레지스터를 통해서 어셈블리 코드를 이해할 수 있습니다.  

 

그리고 r8,r9 등의 레지스터가 있습니다. 이는 함수의 매개변수로 많이 사용됩니다. 

 

 

이제 시스템 콜에 대해 살펴보겠습니다. 

https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/

 

Linux System Call Table for x86 64 · Ryan A. Chapman

Linux 4.7 (pulled from github.com/torvalds/linux on Jul 20 2016), x86_64 Note: 64-bit x86 uses syscall instead of interrupt 0x80. The result value will be in %rax To find the implementation of a system call, grep the kernel tree for SYSCALL_DEFINE.\?(sysca

blog.rchapman.org

다음 블로그의 시스템 콜 함수에 대해 정보를 알 수 있습니다.

확인하시면 다양한 함수들이 커널에서 만들어져있습니다. 

시스템 콜을 불러오기 전에 %rax의 값에 따라 어떤 함수를 불러올지 결정하게 됩니다. 만약 '0' 이 %rax 에 들어 있다면 sys_read 함수가 실행되겠죠. 또 이 함수들의 매개변수가 필요합니다.  

 

'1' 의 값이 들어있어서 sys_write 가 실행되면 %rdi 에 파일 디스크립터가 담기게 되고(나중에 배움) 쓰고 싶은 내용을 %rsi 에 담고 그 길이를 %rdx 에 담습니다. 

 

실제로 코딩할때 이렇게 테이블을 참조하여 코딩을 하면 됩니다. 그럼 위 코드를 다시 볼까요? 

.data 영역에 'Hello World' 라는 문자를 만들어 놓고 이를 가리키는 포인터 변수로 msg 를 선언합니다. 

.text 영역에 가장 첫번째로 시행되는 _start 함수 선언

 

rax 에 1을 담음으로써 sys_write 를 불러올 걸 알려주고 

rdi 에 1을 담음으로써 어떤 것을 출력한다는 걸 매개변수로 알려주고 

rsi 에 msg 을 담아서 출력할 문자를 매개변수로 넣어주고 

rdx에 12를 넣어서 충분한 길이를 매개변수로 넣어주고

syscall을 출력합니다. 

 

그럼 밑에 있는 건 뭘까요?

rax 에 60을 넣어줬네요. 60은 어떤 시스템콜을 부르는 건지 확인해보겠습니다.

프로그램을 종료하는 거네요.  그리고 rdi 에는 error_code 를 넣어주는데요. 여기서는 0을 넣어서 그냥 안전하게 종료를 하면 됩니다. 

728x90
반응형