-
ARM/ARM64 어셈블리#1 - Security/Reversing 2020. 5. 20. 08:05
1. MOV
ARM 어셈블리 명령어는 MOV 명령어와 논리 및 사칙연산 명령어에 모두 쉬프트 연산이
가능한데, 이것을 나타내는 표지가 끝에 붙을 수 있다는 것에 유의한다.
쉬프트 연산에는 ASR(오른쪽 쉬프트, 빈자리는 부호가 따라옴),
LSR(오른쪽으로 쉬프트, 빈자리는 0으로 채워짐),
LSL(왼쪽으로 쉬프트, 빈자리는 0으로 채워짐),
ROR(오른쪽으로 rotation )
정도를 알아두면 유용하다.
예)
MOV r0, [r2,r4] ; r2+r4 의 주소에 있는 값을 읽어서 r0에 저장한다.
MOV r1, r2, ROR #1 ; r2를 오른쪽으로 한 비트만큼 rotation 해서 r1에 저장
2. ADD, SUB, AND, ORR
예)
ADD r1, r2, #4 ; r2에 4를 더해서 r1에 저장
SUB r1, r1, #1 ; r1의 값을 하나 감소
ORR r4, r5, r7, LSR r2 ; r7을 오른쪽으로 논리 쉬프트를 r2만큼 한다음 그 결과를
; r5와 or 연산하여 r4에 저장한다.
3. UMULL, SMULL
곱하기 연산이다. 32비트짜리 두 개를 곱하면 64비트짜리가 나오므로 결과값을 저장하는
데 두 개의 레지스터가 필요하다. 결과 레지스터의 위치에 주의한다. UMULL은 부호가
없는 곱하기이고, SMULL은 부호가 있는 곱하기 이다.
예)
UMULL r4, r5, r1, r2 ; r1과 r2를 곱해서 상위 32비트는 r5에 저장하고 하위 32비트는
; r4에 저장한다.
5. B, BL, BNE, BEQ, CMP
BL은 분기 명령이다.
예)
B there ; 라벨이 there인 곳으로 무조건 분기한다.
BL sub+ROM ; 계산된 위치의 서브루틴을 호출한다.
BNE(0이 아닌 경우 분기)와 BEQ(0이면 분기) 는 branch 명령어이고 CMP는 비교 명령
어이지만 둘이 같이 쓰이는 경우가 많으므로 한꺼번에 설명한다.
예)
CMP r1, #4 ; r1이 4이면 플래그가 0으로 셋팅된다.
BEQ there ; 플래그가 0이면 라벨이 there인 곳으로 분기하고, 그렇지 않으면
; 다음 명령어가 수행된다.
6. LDR, STR
LDR은 load 명령이다. LDR에는 불러오는 변수의 크기에 따라 LDRB, LDRH, LDR의 세
가지 종류가 있다. LDRB는 byte 변수를 불러올 때, LDRH는 short 변수를 불러올 때,
LDR은 int 변수를 불어올 때 쓴다. STR는 store 명령으로 마찬가지로 STRB, STRH, STR
이 있다.
첫 번째 인자는 레지스터가 두번 째 인자는 주소가 된다. 세 번째 인자는 load/store 연
산을 한 다음 주소값을 증가시키고자 할 때, 얼마만큼 증가시킬 지를 지정한다.
예)
LDR r1, [r2, #16] ; r2에 16 byte만큼 더한 주소에서 정수형 값을 읽어와 r1에 저장한다.
STR r1, [r2], #4 ; r2의 주소에 r1을 저장하고 난 후, r2를 4만큼 증가시킨다.
7. CBZ, CBNZ
CBZ 명령은 "CBZ Rn, label" 과 같은 문법 구조이다.
Rn의 값이 0x0이면 label로 분기하고,
Rn의 값이 0x0이 아니면, 다음 번지로 진행합니다.
CBNZ 명령은 CBZ와 반대로
Rn의 값이 0x0이 아니면 label로 분기하고,
Rn의 값이 0x0이면 다음 번지로 진행한다.
출처 :
'#1 - Security > Reversing' 카테고리의 다른 글
[Frida] Hooking ws2_32.dll (send) (0) 2020.05.27