티스토리 뷰
해당 포스트는 기본적으로 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를 더한다.
'Reversing > Assembly' 카테고리의 다른 글
[Assembly] 순서없이 배우는 MIPS 개념정리. (1) | 2020.04.08 |
---|---|
[MASM] MASM으로 구현하는 32Bit Trampoline API Hooking (0) | 2020.03.16 |
[MASM] MASM으로 작성한 SetWindowsHookEx을 이용한 DLL Injection. (0) | 2020.03.11 |
[MASM] MASM(Microsoft Assembler) 시작하기 (x32, x64) (0) | 2020.03.10 |
[Reversing] 어셈블리 정리(1) (0) | 2019.05.13 |