ARM assembly 공부, bof

ARM assembly를 공부하기 위해서 bof redhat 원정대 1번 문제를 ARM환경에서 컴파일하고 단순하게 어셈블리어만 라인바이라인으로 분석해보고 x86 리눅스에서와 어떤식으로 다른지 확인 해 보았다.

bof 1번 문제의 c코드


strcpy에서 버퍼의 크기를 확인하지 않아 버퍼오버플로우가 발생 될 것으로 예상된다.

c코드 바이너리의 어셈블리어코드

push {r11, lr} ;스택에 lr(RET 백업)먼저 넣고 r11(SFP 백업)을 넣는다.
add r11, sp, #4 ;sp에 4더해서 r11에 넣는다.
sub sp, sp, #264 ; 0x108 sp를 0x108만큼 위로 올린다.
str r0, [r11, #-264] ; 0x108 (r11 - 0x108)위치의 메모리에 r0의 값을 저장
str r1, [r11, #-268] ; 0x10c (r11 - 0x10c)위치의 메모리에 r1의 값을 저장
ldr r3, [r11, #-264] ; 0x108 (r11 - 0x108)위치의 메모리의 값을 r3으로 로드
cmp r3, #1 ;sub명령어와 동일하지만 결과값이 버려짐, 결과에 따라 cpsr의 n,z,c,v플레그 변화
bgt 0x8460 <main+48> ;r3가 1과 동일하기 때문에 main+48로 분기하지 않는다
ldr r0, [pc, #60] ; 0x8494 <main+100> pc + 60의 메모리의 값(main+100)을 r0로 로드
bl 0x8348 <puts> ;lr에 다음 실행할 주소를 로드하고 puts함수로 분기 (puts함수에서 조건에 따라 lr을 수정 하는 것 같다.)
mov r0, #0 ;r0레지스터에 0을 넣는다.
bl 0x836c <exit> ;lr에 다음 실핼할 주소를 로드하고 exit함수로 분기
ldr r3, [r11, #-268] ; 0x10c (r11 - 0x10c)의 메모리의 값을 r3으로 로드
add r3, r3, #4 ;r3에 4를 더한 값을 r3에 넣는다.
ldr r3, [r3] ;r3에 들어있는 메모리 주소의 값을 r3에 넣는다.
sub r2, r11, #260 ; 0x104 r3에서 -0x104한 값을 r2에 넣는다.
mov r0, r2 ;r2의 값을 r0에 넣는다. -> 버퍼의 주소
mov r1, r3 ;r3의 값을 r1에 넣는다. -> 이놈이 입력받은 인자 값
bl 0x833c <strcpy> ;lr에 돌아올 주소를 넣고 strcpy로 분기하여 strcpy실행되서 r0의 주소값의 메모리에 r1의 값인 입력값이 복사된다.
sub r3, r11, #260 ; 0x104 r11의 값에서 -0x104를 해주어 r3에 넣는다
mov r0, r3 ;r3의 값을 r0에 넣는다. (왜하지? r0과 r3가 같은디.), puts에 인자 확실히 넣어줄라고하나.
bl 0x8348 <puts> ;lr에 돌아올 주소를 넣고 puts로 분기하여 입력값을 모니터 출력해준다. (돌아올 때 r0,r1,r2가 모두 바뀐다 puts함수에서 조작하는듯)
mov r0, r3 ;r3의 값을 r0에 넣는다. (r3에는 입력값이 들어있는 메모리 주소를 갖고있다.)
sub sp, r11, #4 ;r11에서 +0x4한 값은 sp에 넣는다. sp를 내린다.(스택 정리하는듯)
pop {r11, pc} ;pop해서 r11과 pc에 넣는다.
andeq r8, r0, r8, lsl #10 ;r8을 10만큼 오른쪽으로 쉬프트한 값과 r0의 &연산이 r8와 같다면 분기 (r8 = r0 & (r8<<10))
view raw armasm.asm hosted with ❤ by GitHub

서브루틴으로 진입시 r11, rl 을 사용하여 분기오피코드와 서브함수의 PUSH {r11, lr}로 SFP와 RET를 백업 한다. argv는 r0. r1로 전달한다.
함수를 빠져 나올때는 POP {r11, pc}로 스택프레임과 돌아갈 주소를 복귀시켜준다.
여기서 POP되는 스택을 조작하면 이전처럼 pc를 조작 할 수 있을것 같다.


첫번째 네모가 r11로 팝될 놈이고 두번째 네모가 pc로 팝될 놈이다.
두번째 네모를 덮어 pc를 조작 할 수 있어 보이나 안해봐서 확실하지 않다ㅋ

0 개의 댓글:

댓글 쓰기