Android Dynamic Debugging
테스트 환경 #
- IDA 8.3 Pro
- Pixel 6a AOS 13
IDA #
DEX #
-
앱이나 기기를 디버그 모드로 변경한다
- 앱 리패키징
- AndroidManifest.xml 의 application 태그에
android:debuggable=true를 세팅하고 리패키징 한다.
- AndroidManifest.xml 의 application 태그에
- 또는 MagiskHidePropsConfig 모듈을 사용한다.
- adb shell에서 su 권한 획득 후
props명령 실행 - Add custom props 옵션을 선택해서
ro.debuggable값을1로 설정한다. - 재부팅 후
getprop ro.debuggable로 값을 확인한다. - 개발자 모드나
am set-debug-app -w <package>명령으로 디버그앱으로 설정한다. (혹은am start -D -n <package>/<activity>로 디버그로 실행해도 된다.)- 디버그앱에서 지울땐 adb shell am clear-debug-app
- adb shell에서 su 권한 획득 후
- 앱 리패키징
-
실행할 메인액티비티 설정
Debugger → Debugger options → Set specific options
Fill from AndroidManifest.xml 클릭 후 앱 선택하면 설정할 수 있다.
굳이 추가 옵션을 주지 않더라도 -D 를 사용해서 디버그 모드로 액티비티를 실행한다. -
원하는 위치에 브레이크 포인트를 걸고 실행
DEX 디버깅은 IDA와 프로세스가 PID와 동일한 jdwp로 통신하기 때문에 android_server를 실행시키지 않아도 된다.
SO #
-
(선택) 앱을 디버그 모드로 변경한다.
-
디버깅용 앱을 대기하게 한다. (여기까진 DEX와 동일함)
- 대기시키지 않고 attach 해도 되지만, 앱의 처음 시작부터 분석하기 위해 대기하게 한다.
- 대기하는 방법은
frida --pause옵션을 사용하거나jdwp(dex 디버깅)를 사용할 수 있다. - jdwp 이용하려면 앱이 디버그 모드여야 한다.
-
루팅된 기기에 IDA의 android_server64를 넣고 권한을 준 후 실행시킨다.
-
adb forward tcp:23949 tcp:23946
-
Debugger → Process Option → Remote Android → 127.0.0.1 / 23949 입력 → OK
-
브레이크 포인트를 걸어둔 후 Debugger → Attach to process → 원하는 프로세스 선택
attach 트랩에서 멈추게 된다.
- frida에서 %resume → IDA에서 Continue → same 클릭 디버깅으로 실행되기 때문에 매우 느리지만 언젠가 브레이크포인트에서 멈추게 된다. (그전에 디버깅이 감지되지 않는다면..)
발생할 수 있는 에러 종류 #
Permission Denial: starting Intent #
activity-alias가 설정된 actiivty의 경우 실제 액티비티의 이름으로 접근할 수 없고 별칭으로 접근해야 한다.
IDA에서 2번을 설정할 때 activity 기준으로 am start 명령을 만들기 때문에 권한이 부족하다는 에러가 발생했던 것이다.
1# IDA에서 생성한 인텐트
2$ adb shell am start -D -n 'com.teamviewer.teamviewer.market.mobile/com.teamviewer.remotecontrolviewlib.activity.MainActivity'
3Starting: Intent { ... }
4Exception occurred while executing 'start':
5java.lang.SecurityException: Permission Denial: starting Intent { ... }
6
7# 별칭 이름으로 인텐트를 생성하면 잘 실행된다.
8$ adb shell am start -D -n com.teamviewer.teamviewer.market.mobile/com.teamviewer.remotecontrollib.activity.MainActivity
그럴땐 그냥 직접 activity를 지정해주면 된다.
Timedout while waiting for a JWDP reply #
찾아보니 dex가 너무 크기때문에 발생한 문제라고 한다.
1# 1. baksmali로 dex 파일 풀기
2$ java -jar baksmali.jar d <input.dex> -o <output_dir>
3
4# 2. 필요없는 패키지 삭제
5
6# 3. smali로 다시 패키징
7$ java -jar smali.jar a output_smali -o new_classes.dex