임베디드(Embedded): 내장된, 내재된
임베디드 시스템: 기기에 내장되어 실행되는 시스템
임베디드 기기: 임베디드 시스템이 동작되고 있는 기기. 특정 목적 위해 사용됨 ex) 휴대폰, 공유기, TV
펌웨어: 임베디드 기기의 비휘발성 메모리에 담긴 데이터
(과거 비휘발성 메모리-EPROM, 최근 비휘발성 메모리-Flash memory)
컴퓨터 VS 임베디드
<컴퓨터 구조>
CPU: 명령어 처리
그래픽 카드: 그래픽 처리
HDD/SSD: OS, SW 및 데이터 저장
RAM: SW 실행
메인보드: 각 부품 연결. 업그레이드 위해 필요
<임베디드 구조>
SoC/MCU: CPU처럼 명령어 처리&그 이상의 기능. RISC 아키텍처인 ARM, MIPS 사용(명령어 셋 간소화-명령어 개수 적음, 길이 고정)
Flash memory: HDD와 SSD의 역할을 하는 저장 장치
RAM
보안성 낮음-ex) 미라이 봇넷: 여러 취약한 기기 장악해 DDoS에 사용
임베디드 펌웨어
특정 기기 타겟으로 취약점 분석하려면 펌웨어 획득해야 함 (How? 플래시 메모리의 데이터 읽기)
구조
부트로더: 기기 켜질 때 가장 먼저 실행되는 프로그램. 하드웨어 초기 설정, 커널을 메모리에 올림
기기 하드웨어 초기 설정 → 압축된 커널 이미지를 램으로 복사 → 커널 이미지의 앞단에 있는 커널 압축 푸는 코드 실행
커널: 시스템 자원 관리, 사용자와 HW 간 인터페이스 역할 - 메모리 관리, 화면 출력, 키보드/마우스 조작 등 시스템의 대부분 요소 관리
#include <stdio.h>
int main(void){
printf("Hello World\n");
return 0;
}
위 코드 실행(64bit 리눅스에서) 시 → 메모리에서 프로그램 실행할 공간 할당
→ printf 명령어 실행 → syscall(write) 호출되어 커널에 출력 작업 요청
→ 프로그램 종료 시 → syscall 60(exit) 호출되어 커널에 프로그램 종료 관련 메모리 정리 작업 지시
파일 시스템 종류 다양
디스크 파일 시스템 - ext3, ext4, FAT, NTFS, HFS 등
플래시 파일 시스템 - ubifs, JFFS2, YAFFS 등
특수 파일 시스템 - Squashfs, Cramfs 등
루트 파일 시스템: 기기의 메인이 되는 파일 시스템. 루트 파일 시스템 경로(리눅스) / - 루트 파일 시스템 얻으면 / 경로 아래에 있는 모든 파일 얻을 수 있음
파일 시스템 추출하면 기기의 작동 책임지는 서비스 바이너리(분석할 타겟) 얻을 수 있음
→ 펌웨어 얻어서 파일 시스템 추출해야!
ARM 아키텍처
프로세서
Arm mode(32bit. 고성능 작업) / Thumb mode(16bit. 효율적인 메모리 공간 사용): ARM 프로세서는 프로그램 실행 중 두 mode 전환 가능 → 코드 최적화(코드 실행 효율, 메모리 사용량 최적화)
레지스터
범용 레지스터
특수 레지스터
CPSR 레지스터
Backend 레지스터
ARM 어셈블리
명령어{s}{condition} Rd, Rn, {Operand2}
데이터 이동: MOV, MVN, LDR, STR
산술 연산: ADD, SUB, MUL
논리 연산: AND, ORR, EOR, BIC
비교: CMP, CMN
분기: B, BL, BX, BLX
스택: PUSH, POP
시스템 콜: SVC
ARM 함수 프롤로그/에필로그
# Prologue
push {fp, lr}
add fp, sp, #4
sub sp, sp, #12
...
# Epilogue
sub sp, fp, #4
pop {fp, pc}