모의해킹

주요 어셈블리(Assembly) 명령어 요약

logthink 2020. 2. 19. 20:55

어셈블리언어에 대해 저는 굉장히 약한 편이라...이번에도 스크랩을 통해 조금씩 정리량을 늘려갈 계획입니다.


다만, 말씀드리고 싶은건 굉장히 좋은 자료를 찾았습니다.


강추https://www.yumpu.com/en/document/read/36855107/realview-compilation-tools-iiee-iei-arm-information-


파일 : 

Android SO Helper (ARM 어셈블리어 변조 Tool) 분석 보고서.pdf


간단히 어셈블리어에 대해 나열해보자면, 다음과 같습니다. 


eax 

 리턴값 저장

 ebx 


 간접주소 저장

 ecx 

 반복카운터 저장

 edx eax 

 초과분

 ebp 

 스택프레임 기준점

 esp 

 스택 최상단

 esi 

 출발주소

 edi 

 도착주소

 eip

 다음 실행될 주소

 efl 

 상태값 저장 1:셋팅 0:클리어

어셈블리의 대표적인 종류는 ARM, x86 이 있죠?


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, CBZ, CBNZ


BL은 분기 명령이다.


B there ; 라벨이 there인 곳으로 무조건 분기한다.


BL sub+ROM ; 계산된 위치의 서브루틴을 호출한다.


BNE(0이 아닌 경우 분기)와 BEQ(0이면 분기는 branch 명령어이고 CMP는 비교 명령


어이지만 둘이 같이 쓰이는 경우가 많으므로 한꺼번에 설명한다.


CMP r1, #4 ; r1이 4이면 플래그가 0으로 셋팅된다.


BEQ there ; 플래그가 0이면 라벨이 there인 곳으로 분기하고그렇지 않으면


다음 명령어가 수행된다.


CBZ(Compare and Branch on Zero) 와 CBNZ(Compare and Branch on Non-Zero) 명령에 대해 설명한다.


*Thumb-II 명령어

 

CBZ : Compare and Branch on Zero


CBZ 명령은 "CBZ Rn, label" 과 같은 문법 구조를 가집니다.


Rn의 값이 "0x0"이면 label로 분기하고,


Rn의 값이 "0x0"이 아니면, 다음 번지로 진행합니다.


자세한 것은 아래의 예를 통해 확인해 보시기 바랍니다.


CBZ(Compare and Branch on Zero) 명령으로 비교한 레지스터 값이 0x0이 아닌 경우


아래의 "CBZ R1, 0x08000E56" 의 명령을 수행하는 시점에서, R1의 값은 0xA입니다.


결과적으로 R1!=0x0 이므로 분기 명령이 수행되지 않고, 다음 번지인 0x0800_0E50 으로 진행하게 됩니다.



CBZ(Compare and Branch on Zero) 명령으로 비교한 레지스터 값이 0x0인 경우


아래의 "CBZ R1, 0x08000E56" 의 명령을 수행하는 시점에서, R1의 값은 0x0입니다.


결과적으로 R1==0x0 이므로 0x0800_0E56번지로 분기 명령이 수행됩니다

CBNZ 명령은 "CBNZ Rn, label" 과 같은 문법 구조를 가집니다.


Rn의 값이 "0x0"이 아니면 label로 분기하고,


Rn의 값이 "0x0"이면, 다음 번지로 진행합니다.

 

CBNZ(Compare and Branch on Non-zero) 명령으로 비교한 레지스터 값이 0x0이 아닌 경우


아래의 "CBNZ R0, 0x08000124" 의 명령을 수행하는 시점에서, R0의 값은 0x42입니다.


결과적으로 R0!=0x0 이므로 분기 명령이 수행되어 0x0800_0124 번지로 분기하게 됩니다.


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. LDMFD, STMFD


LDM/STM은 LDR/STR의 변종으로 블록 단위로 load/store 할 때 사용한다중요한 용도


는 스택에 레지스터 값을 저장하거나 복원하는 것이다왜냐하면 스택에 저장/복원할 때


는 여러 개의 레지스터를 저장/복원해야 하기 때문이다.


스택과 관련해서는 LDMFD/STMFD, LDMED/STMED, LDMFA/STMFA, LDMEA/STMEA 


이 사용되고스택과 관련없이 사용할 때는 LDMIA,LDMIB, LDMDA, LDMDB, STMIA,


STMIB, STMDA,STMDB 가 사용된다.


중요한 것은 스택과 관련해서 실제 사용할 때쌍으로 사용한다는 것이다.


LDMFD/STMFD 정도만 잘 사용하면 된다자세한 사항은 ADS 문서를 참고하기 바란다.


STMFD sp!, {r4-r6, lr} ; 스택에 r4-r6와 lr 레지스터를 저장하고 sp를 그만큼 감소시킨다.


LDMFD sp!, {r4-r6, pc} ; 스택에서 r4-r6와 pc를 복원하고 sp를 그만큼 증가시킨다.



ARM Developer Suite(ADS) 1.2 
에서 코드와 ASM 코드 섞어 쓰기


1. C 코드 내에 어셈블리 코드를 inline으로 사용하기


(1) 사용방식

asm("instruction[;instruction]");

또는 C 컴파일러의 구문을 사용하면 다음과 같다.

__asm

{

instruction [; instruction]

...

[instruction]



>>출처


1) 어셈블리 블로그 글 

http://achiven.tistory.com/entry/%EC%A3%BC%EC%9A%94-ARM-%EC%96%B4%EC%85%88%EB%B8%94%EB%A6%AC-%EB%AA%85%EB%A0%B9


2) 한컴 정리 

http://trace32.com/wiki/index.php/CBZ_and_CBNZ


3) 설명을 잘 한 블로그

https://kimhyun2017.tistory.com/79


4) 바이너리 코드 변조 쉽게 설명

http://linforum.kr/bbs/board.php?bo_table=ios&wr_id=15

5) Black Palcon 블로그

https://speedr00t.tistory.com/entry/Android-SO-Helper-ARM-%EC%96%B4%EC%85%88%EB%B8%94%EB%A6%AC%EC%96%B4-%EC%BD%94%EB%93%9C-%EB%B3%80%EC%A1%B0-Tool-%EB%B6%84%EC%84%9D-%EB%B3%B4%EA%B3%A0%EC%84%9C

6) x86, ARM 레지스터 등 어셈블리 정리(강추)