ARM Assembly










  • ARM(Advanced Risc Machine)

x86 으로 대표되는 CISC 라인과는 반대인 최근에는 모바일이 대세가 되면서 ARM(RISC) 프로세서도 많이 사용되고 있다. 모바일 점검을 하다 보면 간혹 ARM 리버싱을 하게 되는 일이 있기도 하지만 이미 몇년 전 부터 CTF 에서도 ARM플랫폼 문제가 종종 나오고 있기 때문에 ARM 아키텍쳐에 대해서 정리해 보려 한다.


  • Thumb 모드 / ARM 모드
  ARM 과 x86 의 가장 큰 차이점은 Thumb 모드라는 것이 있다는 것이다. ARM 자체가 모바일/임베디드 등 PC 와는 다른 환경에 맞춰서 설계했기 때문에 저전력이 핵심 기술 중 한가지였고, 또 한가지로 처음 설계될 당시 임베디드 계열에서는 32비트가 아닌 16비트가 대세였다고 한다. 이러한 여러가지 상황에 맞추기 위해 2가지 모드를 지원하게 되었고, 리버싱을 할 때에도 이 부분을 고려해야 한다. 쉘코드를 작성할 때에도 당연히 바이트 수를 줄이기 위해 Thumb 모드로 작성하는 것이 좋다. 

  • ARM 모드
-   레지스터 : R0 ~ R15 (16개)
-   기계어코드 길이 : 32비트 (4바이트)

  • Thumb 모드 

-   레지스터 : R0 ~ R7 (8개)
-   기계어코드 길이 : 16비트 (2바이트)

  • Thumb <-> ARM 모드 전환

-    BLX / BX 등 X 로 끝나는 분기문 명령으로 모드 전환 




  • 레지스터
레지스터는 x86 과 상당한 차이점이 있다. 일단 범용 레지스터의 수가 더 많으며, x86 에는 존재하지 않는 Link Register 가 존재한다.  

  •   R0 ~ R12   :   범용 레지스터, 인자값 및 임시 계산 저장소 등
  •   R13(SP)     :   Stack Pointer, x86 의 ESP 와 비슷한 역할 수행
  •   R14(LR)     :   Link Register, 함수 호출 전 LR 에 리턴 주소를 저장하고 점프함(함수 호출 시 리턴주소 스택 활용 X)
  •   PC              :   x86 에서의  EIP 레지스터와 동일한 역할 수행. 다음에 실행할 코드의 주소 저장



  • Calling Convention(함수 호출 규약)
x86 에서는 cdecl, fastcall, stdcall 등의 다양한 함수 호출규약이 존재했으나, 
  •   R0 ~ R12   :   범용 레지스터, 인자값 및 임시 계산 저장소 등
  •   R13(SP)     :   Stack Pointer, x86 의 ESP 와 비슷한 역할 수행



  • 실습환경
  • NDK 10   :   Android NDK Version.10
  • IDA Pro   :   디스어셈블 및 분석
  • GDB        :   디버깅
  • ARM 장비:  안드로이드 스마트폰(베가 아이언), OS 버전 4.4   


  • 리버싱 기본
  • 예제 소스  :   test.c       //     기본 api 들을 호출하는 간단한 프로그램    


  • 컴파일 :  디버그 정보를 포함하여 컴파일(기본적으로 ndk-build 는 strip 바이너리를 생성함)

  • # ndk-build NDK_DEBUG=1 
  • .

    ├── jni

    │   ├── Android.mk

    │   └── test.c

    ├── libs

    │   └── armeabi

    │       ├── gdb.setup

    │       ├── gdbserver

    │       └── test    //  stripped binary

    └── obj

        └── local

            └── armeabi

                ├── objs

                │   └── test

                │       ├── test.o

                │       └── test.o.d

                ├── objs-debug

                │   └── test

                │       ├── test.o

                │       └── test.o.d

                └── test     //   strip 되기 전의 디버깅 심볼 포함 파일,  이 파일로 디버깅 진행 



  • IDA Pro 디스어셈블링(ARM 모드로 컴파일)




  • 상세분석

;int __cdecl main(int argc, const char  **argv,  const char **envp)

EXPORT main

main ; DATA XREF: _start+4Co .got:main_ptro


f = -0x70

test = -0x6C

var_8 = -8


STMFD SP!, {R11,LR}                  //  R11 과 LR 을 스택에 저장하고 SP 8 감소

ADD R11, SP, #4                             //  SP+4 를 한 뒤 R11 에 저장

SUB SP, SP, #0x70                        //  SP 70 감소                 

LDR R2, =_GLOBAL_OFFSET_TABLE_ ; PIC mode     // GOT 주소를 R2 에 저장

NOP                                              // 아무일도 하지 않음

LDR R3, =(__stack_chk_guard_ptr - 0xAFBC)  // 스택가드 offset 을 R3에 저장

LDR R3, [R2,R3] ; __stack_chk_guard   // GOT+스택가드offset 을 R3 에 저장

LDR R3, [R3]             // R3 주소의 값을 R3 에 저장(스택쿠키)

STR R3, [R11,#var_8]    // R3 값(스택쿠키)을  R11 + var_8 에 저장

SUB R2, R11, #-test      // test 변수

MOV  R3, #0x64

MOV R0, R2 ; s

MOV  R1, #0 ; c

MOV  R2, R3 ; n

BL memset

MOV R3, #0

STR R3, [R11,#f]


loc_8658 ; CODE XREF: main+A0j

SUB R3, R11, #-test

MOV  R0, R3 ; name

MOV R1, #0x28 ; len

BL gethostname

SUB R3, R11, #-test

MOV  R0, R3 ; s

BL puts

LDR R3, =(aTest_txt - 0x8680)

ADD R3, PC, R3 ; "test.txt"

MOV R0, R3 ; file

MOV  R1, #2 ; oflag

BL open

STR R0, [R11,#f]

LDR R0, [R11,#f] ; fd

LDR R3, =(a12345 - 0x869C)

ADD R3, PC, R3 ; "12345\n"

MOV  R1, R3 ; buf

MOV  R2, #6 ; n

BL write

LDR R0, [R11,#f] ; fd

BL close

MOV  R0, #3 ; seconds

BL sleep

B loc_8658

; End of function main


; ---------------------------------------------------------------------------

off_86B8 DCD _GLOBAL_OFFSET_TABLE_ ; DATA XREF: main+Cr

off_86BC DCD __stack_chk_guard_ptr - 0xAFBC ; DATA XREF: main+14r

off_86C0 DCD aTest_txt - 0x8680 ; DATA XREF: main+60r

; "test.txt"

off_86C4 DCD a12345 - 0x869C ; DATA XREF: main+7Cr

; "12345\n"




    • IDA Pro 디스어셈블링(Thumb 모드로 컴파일)
     





 

   

'Linux System Hacking' 카테고리의 다른 글

ARM-Thumb 모드 컴파일 옵션  (0) 2016.02.23
LD_PRELOAD 를 이용한 Hooking  (0) 2014.05.03

+ Recent posts