用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个简单的步骤:
找到您的开发者证书签名。将您的签名嵌入应用程序中的String常量。检查运行时的签名是否与嵌入式开发人员签名匹配。
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的值:
private static final String 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商店损坏或设备确实没有返回任何这些字符串,我无法弄清楚。 (请参阅我的问题:Is it possible that getInstallerPackageName() is null when app downloaded from Google Play Store?)