Profile

머리정리하는곳

c2w2m2

간단한 Arm 리버싱

진짜 간단한 첫 arm 리버싱이다.


#include<stdio.h> int test(int idx){ printf("In test%d\n",idx); } int main(int argc, char *argv[]){ int i; printf("In main\n"); for(i=0; i<5; i++){ test(i); } return 0; }


이런 간단한 코드로 일단 함수 인자 전달방식, for 문을 통한 분기문 등을 알아보자.


easy


혹시 몰라서 바이너리를 올려놓는다.



첫 MOV R12, SP 는 R12 에 SP 를 저장하는것 같다.


STMFD 는 블럭 전송이라고 하는데 push 랑 같다고 보면 될거같다...?


R11 = R12 - 4 를 해주고, SP 에서 0xC 만큼 감소 시켜준다.


아마 위에서 4줄까지가 함수의 프롤로그 부분인듯 싶다.


그후 STR 명령어로 R11 - 0x10, R11 - 0x14 부분에 각각 R0, R1값을 저장해준다. 


R11 이 아마 main 시작시 SP - 4 값을 가지고 있을 테고, 여기에 -0x10, -0x14 한 부분에 R0, R1 을 일단 저장해 놓는다. 아마 canary 같은 보호기법이 아닐까 생각해본다.


그 후 R0 에 "In main\n" 의 주소값을 저장해주고 printf 를 호출한다.


그리고 R3 에 0 을 저장하고, R11 - 0x18 부분에 R3( 0 ) 을 저장하게 된다. R11 - 0x18 부분에는 아마 우리가 반복을 돌기 위해 선언한 i 의 위치인것 같다.



loc_8218 부분이 반복을 돌리는 부분이다.


R3 에 R11 - 0x18, 즉 변수 i 값을 저장하고 4 랑 비교를 한다. 비교를 했을때 ZF 가 Clear 된 상태이며 NF == VF 이면 loc_823C , main 종료부분으로 뛰게된다


그게 아니라면 R0 에 i 값을 저장하고 test 를 호출한다.



호출하게된 test 에서는 아까 보았던 함수 프롤로그를 하고,


R11 - 0x10 부분에 인자로 받은 i 값을 저장한다.


그리고 R0 에는 "In test%d\n"의 주소값을, R1 에는 아까 저장한 i 값을 가지고, printf 를 호출한다.


마지막 2줄은 함수의 에필로그로 보이는데, R3 의 값을 R0 에 저장하고 ( 함수의 리턴값 ), LDMFD 아까 STMFD 와 반대, 즉 pop 을 하는 명령어를 실행 시키고 끝낸다.



반복문으로 돌아와서, R3 에 R11-0x18 안의 즉 i 값을 저장하고, ADD 로 1 을 더해준 후, 다시 R11 - 0x18 에 저장한 다음, loc_8218 로 뛴다.


이런식으로 반복을 하고 CMP R3, #4 를 만족해서 BGT 를 실행시켜 점프를 하게되면,


R3 에 0 을 넣고, R0 에 R3, 즉 main 의 리턴값을 0 으로 해주고, 함수의 에필로그를 해주고 끝낸다.



이런식으로 간단한 프로그램을 한줄한줄 분석해 보았다.


많이 간단했지만, 역시 처음은 이렇게 간단한 것이라도 한줄한줄 분석하면서 눈에 익히는게 맞다고 본다.









'Reversing' 카테고리의 다른 글

[CodeGate] RamG  (0) 2018.01.05
[???] cuty  (2) 2017.12.05
[Reversing.kr] Replace  (4) 2017.11.13
[DIMICTF2017] ToHard  (0) 2017.07.17