apk 파일만 덩그러니 놓여있을 때, apk 파일의 매니패스트 정보를 추출할 수 있는 방법

AndroidStudio 에서 제공하는 AAPT2 를 이용하는 방법으로

주로 패키지명, Activity 구조, 권한 정보 등을 추출할 때 사용한다.

매번 아주 친절하게 정보를 제공하는 Android 개발자 사이트에 AAPT2 또한 친절히 설명되어 있다.

여기서 주목할 부분은 바로 덤프 (dump) 다.

 

 

AAPT2  |  Android 개발자  |  Android Developers

AAPT2(Android Asset Packaging Tool)는 Android 스튜디오 및 Android Gradle 플러그인이 앱의 리소스를 컴파일하고 패키징하는 데 사용하는 빌드 도구입니다. AAPT2는 리소스를 Android 플랫폼에 최적화된 바이너리

developer.android.com

우선 AAPT 명령어를 사용하기 위해선 Android Studio의 SDK가 설치 된 상태여야 한다.

(버전 상관없이) SDK 설치가 됐다면 다음과 같은 순서로 진행한다.


추출 방법

1. aapt.exe 파일의 디렉토리 복사
보통 C:\Users\윈도우사용자명\AppData\Local\Android\Sdk\build-tools\SDK버전 인 경우가 많다.
※ 필자의 경우 SDK 30 버전이지만, 어떤 버전이든 무관하다.

2. 명령 프롬프트 - 복사해 둔 aapt 디렉토리로 이동 (cd 디렉토리)

Microsoft Windows [Version 10.0.18362.1082]
(c) 2019 Microsoft Corporation. All rights reserved.

C:\Users\UserName> cd C:\Users\UserName\AppData\Local\Android\Sdk\build-tools\SDK버전

--------------실행 결과--------------
C:\Users\UserName\AppData\Local\Android\Sdk\build-tools\SDK버전>

 

3. 매니패스트 정보를 조회할 apk 디렉토리 복사

4. 명령 프롬프트 - aapt dump badging 디렉토리 명령어 실행

aapt dump badging C:\Users\UserName\Desktop\Test\apk\test.apk

-------------- 실행결과 (apk 크기에 따라 굉장히 방대한 양이 나올 수 있으나, 주요 정보만 표기) --------------

package: name='패키지명' versionCode='■■' versionName='■.■.■' compileSdkVersion='■■' compileSdkVersionCodename='■■'
sdkVersion:'■■'
targetSdkVersion:'■■'
uses-permission: name='권한 정보'
launchable-activity: name='기본 액티비티명'

 

(+)

전체적인 매니패스트 구조를 보려면 다음 명령어를 실행하면 모든 Activity 정보를 확인할 수 있다.

aapt dump xmltree C:\Users\UserName\Desktop\Test\apk\test.apk AndroidManifest.xml

 

 

Selenium을 기반으로 하는 APPIUM을 Python Client로 작성 중이라면 굉장히 유용한 사이트

 

 

Selenium with Python — Selenium Python Bindings 2 documentation

Note This is not an official documentation. If you would like to contribute to this documentation, you can fork this project in GitHub and send pull requests. You can also send your feedback to my email: baiju.m.mail AT gmail DOT com. So far 50+ community

selenium-python.readthedocs.io

 

Appium 을 이용한 테스트자동화 프로그램 구축 시
기본적으로 appium 에서는 테스트를 진행할 때마다 새롭게 앱 설치를 진행한다.

(정확히 말하면 Session이 새로 시작될 때마다)
그런데 테스트 사전 세팅이 필요한 경우 매번 앱이 초기화 상태가 되면서 진행이 굉장히 번거로워진다.

 

해결 방안은 Desired Capabilities 설정 차이 !

 


새로 apk 설치 후 테스트 진행

Desired Capabilities에 app 속성에 테스트 apk 를 설정한다.

# 테스트 apk 경로 지정
app = os.path.join(os.path.dirname(__file__), 'C://apk 디렉토리', '파일명.apk')
app = os.path.abspath(app)

desired_caps = {
  'platformName': 'Android',
  'platformVersion': '10',
  'deviceName': 'VELVET',
  'automationName': 'Appium',
  'app': app,
  'appPackage': 'com.application.test',
  'appActivity': 'com.application.test.Activity'
}
self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)

 

이미 설치되어 있는 앱으로 테스트 진행

Desired Capabilities에 app 속성 제거 / noReset = True , fullReset = False 속성값 추가

desired_caps = {
  'platformName': 'Android',
  'platformVersion': '10',
  'deviceName': 'VELVET',
  'automationName': 'Appium',
  'appPackage': 'com.application.test',
  'appActivity': 'com.application.test.Activity',
  'noReset': True,
  'fullReset': False
}
self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)

'Test Automation > APPIUM' 카테고리의 다른 글

APPIUM 스크롤  (0) 2022.01.11
APPIUM logcat 가져오기 : get_log 활용법  (0) 2020.12.08
APPIUM TimeoutException 예외처리  (0) 2020.12.08
APPIUM Desired Capabilities 설정 방법  (0) 2020.12.06
APPIUM Selenium with Python  (0) 2020.12.06

※ LG VELVET 단말 기준으로 단말마다 화면/메뉴 이름이 다를 수 있음

 

타이틀개발자 옵션 ON

1. 연결할 단말의 '설정 앱 - 시스템 - 휴대폰 정보 - 소프트웨어 정보' 화면으로 이동한다.
2. '빌드 번호'를 7회 터치​한다. (친절하게 '개발자가 되려면 N단계 남았습니다.' 라는 토스트가 표시 된다.)
3. '개발자가 되셨습니다.' 토스트가 표시 되면 완료
4. 시스템 화면으로 이동하면 '개발자 옵션' 메뉴가 생성 된다.

 

 

타이틀USB 디버깅 ON

1. 스마트폰을 USB 연결선을 이용하여 PC와 연결한다.
2. USB 연결 옵션을 '사진 및 동영상 전송(PTP)'로 설정한다. ★★★ '파일 전송(MTP)'이면 안되는 경우 ! 
3. 연결한 단말의 '설정 앱 - 시스템 - 개발자 옵션' 화면으로 이동한다.
4. 'USB 디버깅' ON
5. 'USB 디버깅을 허용하시겠습니까?' 다이얼로그창에서 '허용' 
6. PC에 연결한 컴퓨터 RSA 키 지문이 적힌 다이얼로그창에서 '허용'

 

연결 확인

1. 명령 프롬프트 실행 (윈도우 키 + X)
2. adb devices 명령어 입력
3. 연결한 단말의 UDID 옆에 device가 뜨면 성공 !
※ unauthorized 로 뜨면 연결된 PC가 허용되지 않은 상태

C:\Users\UserName>adb devices
List of devices attached
LMG900Nd2e163d1 unauthorized // USB 디버깅 연결 비허용
LMG900Nd2e163d1 device // USB 디버깅 연결 허용

 

테스트 자동화 프로그램을 구축하면서 많이 쓰는 adb 명령어 !

adb 명령어를 사용하려면 환경변수 설정을 해줘야 한다.


사전준비

1. Android Studio SDK 설치

 

Download Android Studio and SDK tools  |  Android 스튜디오

developer.android.com

2. adb.exe 파일의 디렉토리 파악

보통 C:\Users\윈도우사용자명\AppData\Local\Android\Sdk\platform-tools 인 경우가 많다.

adb.exe 파일이 있는 platform-tools 의 디렉토리 파악

환경변수 설정

1. 윈도우 탐색창에서 제어판 - 시스템 환경 변수 편집 실행

 

탐색창에 '환경' 검색 후 실행

 

3. 시스템 속성 - 환경 변수 - Path - 편집 - 새로 만들기 - platform-tools 경로 추가

 

하는 김에 Sdk\emulator 와 Sdk\tools 도 하면 유용하다.

4. 명령 프롬프트 - adb 명령어 수행 결과 확인

 

실행 (윈도우 키 + R) - cmd 입력 (명령 프롬프트 실행) - adb

 

PC에 연결된 디바이스 확인하기

명령 프롬프트 - adb devices 명령어 입력

C:\Users\UserName> adb devices
List of devices attached
LMG900Nd2e163d1 device
emulator-5554   device

실제단말(LMG900Nd2e163d1), 애뮬레이터(emulator-5554) 모두 표시 된다.

명령어 수행 결과에는 USB 디버그 모드가 켜진 단말만 표시 된다.

switch-case문

추가설명동일한 결과값을 수행하는 case는 하나로 묶기
특정 결과값보다는 연산이 필요한 case는 default로 빼내고 매소드 불러오기

switch(입력값) {
  case 1: case 3: case 5:
    수행문1;
    break;
  case 2: case 4: case 8:
    수행문2;
    break;
  case default: // 9, 0 등 위 조건에 해당하지 않는 값
    수행문3;
    break;
}
특정 값 포함 여부 확인

ArrayList 클래스 내부에 특정 데이터가 포함되는지 True/False 형태로 출력

ArrayList<Integer> array = new ArrayList<Integer>(); // 정수형 ArrayList 선언

// array 내부에 데이터 삽입 //

array.contains(1); // array 내부에 1 이라는 데이터가 있으면 True / 없으면 False 반환

 

특정 값 삭제

ArrayList 클래스 내부에 특정 값 삭제

ArrayList의 데이터를 삭제하는 remove 매소드는 Index를 인자로 받으므로, 특정 값의 Index 필요

즉, 특정 값의 Index를 반환하는 indexOf 매소드를 함께 사용한다.

array.remove(array.indexOf(1)); // array 내부에 1 이라는 데이터를 삭제

 

두 배열 데이터 비교하기

한 배열(arr1)의 데이터 중 다른 배열(arr2)에 포함되어 있지 않은 데이터 추출

* arr1에는 중복값이 있을 수 있으며, arr2에 중복값 갯수만큼 데이터가 존재하지 않으면 미포함으로 본다.

 for (int i=0; i<arr1.length; i++) {
             boolean key=false; // 포함여부 확인을 위한 플래그
            
                for (int j=0; j<arr2.length; j++) {
                    if (arr[i].equals(arr2[j])) {
                        key = true;
                        arr2[j]=null; // 한번 사용한 데이터는 삭제하고,
                        break; // 이후 데이터는 건드리지 않는다.
                    }
                }            
                if (key == false) {
                     answer = arr1[i];
                     break;
                }

 

HashMap 사용하기

Key 값과 Value 값을 이용하여 데이터에 접근할 수 있는 자료형

* Key값으로 Value 값을 불러오는 개념으로 Key값은 중복 될 수 없다.

import java.util.HashMap; // HashMap 사용을 위해 import 필수

//HashMap 선언 - String형의 Key값과 Integer형의 Value값 사용 (객체 타입만 사용 가능)
HashMap <String, Integer> example = new HashMap<String, Integer>();

//주요 매소드
example.put("Test1", 1); // 데이터 삽입
example.get("Test1") // Key(Test1)에 해당하는 Value값(1) 반환
example.containsKey("Test1") // Key값에 "Test1" 포함여부 반환 (True/False)
example.containsValue("1") // Value값에 "1" 포함여부 반환 (True/False)

배열을 사용할 때는 Arrays 클래스 활용하자 !

기본적이지만 index는 0부터 시작한다는 걸 항상 기억하자 !

 


배열 추출/분리하기

array (원본 배열)의 start번째부터 end번째까지 추출하여 arr (결과) 배열을 생성한다.

int[] arr = Arrays.copyOfRange(array, start, end);

 

 

배열 정렬하기

array 배열의 원소들을 오름차순으로 정렬한다. (숫자, 문자, 문자열 다 가능)

Arrays.sort(array); // 오름차순

//객체타입 배열은 내림차순 적용 가능 (int형 → Integer 객체타입 변환 필요)
Arrays.sort(array,Collections.reverseOrder());

이 방법은 jks 파일을 가지고 있으나, keystore 암호를 잃어버렸을 때 사용할 수 있다.

 


 

1. keystore(jks) 파일 경로에 AndroidKeystoreBrute.jar 다운로드

아래 링크에 접속해서 최신 버전 tool Download

 

Google Code Archive - Long-term storage for Google Code Project Hosting.

 

code.google.com

 

2. keystore(jks) 파일 경로에 암호 후보들을 적은 텍스트 (wordlist.txt) 파일 저장

각 단어들을 자동으로 조합하면서 암호를 찾기 때문에암호에 들어갈 법한 단어들 단위로 한 줄씩 작성한다.

암호 전체보다는 구성 단위별로 한 줄씩 작성해야 빨리 찾을 확률이 높아진다 !

 

3. 명령 프롬프트 창 실행 후 keystore(jks) 파일 경로로 이동 (cd 뒤에 해당 경로 입력, 필자는 바탕 화면)

Microsoft Windows [Version 10.0.18362.959]
(c) 2019 Microsoft Corporation. All rights reserved.

C:\Users> cd Desktop
C:\Users\Desktop>

 

4. AndroidKeystoreBrute 실행

총 세가지 메소드가 있으나(다운로드 페이지 참고), 사용자가 입력한 암호 후보 단어들을 조합해서 찾는 3번 메소드를 추천

java -jar AndroidKeystoreBrute_v1.05.jar -m 3 -k "jks파일명.jks" -d "wordlist.txt"

 

5. 실행결과

한 줄씩 적었던 단어들을 조합해서 암호를 찾는다.

> java -jar AndroidKeystoreBrute_v1.05.jar -m 3 -k "jks파일명.jks" -d "wordlist.txt"
Number of keys in keystore: 1
Found alias: 
Creation Date: 
Start smart wordlist attack on key!!
Capitalize first letter
Current Pass: a || est. 0 Pass/Sec
Current Pass: Word21Word5word5 || est. 31605 Pass/Sec
Current Pass: Word5Word141 || est. 37944 Pass/Sec
Current Pass: 6Word1Word45 || est. 41029 Pass/Sec
Current Pass: word1Word1word513 || est. 36863 Pass/Sec
Current Pass: word1Word3916 || est. 31037 Pass/Sec
--------------------- 암호를 찾았을 때 ---------------------
Got Password in 0 seconds
Password is: 암호 for alias *****
For updates visit http://code.google.com/p/android-keystore-password-recover/

+ Recent posts