ARM 그렇고 말고 #3

7057 단어 ARMARM

Overview

이번 글에서는 ARM binary가 주어졌을 때 어떻게 이를 debugging 할 것인지를 주로 다루어 볼 것입니다. Debugging에 관한 글을 세 번째로 작성하는 이유는 ARM 환경에서 개발을 목적으로 공부하는 것이 아니기 때문에 대부분의 경우 binary가 제공된다고 가정하기 때문입니다.


QEMU

먼저 debugging을 위해서 필수적으로 필요한 요소 중 하나로 qemu가 있습니다. qemu에 대해 간략하게 설명을 하자면 가상화 솔루션 중 하나로 VMware, Virtumal Box 등과 가장 큰 차이점 한 가지를 꼽자면 다른 architecture 또한 구동할 수 있다는 점입니다.

즉, qemu를 사용하지 않으면 intel binary는 intel cpu에서, ARM binary는 ARM cpu에서 진행해야 하지만 이를 활용하면 다양한 arhictecutre를 하나의 PC에서 구동할 수 있습니다. ARM 뿐만 아니라 MIPS, PowerPC 등 매우 다양한 환경을 지원합니다.

아마 위 내용을 들으면 다음 비교대상으로 docker가 떠오를 수도 있습니다. 마찬가지로 docker 또한 모든 architecture는 아니어도 ARM의 경우 container를 다운로드 받아 구동이 가능하기 때문에 만약 docker를 사용하고 계시다면 이 부분이 접근성이 편하다고 느껴질 수도 있습니다.

qemu의 두 번째 장점은 debugging이 용이하다는 것입니다. 이후 자세한 옵션을 설명하면서도 다룰 얘기이지만 옵션 자체에서 gdbserver와 같은 역할을 할 수 있는 것을 제공하기 때문에 특정 binary를 대상으로 debugging을 수행할 경우 간편하게 실행할 수 있다는 장점이 있습니다.

장단점은 어디까지나 개인의 활용도에 따라 나뉠 수 있지만 ARM 뿐만 아니라 앞으로 다양한 분석을 함에 있어서도 배워둘 필요가 있다고 생각하여 qemu를 사용하기로 결정하였습니다.

qemu의 설치 방법은 다양하지만 이 글에서는 ubuntu 기준에서 작성되었습니다.

Install

설치 방법은 크게 두 가지로 분류할 수 있습니다. apt-get 을 이용한 방법과 git clone 을 이용한 방법이죠. 우선 이 글에서는 apt-get 을 이용하는 방법으로 설치를 진행하였습니다. 설치에 필요한 항목은 다음과 같습니다.

apt-get install qemu qemu-user-static -y
reboot

설치를 완료한 뒤 재시작을 진행하여야 명령어를 자동 완성을 통해 사용 가능합니다. 기본적으로 명령은 /usr/local/bin 에 저장되어 있습니다. 설치할 때의 경우 arm과 aarch64의 구분이 필요하지 않으나 설치 이후에는 아래와 같이 명령에 차이가 존재합니다.

32bit ARM의 경우 arm, 64bit ARM의 경우 aarch64 라는 이름으로 구분됩니다 :)

32bit의 경우 :: qemu-arm-static <arguments>
64bit의 경우 :: qemu-aarch64-static <argument>

이것으로 qemu의 설치 및 초기 설정은 완료되었습니다.


Other Package

Debugging을 진행하기 위해서는 qemu 외에 추가적으로 설치가 필요한 패키지가 존재합니다. 먼저 공통적으로 설치가 필요한 항목은 gdb-multiarch 패키지입니다. 이 패키지는 다른 architecture를 debugging 하고자 할 때 사용할 수 있습니다.

다음으로 설치할 패키지는 OS에 따라 다른 패키지를 설치할 필요가 있습니다. 32bit의 경우 gcc-arm-linux-gnueabi 를, 64bit의 경우 gcc-aarch64-linux 를 다운받으면 됩니다. 한 가지 강조 겸 얘기하자면 OS를 구분하는 기준은 debugging target binary 를 기준으로 합니다.

최종적으로 다운로드가 필요한 항목은 gdb-multiarch + <gcc-arm-linux-gnueabi | gcc-aarch64-linux> + a 가 됩니다.


eabi

32bit용 설치 패키지 중 gnueabi 라는 내용이 있는 패키지가 있습니다. eabi가 무슨 뜻인지 정확하게 몰라도 진행하는데 큰 문제는 없을 수 있지만 실제로 패키지 목록을 확인하면 gnueabi 외에도 gnueabihf 등 비슷한 이름이 존재하기에 어떤 내용인지 간략하게 짚고 넘어갔습니다. 링크1링크2에서 자세한 내용을 확인할 수 있습니다. 완벽하게 이해하지는 않더라도 어떤 것을 의미하는지는 알고 넘어가는 것이 도움이 될 수 있다고 생각합니다.


Debugging

필요한 패키지가 모두 설치되었다면 이제 debugging을 하는 방법을 알아보겠습니다.

gdbserver

기존에 ELF binary를 분석한다고 하면 로컬에서 gdb를 사용하여 진행하였습니다. 그러나 qemu를 사용한 debugging 방식은 gdbserver를 사용하여 target binary를 원격으로 접속할 수 있게끔 한 뒤, 이를 gdb 내의 명령어로 접근하는 방식으로 진행해야 합니다.

물론 여기서는 gdbserver를 통해 실행하는 것이 아닌 qemu에서 제공하는 옵션을 통해 gdbserver와 같은 기능을 수행할 것 입니다. 꼭 qemu의 옵션을 활용하는 것이 아니라도 gdbserver를 사용하여 Windows PC에 설치되어 있는 IDA에서 동적 디버깅을 진행하는 등 활용도가 높은 기능이기에 숙지해두는 편이 좋을 것 같습니다.

QEMU Options

Arhitecture와 관계없이 사용되는 옵션은 동일하기 때문에 먼저 옵션에 대한 설명을 진행하겠습니다.

  • Run QEMU
    qemu-<architecture>-static

가장 기본적으로 qemu를 실행하기 위해 사용되는 명령어입니다.

  • Set LD Path
    -L <Path>

qemu를 통해 구동되는 binary의 경우 host와 다른 library를 사용하기 때문에 적합한 LD 위치를 지정하는 옵션입니다. 주로 해당 옵션의 경로는 /usr 밑에 존재하며 추가 패키지 설치 과정에 따라 상세 경로에는 차이가 있을 수 있습니다.

  • Set gdbserver port
    -g <port number>

해당 옵션을 통해 지정된 port로 접속하면 gdbserver와 동일한 결과를 얻을 수 있습니다. debugging을 위해 별도로 shell을 실행할 필요가 없이 대기 상태로 동작시킬 수 있습니다.


Example

예시에서는 debugging server를 여는 법과 이를 gdb에서 접속하는 법까지 포함하여 정리하였습니다.

32bit

- debugging 시작
qemu-arm-static -L /usr/arm-linux-gnueabi -g 1234 ./binary32

- remote 연결
gdb-multiarch -q ./binary32
set architecture arm
target remote localhost:1234

64bit

- debugging 시작
qemu-aarch64-static -L /usr/aarch64-linux-gnu -g 1234 ./binary64

- remote 연결
gdb-multiarch -q ./binary64
set architecture aarch64
target remote localhost:1234

Reference

좋은 웹페이지 즐겨찾기