사용. 스택에서 입력 받고 결과도 스택으로. 2. 32비트 스택 하나의 요소가 대부분의 타입을 커버. 3. char을 사용해도 기본적으로는 메모리에 이점이 없다. 4. 64비트가 필요한 자료형(double, long)을 사용할 경우 스택 두 요소. 5. 256개의 연산 (실제로는 예약어가 많음.) 6. 스택 기반은 검증하기 쉬움. 7. 레지스터 기반의 실제 기기와 차이가 있어 성능상 단점.
사용. 2. 64K 개의 레지스터 하지만 주로 앞의 256개, 가끔은 16개만 사용. 3. 32비트 레지스터 하나의 요소가 대부분의 타입을 커버. 4. char을 사용해도 기본적으로는 메모리에 이점이 없다. 5. 64비트가 필요한 자료형(double, long)을 사용할 경우 레지스터 2개. 6. 200여개의 연산. 7. 실제 하드웨어와 매핑에 이점. 성능 상의 이점. 메모리를 덜 씀. 8. 상대적으로 검증이 어려움.
통해 .dex 파일로 변환 DX - 안드로이드 스튜디오 3.0 전. D8 - 안드로이드 스튜디오 3.0 이후. gradle.properties에서 android.enableD8 = true | false D8은 써드파티 툴에서 문제가 될 수 있다. - 새로운 DEX를 지원하지 못하는 문제.
1. 아무런 정보가 없었을 때 인터프리터로 해석. (느림) 2. 일정 횟수 이상 수행된 메서드만 컴파일해 JIT 코드 캐쉬에 저장. 3. 메서드 수행 시 JIT 코드 캐쉬에 있다면 인터프리터 대신 캐쉬 사용. 4. 프로파일링 정보에 기반해서 JIT 코드 캐쉬를 업데이트. 5. 주기적으로 dex2aot 데몬이 코드를 빌드해서 .oat 파일을 생성. 6. 다른 앱에 의해 사용되면 전체 빌드하고 아니면 프로파일에 기반해 빌드. 7. JIT 컴파일과 AOT 컴파일이 있다면 JIT 컴파일을 사용. (동적 최적화)
잘 저장. (최악의 경우에는 더 나빠질 수 있음.) 2. 부호가 있는 수를 위한 SLEB128, 부호없는 수를 위한 ULEB128과 -1만 지원하는 ULEB128p1이 있음. 3. 여러 클래스에서 상수를 공유. (Shared Constant Pool) 4. 상대 주소 사용. 5. 하지만 메서드 갯수까지 효율적으로 64K T.T
수는 더 적은 비트로 저장. (1바이트) 2. 최악의 경우 32비트 자료형을 5바이트로 저장할 수 있다. 3. SLEB128P는 전체 값이 -1이면 0이 된다. 음수 중 -1만 지원. 0100110 0001110 1100101 00100110 10001110 11100101
방법. 2. 암호화된 클래스와 로더를 가지는 패커(Packer)와 깨어진 클래스와 복구 코드를 가지는 프로텍터(Protector)로 나누어짐. 3. VM이 암호화된 클래스를 지원하지 않기 때문에 결국 해독을 하여 클래스를 전달해야 한다. 결국, 커스텀 로더가 공격의 취약점이 된다. 4. 많은 패커와 프로텍터는 ODEX 복사나 심지어 Dex2jar툴에 의해 쉽게 풀리기도 한다.
기계어 코드가 자바 / 달빅의 바이트 코드보다 해석하기 어렵다는 장점이 있음. 하지만 인내가 있다면 결국 기계어 코드도 해석할 수 있다. 2. VM 밖은 위험하다. (온갖 하드웨어 이슈를 경험할 수 있다.) .so 파일이 간혈적으로 설치되지 않는 문제 발생. POSIX 함수가 목업이었던 B사. OpenSSL이 목업이었던 L사. 메모리 할당량을 잘못 알려주었던 S사. 재현 불가능한 이슈도 동작한다. 3. ABI 세트를 맞추기 어렵다.
부터 대부분의 도구가 지원. 2. 짧고 간결한 이름으로 클래스, 필드, 메서드의 이름을 변경. 단 외부에서 import되거나 export되는 명칭들은 변경될 수 없음. 3. 짧고 간결한 이름의 경우 공간 복잡도도 줄이고 실행 시간에도 긍정적인 영향을 줄 수 있음. 4. 명칭이 바뀌는 것이기 때문에 공격자의 인내로 해결 가능. 5. 도구마다 고유의 네이밍 패턴이 있음. (APKiD에서 검출)
대신 try-catch 블록을 사용하기도 함. (Replacing if null instructiions with try-catch blocks) 3. Switch 문을 중첩적인 레이블로 변경하기도 함. (Partially trapping switch statements) 4. 브랜치를 jsr 명령 (goto)로 변환하기도 함. (Converting branches to jsr instructions) 일반적으로 속도를 저하시키는 요인.
클래스를 매복시킨다. 3. 네이티브 코드로 핵심 코드를 숨긴다. 4. 서버에 핵심 코드를 숨긴다. 5. 템퍼 감지를 추가한다. 6. 클래스, 필드, 메서드 명을 변경한다. 7. 리플렉션 호출을 추가한다. 8. 노이즈 추가. 9. 제어 흐름. 10. 사용하지 않은 클래스, 필드, 메서드 제거.