安卓广告通过反编译 apk 来防止移除广告

  • 本文关键字:apk 编译 android admob apk
  • 更新时间 :
  • 英文 :


使用APK Easy Tool反编译 apk 并编辑AndroidManifest.xml文件后:

更改它:

<activity android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode" android:exported="false" android:name="com.google.android.gms.ads.AdActivity" android:theme="@android:style/Theme.Translucent"/>

--> "com.google.android.gms.ads.AdActivity">

自:

<activity android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode" android:exported="false" android:name="hacked_com.google.android.gms.ads.AdActivity" android:theme="@android:style/Theme.Translucent"/>

--> "hacked_com.google.android.gms.ads.AdActivity">

或编辑:

<meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="ca-app-pub-0000000000000000~123456789"/> // change app id

并保存并再次编译为 Apk。 我的横幅广告和插页式广告未显示。 如何解决这个硬错误?

从以下来源尝试一下: https://www.airpair.com/android/posts/adding-tampering-detection-to-your-android-app:

2 在运行时验证应用的签名证书

先决条件:Android 开发人员博客有一篇关于对应用进行签名的精彩文章。我建议先阅读本文,因为这种技术依赖于该知识。

简而言之,开发人员必须使用其私钥/证书(包含在 .keystore 文件中)对应用程序进行签名,然后才能在用户设备上安装应用程序。签名证书必须在应用的整个生命周期内保持一致,并且通常具有 25 年的未来到期日期。

Android 系统在处理应用升级时依赖于开发者签名证书的一致性。例如,虽然我可以创建一个与Facebook具有相同应用程序ID的应用程序,但我无法诱骗用户升级到我的版本,因为它没有使用Facebook的证书签名。作为开发人员,我们必须将此证书保密,否则我们将面临其他人能够以我们的身份签署应用程序的风险。

提示:将您的私钥(.keystore 文件)置于源代码控制之外,并保存在单独保护和备份的系统中。

如果以任何方式更改.apk,应用签名将被破坏 - 通常无法安装未签名的应用。例如,我们可以想象攻击者删除许可证检查代码以启用完整的应用程序功能而无需付费。一个更危险的例子是更改.apk,将恶意软件包含在合法应用程序中,以收集敏感的用户数据。为了安装更改的.apk,攻击者必须将其重新签名。

此技术详细介绍了如何确保.apk已使用开发人员证书进行签名,并利用证书保持一致且只有您有权访问它的事实。

我们可以将这种技术分为 3 个简单的步骤:

找到您的开发者证书签名。 将签名嵌入到应用的字符串常量中。 检查运行时的签名是否与我们的嵌入式开发人员签名匹配。

private static final int VALID = 0;
private static final int INVALID = 1;
public static int checkAppSignature(Context context) {
try {
PackageInfo packageInfo = context.getPackageManager()
.getPackageInfo(context.getPackageName(),
PackageManager.GET_SIGNATURES);
for (Signature signature : packageInfo.signatures) {
byte[] signatureBytes = signature.toByteArray();
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
final String currentSignature = Base64.encodeToString(md.digest(), Base64.DEFAULT);
Log.d("REMOVE_ME", "Include this string as a value for SIGNATURE:" + currentSignature);
//compare signatures
if (SIGNATURE.equals(currentSignature)){
return VALID;
};
}
} catch (Exception e) {
//assumes an issue in checking signature., but we let the caller decide on what to do.
}
return INVALID;
}

首先,我们需要找到证书的签名,以便我们可以将其嵌入到应用程序中。我已经包含一行来计算并将其记录到系统日志中 - 不用说,一旦您有副本,就应该将其删除。

检查您的 logcat 输出中是否有类似于以下内容的消息:

10-10 17:37:11.483: D/REMOVE_ME:(111): 478yYkKAQF+KST8y4ATKvHkYibo=

记下编码的签名并替换静态常量 SIGNATURE 的值:

私有静态最终字符串签名 = "478yYkKAQF+KST8y4ATKvHkYibo=";

在运行时,PackageManager 允许我们查询应用程序的签名。我们遍历此签名数组,并将其与我们的签名进行比较。

现在,当您在应用程序上运行 checkAppSignature 时(使用发布开发人员证书签名时),您应该看到它返回 0,即有效。此硬编码签名是 DexGuard 字符串加密的理想候选者。


或者,您可以计算签名。如果中止超过 1 个 ->:

public final String checkSignature()
{
Log.i(TAG, "executeSignatureCheck()");
Signature[] sigs;
try
{
sigs = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES).signatures;
}
catch (PackageManager.NameNotFoundException e)
{
throw new RuntimeException("PackageManager name not found.");
}
String signature = null;
int sigCount = 0;
for (Signature sig : sigs)
{
signature = getSHA1(sig.toByteArray());
Log.i(TAG, "Signature: " + signature);
sigCount++;
}
if (sigCount > 1)
{
throw new RuntimeException("Invalid signature.");
}
return signature;
}

您还应该考虑检查该应用程序是否是从Google Play下载的。(请参阅:我发布的该链接中的"验证安装程序")。 但不幸的是,您无法确定这是否适用于每台设备。我部署了这样的检查并在 Google Play 中发布到 Alpha,但 9 台设备中有 2 台没有返回字符串。我无法弄清楚,如果Google Play商店坏了,或者设备真的没有返回任何这些字符串。(在这里查看我的问题:从Google Play商店下载应用程序时,getInstallerPackageName()是否有可能为空?

最新更新