DexPatcher: დააყენეთ Android APK-ები Java-ს გამოყენებით

DexPatcher საშუალებას აძლევს დეველოპერებს შეასწორონ APK-ები Java-ს გამოყენებით. ამას რამდენიმე უპირატესობა აქვს და DexPatcher-ის გამოყენება ბევრად უფრო ადვილია, ვიდრე კლასიკური Smali მიდგომა.

თქვენ ალბათ გინახავთ ან დააინსტალირეთ შეცვლილი აპლიკაციები, იქნება ეს თქვენი რეზოლუციის დაყენებული აკრიფეთ თუ WhatsApp-ის პერსონალური ვერსია დამატებული ფუნქციებით. როგორ აკეთებენ ამას დეველოპერები? ხშირად, აპლიკაციების წყაროს კოდიც კი არ არის ხელმისაწვდომი, ასე რომ, როგორ მუშაობს ეს ყველაფერი? ჯერ ამას დავინახავთ, შემდეგ გადავხედავთ ახალ ინსტრუმენტს, რომელიც მიზნად ისახავს პროცესის გაადვილებას, და ბოლოს შევადარებთ მას პოპულარულ Xposed ჩარჩოს, რათა დავინახოთ, როგორ განსხვავდებიან ისინი.

თქვენ შეიძლება გსმენიათ იმის შესახებ, თუ როგორ ხდება APK-ების მოდიფიკაცია - დეველოპერები თავად აერთებენ მასში მატრიცა, დაიწყეთ ყველაფრის ხილვა სმალიში და მოიპოვეთ ნივთების მოდიფიკაციის უნარი წყარო. სატელეფონო ზარი საკმარისია იმისათვის, რომ ისინი გამოიტანონ, როგორც კი ეს გაკეთდება, რა დროსაც ისინი მზად არიან გააზიარონ ახალი ბრწყინვალე APK-ები.

უფრო სერიოზულად... დავიწყოთ თავიდან. თუ არ იცნობთ Android აპლიკაციების მოდიფიკაციას, შეიძლება გაინტერესებთ რა არის smali. დეველოპერები ჩვეულებრივ იყენებენ Java პროგრამირების ენას Android აპების კოდირებისთვის. პროგრამა (შემდგენელი) შემდეგ „თარგმნის“ ამ კოდს თქვენი მოწყობილობისთვის შესაფერის სხვა ფორმატში, რის შედეგადაც .dex ფაილები შეიცავს აპლიკაციის პაკეტში (ან APK).

ამ დროს, თქვენ ვეღარ შეხვალთ ორიგინალურ კოდზე (თუ თქვენ არ ხართ დეველოპერი ან აპლიკაცია ღია წყაროა). თუმცა, რაც გაქვთ არის APK, რადგან ის არის დაინსტალირებული თქვენს მოწყობილობაზე. მისგან შეგიძლიათ მიიღოთ dex ფაილები (ჩვეულებრივ classes.dex) და შემდეგ სცადოთ მისი თარგმნა თქვენთვის გასაგებ ფორმატში. სწორედ აქ შემოდის სმალი, როგორც უფრო იკითხებადი, მაგრამ ერთგული თარგმანი. შეგიძლიათ ერთი ნაბიჯით წინ წახვიდეთ და თარგმნოთ ის Java-ზე, თუმცა ეს პროცესი საკმარისად ერთგული არ არის -- თქვენ მიიღებთ გასაგები შედეგია, მაგრამ დიდია შანსი, რომ ვერ შეძლებთ მის პირიქით თარგმნას, რადგან ზოგიერთი დეტალი დაიკარგება გზად. სხვა სიტყვებით რომ ვთქვათ, ნებისმიერი ცვლილება, რომელიც შეიძლება შეიტანოთ, უსარგებლო იქნება, რადგან თქვენ ვერ შეძლებთ მის დაბრუნებას APK-ად ისევ თქვენს მოწყობილობაზე დასაინსტალირებლად… ყოველ შემთხვევაში, დიდი ძალისხმევის გარეშე.

smali/baksmali რეალურად არის ასამბლერი/დისამბლერი dex ფორმატისთვის -- აი რას ნიშნავს ის სიტყვასიტყვით ისლანდიურად. თუმცა, ჩვენ ჩვეულებრივ მივმართავთ ფორმატს, რომელსაც smali ესმის, როდესაც ვამბობთ "Smali" (გაიგონეთ, როგორც ინსტრუქცია ყოველი წვრილმანი დეტალის განსაზღვრა, მაშინაც კი, თუ ეს ყველაფერი ჩვენ ადამიანებს არ გვჭირდება - ამიტომ ეს უფრო მრავლისმეტყველია, ვიდრე ჯავა). ასევე გაითვალისწინეთ, რომ ზემოაღნიშნული ახსნა ცოტათი გამარტივებულია, მაგრამ უნდა იყოს ახლო ანალოგია, თუმცა მაინც ადვილად გასაგები.

რა უნდა გააკეთოს დეველოპერმა აპის შესაცვლელად (წყაროზე წვდომის გარეშე)? პროცესი მეტ-ნაკლებად შემდეგია:

  1. მიიღეთ APK (ვებიდან ან მოწყობილობიდან).
  2. გამოიყენეთ მსგავსი რამ apktool APK-ის დეკომპილაცია სმალიში. (apktool იყენებს smali/baksmali-ს, მაგრამ აადვილებს APK-ების დეკომპილაციას და აღდგენას, ასევე ზრუნავს რესურსების დეკოდირებაზე, როგორიცაა XML ფაილები.)
  3. ამოიღეთ classes.dex APK-დან, შემდეგ გამოიყენეთ dex2jar და ბოლოს ჯავის დეკომპილერი (არასრული, ხშირად გატეხილი, მაგრამ ძირითადად გასაგები) ჯავის კოდის მისაღებად. (ეს არჩევითია, მაგრამ შეიძლება იყოს გამოსადეგი, რადგან სმალი გაცილებით რთული გასაგებია.)
  4. განსაზღვრეთ რა უნდა შეცვალოთ.
  5. რეალურად შეცვალეთ იგი Smali კოდის პირდაპირ რედაქტირებით.
  6. ალტერნატიულად, ჩაწერეთ მოდიფიკაცია Java-ში, შეადგინეთ იგი, გადააკეთეთ ისევ Smali-ზე, შემდეგ დააკოპირეთ მიღებული Smali კოდი.
  7. როდესაც ყველაფერი დასრულდება, გამოიყენეთ apktool ისევ APK-ის აღსადგენად.
  8. ხელი მოაწერეთ APK-ს (ავტორის ვინაობის დასადასტურებლად; ყველა პაკეტი უნდა იყოს ხელმოწერილი) და ბოლოს დააინსტალირეთ.

Smali კოდის დაწერა საკმაოდ რთული და მიდრეკილია შეცდომისკენ. მცირე ცვლილებების შეტანა შესაძლებელია Smali-ში, მაგრამ მასში ახალი ფუნქციების დამატება უფრო რთულია. გარდა ამისა, თქვენ არ გექნებათ შედგენის დროის შეცდომები, ასე რომ, შეცდომაც კი შეიძლება გამოვლინდეს მხოლოდ გაშვების დროს. Smali პატჩების გაფართოება და გაზიარება ასევე შეიძლება იყოს პრობლემური, რადგან განსხვავებები ძალიან სპეციფიკურია APK-ის კონკრეტული ვერსიისთვის. მიუხედავად იმისა, რომ არსებობს გარკვეული ხელსაწყოები ზემოთ ახსნილი პროცესის ნაწილების გასაადვილებლად (ვირტუოზ ათ სტუდია მახსენდება), ის მაინც შეიძლება იყოს დამღლელი.

DexPatcher XDA უფროსი წევრის მიერ ლანჩონი მიზნად ისახავს ამ პრობლემების გამოსწორებას პროცესის გამარტივებით და დეველოპერებს საშუალებას აძლევს სრულად აიცილონ Smali-თან ურთიერთობა. ამის ნაცვლად, დეველოპერებს შეუძლიათ დაწერონ პატჩები მხოლოდ Java-ში და DexPatcher-მა აწარმოოს ყველაფერი დანარჩენი.

ამას აქვს მთავარი უპირატესობა, რომ აქვს ადვილად წასაკითხი და მართვადი პატჩი ფაილები. APK-ების დაყენება ასევე უფრო მოსახერხებელი ხდება ზოგადად. ჩვენ ვნახავთ სრულ მაგალითს, თუ როგორ გამოვიყენოთ DexPatcher, მაგრამ აქ არის სწრაფი მიმოხილვა, თუ რას გვთავაზობს ის პირველ რიგში:

  • Საჯარო წყარო.
  • Cross-Platform: ის უნდა იმუშაოს Linux-ზე, Mac-ზე და Windows-ზე.
  • პატჩი ფაილები: თქვენ მიერ შეტანილი ცვლილებები შეიცავს Java პაჩ ფაილებს, რომელთა დამოუკიდებლად გაზიარება შეგიძლიათ.
  • ჯავა: ეს არ არის სმალი.

თქვენ ასევე იღებთ უპირატესობას შეცდომის შემოწმების პროცესში, ასე რომ, შეცდომები გამოჩნდება განვითარების ციკლის დასაწყისში. შედგენილი ჯავა უზრუნველყოფს მისი ჩვეული შედგენის დროის შემოწმებას (პირველ APK სიმბოლოებზე წვდომით) და DexPatcher ახორციელებს წყაროსა და პაჩის თავსებადობა პაჩის დროს, სასარგებლო ინფორმაციის მიწოდება და გაფრთხილებების მიცემა, როცა რაღაცას აკეთებ ლეგალური, მაგრამ თევზეული.

გარდა ამისა, DexPatcher მოყვება კომპლექტი დამხმარე სკრიპტები (ხელმისაწვდომია მხოლოდ Linux-ზე, თუმცა მათი პორტირება შესაძლებელია სხვა პლატფორმებზეც). ისინი ზრუნავენ სამუშაო სივრცის დაყენებაზე, სამიზნე APK-ის კლასების და რესურსების ამოღებაზე, კლასების დეკომპილირებაზე Java-ზე ( CFR Java დეკომპილერი გამოიყენება ამ უკანასკნელისთვის) და ბოლოს დაყენებული APK-ის შექმნა და ხელმოწერა, როგორც კი დაასრულებთ.

მოდით შევხედოთ მაგალითს (Linux-ზე):

დააინსტალირეთ DexPatcher სკრიპტები

$# Make a directory where we can test stuff out and enter it. 

$ mkdir xda-test

$cd xda-test

$ git clone https://github.com/Lanchon/DexPatcher-scripts.git dexpatcher # Clone the DexPatcher helper scripts repo.

$cd dexpatcher

$ chmod +x dxp-* # Not necessary, but for clarity: we need to make sure the files we'll call later are executable.

DexPatcher სკრიპტების კონფიგურაცია

გახსენით dxp.config თქვენს საყვარელ ტექსტურ რედაქტორში და დარწმუნდით, რომ შეცვალეთ საჭირო ცვლადები თქვენი სისტემისთვის. თქვენ მხოლოდ უნდა შეცვალოთ შემდეგი ხაზი, რათა მიუთითოთ თქვენი Android SDK-ის ინსტალაციის ადგილის ნაცვლად:

dxp_android_sdk_dir=(~/android/sdk)

(DexPatcher ავტომატურად აირჩევს ყველაზე მაღალ პლატფორმის ვერსიას. გარდა ამისა, თქვენ ასევე შეგიძლიათ შეცვალოთ კონფიგურაციის სხვა ვარიანტები, რათა მან გამოიყენოს ზოგიერთი ხელსაწყოს თქვენი საკუთარი ვერსიები შეფუთული ნაგულისხმევის ნაცვლად.)

წვდომის გამარტივებისთვის, ჩვენ შეგვიძლია დავამატოთ დექსპეჩერი დირექტორია ჩვენს ბილიკი, ან თუნდაც სიმბოლურად დააკავშიროთ განსხვავებული dxp-* სკრიპტები იმ ადგილას, რომელიც უკვე თქვენსშია ბილიკი, როგორიცაა ~/ბინა:

export PATH=$PWD:$PATH

აპლიკაციის შეცვლა

ამ მაგალითისთვის ჩვენ გამოვიყენებთ მარტივ და ღია კოდის აპლიკაციას. რა თქმა უნდა, ამ კონკრეტულ შემთხვევაში შესაძლებელი იქნება წყაროს კოდის პირდაპირ დაყენება, მაგრამ ეს სულაც არ არის სახალისო!

ჩვენ მივიღებთ "Get ID" აპლიკაციას basil2style-ის მიერ, აპლიკაცია, რომელიც გიჩვენებთ ზოგიერთ დეტალს თქვენი მოწყობილობის შესახებ. ჩვენი მიზანია შევცვალოთ ღილაკი „ასლი“ „მოწყობილობის ID“-ისთვის და მის ნაცვლად გავაზიაროთ ეს ID:

  • პირველ რიგში, გადმოვწეროთ APK, რომლის შეცვლასაც ვაპირებთ: მიიღეთ ID.
  • განაცხადის დეკომპილირება.
  • შექმენით ხელმოწერის გასაღები, რომელსაც მოგვიანებით გამოვიყენებთ APK-ზე ხელმოწერისთვის.

ჩვენ ასევე შეგვიძლია ეს ყველაფერი გავაკეთოთ ჭურვის საშუალებით, დამხმარე სკრიპტების გამოყენებით:

$cd dexpatcher # Go to our working directory. 

$ curl -O https://f-droid.org/repo/makeinfo.com.getid_1.apk # Download the APK.

$ dxp-setup-for-apk makeinfo.com.getid_1.apk # Unpack and decompile the APK.

$cd makeinfo.com.getid_1 # Go to the newly created directory where everything is unpacked/decompiled to.

$ dxp-create-keystore # Create the APK signing key. Press 6 times (or fill out the info), then "yes".

თქვენ შეამჩნევთ რამდენიმე სხვადასხვა დირექტორიას იქ:

  • გაშიფვრა: თქვენ იპოვით რესურსებს და Smali-ს აქ, როგორც დეკოდირებულია apktool.
  • src: ცარიელი დირექტორია. ეს არის სადაც ჩვენ განვათავსებთ ჩვენს პატჩი ფაილებს.
  • src-cfr: აი სად შდრ დეკომპილირებულია აპლიკაცია (შეცდომებთან ერთად). კარგი ადგილია, რათა გადაწყვიტოთ რა უნდა შეიცვალოს (შეიძლება დაგჭირდეთ რესურსები და მათი ID-ები ზემოთ მოყვანილი დეკოდირების დირექტორიაში, მაგრამ არა ამ კონკრეტული მაგალითისთვის).
  • src-cfr-nodecode: იგივე როგორც ზემოთ, მაგრამ შეიცავს მხოლოდ ცარიელ ნაკერებს (კოდის გარეშე, მხოლოდ ჩონჩხები). თქვენ შეგიძლიათ გამოიყენოთ ეს ფაილები, როგორც თქვენი პაჩის საფუძველი, როგორც ამას ცოტა ხანში დავინახავთ.

როგორც უკვე აღვნიშნეთ, ჩვენ გვინდა შევცვალოთ მოწყობილობის ID ღილაკი „ასლი“, რათა სანაცვლოდ ID ტექსტი გავაზიაროთ. თუ გადავხედავთ წყაროს კოდს, შევამჩნევთ, რომ Device ID Copy ღილაკი (მოწყობილობა_ასლი) onClick ღონისძიებას მართავს ანონიმური კლასი src-cfr/makeinfo/com/getid/MainActivity.java. მიუხედავად იმისა, რომ ჩვენ შეგვეძლო მისი მოდიფიცირება აქ, ჩვეულებრივ სჯობს ვიპოვოთ ამის ალტერნატიული გზა, რადგან ანონიმურ კლასებს აქვთ რიცხვითი სახელები (MainClassName$SomeNumber, მაგალითად. MainActivity $3) რომელიც შეიძლება არაპროგნოზირებად შეიცვალოს ვერსიებს შორის.

ამის ნაცვლად, ჩვენ დავრეგისტრირებთ ჩვენს კლასს ღონისძიებისთვის, შეცვლით Მთავარი აქტივობა კლასი. პირველ რიგში, მოდით დავაკოპიროთ "ჩონჩხის" ვერსია src-cfr-nocode/makeinfo/com/getid/MainActivity.java რომ src/makeinfo/com/getid/MainActivity.java (გვახსოვდეს, რომ src არის სადაც ჩვენი პაჩი იცხოვრებს). (თქვენ ასევე შეგიძლიათ დააკოპიროთ ვერსია სრული კოდით, თუ გსურთ, ეს მხოლოდ გემოვნების საკითხია.)

ახლა შეგვიძლია მისი რედაქტირება შემდეგნაირად:

  • დაამატეთ საჭირო იმპორტი DexPatcher ანოტაციისთვის:
importlanchon.dexpatcher.annotation.*;
  • დაამატეთ ტეგი, რათა მიუთითოთ, რომ კლასს ვასწორებთ. ჩვენ ასევე დავაყენეთ ნაგულისხმევი მოქმედება პაჩების კლასის წევრებისთვის იგნორირება, რაც ნიშნავს, რომ წევრები იმყოფებიან იმისათვის, რომ მოიხსენიონ ჩვენი კოდი ჯავის შედგენის დროს, მაგრამ ისინი იგნორირებული იქნებიან DexPatcher-ის მიერ.
@DexEdit(defaultAction=DexAction.IGNORE)

publicclassMainActivity

// The reference to ActionBarActivity will be satisfied by symbols

// extracted from the app when we build the patch.

extendsActionBarActivity{

  • დამატებით, დაამატეთ ცარიელი სხეულები კონსტრუქტორს და onCreate მეთოდი, ისევე როგორც ყველა სხვა მეთოდი, რომლის გამოყენებასაც ვგეგმავთ (გახსოვდეთ, რომ ისინი იგნორირებული იქნება, როდესაც ჩვენი პატჩი რეალურად იქნება გამოყენებული -- ჩვენ უბრალოდ ვამატებთ მათ, რათა საჭიროების შემთხვევაში აქ მივმართოთ). თქვენ ასევე შეგიძლიათ უბრალოდ დაამატოთ მშობლიური საკვანძო სიტყვა ნაცვლად.
  • ჩვენ უკვე შეგვიძლია შევქმნათ პატჩი ამ ეტაპზე, თუ გაინტერესებთ:
    $ dxp-make # Output: `patched.apk`.
    საკმაოდ მარტივია, არა? გავაგრძელოთ, თუმცა - ჯერ არ დასრულებულა.
  • მოდი ჩავასწოროთ onCreate ახლა საკუთარი თავის დასაყენებლად OnClickListener ასე რომ, ჩვენ შეგვიძლია გავაზიაროთ მოწყობილობის ID ნაცვლად კოპირება ბუფერში:
    // Rename the target method so that we can still call it (the original)// if needed.@DexEdit(target="onCreate")protectedvoidsource_onCreate(Bundlevar1){}// Add our new custom method.@Override@DexAddprotectedvoidonCreate(Bundlevar1){// Call the original method:source_onCreate(var1);// Replace the text and handler:device_copy.setText("Share");device_copy.setOnClickListener(newDeviceCopyOnClick());}// Note that we don't use an anonymous class to avoid nameclashing with// MainActivity$1, which already exists.// We also could've defined a nested MainActivity.Patch class and used// an anonymous class in MainActivity.Patch.onCreate(), and then called// MainActivity.Patch.onCreate() from MainActivity.onCreate().@DexAddclassDeviceCopyOnClickimplementsView.OnClickListener{@OverridepublicvoidonClick(Viewobject){if(MainActivity.this.val){Intentintent=newIntent(Intent.ACTION_SEND);intent.setType("text/plain");intent.putExtra(Intent.EXTRA_SUBJECT,"Device ID");intent.putExtra(Intent.EXTRA_TEXT,device.getText().toString());startActivity(Intent.createChooser(intent,"Share Device ID"));}else{Toast.makeText(MainActivity.this.getApplicationContext(),"Nothing to Share",0).show();}}}
  • როგორც ჩანს, ჩვენ ახლა დავასრულეთ! სრული პატჩი უნდა გამოიყურებოდეს ეს. ახლა ჩვენ შეგვიძლია შევქმნათ დაყენებული APK და დავაინსტალიროთ:
    $ dxp-make$ adb install patched.apk
  • მოდით შევხედოთ შედეგს:

(მადლობა ლანჩონს, რომ დაეხმარა ნიმუშის კოდს!)

Xposed უაღრესად პოპულარულია და კარგი მიზეზის გამო - ის აადვილებს მოდების შექმნას, გაზიარებას და ინსტალაციას როგორც დეველოპერებისთვის, ასევე მომხმარებლებისთვის. არსებობს რამდენიმე განსხვავება DexPatcher-სა და Xposed-ს შორის, რამაც შეიძლება ზოგიერთს უპირატესობა მიანიჭოს ერთს მეორეზე:

  1. Xposed თავის ჯადოსნობას აკეთებს მეთოდების გაშვების დროს და დეველოპერებს საშუალებას აძლევს გააკეთონ რაიმე ნებისმიერი მეთოდის წინ, შემდეგ ან მის ნაცვლად. მეორე მხრივ, DexPatcher ცვლის ყველაფერს გაშვების დრომდე და აწარმოებს დამოუკიდებელ, შეცვლილ APK-ს -- კოდის გაშვება მეთოდების წინ, შემდეგ ან მის ნაცვლად ჯერ კიდევ შესაძლებელია და თქვენ რეალურად გაქვთ დამატებითი თავისუფლება.
  2. დამოუკიდებელი APK-ის წარმოება ნიშნავს, რომ ის არ არის დამოკიდებული რაიმე გარე ჩარჩოზე. ეს ასევე ნიშნავს, რომ root არ არის საჭირო მომხმარებლის აპების შესაცვლელად.
  3. მას შემდეგ, რაც თქვენ შექმენით ახალი APK DexPatcher-ით, ის სხვაგვარად იქნება ხელმოწერილი. ეს ნიშნავს, რომ მომხმარებლები ვერ მიიღებენ ოფიციალურ განახლებებს ორიგინალური ავტორისგან და შეიძლება გამოიწვიოს გარკვეული პრობლემები აპებთან, როგორიცაა Google Apps, თუ ხელმოწერები შემოწმებულია.
  4. ორივე მოდულის და DexPatcher პატჩების წყაროს კოდი შეიძლება ადვილად გავრცელდეს და შეიცვალოს. ისინი ასევე იზიარებენ ბევრ მსგავსებას, თუ ცოტათი გაეცანით თითოეულს.

ჩვენ საკმარისად ვისაუბრეთ DexPatcher-ზე. ახლა შენი ჯერია, ასე რომ, გადადი DexPatcher ფორუმის თემა რომ დაუყოვნებლივ დაიწყოთ!