
컴파일된 DEX 아티팩트를 직접 조회하여 전처리 없이 밀리초 단위로 클래스와 상호 참조를 추출하는 빠른 Android APK 디컴파일러 프런트엔드입니다.
대규모 Android APK를 디컴파일할 때, 표준 절차는 기다리는 것입니다. 도구가 기가바이트의 RAM을 소비하고, 아티팩트를 완전히 부풀리며, 무거운 전역 인덱스와 상호 참조를 구축하는 데 수십 분을 소비할 때까지 기다립니다... 이 모든 것은 나중에 빠른 코드 검색을 보장하기 위한 것이지만, 여기에 모순이 있습니다. 컴파일된 아티팩트는 이미 고도로 구조화되어 있는데, 현대 디컴파일러는 이를 활용하지 않고 이미 구조화된 데이터 위에 부풀려진 코드 관계 데이터베이스를 재구성하는 데 막대한 시간과 메모리를 낭비합니다. 이러한 엔지니어링 접근 방식은 상식을 벗어납니다. APK에서 밀리초 단위로 모든 코드 관계를 직접 추출할 수 있다면, 이러한 전처리가 여전히 가치가 있을까요?
디컴파일러를 무거운 전처리에 강제로 넣는 대신, 우리는 컴파일된 아티팩트를 데이터베이스로 직접 쿼리하기로 선택했습니다. 우리는 밀리초 단위로 요청 시 코드를 추출하고 검색하는 상태 비저장, 제로 오버헤드 엔진을 구축했습니다. 이 브리핑에서는 전통적인 병목 현상을 우회하는 데 필요한 근본적인 엔지니어링을 탐구합니다. Deflate 비트스트림 내부에서 직접 탐색하여 전체 인플레이트를 포기하고, 관련 없는 데이터 블록을 건드리지 않고 핵심 메타데이터를 추출하기 위한 조밀한 Huffman 조회 테이블을 구축하는 방법을 시연합니다. 또한 R8 컴파일러의 최적화 세부 사항, 특히 결정론적 상수 재배치와 명령어 중복 제거가 어떻게 고도로 집중된 물리적 레이아웃을 남기는지 설명하고, 이 컴파일러 동작을 무기화하여 번개처럼 빠른 교차 DEX 코드 검색을 실행합니다. 이러한 원시 바이트코드 오프셋을 메서드에 다시 매핑하기 위해, 우리는 O(1) 명령어 위치 지정 프리미티브를 설계하여 무거운 매핑 테이블을 구축하지 않고도 상수 시간 메서드 해석을 달성했습니다. 마지막으로, 목표에 도달하면 Droid ASC는 특정 바이트코드와 그 종속성만 추출하여 즉각적인 디컴파일을 위해 메모리 내에서 최소한의 자기 일관성 있는 DEX를 동적으로 재구성합니다.
우리는 352MB 상용 APK에 대해 이 아키텍처를 라이브로 시연할 것입니다. Droid ASC는 1.79초 만에 전역 상호 참조 검색을 실행하고 141MB의 RAM만 사용하여 177밀리초 만에 대상 클래스를 디컴파일합니다. 아티팩트를 읽기 전용 데이터베이스로 취급하고 제로 전처리로 작동함으로써, 우리는 디컴파일러를 핵심 본질로 되돌립니다. 더 이상 부풀려진 인덱싱 도구가 아니라, 컴파일된 코드를 분석하는 방식을 근본적으로 재정의하는 번개처럼 빠른 온디맨드 디컴파일 엔진입니다.

https://github.com/user-attachments/assets/4c4a6813-8561-490c-a573-ef113da861b6
# from PyPI
pip install droidasc
# or from source
pip install .
설치 후 droidasc CLI 명령을 전역적으로 사용할 수 있습니다:
usage: droidasc [-h] {getclass,listclass,getmanifest,findrefs} ...
ASC tooling entry.
positional arguments:
{getclass,listclass,getmanifest,findrefs}
getclass Locate the target class in APK, extract one DEX in memory, then decompile.
listclass List classes defined across all DEX entries in APK.
getmanifest Decode AndroidManifest.xml from APK and print it as XML.
findrefs Find code references for string/type/method/field across all DEX entries in APK.
options:
-h, --help show this help message and exit
examples:
droidasc app.apk --gui
droidasc getclass app.apk Lcom/poc/Main; -o Main.java
droidasc getclass app.apk com.poc.Main --threads 16
droidasc listclass app.apk -o classes.txt
droidasc listclass app.apk --prefix com.poc
droidasc getmanifest app.apk -o AndroidManifest.xml
droidasc findrefs app.apk string token -o string_refs.txt
droidasc findrefs app.apk type com.poc.Main
droidasc findrefs app.apk method onCreate --class com.poc.Main
droidasc findrefs app.apk method notify --class MainActivity --fuzzy-class -o method_refs.txt
droidasc findrefs app.apk field apiKey -o field_refs.txt
listclass는 APK/DEX 정의 순서대로 Dalvik 클래스 디스크립터를 한 줄에 하나씩 출력합니다. -o를 사용하면 출력이 stdout 대신 선택한 파일에 기록됩니다. --prefix com.poc는 Lcom/poc로 필터링합니다. 이미 정규화된 접두사(예: Lcom/poc)는 변경되지 않고 유지됩니다.
이전과 같이 python main.py를 사용할 수도 있습니다 — 동일한 진입점으로 위임됩니다.
| 스폰서 | 금액 |
|---|---|
| HTTChina | 5000¥ |
| c01ns | 11.9¥ |
| gguowang AND cococount | 2¥ |
| Ylarod | 50.11¥ |
모든 스폰서의 지원에 감사드립니다!
ASC는 모든 사람이 리버스 엔지니어링 워크플로우를 개선하는 데 실질적으로 도움이 되기를 바라는 마음으로 만들어졌습니다 — 지루한 부분을 가속화하는 것부터 불가능한 일을 일상적으로 느끼게 하는 것까지.
Droid ASC에서 사용하는 Android 리버스 엔지니어링 및 DEX 분석 기반을 제공한 Androguard 프로젝트에 감사드립니다.