УВАГА! Дзеля таго, каб Вашы патчы працавалі пад ART, нельга цалкам прыбіраць скачкі або рабіць іх безумоўнымі, бо ў гэтым выпадку застаецца код, у які аптымізатар не можа трапіць (віслы код), і ён валіцца з крытычнай памылкаю пры аптымізацыі. Каб гэтага ўнікнуць, неабходна замяняць скокі ўмоўнымі пераходамі, якія заўсёды спрацоўваюць. Да прыкладу, калі Вам трэба абавязкова скокнуць у нейкім месцы, то заменіце скок там на if-eq v0,v0 (в байтах это 32 00 ?? ??). Калі ж Вам не неабходна скакаць у нейкім месцы,то можна там паставіць скок if-ne v0,v0 (у байтах гэта 33 00 ?? ??) або самі пагледзіце якім эквівалентам можна замяніць.

1. Тэкставы файл неабходна зваць таксама як і пакейдж праграмы... Да прыкладу для Titanium Backup трэба стварыць такое імя файла: com.keramidas.TitaniumBackup.txt (абавязкова выконваць загалоўныя і малыя літары з назвы пакейджа, інакш не знойдзе (linux - маці яго)). Калі файл карыстальніцкага патча для дадатку ўжо існуе, вы можаце проста дадаць напачатку імя файла кожны тэкст і захаваць яго каля існуючага. У гэтым выпадку, пры выбары ў дадатку "Карыстальніцкі патч", Lucky Patcher прапануе Вам спіс карыстальніцкіх патчаў для дадатку на выбар. Калі Вы жадаеце напісаць патч адразу на цэлую серыю праграм адной фірмы, тое пад канец назвы файла карыстальніцкага патча, можна выкарыстоўваць ідэнтыфікатар _%25ALL%25 , да прыкладу, назва патча для ўсіх галасоў SVOX будзе выглядаць так: com.svox.classic.langpack_%25ALL%25.txt. На _%25ALL%25 замяняецца частка ў назве пакета, якая змяняецца ў залежнасці ад дадатку дадзенай фірмы. Калі яшчэ неабходна дадаць спачатку назвы файла сваё імя, да прыкладу, то можна выкарыстаць %25ALL%25_ і _%25ALL%25. (Прыклад:chelpus.%25ALL%25_com.android._%25ALL%25.txt). Пры ўводзе імёнаў карыстальніцкіх патчаў у самай праграме %25ALL%25_ хаваецца для прастаты ўспрымання. У самым тэксце карыстальніцкага патча можна выкарыстоўваць %25PACKAGE_NAME%25, замест якога падчас патча будзе падстаўлена імя пакета дадатку мэты. Гэта карысна ў патчах для групы дадаткаў, дзе шлях да файла будзе змяняцца ў залежнасці ад імя пакета (Прыклад:/data/data/%25PACKAGE_NAME%25/files/trial.txt).

2. Такім чынам, вось прыклад. Я напхаў туды ўсё што ёсць з магчымасцяў. На практыцы Вам спатрэбіцца нашмат меней функцый. У целе файла пішам прыкладна ў такой форме (падзельнік толькі адзінарны прабел-інакш памылку будзе выдаваць):

[BEGIN]
Гэты карыстальніцкі патч дадае ружаньку ў зубы Keramidas. ver.4.4.4
[PACKAGE]
[CLASSES]
{"search":"15 01 00 30 ** 20 ** ** 31 ** 20 ** ** ** ** R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 12 ** R11 R12 R13 0E 00"}
{"search":"10 ** ** ** ** 0C 01 1A 04 R14 R15 1A 05 00 00 72 30 ** ** ** ** 0C 04"}
{"search":"0C 01 1A 03 ** ** 72 30 R16 ** ** ** 72 10"}
 
{"group":"1"}
{"original":"12 ** 22 00 ** 04 ** W0 ** W2 ** W3 22 02 ** 04"}
{"replaced":"** S1 ** ** ** ** W16 ** W16 ** W16 ** ** ** ** **"}
 
{"group":"1"}
{"original":"0c 07 ** ** ** ** ** ** 38 ** ** ** 70"}
{"replaced":"** ** ** ** ** ** ** ** W11 W11 W11 W11 **"}
 
{"original":"12 ** 12 ** 6a ** ** ** 38 ** ** **"}
{"replaced":"** S0 ** ** ** ** ** ** 00 00 00 00"}
{"original":"12 ** 12 ** 6a ** ** ** 38 ** ** **"}
{"replace_from_file":"array.tb.bin"}
 
[LIB]
{"name":"libtitanium.so"}
{"original":"00 ** 50 e2"}
{"replaced":"00 00 50 e1"}
 
{"original":"01 0c 80 e2"}
{"replaced":"00 00 a0 e1"}
 
 
[OTHER FILES]
{"name":"/files/shell.dex"}
 
{"original":"0F 00 00 00 1A 00 00 00 0F 00 00 00 59 00 00 00 2F"}
{"replaced":"0F 00 00 00 0F 00 00 00 0F 00 00 00 59 00 00 00 2F"}
 
 
[OTHER FILES]
{"name":"/mnt/sdcard/Android/package-name/files/lives.xml"}
 
{"original":"63 68 65 6C 70 61"}
{"insert":"63 68 65 6c 70 61 61 61"}
 
[END]
Congratulations! Program cracked!
Run Titanium Backup and check License State!
Good Luck!
Chelpus.


Растлумачу зараз што там дзе... Я сапраўды думаю, тыя каму неабходна, ужо зразумелі....:

Такім чынам:

[BEGIN] - метка пачала, увесь тэкст пасля яе і да першага поля [CLASSES], [LIB], [END] і інш. будзе выведзены напачатку лога патча для карыстальніка.
[PACKAGE] - гэта метка кажа пра тое, што патчыць мы будзем не dalvik-cache наўпрост, а выцягнем classes.dex з apk праграмы, прапатчым (патчамі, якія ідуць следам пасля ідэнтыфікатараў [CLASSES] або [ODEX]), створым выяву odex са зменамі і падсунем яго дадатку. Менавіта такая выява, да прыкладу, патрэбен TitaniumBuckup, бо ён правярае яго і ўсё чэк-сумы ўнутры яго павінны быць слушныя. Гэту метку пажадана выкарыстоўваць заўсёды, бо такі патч найболей слушны, але калі гэта выклікае якія праблемы, можна і без яго.
[CLASSES] - тут ідуць радкі для патча classes.dex. Яны могуць быць пошук(search) і арыгінал-замена(original-replaced).
радок original-replaced у original мы паказваем паслядоўнасць байт, якую шукаем у файле, і замяняем яе на байты з replaced. Значэнні для гэтых радкоў звычайна глядзяць у IDA Pro. Значэнні байтаў у шаснаццатковай форме, падзеленыя адзінарнымі прабеламі, дзе ** ці ?? - гэта хоць які байт (патрэбныя, каб патч працаваў на розных версіях дадаткаў, бо некаторыя байты змяняюцца).
радок replace_from_file - замяняе байты, пачынаючы са знойдзенага месца, на байты з файла з паказаным назвай і ляжалым каля файла самага карыстальніцкага патча (зроблена дзеля вельмі доўгіх шаблонаў замены, якія ванітоўна ўбіваць у тэкставы файл).
радок insert - ужываецца ў выпадках, калі неабходна замяніць знойдзены арыгінал на колькасць байт перавышальная колькасць байт арыгінальнага шаблону пошуку. Найчасцей гэта неабходна ў розных тэкставых файлах. Да прыкладу, калі ў файле xml такое:"lives=9", а неабходна замяніць на "lives=999", менавіта ў гэтым выпадку дапаможа insert, не памяняўшы пры гэтым дадзеныя пасля "lives=9".
радок search - шукае байты ў пазіцыях пазначаных R[0, 1, 2, 3, ...], дзе нумар гэта нумар вочка куды захавацца байт (нумары вочак павінны ісці па парадку ад 0 і далей і не павінны паўтарацца). Да прыкладу: {"search":"15 01 00 R0 R1 R2 12 ** 0E 00"} азначае, што байты на тых пазіцыях будуць захаваны ў R0, R1, R2. Зараз, калі яны знойдзены і захаваны, можна іх выкарыстоўваць у шаблонах пошуку замены, толькі замяняючы R на W:
тут:
** ці ?? - азначае хоць які байт,
W0, W1, W2 - эгэта захаваныя байты ў search,
S0,S1 и SQ- гэта азначае ўсталяваць зменную smali у 0 (прыклады 43->03,54->04...) або 1 (напрыклад 43->13,04->14...) адпаведна, SQ выконвае шаснаццатковыя разрады (напрыклад 23->33, 62->22...):
да прыкладу, у кодзе ёсць зменная const/4 v?,0x00 - я не проста так там паставіў знак ?, а таму што нумар яе Вам не вядомы (да прыкладу, пасля абнаўлення дадатку ён можа змяніцца), але Вы дакладна ведаеце, што там заносяць у нейкую зменную 0, а Вам неабходна занесці 1, тады шаблон замены будзе выглядаць так:
{"original":"12 ?? ?? ?? ?? ??"}
{"replaced":"12 S1 ?? ?? ?? ??"}
а калі Вам неабходна занесці 0, тады шаблон замены будзе выглядаць так::
{"original":"12 ?? ?? ?? ?? ??"}
{"replaced":"12 S0 ?? ?? ?? ??"}
усё астатняе простае HEX байты.
Колькасць байт origanal і replaced абавязкова павінны супадаць. І абавязкова помніце, што байты далвік-кэшу і classes.dex не ўсе аднолькавыя, у гэтым Вы можаце пераканацца, скапіяваўшы файл dalvik-cache з /data/dalvik-cache/ да сябе на кампутар і адкрыўшы ў IDA Pro.
поле group - адзначае шаблоны адной групы (групы могуць быць ад 1 і вышэй). Што гэта значыць? А значыць гэта тое, што калі хоць бы адзін з групы спрацуе, карыстачу пакажуць дыялог, што патч завяршыўся ўдала. Гэта патрэбна, прыкладам, дзеля таго, каб зрабіць універсальны патч адразу на шмат версій аднаго і таго ж дадатку (да прыкладу, патч дзеля ўсіх версій Google Play на адключэнне аўтаабнаўлення).
[ODEX] - замест ідэнтыфікатара [CLASSES], можна выкарыстоўваць гэты. Тады змены classes.dex будуць захаваны не ў dalvik-cache, дзе яны перыядычна знікаюць пры абнаўленні кэша сістэмай, а ў асобным файле з пашырэннем odex побач з apk дадатку, што зафіксуе ўсе змены і пакіне арыгінальны dalvik-cache некранутым - гэта на выпадак, калі дадатак яго правярае. Можна выкарыстоўваць [ODEX] пасля [CLASSES], тады змены ўнясуцца ў далвік-кэш і аўтаматычна зафіксуюцца ў odex.
[ODEX-PATCH] - бываюць сітуацыі, калі трэба змяніць ужо прапатчаны дадатак, да прыкладу, у якога ўжо знялі праверку ліцэнзіі аўтаматычным патчам, тады на падмогу прыходзіць гэта метка. Усе шаблоны <арыгінал-замена> пасля яе будуць ужыты да odex файлу, які ўжо стварылі іншыя патчы. Да прыкладу, гэта запатрабавалася ўпершыню ў Final Fantasy III, калі людзі лячылі гульню Экстрэмальным рэжымам выдалення праверкі ліцэнзіі, але каб пераклад адлюстроўваўся ў слушнай кадоўцы, патрабаваліся дадатковыя патчы ў odex файле, якія стала магчыма ўжыць з дапамогай гэтай пазнакі.
[LIB] - гэта азначае, што далей пойдуць радкі для патча бібліятэкі гэтай праграмы, name - гэта імя бібліятэкі (калі замест імя паставіць *, то будуць патчыцца ўсе бібліятэкі дадатку). Часам у дадатку бываюць некалькі бібліятэк пад розныя архітэктуры працэсараў, тады лепш выкарыстоўваць [LIB-ARMEABI],[LIB-ARMEABI-V7A],[LIB-MIPS] або [LIB-X86] для патрэбнай бібліятэкі, каб шаблоны ад іншай бібліятэкі не ўжываліся да бягучай.
[OTHER FILES] - гэта азначае, што далей пойдуць радкі для патча файла які ляжыць ў тэчцы дадатку /data/data/<імя пакета>, name - гэта шлях ад /data/data/<імя пакета> і імя файла. Каб файлы там з'явіліся, патрабуецца хоць бы адзін запуск дадатку. Яшчэ ёсць варыянт указання шляху да файла на sdcard, для гэтага неабходна ўпісаць шлях пачынальна яго з "/mnt/sdcard/", тады, калі файл не будзе знойдзены па паказаным шляху, Lucky Patcher будзе замяняць "/mnt/sdcard/" на розныя агульнапрынятыя іншыя варыянты месцавання sdcard. Да прыкладу так:"/mnt/sdcard/Android/package-name/files/lives.xml"
[FILE_IN_APK] - гэта азначае, што далей пойдуць радкі для патча файла, што знаходзіцца ўнутры apk (такі патч будзе працаваць толькі пры ўжыванні такога патча для перазборкі apk, у рэжыме звычайнага патча гэты тэг ігнаруецца). Гэта патрэбна для патча файлаў, якія не з'яўляюцца падчас працы дадатку ў якім або з падзелаў, каб атрымаць да іх доступ і прапатчыць (да прыкладу, файлы з assets), або такі файл пасля выкарыстання падаляецца і потым ізноў распакоўваецца ў месца, дзе быў раней. Прыклад:
[BEGIN]
Патч для перазборкі апк
[FILE_IN_APK]
{"name":"/assets/bin/Data/Managed/O7SharpCompress.dll"}
{"original":"4D 5A 90 00 03 00 00 00 04 00 00 00"}
{"replaced":"00 00 00 00 00 00 00 00 00 00 00 00"}
[END]
Файл перасабраны з патчам.
[ADD-BOOT] - Аўтаматычна дадае бягучы карыстальніцкі патч у загрузны ліст, каб патч ужываўся пры кожнай перазагрузцы. Гэта патрэбна пры патчах бібліятэк або калі вы скарыстаеце [CLASSES] без [ODEX] або без [PACKAGE], бо патчыцца будзе далвік кэш, а ён мае ўласцівасць абнаўляцца сістэмай і ўсе змены знікаюць.
[COMPONENT] - Часам дадатак адключае сваё актывіці і іншыя кампаненты, каб абмежаваць сваю функцыянальнасць, тады можа спатрэбіцца гэта магчымасць уключыць яе назад. Так можна ўлучаць актывіці, сэрвісы, правайдары і іншыя кампаненты. Галоўнае паказваць іх імёны ў строгай адпаведнасці з загалоўнымі і малымі літарамі. Вось прыклад, які дэманструе адключае кампанент у дадатку з назвай com.superApp.adsActivity і дазвол com.android.vending.CHECK_LICENSE
[BEGIN]
Ads disabler
[COMPONENT]
{"disable":"com.superApp.adsActivity"}
{"disable":"com.android.vending.CHECK_LICENSE"}
[END]
Congratulations! Ads hidden!

Ці вось прыклад, які дэманструе ўлучэнне кампанента ў дадатку з назвай com.superApp.adsActivity і дазволы com.android.vending.CHECK_LICENSE
[BEGIN]
Ads disabler
[COMPONENT]
{"enable":"com.superApp.adsActivity"}
{"enable":"com.android.vending.CHECK_LICENSE"}
[END]
Congratulations! Ads hidden!

[SQLITE] - Часам у мэтавым дадатку неабходна што-небудзь змяніць у базе дадзеных, у якую яно запісвае якія-небудзь падзеі або дадзеныя, тады на дапамогу прыходзіць гэты ідэнтыфікатар, пасля яго ідзе канструкцыя выгляду:
[BEGIN]
Trial Reset
[SQLITE]
{"database":"/data/data/com.package.megaapp/databases/settings.db"}
{"execute":"DELETE FROM table_settings WHERE name = 'SETTING__LIC'"}
{"execute":"UPDATE table_settings SET UsedDays=0 WHERE name='Trial_set'"}
[END]
Congratulations! You have new Trial Period!

database - гэта шлях да базы дадзеных на вашай прыладзе і меркавана на прыладах астатніх карыстальнікаў. Можна не паказваць шлях да базы, а паказаць толькі імя яе файла, тады Lucky Patcher паспрабуе яе сам знайсці.
execute - гэта SQLite запыт, складаецца па звычайных правілах (гэта можна прачытаць у сеціве).

[SET_PERMISSIONS] - аналог каманды linux "chmod дазволы імя_файла" дзеля файлаў з тэчкі дадзеных дадатку (прыкладам даць правы толькі на чытанне пасля рэдагавання):
[BEGIN]
Trial Reset
[SET_PERMISSIONS]
{"file_name":"/files/stats"}
{"permissions":"777"}
[END]

[COPY_FILE] - капіюе файл з тэчкі Lucky Patcher-а ў паказаную тэчку з новым назвай файла:
[BEGIN]
Капіюе файл з грашыма
[COPY_FILE]
{"file_name":"file_for_money.bin"}
{"to":"/data/data/game_package/files/settings.xml"}
[END]

[OTHER FILES]
{"name":"/files/stats"}

{"original":"4D 4D 46 31"}
{"replaced:"4D 00 00 00"}
[END]

[SET_PERMISSIONS]
{"file_name":"/files/stats"}
{"permissions":"444"}
[END]
Congratulations! You have new Trial Period!

[END] - ідэнтыфікатар канца шаблонаў ад патчаў, увесь тэкст з наступнага радка будзе выведзены пры паспяховым патчы праграмы.

Усё адрэдагавалі, захоўваеце і кідаеце файл com.keramidas.TitaniumBackup.txt у дырэкторыю /sdcard/LuckyPatcher/...
Зараз праграма падсвятляецца жоўтым і можна дастасаваць да ёй гэты патч.


Калі што, задавайце пытанні. Поспехаў..