ARM Assembly
http://recipes.egloos.com/5027277
http://armconverter.com/- 주소 부분이 0xffffff???
로 나올 때는 직접 수정해주면 된다.
- ARM assembly instruction은 기본적인 명령어에 추가적인 옵션을 덧붙여 사용하는 식으로 구성되어 있다.
- RISK라서 모든 instruction의 크기가 같다. 단, ARM mode와 Thumb mode로 나뉜다.
- 연산 방향은 ←
- arg/return value pass에 레지스터
r0-r3
와 stack을 사용한다. - i386/amd64와 달리 ARM에서는
pc
에 접근해 인자로 사용할 수 있을 뿐만 아니라 수정할 수도 있다. 그러나 여기서도push {pc}
는 안된다.
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
int f(int i){
putchar('a');
putchar('\n');
return i;
}
int main(){
printf("%p\n", f);
\_\_asm\_\_ \_\_volatile\_\_(
"mov r0, #1 \n\t" // pass arg
"bl 0x83f5 \n\t" // call 0x83f5
// "bl f \n\t" // 0x83f5 == f
/\* "ldr r2, =0x83f5 \n\t"
"blx r2 \n\t" \*/
);
printf("return back\n");
return 0;
}
shellcode를 만드는 경우, 쉘코드 실행을 마치고 원래 진행하던 부분으로 돌아갈 수 있게 push {lr} ... pop {pc}
를 반드시 적어주어야 한다.
b / bl
1
2
3
4
5
b addr // jmp addr
=> mov pc, =dest
bl addr // call addr
=> mov lr, =next instruction (pc) // lr == r14
=> mov pc, =dest
bx / blx
x : exchange
1
2
bx Rm
blx Rm || label
- Rm의 비트[0]이 0일 경우 프로세서가 ARM 상태로 변경되거나 ARM 상태를 유지한다.
- Rm의 비트[0]이 1일 경우 프로세서가 Thumb 상태로 변경되거나 Thumb 상태를 유지한다.
ldr(load) / str(store)
* str
만 연산 방향이 반대. * Rn == pc
일 때는 update를 방지하기 위해 write back 연산자 !
를 사용할 수 없다.
1
2
3
4
5
6
7
8
9
10
str Rd, [Rn, #offset] // \*(Rn+offset) = Rd's value
ldr Rd, [Rn, #offset] // Rd's value = \*(Rn+offset)
ldr Rd, [Rn, #offset]! // Rn=Rn+offset으로 update 후, Rd's value = \*(Rn) {pre-indexed 방식}
ldr Rd, [Rn], #offset // Rd = \*(Rn) 후, Rn = Rn+offset으로 update {post-indexed 방식}
ldr Rd, 0x800a12ab // Rd's value = \*0x800a12ab
// 아래는 pseudo-instruction. compile 시 위 형식 또는 mov...로 변환된다.
ldr Rd, =0x800a12ab // Rd's value = 0x800a12ab
=> mov Rd, #0x800a12ab // 단, 직접 이렇게 넣으면 mov의 operand 크기 제한 때문에
// 제대로 동작하지 않을 수 있음. 그래서 pseudo-instruction이 있는 것.
NOP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[ARM A32] ( arm )
NOP ==> 0x00000000
mov r0, r0 ==> 0xe1a00000
mov r1, r1 ==> 0xe1a01001
mov r2, r2 ==> 0xe1a02002
... r3-r9, sl, fp, ip, sp(r13), lr(r14)
mov pc, pc ==> 0xe1a0f00f
[ARM T32 - 16 bit] ( Thumb )
NOP ==> 0xb000
mov r8, r8 ==> 0x46c0
[ARM T32 - 32 bit] ( Thumb )
NOP ==> 0xf3af 8000
[ARM A64 - 64 bit] ( ARMv8-A == AArch 64 )
NOP ==> 0xd503201f
This post is licensed under CC BY 4.0 by the author.