D’App huet op Android 9 funktionéiert an stierft um selwechten Telefon nom Update op Android 10. Däi Profil ass onberéiert, d’Zertifikater sinn déiselwecht, an de Crash kënnt virun all Authentifikatiounstraffic. Logcat weist fir d’éischt en Nullzeiger, an e puer Zeilen driwwer steet Cannot run program ...: error=13, Permission denied. Déi Noriicht geet ëm d’Ausféiere vun enger Datei, net ëm d’Liese vun denger Konfiguratioun.

Wat de Feeler 13 wierklech verweigert

Android 10, API-Niveau 29, huet Apps opgehalen, Dateien auszeféieren, déi se an hiren eegenen Datesverzeechnis geschriwwen hunn. D’Regel zielt op Späicher, deen éischt schreifbar an duerno ausféierbar ass, an dat ass genee dat, wat e Launcher mécht, deen aus den Assets kopéiert. Méi al Builden vum ics-openvpn-Kär packen beim éischte Start eng ausféierbar Datei openvpn aus dem APK aus a starten se mat ProcessBuilder. D’Auspaken geléngt nach ëmmer; verweigert gëtt d’Ausféieren. Eng App, déi op API 29 zielt, ierft d’Regel och dann, wann se op engem Gerät leeft, dat mat enger méi aler Versioun ausgeliwwert gouf, a dofir kann en Update e Build briechen, deen keen ugepaakt huet.

Näischt un der Verweigerung ass spezifesch fir een eenzegen Dossiernumm. Eng Datei, déi d’App ënner hirem Datesverzeechnis ugeluecht huet, gëtt onofhängeg vum Pad als net-ausféierbar behandelt, also schléit getFilesDir(), getCacheDir() an en eegenen Ënnerverzeechnis all gläichzäiteg feel.

Trenn den Hëllefs-Crash vun engem Profilproblem

Liest de Log ronderëm de Prozessstart, amplaz vun uewen ze scrollen. D’Signatur, déi s du siche muss, ass d’Zeile error=13, an de Stacktrace driwwer nennt meeschtens d’Launcher-Method, déi ProcessBuilder opgeruff huet:

adb logcat -d | grep -n -i -E "cannot run program|permission denied|startOpenVPN"

Wann den Hëllef ni gestart gouf, gesäis du guer keng OpenVPN-Logausgab: keng Cipher-Verhandlung, keng gepuschte Routen, keng DNS-Konfiguratioun. Wann déi Zeilen awer erschéngen an de Feeler méi spéit kënnt, ass d’Binärdatei gelaf an de Problem läit am Profil, am Server oder an der Routing-Schicht. Dee eenzegen Ënnerscheed spuert vill Zäit, déi soss fir d’Bearbechte vu Fichieren .ovpn dru gi wier, déi ni schëlleg waren. Et seet der och, wéi eng vun den zwou Korrekturen hei drënner s du wierklech brauchs.

Kontrolléier och den API-Niveau op deem Gerät, dees du testest, net deen aus denger Build-Konfiguratioun. En Emulator-Image op API 28 reproduzéiert näischt, well d’Restriktioun eréischt vun 29 un opwärts beißt. Kontrolléier gläichzäiteg de Ziel-SDK an denger Build-Datei: et ass d’Erhéijung dovun, déi d’Regel erabréngt.

adb shell getprop ro.build.version.sdk

Firwat d’Kopéiere vun der Binärdatei soss anzwousch net hëlleft

Den offensichtlechen Ëmwee, den Hëllef an en aneren schreifbaren Dossier ze schreiwen, schléit aus demselwecht Grond feel wéi d’Original. Android erlaabt nach ëmmer d’Ausféiere vu gedeelte Bibliothéiken, déi an den nativen Bibliothéiks-Dossier vun der App installéiert goufen, well den Installateur se packt an net se zur Lafzäit geschriwwen ginn. Dee Dossier ass déi eenzeg Plaz, op déi de Launcher weise soll. Alles, wat s du zur Lafzäit selwer auspaks, wéi s du et och nenns, bleift an der verweigerter Kategorie.

Externe Späicher ass schléchter: en ass mat noexec montéiert, an en Hëllef, deen do läit, kann vun kenger App gestart ginn. D’App-Daten ze läschen hëlleft och net, well den nächste Start einfach déiselwecht net-ausféierbar Kopie nees uleet.

Richt de Launcher op eng gepackte Bibliothéik

Benenn den Hëllef an en Numm vun enger gedeelter Bibliothéik ëm a liwwer en ënner jniLibs fir all ABI, deen s du ënnerstëtz, a loos de Launcher dann vun API 28 un de Pad vun der installéierter Bibliothéik zréckginn:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
    return new File(context.getApplicationInfo().nativeLibraryDir,
                    "libovpnexec.so").getPath();
}

D’Bibliothéik muss bei der Installatioun ausgepakt ginn, fir datt dee Pad eng richteg Datei enthält, also setz android:extractNativeLibs="true" um Element <application>. Wann e Manifest-Merger en anere Wäert erabréngt, füüg tools:replace="android:extractNativeLibs" derbäi. Referenz zum application-Element dokumentéiert, wat den Attribut steiert.

Pass op eng duebel lokal Variabel op, wann s du de Launcher vun Hand patchs. Méi al Quellen deklaréieren nativeAPI méi spéit an der selwechter Method, an eng zweet Deklaratioun ass e Kompiléierfeeler an net e Lafzäitfeeler, also schléit de Build séier feel an de Feeler ass einfach ze gesinn. Halt d’ABI-Lëscht am Gradle-Block mat den Dossieren, déi s du derbäisetz, am Gläichgewiicht.

Looss den Release-Artefakt zum Testbuild passen

En Debug-APK kann den Tunnel opbauen, wärend e Release-Bundle nach ëmmer crasht, well e Bundle nativen Bibliothéike an enger anerer Form packt a se kompriméiert aus dem Archiv ka liwweren. Wann nëmme Bundle-Ofgeleeëte Builden feel schléien, füüg dëst an gradle.properties an a bau nei:

android.bundle.enableUncompressedNativeLibs=false

Bestätegt duerno, datt de installéierte Paket déi ABI melli, déi s du erwaarts, a widderhuel d’Kontroll op engem 32-Bit- an engem 64-Bit-Gerät, wann s du béides liwwers. De Pakmanager nennt d’ABI, déi hien ausgewielt huet, also erschéngt e Gerät, dat op 32 Bit zréckgefall ass, hei an net an engem Crashrapport:

adb shell dumpsys package com.example.openvpn | grep -i primaryCpuAbi

Eng fehlend Bibliothéik fir eng ABI reproduzéiert den ursprénglechen Zougrëffsfeeler nëmmen op deem Gerät, an dofir ass een eenzegen erfollegräiche Testtelefon kee Beweis. Liwwer d’Manifestflag, den Numm vun der Bibliothéik an d’Bundle-Astellung zesummen; wann s du eng änderst an déi aner vergiess, bass du erëm beim selwechte Crash. D’dauerhaft Léisung ass den Iwwergank op eng ënnerhalen Kärversioun, amplaz de Patch fir ëmmer matzeschleefen.

Ähnlech Artikelen