티스토리 뷰

반응형
해당 포스트는 기본적으로 Register 등의 지식이 있다고 가정하여 작성되었다.
순서없이 리버싱에 도움이되는 간단한 Assembly 문법에 대해서만 나열했다.

 

# Thumb Mode

 x86 아키텍쳐와 다르게 ARM 아키텍쳐에만 존재하는 Thumb 모드 !!

 Thumb Mode는 ARM Mode의 반쪽짜리 Version이라고 볼 수 있다. 원래 ARM은 32bit RISC machine이고, 32bit로 동작하는게 가장 최상의 Performance를 제공할 수 있다. Machine마다 word size가 다르다. word size는 CPU가 한번에 처리할 수 있는 크기를 말한다.

 

 근데 어째서 32bit ARM에 16bit Thumb Mode가 포함된걸까...?

 개발 당시 16bit data line을 가진 Memory를 사용하는 Embedded System이 많았기 때문이다.

 

 ARM Mode와 가장 큰 차이점이라고 하면 저전력, 16bit, Register의 수(8개)가 있다.

 모든 명령어는 기계어로 2Byte이기 때문에 쉘 코드의 Byte수를 감소시키기 위해서 사용될 수도 있다.

 

 

# Register 

 R0, R1, R2 ... R12 : 범용 레지스터. 특히 R0은 함수의 반환값을 저장하는 용도로 사용된다.

                                                       ( x86의 EAX와 같은 역할을 수행한다고 생각하면 될 것 같다. )

 R13 (SP) : Stack Pointer ( x86의 ESP와 같은 역할을 수행한다. )

 R14 (LR) : Link Register ( x86에는 없는 특이한 녀석인데 함수 호출시 반환되어 돌아오는

                                  주소를 저장하기 위한 레지스터이다. x86에선 Stack에 저장을 했다. )

 R15 (PC) : Program Counter ( x86에서 EIP와 같은 역할을 수행한다. )

 

 ARM 아키텍쳐에서는 총 7개의 서로다른 Mode가 존재하는데, Mode에 따라 서로 다른 레지스터를 사용하게 된다. 무조건적으로 모든 레지스터가 서로 다르지는 않고 일부 레지스터들은 공유해서 사용하기도 한다.

따라서 총 7개의 Mode에서 총 37개의 Register을 사용하게된다.

 

부가설명을 하자면 각 Mode의 전환은 주로 Exception 상황에서 발생하게된다.

 

 

# 함수호출규약 

 R0 ~ R3 : 인자 및 반환 값을 저장하기 위한 Register로 사용된다.

               그러나 인자의 수가 4개 이상일 경우 Stack을 통해 인자를 전달한다.

 

 

# 지역변수활용

 R4 ~ R11 : 사용시 Stack에 기존 데이터를 저장 후 사용하고,

                사용을 마친 후에 원상복귀 과정을 거치게 된다.

 

 

# 데이터 이동 명령어 ( MOV, MVN )

 MOV R1, #92

 MOV R1, R5                 - Rd = N

 ( MOV는 조금 뻔하누..? 상수에 #을 붙이는 것만 빼면 똑같다. )

 

 MVN Rd, [ 값 또는 레지스터 ]              - Rd = ~N

 ( MOV와 동일하지만 Operand2에 비트 연산 NOT을 수행한 후 Rd 에 저장한다. )

 

 MOV Rd, N, LSL #2

 ( 이와 같은 형태로 사용될 수 있다는 것만 기억하자. )

 ( Shift 연산자를 N에 대해 수행하고 그 수행된 결과를 Rd에 저장한다. )

 ( Shift 연산자에는 LSL, LSR, ASR, ROR 등이 존재한다. )

 

 

 

# CPSR ( Current Program Status Register )

 ARM 아키텍쳐에서 Flag에 해당하는 정보를 저장하고 있는 Register이다.

우선은 N, Z, C, V 에 대해서만 기억을 하고 넘어가자.

 

 

 

# 비교명령어 ( CMN, CMP, TEQ, TST )

 " 기본적인 사용 포맷 "

  [ 명령어 Rd, Operand2 ]

 

CMN : 음수 비교, Operand2에 -1을 곱해서 CMP 명령어를 수행한다.

  ( Rd + Operand2 한 결과로 Flag를 갱신한다. )

CMP : 기본적으로 x86 아키텍쳐에서 사용하던 CMP 명령어와 동일한 역할을 수행한다.

  ( Rd - Operand2 한 결과로 Flag를 갱신한다. )

TEQ : 두 Operand를 XOR하여 결과에 대해서 Flag를 갱신한다.

  ( Rd ^ Operand2 한 결과로 Flag를 갱신한다. )

TST : x86 아키텍쳐에서 사용하던 Test 명령어와 동일한 역할을 수행한다.

  ( Rd & Operand2 한 결과로 Flag를 갱신한다. )

 

 

 

# 분기명령어 ( B, BL, BX, BLX )

 B : [ B label ] 의 형태로 사용되며 단순하게 PC를 label로 변경한다.

     함수의 호출형태가 아니라 단순히 JMP에 해당한다. 주로 조건부 분기에서 조건과 같이 사용된다.

 

 BL : [ B label ] 의 형태로 PC를 label로 변경하는 것까지는 B와 동일하지만,

      LR을 현재 명령어의 다음명령어 주소로 변경한다는 것이 차이점이다.

      서브루틴(함수) 호출 분기시 사용되는 명령어이다.

 

 BX, BLX : ARM/Thumb 모드 전환시 사용되는 분기문이다. 내용은 위와 동일하다.

 

 [ 조건부 ..? ]

  주로 B 명령어와 결합되어 사용된다.

  EQ, NE, GE, GT, LE, LT, MI, PL, AL ...  이외에도 많지만 이정도만 기억하자.

    ( 일일히 해석은 달지 않을 예정이다. 이것만 보고도 뭔지 감을 잡을수 있어야한다. )

 

 

 

# 메모리에 읽고 쓰는 명령어

 ( LDR, LDRB, LDRH, LDRSB, LDRSH )

 ( STR, STRB, STRH )

 

 LDR, STR이 기본적으로 4Byte에 해당하는 명령어이며, 뒤에 붙는 B는 1Byte, H는 2Byte에 대해 명령어를 수행할 경우에 접미사로 붙여주게된다. LDR은 메모리에서 레지스터로, STR은 레지스터에서 메모리로 데이터를 전달할 때 사용되는 명령어들이다.

 

 

 

# 메모리 Indexing 하는 법

 1. PreIndexing : [ r1, #4 ] : r1에 4Byte를 더한 주소를 나타낸다.

 2. PostIndexing : [ r1 ], #4 : r1을 통해 명령어를 실행한 후 다음 명령어로

                                        넘어가기 전에 4Byte를 r1에 더한다.

 3. AutoIndexing : [ r1, #4 ]! : PreIndexing과 PostIndexing을 더한 것 처럼 동작한다.

                                        r1에 4Byte를 더한 주소를 통해 명령어를 실행하고,

                                        다음 명령어로 넘어가기 전에 r1에 4Byte를 더한다.

 

 

 

 

 

반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함