arm 어셈블리어 란? - (펌)아제 리아 연구소
- ◎◇
- 안드로이드 게임 분석/arm|어셈블리어
- 2020. 1. 15.
https://azeria-labs.com/writing-arm-assembly-part-1/
한글번역-구글번역
ARM 어셈블리 기본 사항에 대한이 자습서 시리즈에 오신 것을 환영합니다. 이것은 ARM 익스플로잇 개발 에 대한 후속 튜토리얼 시리즈의 준비입니다 . ARM 셸 코드를 작성하고 ROP 체인을 작성하기 전에 먼저 ARM 어셈블리 기본 사항을 다루어야합니다.
다음 주제는 단계별로 설명됩니다.
ARM 어셈블리 기초 튜토리얼 시리즈 :
1 부 : 소개 ARM 어셈블리에
데이터 형식 레지스터 : 제 2 부
제 3 부 : ARM 명령어 세트
4 부 : 메모리 지침 :로드 및 데이터 저장
제 5 부 : 다중로드 및 저장
제 6 부 : 조건부 실행 및 분기
부 7 : 스택과 함수
예제와 함께 진행하려면 ARM 기반 랩 환경이 필요합니다. ARM 장치 (예 : Raspberry Pi)가없는 경우이 자습서 를 따라 QEMU 및 Raspberry Pi 배포판을 사용하여 가상 컴퓨터에서 자체 랩 환경을 설정할 수 있습니다 . GDB를 사용한 기본 디버깅에 익숙하지 않은 경우이 학습서에서 기본 사항을 얻을 수 있습니다 . 이 자습서에서는 ARM 32 비트에 중점을두고 예제는 ARMv6에서 컴파일됩니다.
왜 ARM인가?
이 자습서는 일반적으로 ARM 어셈블리의 기본 사항을 배우려는 사람들을위한 것입니다. 특히 ARM 플랫폼에서의 익스플로잇 작성에 관심이있는 사용자에게 적합합니다. ARM 프로세서가 주변 어디에나 있다는 것을 이미 알고있을 것입니다. 내 주변을 살펴보면 인텔 프로세서보다 집에 ARM 프로세서가 장착 된 훨씬 더 많은 장치를 셀 수 있습니다. 여기에는 전화, 라우터가 포함되며 요즘 판매에서 폭발적으로 증가하는 IoT 장치를 잊지 마십시오. 즉, ARM 프로세서는 세계에서 가장 널리 사용되는 CPU 코어 중 하나가되었습니다. PC와 마찬가지로 IoT 장치는 버퍼 오버플로와 같은 부적절한 입력 유효성 검사 남용에 취약하다는 사실을 알 수 있습니다. ARM 기반 장치의 광범위한 사용과 오용 가능성을 고려할 때 이러한 장치에 대한 공격이 훨씬 더 일반화되었습니다.
그러나 ARM 어셈블리 언어는 널리 사용되는 가장 쉬운 어셈블리 언어이지만 ARM보다 x86 보안 연구에 특화된 전문가가 더 많습니다. 그렇다면 왜 더 많은 사람들이 ARM에 집중하지 않습니까? 아마도 ARM에 대한 것보다 인텔에 대한 악용에 대해 더 많은 학습 리소스가 있기 때문일 것입니다. Fuzzy Security 또는 Corelan 팀의 Intel x86 Exploit 작문에 대한 훌륭한 자습서를 생각해보십시오.– 이와 같은 지침은이 특정 영역에 관심이있는 사람들이 실제적인 지식을 얻고 해당 자습서에서 다루는 내용 이상으로 배울 수있는 영감을 얻도록 도와줍니다. x86 익스플로잇 작성에 관심이 있다면 Corelan 및 Fuzzysec 튜토리얼이 완벽한 출발점입니다. 이 자습서 시리즈에서는 어셈블리 기본 사항에 중점을두고 ARM에 대한 글쓰기를 활용합니다.
Intel과 ARM에는 많은 차이점이 있지만 가장 큰 차이점은 명령어 세트입니다. 인텔은 CISC (Complex Instruction Set Computing) 프로세서로서 더 크고 기능이 풍부한 명령어 세트를 가지고 있으며 많은 복잡한 명령어가 메모리에 액세스 할 수 있도록합니다. 따라서 모드를 처리하는 작업이 많지만 ARM보다 레지스터가 적습니다. CISC 프로세서는 주로 일반 PC, 워크 스테이션 및 서버에서 사용됩니다.
ARM은 RISC (Reduced Instruction Set Computing) 프로세서이므로 CISC보다 단순화 된 명령어 세트 (100 명령어 이하)와 더 범용 레지스터가 있습니다. Intel과 달리 ARM은 레지스터에서만 작동하는 명령을 사용하고 메모리 액세스에로드 / 저장 메모리 모델을 사용하므로로드 / 저장 명령 만 메모리에 액세스 할 수 있습니다. 즉, ARM의 특정 메모리 주소에서 32 비트 값을 증가 시키려면 먼저 특정 주소의 값을 레지스터에로드하고 레지스터 내에서 증가시키고 저장하기 위해 세 가지 유형의 명령어 (로드, 증분 및 저장)가 필요합니다. 레지스터에서 메모리로 돌아갑니다.
축소 된 명령어 세트에는 장점과 단점이 있습니다. 장점 중 하나는 명령어를보다 빠르게 실행할 수있어 잠재적으로 더 빠른 속도를 허용한다는 것입니다 (RISC 시스템은 명령어 당 클럭주기를 줄임으로써 실행 시간을 단축시킵니다). 단점은 명령이 적을수록 사용 가능한 제한된 명령으로 소프트웨어를 효율적으로 작성하는 데 더 중점을 두는 것입니다. 또한 ARM에는 ARM 모드와 Thumb 모드의 두 가지 모드가 있습니다. Thumb 명령어는 2 바이트 또는 4 바이트 일 수 있습니다 ( 제 3 부 : ARM 명령어 세트의 내용 참조 ).
ARM과 x86의 차이점은 다음과 같습니다.
- ARM에서는 대부분의 명령어를 조건부 실행에 사용할 수 있습니다.
- 인텔 x86 및 x86-64 시리즈 프로세서는 리틀 엔디안 형식을 사용 합니다.
- ARM 아키텍처는 버전 3 이전의 리틀 엔디안이었습니다. 이후 ARM 프로세서는 BI 엔디안 이되었으며 전환 가능한 엔디안 을 허용하는 설정이 있습니다 .
인텔과 ARM 사이뿐만 아니라 다른 ARM 버전 자체에도 차이점이 있습니다. 이 자습서 시리즈는 ARM의 작동 방식에 대한 일반적인 이해를 돕기 위해 가능한 한 일반적인 내용을 유지하기위한 것입니다. 기본 사항을 이해하면 선택한 대상 ARM 버전의 미묘한 차이를 쉽게 배울 수 있습니다. 이 자습서의 예제는 32 비트 ARMv6 (Raspberry Pi 1)에서 작성되었으므로 설명은이 정확한 버전과 관련이 있습니다.
다른 ARM 버전 의 이름 도 혼동 될 수 있습니다.
ARM 제품군 | ARM 아키텍처 |
---|---|
ARM7 | ARM v4 |
ARM9 | ARM v5 |
ARM11 | ARM v6 |
피질 -A | ARM v7-A |
피질 -R | ARM v7-R |
피질 -M | ARM v7-M |
ARM 익스플로잇 개발에 뛰어 들기 전에 먼저 어셈블리 언어 프로그래밍의 기본 사항을 이해해야합니다. 어셈블리 언어 프로그래밍에 대한 지식이 필요합니다. 그러나 ARM 어셈블리가 필요한 이유는 무엇입니까?“일반적인”프로그래밍 / 스크립트 언어로 익스플로잇을 작성하는 것만으로는 충분하지 않습니까? 리버스 엔지니어링을 수행하고 ARM 바이너리의 프로그램 흐름을 이해하고, 자체 ARM 셸 코드를 작성하고, ARM ROP 체인을 제작하고, ARM 응용 프로그램을 디버깅하려는 경우가 아닙니다.
리버스 엔지니어링을 수행하고 개발을 이용할 수 있도록 어셈블리 언어의 모든 세부 사항을 알 필요는 없지만 더 큰 그림을 이해하려면 일부가 필요합니다. 기본 사항은이 튜토리얼 시리즈에서 다룰 것입니다. 자세한 내용을 알아 보려면이 장 끝에있는 링크를 방문하십시오.
그렇다면 어셈블리 언어는 정확히 무엇입니까? 어셈블리 언어는 명령어로 구성된 기계어 코드의 얇은 구문 계층 일 뿐이며, 이진 표현 (기계어 코드)으로 인코딩되어 컴퓨터가 이해합니다. 그렇다면 기계 코드를 대신 작성하지 않는 이유는 무엇입니까? 음, 그것은 엉덩이에 고통이 될 것입니다. 이러한 이유로 우리는 인간이 이해하기 훨씬 쉬운 어셈블리 ARM 어셈블리를 작성할 것입니다. 우리 컴퓨터는 기계 코드가 필요하기 때문에 어셈블리 코드 자체를 실행할 수 없습니다. 우리는 기계 코드에 어셈블리 코드를 조립하는 데 사용할 도구는에서 GNU 어셈블러 인 GNU Binutils의의 라는 이름의 프로젝트 로 * .S 확장자를 가진 소스 파일과 함께 작동한다.
확장명이 * .s 인 어셈블리 파일을 작성한 후에는 as 로 어셈블하고 ld 와 링크해야합니다 .
$ ld program.o -o 프로그램
맨 아래부터 시작하여 어셈블리 언어까지 진행해 봅시다. 가장 낮은 레벨에서는 회로에 전기 신호가 있습니다. 신호는 0V ( 'off') 또는 5V ( 'on')의 두 가지 레벨 중 하나로 전압을 전환하여 형성됩니다. 회로를 보면 전압을 쉽게 알 수 없기 때문에 0과 1의 숫자로 시각적 표현을 사용하여 온 / 오프 전압의 패턴을 쓰도록 선택합니다. 또한 0과 1은 이진 시스템의 숫자이기 때문입니다. 그런 다음 0과 1의 시퀀스를 그룹화하여 컴퓨터 프로세서의 가장 작은 작업 단위 인 기계 코드 명령어를 형성합니다. 다음은 기계 언어 명령어의 예입니다.
1110 0001 1010 0000 0010 0000 0000 0001
지금까지는 좋지만 이러한 각 패턴 (0과 1)의 의미를 기억할 수는 없습니다. 이러한 이유로 우리는 소위 니모닉 (mnemonics)이라는 약어를 사용하여 각 머신 코드 명령어에 이름이 지정된 이진 패턴을 기억하는 데 도움을줍니다. 이 니모닉은 종종 세 글자로 구성되지만 의무 사항은 아닙니다. 이러한 니모닉을 지침으로 사용하여 프로그램을 작성할 수 있습니다. 이 프로그램을 어셈블리 언어 프로그램이라고하며 컴퓨터의 기계 코드를 나타내는 데 사용되는 니모닉 세트를 해당 컴퓨터의 어셈블리 언어라고합니다. 따라서 어셈블리 언어는 사람이 컴퓨터를 프로그래밍하는 데 사용하는 가장 낮은 수준입니다. 명령의 피연산자는 니모닉 뒤에옵니다. 예를 들면 다음과 같습니다.
MOV R2, R1
어셈블리 프로그램이 니모닉 (mnemonics)이라는 텍스트 정보로 구성되어 있음을 알았으므로 이제이를 기계 코드로 변환해야합니다. 위에서 언급 한 것처럼 ARM 어셈블리의 경우 GNU Binutils 프로젝트는라는 도구 를 제공 합니다. 같은 어셈블러를 사용하는 과정 으로 (ARM) 기계 코드 (ARM) 어셈블리 언어 변환하는 방법은 조립이라고합니다.
요약하면, 우리는 컴퓨터가 전압 (신호)의 유무를 이해 (응답)하고 0과 1 (비트) 순서로 여러 신호를 나타낼 수 있다는 것을 배웠습니다. 머신 코드 (신호 시퀀스)를 사용하여 컴퓨터가 잘 정의 된 방식으로 응답 할 수 있습니다. 이러한 모든 시퀀스의 의미를 기억할 수 없으므로 약어 (니모닉)를 사용하여 명령어를 나타내는 데 사용합니다. 이 니모닉 세트는 컴퓨터의 어셈블리 언어이며 컴파일러는 고급 언어의 컴파일러와 같은 방식으로 코드를 니모닉 표현에서 컴퓨터가 읽을 수있는 기계 코드로 변환하기 위해 Assembler라는 프로그램을 사용합니다.
'안드로이드 게임 분석 > arm|어셈블리어' 카테고리의 다른 글
자주쓰는 arm 어셈블리어 명령어2 (0) | 2020.03.04 |
---|---|
c# 어셈블리어 변환 ARM (0) | 2020.02.27 |
어셈블리어 명령어 모듬2 기본(펌) (0) | 2020.02.01 |
어셈블리어 명령어 모음ARM (0) | 2020.01.20 |
어셈블리어 명령어 기본 (0) | 2020.01.15 |