본문 바로가기

ARM아키텍쳐

[ARM] Hello World!_Part 2

저번에는 syscall을 이용하여 .s파일을 만들고 실행파일로 변경하여 Hello World! 문자열을 출력하는 어셈블리 소스 코드를 작성 하였다.

 

이번에는 libc functions을 이용하여 같은 동작을 하는 프로그램을 작성할 것이다.

 

 

stmfd sp!, {lr} //lr 값을 저장한다.

ldr r0, =string //첫번째 파라미터를 r0에 저장하므로 string의 주소를 r0에 저장한다.

bl printf //bl명령어로 printf 함수를 호출한다.

ldmfd sp!, {pc} //pc를 복구한다.

 

다음과 같이 syscall과는 차이가 있다. 가장 큰 차이는 main함수가 있고 bl 명령어를 통해 함수를 호출한다.

 

 

 

info proc mappings 명령어를 통해 libc shared library(libc-2.19.so)가 어디에 있는지 알려준다.

 

 

x/5i $pc 명령어를 통해 .s파일에 있던 어셈블리 명령어 코드를 볼 수 있다. 여기서 0x10428 주소에 있는 명령어는 PLT에 접근 할 수 있는 메모리 주소이다. PLT는 외부 프로시져를 연결해줄 수 있는  테이블로 PLT를 통해 다른  라이브러리에 있는  프로시져를 호출해 사용할 수 있다. 또한 GOT 영역으로 점프해 가는데 GOT 영역은 PLT가 참조하는 테이블로 함수들의 실제 주소가 쓰여있다. 

 

그럼 왜 처음부터 GOT로 가서 함수의 실제 주소를 참조하면 안되나? 라는 의문이 생길 수 있다.

 

소스 코드를 만들어서 컴파일 과정을 통해 오브젝트 파일을 만들면 그 파일 자체만으로는 파일을 실행 시킬 수 없다.

오브젝트파일에 있는 printf 같은 함수는 파일 안에서 구현이 되어 있지 않기 때문이다. printf와 같은 함수들이 정의 되어 있는 파일을 라이브러리라고 한다. 따라서 실행파일을 만들때는 오브젝트 파일이 라이브러리를 어떠한 방식으로든 참조를 해야한다. 여기서 참조를 링크 한다고 한다.

 

여기서 링크할 수 있는 방법에는 두가지가 있다. 첫번째는 Static linked방식이고 두번째는 Dynamic linked 방식이다. 

static linked방식은 오브젝트 파일 안에 라이브러리를 포함하여 실행파일을 만드는 것이다. 이러면 외부 참조 없이 실행 파일을 실행 시킬 수 있지만 파일이 커진다는 단점이 생긴다.

 

반면에 Dynamic linked 방식은 외부에 있는 라이브러리를 참조하는 것이다. 이런 방식은 파일의 크기가 줄어든다는 장점이 있지만 라이브러리 없이는 실행이 불가하다는 단점이 있다.

 

이때 Dynamic linked 방식으로 컴파일을 하면 PLT와 GOT를 사용하게 된다. 

그 이유는 라이브러리가 외부에 있기 때문에 함수의 주소를 알아오는 과정이 필요하기 때문이다.

 

그러나 gdb로는 함수의 got를 보는 방법을 모르겠다.

모르면 무조권 ida로 본다.

 

ida에서는 got영역도 보여준다. 여기서 예시로 read의 got 주소는 0x0002100C이다.

 

gdb로 본 read의 plt주소다.(0x10308)

 

결과적으로 bl 0x10308로 read의 plt로 점프하면 read@plt에서 jmp got(0x0002100C) 부분이 있다.

따라서 plt는 got를 가리키고 got의 주소에는 함수가 실질적으로 설계된 코드가 존재하는 것이다.

 

그래서 libc functions을 이용해서 Hello World를 작성하면 위와 같은 과정을 거친다.

'ARM아키텍쳐' 카테고리의 다른 글

[ARM] ROPlevel1  (0) 2020.05.04
[ARM] exploit RTL Chaining  (0) 2020.03.25
[ARM] Hello World!_Part 1  (0) 2020.01.08
[ARM] exploit_RTL  (0) 2019.12.22
[ARM] exploit_ROP  (0) 2019.12.22