Android Question [no longer neccessary ] How to read manifest settings at runtime?

fredo

Well-Known Member
Licensed User
Longtime User
This use case concerns pirated apks.

It is well known that it is an eternal cat-and-mouse game between developers and hackers to build and circumvent protection.

In this case, our app is offered in a manipulated version at Aptoide.com, among others. Users can thus avoid buying the subscription, as the implemented mechanisms are bypassed.

An analysis of the offered APK file and a comparison with the Playstore original revealed significant differences.

Edit
As it turned out in the meantime, the offered APK file is a kind of Playstore replacement.
After the first installation, the originally desired app is offered for download.

So this thread is no longer necessary.


--------------------------------------

2021-07-17_17-33-47 (1).jpg

Malicious Manifest:
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android" android:compileSdkVersion="28" android:compileSdkVersionCodename="9" package="cm.aptoide.pt" platformBuildVersionCode="28" platformBuildVersionName="9">
    <uses-feature android:name="android.hardware.camera" android:required="false"/>
    <uses-permission android:name="android.permission.READ_SYNC_STATS"/>
    <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.INSTALL_PACKAGES"/>
    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/>
    <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"/>
    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
    <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.USE_CREDENTIALS"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.CAMERA"/>
    <application android:allowBackup="false" android:appComponentFactory="androidx.core.app.CoreComponentFactory" android:fullBackupContent="@xml/vungle_backup_rule" android:hardwareAccelerated="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:name="cm.aptoide.pt.NotificationApplicationView" android:networkSecurityConfig="@xml/network_security_config" android:supportsRtl="true" android:theme="@style/AppBaseTheme.NoTitle.Transparent">
        <activity android:configChanges="keyboardHidden|orientation|screenSize" android:name="com.mopub.common.privacy.ConsentDialogActivity"/>
        <activity android:configChanges="keyboardHidden|orientation|screenSize" android:name="com.mopub.common.MoPubBrowser"/>
        <activity android:configChanges="keyboardHidden|orientation|screenSize" android:name="com.mopub.mobileads.MoPubActivity"/>
        <activity android:configChanges="keyboardHidden|orientation|screenSize" android:name="com.mopub.mobileads.MraidActivity"/>
        <activity android:configChanges="keyboardHidden|orientation|screenSize" android:name="com.mopub.mobileads.RewardedMraidActivity"/>
        <activity android:configChanges="keyboardHidden|orientation|screenSize" android:name="com.mopub.mobileads.MraidVideoPlayerActivity"/>
        <activity android:launchMode="singleTask" android:name="cm.aptoide.pt.view.MainActivity" android:theme="@style/AppBaseTheme" android:windowSoftInputMode="adjustPan">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
            <meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts"/>
        </activity>
        <activity android:configChanges="fontScale|keyboard|keyboardHidden|locale|mcc|mnc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|touchscreen|uiMode" android:hardwareAccelerated="true" android:name="com.unity3d.services.ads.adunit.AdUnitActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen"/>
        <activity android:configChanges="fontScale|keyboard|keyboardHidden|locale|mcc|mnc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|touchscreen|uiMode" android:hardwareAccelerated="true" android:name="com.unity3d.services.ads.adunit.AdUnitTransparentActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"/>
        <activity android:configChanges="fontScale|keyboard|keyboardHidden|locale|mcc|mnc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|touchscreen|uiMode" android:hardwareAccelerated="false" android:name="com.unity3d.services.ads.adunit.AdUnitTransparentSoftwareActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"/>
        <activity android:configChanges="fontScale|keyboard|keyboardHidden|locale|mcc|mnc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|touchscreen|uiMode" android:hardwareAccelerated="false" android:name="com.unity3d.services.ads.adunit.AdUnitSoftwareActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen"/>
        <activity android:excludeFromRecents="true" android:name="cm.aptoide.pt.wallet.WalletInstallActivity" android:taskAffinity=".wallet.WalletInstallActivity" android:theme="@style/Aptoide.WalletDialogTheme" android:windowSoftInputMode="adjustPan"/>
        <activity android:configChanges="orientation|screenSize" android:name="com.applovin.adview.AppLovinInterstitialActivity"/>
        <activity android:configChanges="orientation|screenSize" android:name="com.applovin.adview.AppLovinConfirmationActivity"/>
        <meta-data android:name="applovin.sdk.key" android:value="NGgBA4BT14gGfXpsFDkgiALKb6v5cWAJOXGNy9XWJ3FrtA-LTIQ3EcNwBGk_SeUd1lgAHe0-DS-cTX1x0wEd73"/>
        <meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="ca-app-pub-5389160260063028~2982824200"/>
        <activity android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize" android:hardwareAccelerated="true" android:name="com.inmobi.rendering.InMobiAdActivity" android:resizeableActivity="false" android:theme="@android:style/Theme.NoTitleBar"/>
        <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
        <service android:name="cm.aptoide.pt.account.AccountAuthenticatorService">
            <intent-filter>
                <action android:name="android.accounts.AccountAuthenticator"/>
            </intent-filter>
            <meta-data android:name="android.accounts.AccountAuthenticator" android:resource="@xml/authenticator"/>
        </service>

...(more than 1600 lines)

Original xml file:
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android" android:compileSdkVersion="30" android:compileSdkVersionCodename="11" android:installLocation="preferExternal" package="my.package" platformBuildVersionCode="30" platformBuildVersionName="11">
    <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true"/>
    <uses-permission android:maxSdkVersion="18" android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <permission android:name="my.package.permission.C2D_MESSAGE" android:protectionLevel="signature"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="com.android.vending.BILLING"/>
    <uses-permission android:name="android.permission.VIBRATE"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
    <uses-permission android:name="android.permission.ACTION_OPEN_DOCUMENT"/>
    <uses-permission android:name="android.permission.MANAGE_DOCUMENTS"/>
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
    <uses-permission android:name="my.package.permission.C2D_MESSAGE"/>
    <application android:icon="@mipmap/ic_launcher" android:label="MyAppName" android:theme="@style/DarkTheme">
        <activity android:exported="false" android:name="com.google.android.gms.common.api.GoogleApiActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
        <meta-data android:name="com.google.android.play.billingclient.version" android:value="3.0.1"/>
        <activity android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize" android:name="com.android.billingclient.api.ProxyBillingActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
        <provider android:authorities="my.package.provider" android:exported="false" android:grantUriPermissions="true" android:name="androidx.core.content.FileProvider">
            <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths"/>
            <activity android:exported="false" android:name="com.google.android.gms.common.api.GoogleApiActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
            <meta-data android:name="com.google.android.gms.version" android:value="[USER=21225]@Integer[/USER]/google_play_services_version"/>
            <receiver android:enabled="true" android:exported="false" android:name="com.google.android.gms.measurement.AppMeasurementReceiver"/>
            <service android:enabled="true" android:exported="false" android:name="com.google.android.gms.measurement.AppMeasurementService"/>
            <receiver android:enabled="true" android:exported="true" android:name="com.google.android.gms.measurement.AppMeasurementInstallReferrerReceiver" android:permission="android.permission.INSTALL_PACKAGES">
                <action android:name="com.android.vending.INSTALL_REFERRER"/>
            </receiver>
            <service android:enabled="true" android:exported="false" android:name="com.google.android.gms.measurement.AppMeasurementJobService" android:permission="android.permission.BIND_JOB_SERVICE"/>
            <service android:directBootAware="true" android:name="com.google.firebase.components.ComponentDiscoveryService">
                <meta-data android:name="com.google.firebase.components:com.google.firebase.analytics.connector.internal.AnalyticsConnectorRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/>
                <meta-data android:name="com.google.firebase.components:com.google.firebase.iid.Registrar" android:value="com.google.firebase.components.ComponentRegistrar"/>
                <meta-data android:name="com.google.firebase.components:com.google.firebase.auth.FirebaseAuthRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/>
                <meta-data android:name="com.google.firebase.components:com.google.firebase.storage.StorageRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/>
                <meta-data android:name="com.google.firebase.components:com.google.firebase.firestore.FirestoreRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/>
                <meta-data android:name="com.google.firebase.components:com.google.firebase.database.DatabaseRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/>
                <meta-data android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/>
                <meta-data android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/>
                <meta-data android:name="com.google.firebase.components:com.google.firebase.crashlytics.CrashlyticsRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/>
            </service>
            <provider android:authorities="my.package.firebaseinitprovider" android:directBootAware="true" android:exported="false" android:initOrder="100" android:name="com.google.firebase.provider.FirebaseInitProvider"/>
            <receiver android:exported="true" android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver" android:permission="com.google.android.c2dm.permission.SEND">
                <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
                <action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
                <category android:name="my.package"/>
            </receiver>
            <receiver android:exported="false" android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver"/>
            <service android:exported="true" android:name="com.google.firebase.iid.FirebaseInstanceIdService">
                <intent-filter android:priority="-500">
                    <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
                </service>
                <service android:directBootAware="true" android:exported="true" android:name="com.google.firebase.messaging.FirebaseMessagingService">
                    <intent-filter android:priority="-500">
                        <action android:name="com.google.firebase.MESSAGING_EVENT"/>
                    </service>
                    <service android:name="anywheresoftware.b4a.objects.FirebaseNotificationsService">
                        <action android:name="com.google.firebase.MESSAGING_EVENT"/>
                    </service>
                    <service android:exported="false" android:name="com.google.android.datatransport.runtime.backends.TransportBackendDiscovery">
                        <meta-data android:name="backend:com.google.android.datatransport.cct.CctBackendFactory" android:value="cct"/>
                    </service>
                    <service android:exported="false" android:name="com.google.android.datatransport.runtime.scheduling.jobscheduling.JobInfoSchedulerService" android:permission="android.permission.BIND_JOB_SERVICE"/>
                    <receiver android:exported="false" android:name="com.google.android.datatransport.runtime.scheduling.jobscheduling.AlarmManagerSchedulerBroadcastReceiver"/>
                    <meta-data android:name="firebase_crashlytics_collection_enabled" android:value="false"/>
                    <activity android:label="MyAppName" android:launchMode="singleTop" android:name=".main" android:screenOrientation="portrait" android:windowSoftInputMode="stateHidden">
                        <action android:name="android.intent.action.MAIN"/>
                        <category android:name="android.intent.category.LAUNCHER"/>
                        <action android:name="android.intent.action.SEND"/>
                        <data android:mimeType="*/*"/>
                        <intent-filter> android:icon="@drawable/icon"
                    android:label="@string/app_name"
                    android:priority="50" &gt;
                            <action android:name="android.intent.action.VIEW"/>
                            <data android:scheme="file"/>
                            <data android:scheme="content"/>
                            <data android:host="*"/>
                            <data android:mimeType="*/*"/>
                            <data android:pathPattern=".*\\.myextension"/>
                            <data android:pathPattern=".*\\..*\\.myextension"/>
                            <data android:pathPattern=".*\\..*\\..*\\.myextension"/>
                            <data android:pathPattern=".*\\..*\\..*\\..*\\.myextension"/>
                            <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.myextension"/>
                            <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.myextension"/>
                            <service android:name=".starter"/>
                            <receiver android:name=".starter$starter_BR"/>
                            <service android:name=".firebasemessaging"/>
                            <receiver android:name=".firebasemessaging$firebasemessaging_BR"/>
                            <service android:name=".myservice"/>
                            <receiver android:name=".myservice$myservice_BR"/>
                            <service android:name=".httputils2service"/>
                            <receiver android:name=".httputils2service$httputils2service_BR"/>

Particularly noticeable is the manifest file, which is now 120k in size instead of about 10k.

Without setting up elaborate protection, I would like to check the active app at runtime for suspicious values or settings that I did not intend.


Since the "evil" manifest file makes an extremely large number of entries, it must be possible to read out e.g. the registrierent intent filter etc. ...



Does anyone know how to read the entries in the manifest file at runtime?
 
Last edited:

Johan Schoeman

Expert
Licensed User
Longtime User
Here is a starting point

 
Upvote 0

Sandman

Expert
Licensed User
Considering they seem to be able to modify your app, how do you intend to stop them using what you read from the manifest?
 
Upvote 0

fredo

Well-Known Member
Licensed User
Longtime User
At the moment I assume that no one will bother to analyze my app. I think that an automated mechanism will simply replace the payment relevant part.
My approach is to do the manifest check after a certain time and then crash the app.
That way the user might lose patience to use pirated versions and I can see in crashlytics how much users are using the cracked version.
 
Upvote 0

Sandman

Expert
Licensed User
My approach is to do the manifest check after a certain time and then crash the app.

That way the user might lose patience to use pirated versions
1626608675494.png


It might not be entirely obvious for the user that the crash is because they used a pirated copy.
 
Upvote 0
Top