Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

Session 6 l 카카오뱅크 김용욱

Slide 4

Slide 4 text

Obfuscation 101 KakaoBank | Leonardo YongUk Kim ZFMMPX'"&3(# CMBDL&&&3(# ஠஠য়ߛ௼জই੉௑@ചݶ ୭ࣗࢎ੉ૉ٣߄੉झചݶ೧࢚بীٮۄ౸ױೞݴ оةࢿਸ೧஖஖ঋח੸੺ೠ௼ӝܳҊ۰ೞৈࢎਊ

Slide 5

Slide 5 text

이 발표에서 다루지 않는 것. 1. ProGuard 사용법 2. 난독화 도구 벤치마크 3. 앱을 해킹하는 방법 4. ProGuard 유즈 케이스 5. 소스 코드에 기반한 분석 6. 복잡한 난독화 이론 7. 안드로이드 10 이름 8. 구글, 네이버, 라인, 카카오, 카뱅 입사

Slide 6

Slide 6 text

이 발표에서 다루는 것. 1. 안드로이드 코드의 특징 2. 바이트 코드에 대한 간략한 이해 3. Transform API 4. 난독화와 앱 보호에 대한 간략한 이론 5. ProGuard와 R8의 역할

Slide 7

Slide 7 text

안드로이드 코드의 특징 1. 이식에 좋은 바이트 코드를 사용. 2. 동적 컴파일에 기반한 성능 향상. 3. 의존성도 동적으로 로드. 4. 암호화되지 않은 클래스와 리소스로 구성. 5. 공간 효율적인 데이터 포맷.

Slide 8

Slide 8 text

안드로이드 코드의 특징 1. 이식에 좋은 바이트 코드를 사용. 2. 동적 컴파일에 기반한 성능 향상. 3. 의존성도 동적으로 로드. 4. 암호화되지 않은 클래스와 리소스로 구성. 5. 공간 효율적인 데이터 포맷.

Slide 9

Slide 9 text

이식에 좋은 바이트 코드 자바 Bytecode 1. 스택 기반의 VM을 사용. 스택에서 입력 받고 결과도 스택으로. 2. 32비트 스택 하나의 요소가 대부분의 타입을 커버. 3. char을 사용해도 기본적으로는 메모리에 이점이 없다. 4. 64비트가 필요한 자료형(double, long)을 사용할 경우 스택 두 요소. 5. 256개의 연산 (실제로는 예약어가 많음.) 6. 스택 기반은 검증하기 쉬움. 7. 레지스터 기반의 실제 기기와 차이가 있어 성능상 단점.

Slide 10

Slide 10 text

스택 기반 VM 스택 변수 Frame 상수 풀 상수의 종류를 구분하지 않는 것이 특징. (안드로이드는 분리함.)

Slide 11

Slide 11 text

스택 기반 VM 1 + 2 = ? 1 스택에 1과 2를 넣는다. istore_1 // 1을 스택에 넣는다. int 상수 -1(m1)부터 5(0)까지는 별도의 istore 명령을 제공한다.

Slide 12

Slide 12 text

스택 기반 VM 1 + 2 = ? 1 2 스택에 1과 2를 넣는다. istore_1 // 1을 스택에 넣는다. istore_2 // 2를 스택에 넣는다. int를 위한 연산

Slide 13

Slide 13 text

스택 기반 VM 1 + 2 = ? 1 2 스택에서 값을 빼고 합산한다. istore_1 // 1을 스택에 넣는다. istore_2 // 2를 스택에 넣는다. iadd // 두 개의 수를 더해 스택에 넣는다. 사칙연산도 Java는 타입을 따진다. (닷넷은 따지지 않음.)

Slide 14

Slide 14 text

스택 기반 VM 1 + 2 = ? 3 합산된 3을 스택에 넣는다. istore_1 // 1을 스택에 넣는다. istore_2 // 2를 스택에 넣는다. iadd // 두 개의 수를 더해 스택에 넣는다.

Slide 15

Slide 15 text

스택 기반 VM 1 + 2 = ? istore_1 명령을 나열해보자. istore_2 iadd

Slide 16

Slide 16 text

스택 기반 VM 1 + 2 = ? 0x04 실제 opcodes로 바꾸어 보자. 0x05 0x60 낯설어도 x86, ARM 기계어보다 단순. https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html istore_1 istore_2 iadd

Slide 17

Slide 17 text

이식에 좋은 바이트 코드 달빅 Bytecode 1. 레지스터 기반의 VM을 사용. 2. 64K 개의 레지스터 하지만 주로 앞의 256개, 가끔은 16개만 사용. 3. 32비트 레지스터 하나의 요소가 대부분의 타입을 커버. 4. char을 사용해도 기본적으로는 메모리에 이점이 없다. 5. 64비트가 필요한 자료형(double, long)을 사용할 경우 레지스터 2개. 6. 200여개의 연산. 7. 실제 하드웨어와 매핑에 이점. 성능 상의 이점. 메모리를 덜 씀. 8. 상대적으로 검증이 어려움.

Slide 18

Slide 18 text

달빅 bytecode 1+2 = ? const/4 v2, 0x1 // 레지스터 v1에 4비트 상수 0x1을 넣습니다. const/4 v3, 0x2 // 레지스터 v2에 4비트 상수 0x2를 넣습니다. add-int v0, v2, v3 // 레지스터 v1과 v2의 합을 v0에 저장한다. const/4 0x1, v2 0x12 0x12 http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html

Slide 19

Slide 19 text

달빅 bytecode 1+2 = ? const/4 v2, 0x1 // 레지스터 v1에 4비트 상수 0x1을 넣습니다. const/4 v3, 0x2 // 레지스터 v2에 4비트 상수 0x2를 넣습니다. add-int v0, v2, v3 // 레지스터 v1과 v2의 합을 v0에 저장한다. add-int v0 0x90 0x00 v2 v3 0x02 0x03

Slide 20

Slide 20 text

달빅 bytecode 조금 더 작은 바이너리 const/4 v2, 0x1 // 레지스터 v1에 4비트 상수 0x1을 넣습니다. const/4 v3, 0x2 // 레지스터 v2에 4비트 상수 0x2를 넣습니다. add-int/2addr v2, v3 // 레지스터 v2에 v3를 더한다. add- int/2addr v3, v2 0xB0 0x32

Slide 21

Slide 21 text

자바와 달빅 bytecode가 다른데? javac desugar dex .java .class .class .dex

Slide 22

Slide 22 text

자바와 달빅 bytecode가 다른데? javac desugar dex .java .class .class .dex JAVA 8 기능을 사용하는 코드를 JAVA7 바이트 코드로 변형.

Slide 23

Slide 23 text

자바와 달빅 bytecode가 다른데? javac desugar dex .java .class .class .dex .class 파일을 dex(dx, d8)을 통해 .dex 파일로 변환

Slide 24

Slide 24 text

DX와 D8은 무엇인가요? dex .class .dex .class 파일을 dex(dx, d8)을 통해 .dex 파일로 변환 DX - 안드로이드 스튜디오 3.0 전. D8 - 안드로이드 스튜디오 3.0 이후. gradle.properties에서 android.enableD8 = true | false D8은 써드파티 툴에서 문제가 될 수 있다. - 새로운 DEX를 지원하지 못하는 문제.

Slide 25

Slide 25 text

DX와 D8은 무엇인가요?

Slide 26

Slide 26 text

DX와 D8은 무엇인가요?

Slide 27

Slide 27 text

D8가 진짜 좋나요? https://developer.android.com/studio/build/apk-analyzer

Slide 28

Slide 28 text

한번에 달빅 바이너리로 빌드하면 안되요? Jack & Jill .dex 구글은 Jack & Jill을 통해 한번에 빌드하는 것을 시도 .java

Slide 29

Slide 29 text

우리에겐 꿈과 희망이 없어. 렌더스크립트에 몰빵했던 투자했던 1인으로 구글의 신기술은 비판적으로 수용하게 됩니다…

Slide 30

Slide 30 text

구글은 결국 써드파티를 위한 API을 열었습니다. javac desugar 3rd party transformers dex 바이트 코드를 써드파티도 조작할 수 있다. Transform API

Slide 31

Slide 31 text

구글은 결국 써드파티를 위한 API을 열었습니다. Transformer .class .class 안드로이드 빌드 툴에서 제공하는 클래스 파일 변조 표준. 프로가드 등의 도구들도 Transform API에 의존적. 다만 여전히 Transform API를 사용하지 못하거나 이해하지 못하는 도구들이 존재.

Slide 32

Slide 32 text

구글은 결국 써드파티를 위한 API을 열었습니다. Transform을 상속받고 transform을 구현합니다. 입력으로 클래스 파일을 받아 출력으로 클래스를 내보내면 됩니다. (실제로는 다른 파일에 접근 가능하지만 대부분은 클래스에)

Slide 33

Slide 33 text

구글은 결국 써드파티를 위한 API을 열었습니다. ProGuard .class .class Realm Transformer .class .class Desugar .class .class 구글 코드들 조차도 표준화된 API를 따릅니다.

Slide 34

Slide 34 text

구글도 Transform API를 사용한다. 1. FixStackFramesTransform – 스택을 검증하기 위해 바이트 코드 재계산. 2. DesugarTransform – Java 8 코드의 기능을 Java 7으로 변경. (람다!) 3. StripDebugSymbolTransform – 네이티브 라이브러리 디버그 심볼 제거. 4. ProGuardTransform – 프로가드 적용 트랜스포머. 5. R8Transform – D8에 난독화를 추가한 R8을 적용. (신기능) 6. JarMergingTransform – 여러 Jar를 합쳐줌. 7. DexMergerTransform - 여러 Dex를 합침. ... https://android.googlesource.com/platform/tools/base/+/studio-master- dev/build-system/gradle- core/src/main/java/com/android/build/gradle/internal/transforms/

Slide 35

Slide 35 text

여러분도 Transformer를 만들고 싶다면 바이트 코드를 한땀 한땀 작성합시다.

Slide 36

Slide 36 text

여러분도 Transformer를 만들고 싶다면 ASM BCEL Javassist AspectJ Low Level High Level 바이트 코드를 손으로 한땀 한땀 조작 도구를 사용합시다. 구글은 ASM을 좋아하는 것 같으며, Realm은 Javassist를 선택했고, Jake Wharton이 AspectJ를 쓴 걸 봤어요.

Slide 37

Slide 37 text

안드로이드 코드의 특징 1. 이식에 좋은 바이트 코드를 사용. 2. 동적 컴파일에 기반한 성능 향상. 3. 의존성도 동적으로 로드. 4. 암호화되지 않은 클래스와 리소스로 구성. 5. 공간 효율적인 데이터 포맷.

Slide 38

Slide 38 text

동적 컴파일에 기반한 성능 향상 인터프리터 vs JIT vs AOT 1. 아무런 정보가 없었을 때 인터프리터로 해석. (느림) 2. 일정 횟수 이상 수행된 메서드만 컴파일해 JIT 코드 캐쉬에 저장. 3. 메서드 수행 시 JIT 코드 캐쉬에 있다면 인터프리터 대신 캐쉬 사용. 4. 프로파일링 정보에 기반해서 JIT 코드 캐쉬를 업데이트. 5. 주기적으로 dex2aot 데몬이 코드를 빌드해서 .oat 파일을 생성. 6. 다른 앱에 의해 사용되면 전체 빌드하고 아니면 프로파일에 기반해 빌드. 7. JIT 컴파일과 AOT 컴파일이 있다면 JIT 컴파일을 사용. (동적 최적화)

Slide 39

Slide 39 text

JIT + AOT

Slide 40

Slide 40 text

JIT 컴파일

Slide 41

Slide 41 text

AOT 컴파일

Slide 42

Slide 42 text

전체 컴파일

Slide 43

Slide 43 text

안드로이드 코드의 특징 1. 이식에 좋은 바이트 코드를 사용. 2. 동적 컴파일에 기반한 성능 향상. 3. 의존성도 동적으로 로드. 4. 암호화되지 않은 클래스와 리소스로 구성. 5. 공간 효율적인 데이터 포맷.

Slide 44

Slide 44 text

의존성도 동적으로 로드. 1. import / export 해야하는 부분은 숨길 수 없다. 2. 메서드 명, 클래스 명, 필드 명이 공개된다. 3. 안드로이드 앱의 경우 Activity, Fragment, Service 등을 외부로 공개해야 한다. 4. 난독화 도구에 exclude/include 항목을 설정해야 함.

Slide 45

Slide 45 text

안드로이드 코드의 특징 1. 이식에 좋은 바이트 코드를 사용. 2. 동적 컴파일에 기반한 성능 향상. 3. 의존성도 동적으로 로드. 4. 암호화되지 않은 클래스와 리소스로 구성. 5. 공간 효율적인 데이터 포맷.

Slide 46

Slide 46 text

암호화되지 않은 클래스와 리소스로 구성 1. 클래스와 리소스는 암호화되지 않음. 2. 기본 클래스 로더가 지원하지 않아 한계가 존재. 기본 클래스 로더가 호출되기 전에 암호화가 풀린 클래스를 가로챌 수 있음. 3. 클래스 암호화는 선호되는 보호 방법이 아님.

Slide 47

Slide 47 text

안드로이드 코드의 특징 1. 이식에 좋은 바이트 코드를 사용. 2. 동적 컴파일에 기반한 성능 향상. 3. 의존성도 동적으로 로드. 4. 암호화되지 않은 클래스와 리소스로 구성. 5. 공간 효율적인 데이터 포맷.

Slide 48

Slide 48 text

공간 효율적인 데이터 포맷 1. LEB-128을 사용하여 가변 바이트(1-5바이트)로 32비트 잘 저장. (최악의 경우에는 더 나빠질 수 있음.) 2. 부호가 있는 수를 위한 SLEB128, 부호없는 수를 위한 ULEB128과 -1만 지원하는 ULEB128p1이 있음. 3. 여러 클래스에서 상수를 공유. (Shared Constant Pool) 4. 상대 주소 사용. 5. 하지만 메서드 갯수까지 효율적으로 64K T.T

Slide 49

Slide 49 text

LEB-128 (Little Endian Base-128) 10011000011101100101 7비트 단위로 나누어 그룹화. 0100110 0001110 1100101

Slide 50

Slide 50 text

LEB-128 (Little Endian Base-128) 10011000011101100101 제일 앞 그룹은 0, 그 외는 앞에 1을 붙인다. 0100110 0001110 1100101 00100110 10001110 11100101

Slide 51

Slide 51 text

LEB-128 (Little Endian Base-128) 10011000011101100101 1. 가변 바이트를 사용해 작은 수는 더 적은 비트로 저장. (1바이트) 2. 최악의 경우 32비트 자료형을 5바이트로 저장할 수 있다. 3. SLEB128P는 전체 값이 -1이면 0이 된다. 음수 중 -1만 지원. 0100110 0001110 1100101 00100110 10001110 11100101

Slide 52

Slide 52 text

Shared Constant Pool

Slide 53

Slide 53 text

Shared Constant Pool

Slide 54

Slide 54 text

상대주소 fieldA 1024 fieldB 1 (1024 + 1)

Slide 55

Slide 55 text

안드로이드 코드를 어떻게 숨길까? 1. 클래스/리소스에 암호화를 적용한다. 2. 리소스 사이에 클래스를 매복시킨다. 3. 네이티브 코드로 핵심 코드를 숨긴다. 4. 서버에 핵심 코드를 숨긴다. 5. 템퍼 감지를 추가한다. 6. 클래스, 필드, 메서드 명을 변경한다. 7. 리플렉션 호출을 추가한다. 8. 노이즈 추가. 9. 제어 흐름.

Slide 56

Slide 56 text

안드로이드 코드를 어떻게 숨길까? 1. 클래스/리소스에 암호화를 적용한다. 2. 리소스 사이에 클래스를 매복시킨다. 3. 네이티브 코드로 핵심 코드를 숨긴다. 4. 서버에 핵심 코드를 숨긴다. 5. 템퍼 감지를 추가한다. 6. 클래스, 필드, 메서드 명을 변경한다. 7. 리플렉션 호출을 추가한다. 8. 노이즈 추가. 9. 제어 흐름.

Slide 57

Slide 57 text

클래스/리소스에 암호화를 적용한다. 1. 클래스를 암호화 하고 커스텀 로더를 사용하는 방법. 2. 암호화된 클래스와 로더를 가지는 패커(Packer)와 깨어진 클래스와 복구 코드를 가지는 프로텍터(Protector)로 나누어짐. 3. VM이 암호화된 클래스를 지원하지 않기 때문에 결국 해독을 하여 클래스를 전달해야 한다. 결국, 커스텀 로더가 공격의 취약점이 된다. 4. 많은 패커와 프로텍터는 ODEX 복사나 심지어 Dex2jar툴에 의해 쉽게 풀리기도 한다.

Slide 58

Slide 58 text

패커 (Packer) 클래스 로더 암호화된 코드를 해독. 암호화된 클래스 실제 코드가 암호화.

Slide 59

Slide 59 text

프로텍터 (Protector) 스텁 어플리케이션 깨어진 코드를 복구. 망가진 클래스 실제 코드가 깨어짐.

Slide 60

Slide 60 text

안드로이드 코드를 어떻게 숨길까? 1. 클래스/리소스에 암호화를 적용한다. 2. 리소스 사이에 클래스를 매복시킨다. 3. 네이티브 코드로 핵심 코드를 숨긴다. 4. 서버에 핵심 코드를 숨긴다. 5. 템퍼 감지를 추가한다. 6. 클래스, 필드, 메서드 명을 변경한다. 7. 리플렉션 호출을 추가한다. 8. 노이즈 추가. 9. 제어 흐름.

Slide 61

Slide 61 text

리소스 사이에 클래스를 매복시킨다. 1. 이미지 파일로 dex 파일을 숨기는 방법 등을 사용한다. 2. 수상하게 큰 파일을 찾거나 파일 포맷이 올바른지 검증하는 것만으로 혐의가 좁혀진다.

Slide 62

Slide 62 text

안드로이드 코드를 어떻게 숨길까? 1. 클래스/리소스에 암호화를 적용한다. 2. 리소스 사이에 클래스를 매복시킨다. 3. 네이티브 코드로 핵심 코드를 숨긴다. 4. 서버에 핵심 코드를 숨긴다. 5. 템퍼 감지를 추가한다. 6. 클래스, 필드, 메서드 명을 변경한다. 7. 리플렉션 호출을 추가한다. 8. 노이즈 추가. 9. 제어 흐름.

Slide 63

Slide 63 text

네이티브 코드로 핵심 코드를 숨긴다. 1. 성능 상의 이점이 있으며 기계어 코드가 자바 / 달빅의 바이트 코드보다 해석하기 어렵다는 장점이 있음. 하지만 인내가 있다면 결국 기계어 코드도 해석할 수 있다. 2. VM 밖은 위험하다. (온갖 하드웨어 이슈를 경험할 수 있다.) .so 파일이 간혈적으로 설치되지 않는 문제 발생. POSIX 함수가 목업이었던 B사. OpenSSL이 목업이었던 L사. 메모리 할당량을 잘못 알려주었던 S사. 재현 불가능한 이슈도 동작한다. 3. ABI 세트를 맞추기 어렵다.

Slide 64

Slide 64 text

VM 밖은 위험하다. 강제로 .so 파일을 재설치하는 라이브러리 ReLinker

Slide 65

Slide 65 text

VM 밖은 위험하다.

Slide 66

Slide 66 text

VM 밖은 위험하다.

Slide 67

Slide 67 text

ABI 세트를 맞추기 어렵다.

Slide 68

Slide 68 text

안드로이드 코드를 어떻게 숨길까? 1. 클래스/리소스에 암호화를 적용한다. 2. 리소스 사이에 클래스를 매복시킨다. 3. 네이티브 코드로 핵심 코드를 숨긴다. 4. 서버에 핵심 코드를 숨긴다. 5. 템퍼 감지를 추가한다. 6. 클래스, 필드, 메서드 명을 변경한다. 7. 리플렉션 호출을 추가한다. 8. 노이즈 추가. 9. 제어 흐름.

Slide 69

Slide 69 text

서버에 핵심 코드를 숨긴다. 1. 리얼 타임 응답성이 떨어진다. 웹 소켓 등의 상시 연결을 하더라도 로컬만큼 쾌적하기 어렵다. 응답성을 올리기 위해 로컬 데이터베이스등이 필요할 수 있다. 2. 서버가 다운된 경우 어플리케이션을 사용할 수 없다. 로컬 캐쉬를 이용해서 폴백을 구현하기 쉽지 않다.

Slide 70

Slide 70 text

안드로이드 코드를 어떻게 숨길까? 1. 클래스/리소스에 암호화를 적용한다. 2. 리소스 사이에 클래스를 매복시킨다. 3. 네이티브 코드로 핵심 코드를 숨긴다. 4. 서버에 핵심 코드를 숨긴다. 5. 템퍼 감지를 추가한다. 6. 클래스, 필드, 메서드 명을 변경한다. 7. 리플렉션 호출을 추가한다. 8. 노이즈 추가. 9. 제어 흐름.

Slide 71

Slide 71 text

템퍼 감지를 추가한다. 1. 디버거, ptrace를 발견하는 코드를 삽입한다. 2. 에뮬레이터 등에 감지한다. 3. 해당 부분을 우회하면 대부분 앱에 진입할 수 있다.

Slide 72

Slide 72 text

안드로이드 코드를 어떻게 숨길까? 1. 클래스/리소스에 암호화를 적용한다. 2. 리소스 사이에 클래스를 매복시킨다. 3. 네이티브 코드로 핵심 코드를 숨긴다. 4. 서버에 핵심 코드를 숨긴다. 5. 템퍼 감지를 추가한다. 6. 클래스, 필드, 메서드 명을 변경한다. 7. 리플렉션 호출을 추가한다. 8. 노이즈 추가. 9. 제어 흐름.

Slide 73

Slide 73 text

클래스, 필드, 메서드 등의 이름을 변경한다. 1. 무료 도구인 ProGuard 부터 대부분의 도구가 지원. 2. 짧고 간결한 이름으로 클래스, 필드, 메서드의 이름을 변경. 단 외부에서 import되거나 export되는 명칭들은 변경될 수 없음. 3. 짧고 간결한 이름의 경우 공간 복잡도도 줄이고 실행 시간에도 긍정적인 영향을 줄 수 있음. 4. 명칭이 바뀌는 것이기 때문에 공격자의 인내로 해결 가능. 5. 도구마다 고유의 네이밍 패턴이 있음. (APKiD에서 검출)

Slide 74

Slide 74 text

Arxan이 가지는 네이밍 패턴

Slide 75

Slide 75 text

안드로이드 코드를 어떻게 숨길까? 1. 클래스/리소스에 암호화를 적용한다. 2. 리소스 사이에 클래스를 매복시킨다. 3. 네이티브 코드로 핵심 코드를 숨긴다. 4. 서버에 핵심 코드를 숨긴다. 5. 템퍼 감지를 추가한다. 6. 클래스, 필드, 메서드 명을 변경한다. 7. 리플렉션 호출을 추가한다. 8. 노이즈 추가. 9. 제어 흐름.

Slide 76

Slide 76 text

리플렉션 호출을 추가 1. 메서드 호출에 단계를 추가하여 해석하기 어렵게 만듬. 2. ProGuard는 지원하지 못하지만 DexGuard나 Arxan 등의 유료 도구에서 지원. 3. 리플렉션이 반복적인 패턴을 가지기 때문에 기계적으로 풀 수 있음. (예: Dex-Oracle에서 DexGuard 패턴 해제.) 4. 많은 단말에서 리플렉션 크래시가 보고됨. 리플렉션 실행이 랜덤하게 실패하는 것으로 보임. (혼탁한 안드로이드의 세계)

Slide 77

Slide 77 text

리플렉션 호출을 추가

Slide 78

Slide 78 text

안드로이드 코드를 어떻게 숨길까? 1. 클래스/리소스에 암호화를 적용한다. 2. 리소스 사이에 클래스를 매복시킨다. 3. 네이티브 코드로 핵심 코드를 숨긴다. 4. 서버에 핵심 코드를 숨긴다. 5. 템퍼 감지를 추가한다. 6. 클래스, 필드, 메서드 명을 변경한다. 7. 리플렉션 호출을 추가한다. 8. 노이즈 추가. 9. 제어 흐름.

Slide 79

Slide 79 text

노이즈 추가 1. 메서드 외부에 아무런 영향이 없는 코드를 추가. 2. 클래스 상태 변경, I/O, 반환 값 등이 없음. 3. 디버거나 디스컴파일러가 깨지는 코드를 추가하기도 한다. 하지만 몇 줄로 망가트린 문제는 그만큼 쉽게 고쳐진다.

Slide 80

Slide 80 text

노이즈 추가 1201 3801 0300 FFFF V1에 0을 적재 다음줄 스킵 불량 코드

Slide 81

Slide 81 text

안드로이드 코드를 어떻게 숨길까? 1. 클래스/리소스에 암호화를 적용한다. 2. 리소스 사이에 클래스를 매복시킨다. 3. 네이티브 코드로 핵심 코드를 숨긴다. 4. 서버에 핵심 코드를 숨긴다. 5. 템퍼 감지를 추가한다. 6. 클래스, 필드, 메서드 명을 변경한다. 7. 리플렉션 호출을 추가한다. 8. 노이즈 추가. 9. 제어 흐름.

Slide 82

Slide 82 text

제어 흐름 1. 반복문이나 분기문을 불 필요하게 추가. 2. If문 대신 try-catch 블록을 사용하기도 함. (Replacing if null instructiions with try-catch blocks) 3. Switch 문을 중첩적인 레이블로 변경하기도 함. (Partially trapping switch statements) 4. 브랜치를 jsr 명령 (goto)로 변환하기도 함. (Converting branches to jsr instructions) 일반적으로 속도를 저하시키는 요인.

Slide 83

Slide 83 text

프로가드는 무엇을 지원할까? 1. 클래스/리소스에 암호화를 적용한다. 2. 리소스 사이에 클래스를 매복시킨다. 3. 네이티브 코드로 핵심 코드를 숨긴다. 4. 서버에 핵심 코드를 숨긴다. 5. 템퍼 감지를 추가한다. 6. 클래스, 필드, 메서드 명을 변경한다. 7. 리플렉션 호출을 추가한다. 8. 노이즈 추가. 9. 제어 흐름.

Slide 84

Slide 84 text

프로가드는 무엇을 지원할까? 1. 클래스/리소스에 암호화를 적용한다. 2. 리소스 사이에 클래스를 매복시킨다. 3. 네이티브 코드로 핵심 코드를 숨긴다. 4. 서버에 핵심 코드를 숨긴다. 5. 템퍼 감지를 추가한다. 6. 클래스, 필드, 메서드 명을 변경한다. 7. 리플렉션 호출을 추가한다. 8. 노이즈 추가. 9. 제어 흐름. 10. 사용하지 않은 클래스, 필드, 메서드 제거.

Slide 85

Slide 85 text

프로가드는 무엇을 지원할까? ProGuard .class .class Shrinker .class .class Name Obfuscator .class

Slide 86

Slide 86 text

안드로이드 빌드에 통합된 프로가드 ProGuard Transform javac Desugar Transform ProGuard .java .class .class .class Dex .dex 제대로 통합되지 않은 툴이 많은 것을 감안하면 엄청난 장점.

Slide 87

Slide 87 text

통합되지 않은 난독화 도구들의 흐름 javac Desugar Transform .java .class .class Dex .dex Dex2jar Obfuscator .class .class .class Dex .dex

Slide 88

Slide 88 text

구글의 신 병기 R8 R8 javac Desugar Transform .java .class .class .dex R8 = D8 + Shrinker + Name Obfuscator https://android.googlesource.com/platform/external/r8/ ProGuard를 버리겠다는 계획. 갑자기 괜히 렌더스크립트, Jack & Jill을 불러보고 싶다.

Slide 89

Slide 89 text

일관성 (Consistency) 가용성 (Availability) 분할내성 (Partial tolerance) 데이터베이스에 CAP 정리가 있다.

Slide 90

Slide 90 text

성능 (Performance) 안정성 (Relability) 보안 (Security) 앱에서 아래 셋은 다 가질 수 있는 것인가? (PRS?) 방금 지어냄.

Slide 91

Slide 91 text

감사합니다.