728x90

Apple의 코드사인(Code Signing) 메커니즘은 macOS, iOS 등 Apple 플랫폼에서 실행 파일(앱, 프레임워크, dylib 등)의 무결성, 인증, 신뢰성을 보장하기 위한 보안 기술입니다. 

 

 Apple 코드사인 메커니즘 개요

1. 목적

  • 코드가 수정되지 않았음 (무결성 확인)
  • 코드의 출처가 신뢰할 수 있음 (인증)
  • 시스템이 해당 코드를 허용해도 되는지 판단 (신뢰성 검증)

코드사인의 구성요소

Apple의 코드서명은 Mach-O 파일 내부와 함께 .app 번들 외부에도 정보가 포함됩니다.

1. Code Signature (서명 블록)

Mach-O 파일 끝에 추가되는 구조체이며, 아래 정보 포함:

  • CodeDirectory: 해시 테이블 및 서명 메타데이터
  • CMS Signature: 실제 서명 (X.509 인증서 기반 CMS 구조)
  • Entitlements: 앱 권한 (예: 앱이 카메라 접근 가능한지 등)
  • Requirements: 실행 정책 요구사항 (예: Team ID 매칭)

2. X.509 인증서 체인

  • 인증서에는 Apple Developer ID 또는 Apple 공인 서명자가 포함되어야 함.
  • 이 인증서는 codesign 명령어로 서명할 때 같이 포함됨.

3. Mach-O 내 서명 데이터 위치

  • __LINKEDIT 세그먼트의 마지막에 서명 정보가 추가됨.
  • otool로 보면:
  • LC_CODE_SIGNATURE dataoff = <offset> datasize = <size>

 

 코드사인의 동작 원리

1. 앱/라이브러리 서명

개발자는 다음 명령어로 Mach-O 파일을 서명합니다:

codesign -s "Developer ID Application: Your Name (TEAMID)" binary_or_app

이 과정에서:

  • 바이너리의 각 섹션을 해시 → CodeDirectory 생성
  • CodeDirectory에 대해 CMS 서명 수행
  • 전체 서명 구조를 Mach-O 파일의 끝에 삽입

2. 앱 실행 시 검증 흐름

시스템 또는 커널에서 다음을 확인:

  1. 서명이 존재하는지 (LC_CODE_SIGNATURE 확인)
  2. CodeDirectory의 해시가 CMS 서명에 포함된 인증서로 검증되는지
  3. 실행 중인 Mach-O 바이너리의 섹션들이 CodeDirectory에 정의된 해시와 일치하는지
  4. Entitlements, Requirements 등 정책 조건 충족 여부 확인

3. System Integrity Protection (SIP), Gatekeeper와 연계

  • macOS의 Gatekeeper는 App Store 외부에서 실행되는 앱의 서명을 강제 확인
  • SIP는 시스템 영역의 바이너리 수정 자체를 방지

 코드 무결성 검증 방식

  • Mach-O의 특정 영역만 서명에 포함됩니다:
    • 일반적으로 __TEXT, __DATA 등의 실제 코드/데이터 영역
    • 서명 자체가 들어간 __LINKEDIT는 제외됨
  • 따라서 서명 이후 __TEXT가 바뀌면 무조건 서명 검증 실패

 

애플 코드사인이 깨지는 조건

원인 설명
바이너리 섹션 수정 __TEXT, __DATA 등 서명된 코드 변경
데이터 추가 Mach-O 파일 끝에 HMAC 등 추가
서명된 리소스 변경 Info.plist, entitlements 등 수정
인증서 문제 만료/철회된 개발자 인증서
번들 구조 변경 .app 내부 파일 추가/삭제/이동
dylib 로딩 오류 dylib 위치, 서명, 무결성 문제

 

728x90

'Programming > IOS, macOS, Android' 카테고리의 다른 글

apple IOS macOS의 Mach-O 파일 구조 개념  (0) 2025.04.24
728x90

Mach-O(Mach Object) 파일 포맷은 macOS, iOS 등 Apple 운영체제에서 사용되는 실행 파일, 라이브러리(.dylib), 커널 모듈 등 바이너리의 파일 포맷입니다. ELF(Linux)나 PE(Windows)와 같은 목적을 가지며, 모듈화된 구조와 다양한 아키텍처 지원을 위해 설계되었습니다.

Mach-O 파일의 기본 구조

+----------------------+
| Mach Header          | ← 파일 시작
+----------------------+
| Load Commands        |
+----------------------+
| Segment & Section    | ← 실제 바이너리 코드 및 데이터
|   (__TEXT, __DATA 등)|
+----------------------+
| Symbol Table (선택) |
+----------------------+
| String Table (선택) |
+----------------------+

 

1.  Mach Header

파일의 기본 정보를 담고 있습니다. 예:

  • CPU 아키텍처 (x86_64, arm64 등)
  • 파일 타입 (실행파일, dylib, bundle 등)
  • load command 개수
  • 32bit / 64bit 여부
struct mach_header_64 {
    uint32_t magic;          // 0xFEEDFACF (64비트), 0xFEEDFACE (32비트)
    cpu_type_t cputype;
    cpu_subtype_t cpusubtype;
    uint32_t filetype;
    uint32_t ncmds;
    uint32_t sizeofcmds;
    uint32_t flags;
    uint32_t reserved;       // only for 64-bit
};

 

 

2. Load Commands

Mach-O의 중앙 디렉터리 같은 개념입니다. 파일 안에 있는 세그먼트 정보, 심볼, 동적 라이브러리, Entry point 등 메타데이터를 정의합니다.

Load Command는 LC_*로 시작하는 다양한 타입이 있습니다.

예시:

  • LC_SEGMENT_64: 세그먼트를 정의함
  • LC_SYMTAB: 심볼 테이블 정보
  • LC_LOAD_DYLIB: 외부 .dylib 로딩 정보
  • LC_MAIN: main entry point (iOS/macOS에서)

 

3.  Segment & Section

세그먼트(Segment)는 메모리에 매핑되는 논리적 블록이고, 섹션(Section)은 세그먼트 내에 존재하는 세부 블록입니다.

주요 세그먼트

세그먼트 설명
__TEXT 실행 코드, 상수, 문자열
__DATA 초기화된 전역 변수, HMAC 저장 가능
__LINKEDIT 심볼, 디버깅 정보 등
__PAGEZERO NULL 포인터 방지용 (읽기/쓰기 불가 메모리)

 

주요 섹션

각 세그먼트는 여러 섹션을 포함합니다.

세그먼트섹션 이름설명

세그먼트 섹션 설명
__TEXT __text 실제 코드
__TEXT __cstring 문자열 상수
__DATA __data 초기화된 데이터
__DATA __bss 초기화되지 않은 데이터 (런타임에 0으로 초기화됨)

 

4.  Symbol Table (옵션)

심볼 테이블은 함수명, 전역변수명 등 심볼의 이름과 주소를 연결합니다. nm, objdump 같은 도구로 분석 가능.


5. String Table (옵션)

심볼의 이름 등 문자열 정보가 여기에 저장됩니다.

 

mach-o 파일 구조 분석 도구 otool

otool은 macOS에서 Mach-O 파일을 분석하는 명령어입니다.
리눅스의 objdump, readelf, nm과 유사하게, 바이너리의 구조, 섹션, 심볼, 라이브러리 종속성 등을 확인할 수 있습니다.

$otool -l mylib.dylib

 

출력 예시:

Load command 0
      cmd LC_SEGMENT_64
  cmdsize 712
  segname __TEXT
   vmaddr 0x0000000100000000
   ...
   Section
     sectname __text
     segname  __TEXT
     addr     0x100000f60
     size     0x0000001c0

 

 

옵션 설명
-h Mach-O 헤더 출력
-l Load Commands 출력
-L 연결된 외부 .dylib 목록 (LC_LOAD_DYLIB)
-t __TEXT, __text 섹션의 기계어 출력 (디스어셈블링 없이)
-v 기계어를 가독성 있게 출력
-V 기계어를 AT&T 어셈블리로 디스어셈블
-s <segment> <section> 특정 세그먼트/섹션의 헥사 값 출력
-S 모든 섹션의 내용을 출력
-r 재배치 정보 (relocation entries) 출력
-M Objective-C 메서드 목록 출력
-I indirect symbol table 출력
-dyld_info dyld 정보 출력 (lazy symbol, bindings 등)

 

 

728x90

'Programming > IOS, macOS, Android' 카테고리의 다른 글

Apple 코드사인(CodeSign) 개념  (0) 2025.04.24

+ Recent posts