cgy12306

[Android] split(분할된) APK 합치기 본문

Mobile

[Android] split(분할된) APK 합치기

cgy12306 2023. 7. 5. 10:48

 

 

'/data/app/앱' 경로에 ADB를 통해 앱을 받아보면 받아보면 split된 APK를 확인할 수 있습니다.

 

base.apk만 jadx나 JEB로 열어보면 클래스가 덜 나와있는걸 볼 수 있습니다.

 

해당 apk들을 합쳐야만 정상적으로 모든 내용을 볼 수 있습니다.

 

apk를 병합하는 방법은 아래와 같습니다.

 

1. 분할된 APK 파일들을 apktool로 디컴파일(2.6.1)

java -jar apktool.jar d base.apk
java -jar apktool.jar d split_config.arm64_v8a.apk
java -jar apktool.jar d split_config.ko.apk
java -jar apktool.jar d split_config.xxhdpi.apk

2. split_config 폴더들에 있는 lib 또는 res 폴더를 base 폴더에 넣는다. 덮어쓰기는 하지 않음.

 

3. base 폴더의 AndroidManifest.xml 파일에서 android:isSplitRequired=”true” 부분 옵션 삭제

4. base 폴더의 apktool.yml 파일에서 doNotCompress 태그를 찾아 2번에서 넣은 폴더 이름을 모두 추가

5. base 리패키징

java -jar apktool.jar b base -o non_split.apk

non_split.apk를 JEB로 열어보면 모든 내용을 정상적으로 볼 수 있습니다.

 

위의 내용을 자동화 해주는 스크립트도 작성해봤습니다.

base.apk가 위치해 있는 폴더에 스크립트를 넣고 실행하시면 됩니다.

import os
import shutil
import time

os.system("apktool d base.apk | apktool d split_config.ko.apk | apktool d split_config.arm64_v8a.apk | apktool d split_config.xxhdpi.apk")

time.sleep(1)

append_do_not_Compress = []
def Copy_to_Base(current_dir, folder, Type):
    append_do_not_Compress.append(folder)

    base = ".\\base"
    current_dir = os.path.join(current_dir, folder)
    if Type == "res":
        base = os.path.join(base, Type)
    elif Type == "lib":
        base = os.path.join(base, Type)

    if not os.path.exists(base):
        os.mkdir(base)

    base = os.path.join(base, folder)

    if not os.path.exists(base):
        shutil.copytree(current_dir, base)
    else:
        file_list = os.listdir(current_dir)
        for fl in file_list:
            bf = os.path.join(base, fl)
            if not os.path.exists(bf):
                cf = os.path.join(current_dir, fl)
                shutil.copy(cf, bf)

def Copy(current_dir):
    dir_list = os.listdir(current_dir)
    for dl in dir_list:
        if dl == "lib":
            current_dir = os.path.join(current_dir, 'lib')
            file_list = os.listdir(current_dir)
            for f in file_list:
                Copy_to_Base(current_dir, f, 'lib')

        if dl == "res":
            current_dir = os.path.join(current_dir, 'res')
            file_list = os.listdir(current_dir)
            for f in file_list:
                Copy_to_Base(current_dir, f, 'res')

def ChangeXML():
    data = ""
    with open(".\\base\\AndroidManifest.xml", 'r') as f:
        data = f.read()
    with open(".\\base\\AndroidManifest.xml", 'w') as f:
        f.write(data)

def ChangeYML():
    data = b""
    with open(".\\base\\apktool.yml", 'rb') as f:
        while True:
            line = f.readline().rstrip()

            if line == b"isFrameworkApk: false":
                for adnc in append_do_not_Compress:
                    data += b"- " + bytes(adnc, 'utf-8') + b"\x0a"
            
            if line == b"":
                break
            data += line + b"\x0a"
    with open(".\\base\\apktool.yml", 'wb') as f:
        f.write(data)
            
        

Copy("split_config.arm64_v8a")
Copy("split_config.ko")
Copy("split_config.xxhdpi")

ChangeXML()

ChangeYML()

os.system("apktool b base -o non_split.apk")

 

 

출처

https://velog.io/@koo00/18

 

[AOS] How to turn a split APK into a normal non-split APK

분할된 APK 파일 하나로 합치는 방법

velog.io

 

 

Comments