Phantom

ARMv1 본문

Pwnable/ARM, MIPS

ARMv1

Ph4nt0m_ 2018. 7. 4. 23:15
반응형
Arm 공부에 앞서.... qemu로 Arm을 구동하기 위해 구동법부터 적겠다.


sudo apt-get install qemu

실행 방법
qemu-system-arm -M vexpress-a9 \
    -kernel vmlinuz-3.2.0-4-vexpress \
    -initrd initrd.img-3.2.0-4-vexpress \
    -drive if=sd,file=debian_wheezy_armhf_standard.qcow2 \
    -append "root=/dev/mmcblk0p2 console=ttyAMA0" \
    -redir tcp:2222::22 -redir tcp:8080::80\
    -nographic

이것에 대한 내용은 잘 모르겠다.

구동엔 성공했고 이제 어셈을 공부할 차례다
Arm apt 레포가 debian이라그런가 좀 느렸다.

참조한 문서는 구동- link
2013 인코그니토  Basic ARM Exploit
http://5kyc1ad.tistory.com/187 이다.

우선 간단한 Hello world출력 프로그램을 C로 짜고 디버깅을 했다.


Arm의 명령 구조는 총 세 단계의 구조를 가지는데 이것을 Instruction Pipeline이라고도 한다.
이 단계는 명령어를 메모리에 적재하는 Fetch,
적재된 명령어를 해석하는 Decode,
해석된 명령어를 실행하는 Execute로 나뉜다.

ARM에서는 이 세가지가 한번에 실행된다.
하나의 명령이 Execute되는 도중, 다음 명령어가 Decode되고 있으며, 그 다음 실행될 명령어가 적재(Fetch)되고 있다는 것이다. 한번에 +3라인을 읽어들인다.

ARM의 레지는 r0~r15까지 총 16개가 존재하는데, 
R0는 리턴값을 저장하는 역할을 한다. 그리고 또한
R0 ~ R3 레지스터 들은 함수 호출 시에 인자 전달목적으로 자주 사용되며 인자가 4개 이상이면 스택을 사용한다.
R11은 현재 스택 프레임의 Base Pointer를 저장한다.
R13은 Stack Pointer로 사용되며, 스택의 최상단을 가리킨다.
R14는 Link Register로 Return Address를 저장하고 있다. BL명령으로 서브루틴 호출 시 복귀할 주소를 저장한다. 다른 함수들의 EBP와 비슷하다.
R15는 Program Counter로 EIP와 같은 역할을 한다.

이제 위의 어셈을 분석해보자

push {r7, lr} - 스택에 값을 push하는데 lr, r7 순서로 적재된다 빨간색이 Link Register, 파란색이 r7.
함수 프롤로그에 해당한다.


sub sp, #8 - sp에서 8만큼을 뺀다. 공간을 8만큼 확보한다. 그리고 arm에선 상수에 #을 붙인다.

add r7, sp, #0 - 이것의 ARM의 특징중 하나인데 한번에 3개까지의 피연산자를 가진다.
r7(Rd)에 Rn+Rm를 더해서 저장하는 역할을 한다. 여기서는 sp와 0을 더해서 r7에 저장한다.

str r0, [r7, #4] - 이건 또 뭐냐......STR 명령은 명령어의 순서가 반대다. *(Rn+Rm)에 Rd를 집어넣는다.
그렇다면 r7의 값에 +4한부분에 Rd를 넣는다
여기선 r7은 0x7efffcb8 이고 +4를 한 곳 = 0x7efffcbc에 r0의 값인 1을 넣는다


거참 신기한 명령어이다.

str r1, [r7, #0] 역시 같은 명령어이다 r1에다 넣을 뿐

movw r0, #33808 - mov word의 약자이다. #33808 = 0x8410을 r0에 넣는다.

movt - 값을 Rd에 이동하는데 비트로 표현했을때 [31:16]에 immed_16값을 옮깁니다. Rd[15:0]에 영향을 주지 않습니다.

blx 0x82ec <puts> - Call과 비슷한 명령같은데 이 블로그 - link에 명언이 있었다.

   B _printf             ; _printf로 jump 하라
   BL  _printf           ; _printf로 jump를 히되 R14에 돌아올 주소를 넣고 가라.
                                돌아와야 되니까 R14 (LR)에 돌아올 주소를 꼭~ 넣어라~
   BX _printf            ; 현재 mode가 ARM이라면 Thumb으로 mode바꾸고 가고
                               Thumb라면 ARM으로 mode 잘 바꿔서 가라.
   BLX _printf           ; 위 두개의 짬뽕이다.

내 현재 모드는 잘 모르겠으나 모드를 바꾸고 R14 ebp역할을 하는 레지스터에게 주소를 넣고 함수를 Call한다.

mov.w r3, #0 - movw와같은 명령어인것 같다 r3에 0을 넣는다.
mov r0, r3 - r3을 r0에 넣는다.

add.w - add word의 약자같은데... r7 + #8값을 r7에 넣는다. 사용 공간을 축소시키는 걸로 보인다.
mov sp, r7 - r7값을 sp에 넣는다
pop {r7, pc} - pc, r7순으로 pop 한다. 이 부분이 함수 에필로그 같다.

전체 어셈 흐름을 보자면... 함수 프롤로그 후 공간 확보하고 
r7(BP)+4지점에 r0의 값
r7(BP)+0지점에 r1의 값, 인자가 2개인것같다.
r0에 0x8410(Hello World!) 값을 넣고 하위 16비트에 0x0을 넣는다 NULL 표시인것 같다.
그렇게 blx로 BP를 저장하고 puts함수를 실행한다.
그 후에 r3에 0을 넣고 r0로 옮긴다. r0는 리턴값이다.
그리고 스택을 정리하고 함수 에필로그... 끝 RET없이 r0에 0을 넣는것 같다.

이걸 Hand-ray하기엔 아직 모르는게 많은것 같다 다른 소스들로 많이 테스트해봐야겠다.


반응형

'Pwnable > ARM, MIPS' 카테고리의 다른 글

ARMv3 Incognito 2013 GotaShell  (0) 2018.07.06
ARMv2 Hand-ray  (0) 2018.07.05
Comments