jBART. NXT patches

Автор: | 12.02.2015

NXT patches — patching framework to change smali, build.prop and other files in rom.

Главный файл, который содержит в себе список всех патчей (файлов патчей), которые необходимо будет подгружать и использовать во время патчинга прошивки (или одиночного apk/jar файла), находится в папке data/patches и имеет имя patch_data.

Вот его возможное содержимое:

#include "%patches_dir%/nxt/Music.ptch";

#System Apps
include "%patches_dir%/nxt/MiuiHome.ptch";
include "%patches_dir%/nxt/Updater.ptch";
include "%patches_dir%/nxt/MiuiVideo.ptch";
include "%patches_dir%/nxt/SettingsProvider/SP.ptch";

#Extras Files
include "%patches_dir%/nxt/extras/notes.ptch";
include "%patches_dir%/nxt/extras/clock.ptch";
include "%patches_dir%/nxt/extras/calendar.ptch";
include "%patches_dir%/nxt/apps/MiBand.ptch";

Здесь %patches_dir% — это путь к папке data/patches

Закомментированные значком решетки (#) строки обрабатываться при чтении списка патчей не будут.

Файлы с расширениями .ptch — это уже сами файлы патчей. Причем расширение вы вправе использовать любое, главное, чтобы имена файлов из главного файла совпадали с реальными именами созданных вами файлов патчей.

Пример содержимого одного из файлов патча:

appfile <Updater.apk>;
replaceinall "com.sina.weibo" "com.vkontakte.android";
replaceinfile "%smali%/com/android/updater/ShareActivity.smali" "com.tencent.WBlog" "com.twitter.android";

Ниже будут рассмотрены все возможные директивы для файлов патчей.

Возможные директивы в файле патча

appfile <Contacts.apk>;
apppackage <com.android.contacts>;
extrafile <calendar>;
encode_utf8 true;
device <cancro>;
replaceinall "to replace" "replacement";
replaceinfile "file" "to replace" "replacement";
replaceinmethod "path to smali file" "full method name to searh the string inside it" "original string" "replacement string";
copyfile "file from" "file to";
copy "file or dir from" "file or dir to";
delete "file";
methodreplace "file" "full method name" "new method file";

Первым делом мы должны дать системе патчинга понять, в каком конкретном файле мы хотим что-то сделать. Для этой цели служит одна из трех директив из списка выше — либо appfile <>; либо extrafile <>; (apppackage <>; пока не работает).

appfile <Contacts.apk>;

Данная директива всегда должна присутствовать в файле патча (обычно самая первая строка) и говорит системе патчинга, в каком конкретно apk (или jar) файле мы собираемся что-то сделать.

apppackage <com.android.contacts>;

Аналогично директиве appfile, но используется имя пакета вместо имени файла программы (пока не используется, соответственно и не работает).

extrafile <calendar>;

Данная директива говорит, что патчить мы собираемся не apk или jar файл, а один из описанных в конфигурационном файле rom.extras.conf из папки settings jbart extra-файлов из обрабатываемой прошивки. Причем имя должно совпадать с именем, указанным в данном конфигурационном файле. В нашем случае — это calculator (в rom.extras.conf он указан как: calendar=system/media/theme/default/gadgets/calendar.mtz).

encode_utf8 true;

Эта директива применяется только в связке с предыдущей директивой (extrafile). Может принимать значения либо true либо false. Служит она для того, чтобы при применении изменений в файле, указанном директивой extrafile, не кодировать текст в UTF-8 (при замене строк текст кодируется, чтобы избежать так называемых «кракозябр» при замене какого-либо текста в smali, xml или любом другом файле на текст, содержащий символы, которых нет в латинском алфавите, как в случае с кириллицей, например).

device <cancro>;

Здесь можно указать, для какого устройства применять патчи. Можно указать несколько устройств (это данные из build.prop из раздела ro.product.device), разделив их имена через запятую — device <cancro, aries, hammerhead>;, т.е. применять патчи для телефонов Mi3/4, Mi2 и Nexus 5. Если данная директива отсутствует в файле патча либо указана как device <all>;, то патчи из файла будут применяться ко всем моделям устройств.

replaceinall «String to replace» «Replacement string»;

Данной директивой можно заменять строку String to replace во всех smali файлах декомпилированного apk/jar на строку Replacement string. Причем эти строки могут иметь внутри себя символы кавычек, которые не нужно избегать с помощью слеша (\).
Пример:

replaceinall «sget-boolean v0, Lmiui/os/Build;->IS_INTERNATIONAL_BUILD:Z» «const/4 v0, 0x0»;

Этой директивой строка sget-boolean v0, Lmiui/os/Build;->IS_INTERNATIONAL_BUILD:Z будет заменена на строку const/4 v0, 0x0 во всех smali файлах.

replaceinfile «file» «to replace» «replacement»;

Данной директивой можно заменять строку to replace в файле file (полный путь к файлу) на строку replacement. Причем эти строки так же могут иметь внутри себя символы кавычек, которые не нужно избегать с помощью слеша (\).
Пример:

replaceinfile «%smali%/com/android/updater/ShareActivity.smali» «com.tencent.WBlog» «com.twitter.android»;

Этой директивой в файле %smali%/com/android/updater/ShareActivity.smali строка com.tencent.WBlog будет заменена на строку com.twitter.android.

replaceinmethod «path to smali file» «full method name to searh the string inside it» «original string» «replacement string»;

Данной директивой можно заменять строку original string в файле path to smali file (полный путь к файлу) на строку replacement string в методе full method name to searh the string inside it. Полезно при замене строк, которые есть в нескольких местах в smali файле (чтобы не менять весь метод целиком).
Пример:

replaceinmethod «%smali%/com/android/misc/ui/MainActivityView.smali» «.method public getTitle()Ljava/lang/String;» «move-result-object v0» «move-result-object v1\n\n    if-eqz v1, :cond_0»;

Этой директивой в файле %smali%/com/android/misc/ui/MainActivityView.smali в методе .method public getTitle()Ljava/lang/String; строка move-result-object v0 будет заменена на строку (точнее на две) move-result-object v1\n\n    if-eqz v1, :cond_0.

copyfile «file from» «file to»;

Данная директива служит для копирования файлов. Если будет указана папка, то скопируются только сама папка и ее подпапки, файлы внутри папок скопированы не будут. Для копирования папок используйте директиву copy, описанную ниже.

copy «file or dir from» «file or dir to»;

Данная директива служит для копирования файлов и папок.

delete «file»;

Данная директива служит для удаления файлов и папок.

methodreplace «file» «full method name» «new method file»;

Данной директивой можно заменять целые методы внутри smali файлов.
Пример:

methodreplace «%smali%/miui/provider/ExtraTelephony.smali» «private static isContact(Landroid/content/Context;Ljava/lang/String;)Z» «%here%/methods/telephony.m»;

В файле %smali%/miui/provider/ExtraTelephony.smali метод private static isContact(Landroid/content/Context;Ljava/lang/String;)Z будет заменен методом, код которого мы записали в файле  %here%/methods/telephony.m. 

%here% - путь к папке, в которой находится текущий файл патча
%smali% - путь к папке smali внутри декомпилированного приложения
%res% - путь к папке res внутри декомпилированного приложения
%extra% - путь к папке распакованного extra файла из прошивки

Кодировка всех конфигурационных файлов и файлов патчей должна быть UTF-8 w/o BOM.

В Linux и OS X она такой будет по умолчанию, в Windows можно использовать Notepad++ для преобразования файлов в эту кодировку, т.к. по умолчанию файлы будут в кодировке Widows-1251)