1000sj
SJ CODE
1000sj
전체 방문자
오늘
어제
  • 분류 전체보기
    • Algorithms
      • Crypto
      • Formal Methods
    • Security
      • Fuzzing
      • Exploit
    • System Programming
      • Kernel
      • Compiler
      • Device Driver
      • Emulator
      • Assembly
      • Memory
      • Network
    • Architecture
      • ARM
      • RISC-V
    • Cloud Computing
      • Infrastructure
      • SDN
    • TroubleShooting
      • Debugging
      • Testing
    • Performance improvements
      • Parrelel Processing
      • HPC
    • ETC
      • 문화 생활
      • 커뮤니티

인기 글

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
1000sj

SJ CODE

Security/Fuzzing

LLVM Sanitizer 작성하는 법

2026. 2. 4. 11:51

전체 컴파일 파이프라인

핵심은 컴파일러 드라이버가 모든것을 연결한다는 점이다. 

 

1. 프론트엔드 호출 (소스 → AST → IR)

2. 패스 스케줄링 (어떤 패스를 어떤 순서로 실행할지)

3. 런타임 라이브러리 링킹 (compiler-rt 연결)

 

  • Clang Frontend: 소스코드 → AST → LLVM IR 생성
  • LLVM: IR에 패스 적용 후 백엔드에서 기계어 생성
  • Compiler-rt: 런타임 라이브러리 링킹
  • Sanitizer pass는 항상 마지막에 실행
    • 다른 최적화 패스가 sanitizer가 삽입한 코드를 변경하거나 제거할 수 있기 때문

 

CodeGen 타입 변환

int x = 42;

C/C++ 타입이 LLVM 타입으로 어떻게 변환되는지

 

C 타입 LLVM 타입 크기
int i32 32비트
char i8 8비트
bool i8 8비트
long i64 64비트
int* i32* 포인터

 

Sanitizer가 타입 정보를 활용해서 메모리 접근을 검사할 수 있다. (예를 들어 "이 포인터는 i32를 가리켜야 하는데 i8처럼 접근하고 있다" 같은 것을 탐지)

 

Pass Manager

Clang CodeGen이 패스 순서 결정한다. pass manager가 IR을 받아서 패스들을 순서대로 실제 실행한다.

 

0. 원본 코드

void foo() { bar(); }
void bar() { /* ... */ }

1. Function Inlining 후

void foo() { /* bar의 내용이 여기에 */ }

2. Loop Unrolling 후

// (루프가 있다면 펼쳐짐)

 

3. Sanitizer Pass 후

void foo() {
    __sanitizer_check();  // ← 삽입됨
    /* bar의 내용 */
    __sanitizer_check();  // ← 삽입됨
}

 

만약 Sanitizer가 먼저 실행되면 Inlining이 sanitizer 체크 코드를 이상하게 변형시키거나, 최적화가 체크 코드를 "불필요하다"고 판단해 제거할 수 있다. 따라서 패스 실행 순서가 중요하다.

 

 

Sanitizer 계측 + 런타임 링킹

 

1단계: Pass가 함수 호출 삽입

[Before]                      [After]
┌────────────────┐           ┌────────────────┐
│ Function       │           │ Function       │
│ BasicBlock     │           │ BasicBlock     │
│   Inst         │  ──────▶  │   call SanFunc │ ← 새로 삽입!
│   Inst         │           │   Inst         │
│   call Malloc  │           │   Inst         │
└────────────────┘           │   call Malloc  │
                             └────────────────┘

2단계: 링킹 시 함수 연결

┌─────────────┐              ┌─────────────────┐
│  MyFile.o   │              │   Compiler-RT   │
├─────────────┤              ├─────────────────┤
│ SanFunc ────┼──── 링킹 ────┼→ SanFunc 구현체 │
│ Malloc  ────┼── 가로채기 ──┼→ Interceptor_   │
│             │              │    Malloc       │
└─────────────┘              └─────────────────┘

 

함수 가로채기(Interception)는 링커의 심볼 해석 순서를 이용한 트릭이다. (compiler-rt → libc)

// 원래 프로그램
ptr = malloc(100);

// Sanitizer가 가로챈 후 실제 실행되는 것
ptr = interceptor_malloc(100);  // compiler-rt 함수

// interceptor_malloc 내부
void* interceptor_malloc(size_t size) {
    __sanitizer_before_malloc(size);  // 검사
    void* ptr = real_malloc(size);     // 진짜 malloc 호출
    __sanitizer_after_malloc(ptr);     // 추적
    return ptr;
}

 

 

정리하자면 Sanitizer를 만들려면 수정할 곳은

컴포넌트 위치 역할
Pass llvm/lib/Transforms/ IR에 계측 코드 삽입
드라이버 clang/lib/Driver/ -fsanitize=xxx 옵션 처리
CodeGen clang/lib/CodeGen/ 패스 등록, 순서 지정
Runtime compiler-rt/lib/ 실제 검사 로직, 함수 가로채기

 

References

  • https://faculty.sist.shanghaitech.edu.cn/faculty/songfu/course/spring2018/CS131/llvm.pdf
  • https://www.cs.cornell.edu/~asampson/blog/llvm.html
  • https://eli.thegreenplace.net/
  • https://compilers.iecc.com/crenshaw/
  • https://blog.trailofbits.com/2019/06/25/creating-an-llvm-sanitizer-from-hopes-and-dreams/
  • https://blog.trailofbits.com/2024/05/16/understanding-addresssanitizer-better-memory-safety-for-your-code/

 

'Security > Fuzzing' 카테고리의 다른 글

Linux KCOV(Kernel Coverage)  (0) 2026.01.02
syzbot, qemu, gdb를 사용하여 linux kernel의 버그 수정  (0) 2025.12.12
syzkaller를 이용한 커널 퍼징 #4 실제 커널 퍼징  (0) 2025.12.11
syzkaller를 이용한 커널 퍼징 #3 syz-manager 설정 및 syz-executor 실행  (0) 2025.12.10
syzkaller를 이용한 커널 퍼징 #2 Syzkaller의 동작 구조  (0) 2025.12.10
    'Security/Fuzzing' 카테고리의 다른 글
    • Linux KCOV(Kernel Coverage)
    • syzbot, qemu, gdb를 사용하여 linux kernel의 버그 수정
    • syzkaller를 이용한 커널 퍼징 #4 실제 커널 퍼징
    • syzkaller를 이용한 커널 퍼징 #3 syz-manager 설정 및 syz-executor 실행
    1000sj
    1000sj

    티스토리툴바