Mae deuaidd cynorthwyol OpenVPN yn methu ar Android 10: caniatâd wedi’i wrthod
Mae Android 10 yn gwrthod gweithredu cynorthwyydd a ysgrifennodd yr ap i’w storfa ei hun. Darllenwch logcat, danfonwch y cynorthwyydd fel llyfrgell frodorol, a thrwsiwch adeiliadau bwndel.
Roedd yr ap yn gweithio ar Android 9 ac mae’n marw ar yr un ffôn ar ôl y diweddariad i Android 10. Mae eich proffil heb ei gyffwrdd, mae’r tystysgrifau yr un peth, ac mae’r chwalfa’n cyrraedd cyn unrhyw draffig dilysu. Mae logcat yn dangos pwyntydd nwl yn gyntaf, ac ychydig linellau uwch ei ben mae Cannot run program ...: error=13, Permission denied. Mae’r neges honno’n ymwneud â gweithredu ffeil, nid â darllen eich ffurfweddiad.
Beth mae gwall 13 yn ei wrthod mewn gwirionedd
Rhoddodd Android 10, lefel API 29, stop ar apiau rhag gweithredu ffeiliau a ysgrifennent i’w cyfeiriadur data eu hunain. Mae’r rheol yn targedu storfa y gellir ysgrifennu iddi ac yna ei gweithredu, sef yn union yr hyn y mae lansiwr sy’n copïo o assets yn ei greu. Mae adeiliadau hŷn o graidd ics-openvpn yn dadbacio ffeil weithredu openvpn o’r APK ar y rhedeg cyntaf ac yn ei chychwyn gyda ProcessBuilder. Mae’r dadbacio’n dal i lwyddo; y gweithredu sy’n cael ei wrthod. Mae ap sy’n targedu API 29 yn etifeddu’r rheol hyd yn oed pan mae’n rhedeg ar ddyfais a ddaeth gyda rhyddhad hŷn, a dyna pam y gall diweddariad dorri adeiliad na chyffyrddodd neb â hi.
Nid oes dim yn y gwrthodiad sy’n benodol i un enw ffolder. Mae ffeil a grëwyd gan yr ap o dan ei gyfeiriadur data yn cael ei thrin fel un annefnyddiadwy waeth beth yw’r llwybr, felly getFilesDir(), getCacheDir() ac is-gyfeiriadur arferol i gyd yn methu yr un ffordd.
Gwahaniaethwch chwalfa’r cynorthwyydd oddi wrth broblem proffil
Darllenwch y log o amgylch cychwyn y broses yn lle sgrolio o’r brig. Y llofnod i chwilio amdano yw’r llinell error=13, ac mae’r ôl-trawst yn uwch ei phen fel arfer yn enwi dull y lansiwr a alwodd ProcessBuilder:
adb logcat -d | grep -n -i -E "cannot run program|permission denied|startOpenVPN"Os na chychwynnodd y cynorthwyydd erioed, ni welwch unrhyw allbwn log OpenVPN o gwbl: dim trafod seiffr, dim llwybrau wedi’u gwthio, dim ffurfweddiad DNS. Os yw’r llinellau hynny’n ymddangos a’r methiant yn dod yn hwyrach, gweithredodd y deuaidd ac mae’r broblem yn y proffil, y gweinydd neu’r haen lwybro. Mae’r un gwahaniaeth hwnnw’n arbed llawer o amser a dreulid yn golygu ffeiliau .ovpn nad oeddent byth ar fai. Mae hefyd yn dweud wrthych pa un o’r ddau atgyweiriad isod sydd ei angen arnoch mewn gwirionedd.
Gwiriwch lefel API ar y ddyfais rydych yn ei phrofi hefyd, nid yr un yn eich ffurfweddiad adeiladu. Nid yw delwedd emwlator ar API 28 yn atgynhyrchu dim, oherwydd dim ond o 29 i fyny y mae’r cyfyngiad yn brathu. Gwiriwch y SDK targed yn eich ffeil adeiladu ar yr un pryd: codi hwnnw sy’n tynnu’r rheol i mewn.
adb shell getprop ro.build.version.sdkPam nad yw copïo’r deuaidd i rywle arall yn helpu
Mae’r gwaith o gwmpas amlwg, sef ysgrifennu’r cynorthwyydd i gyfeiriadur y gellir ysgrifennu iddo, yn methu am yr un rheswm ag y methodd yr un gwreiddiol. Mae Android yn dal i ganiatáu gweithredu llyfrgelloedd a rennir a osodwyd yng nghyfeiriadur llyfrgelloedd brodorol yr ap, oherwydd y gosodwr sy’n eu pecynnu yn hytrach na’u hysgrifennu ar amser rhedeg. Y cyfeiriadur hwnnw yw’r un lle y dylai’r lansiwr fod yn pwyntio ato. Mae unrhyw beth rydych yn ei ddadbacio eich hun ar amser rhedeg, beth bynnag a’i galwch, yn aros yn y categori a wrthodwyd.
Mae storfa allanol yn waeth: mae wedi’i osod gyda noexec, ac ni all unrhyw ap gychwyn cynorthwyydd a osodir yno. Nid yw clirio data’r ap yn adfer yr hen ymddygiad chwaith, oherwydd mae’r rhedeg nesaf yn syml yn ailgreu’r un copi annefnyddiadwy.
Pwyntiwch y lansiwr at lyfrgell wedi’i phecynnu
Ailenwch y cynorthwyydd yn enw llyfrgell a rennir a’i ddanfon o dan jniLibs ar gyfer pob ABI rydych yn ei gefnogi, yna gadewch i’r lansiwr ddychwelyd llwybr y llyfrgell osodedig o API 28 ymlaen:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
return new File(context.getApplicationInfo().nativeLibraryDir,
"libovpnexec.so").getPath();
}Rhaid dadbacio’r llyfrgell ar amser gosod er mwyn i’r llwybr hwnnw gynnwys ffeil go iawn, felly gosodwch android:extractNativeLibs="true" ar yr elfen <application>. Os yw uniadwr maniffest yn dod â gwerth gwahanol i mewn, ychwanegwch tools:replace="android:extractNativeLibs" wrth ei ymyl. Mae cyfeirlyfr elfen application yn dogfennu beth mae’r priodoledd yn ei reoli.
Gwyliwch am newidyn lleol dyblyg pan glytïwch y lansiwr â llaw. Mae ffynonellau hŷn yn datgan nativeAPI yn hwyrach yn yr un dull, ac mae ail ddatganiad yn wall cyfuno yn hytrach na gwall rhedeg, felly mae’r adeiliad yn methu’n gyflym ac mae’r camgymeriad yn hawdd ei weld. Cadwch y rhestr ABI ym mhloc Gradle yn cyd-fynd â’r ffolderi rydych yn eu hychwanegu.
Gwnewch i arteffact y rhyddhad gyd-fynd â’r adeiliad prawf
Gall APK dadfygio godi’r tiwnel tra bo bwndel rhyddhad yn dal i chwalu, oherwydd mae bwndel yn pecynnu llyfrgelloedd brodorol ar ffurf wahanol ac yn gallu eu cyflwyno wedi’u cywasgu o’r archif. Os mai dim ond adeiliadau sy’n deillio o fwndel sy’n methu, ychwanegwch hyn at gradle.properties ac ailadeiladwch:
android.bundle.enableUncompressedNativeLibs=falseYna cadarnhewch fod y pecyn osodedig yn adrodd yr ABI rydych yn ei ddisgwyl, ac ailadroddwch y gwiriad ar ddyfais 32-bit a 64-bit os ydych yn danfon y ddau. Mae’r rheolwr pecynnau yn enwi’r ABI a ddewisodd, felly mae dyfais a syrthiodd yn ôl i 32-bit yn ymddangos yma yn lle mewn adroddiad chwalfa:
adb shell dumpsys package com.example.openvpn | grep -i primaryCpuAbiMae llyfrgell ar goll ar gyfer un ABI yn atgynhyrchu’r gwall caniatâd gwreiddiol ar y ddyfais honno yn unig, a dyna pam nad yw un ffôn prawf llwyddiannus yn brawf. Danfonwch faner y maniffest, enw’r llyfrgell a gosodiad y bwndel gyda’i gilydd; mae newid un a anghofio’r lleill yn eich rhoi yn ôl yn yr un chwalfa. Yr atgyweiriad parhaol yw symud i ryddhad craidd a gynhelir yn hytrach na chario’r clwt am byth.