我已经彻底搜索此网站以及其他人的答案,并没有发现任何实际的答案。保护应用内购买自由Hack
我的问题是Freedom Hack(它允许用户无需付费即可购买应用程序内购买)确实做了什么。也就是说,这个过程的哪个部分被改变了。我发现this list的黑客运行的应用程序,其中一些条目的日期可能在本月,也就是说尚未完全修复。我见过的回复是“在服务器上验证应用程序”,但是如果黑客修改了Java.Security的签名验证功能,所以它总是返回true,然后在服务器中添加我自己的签名不会帮助很大。
我已经彻底搜索此网站以及其他人的答案,并没有发现任何实际的答案。保护应用内购买自由Hack
我的问题是Freedom Hack(它允许用户无需付费即可购买应用程序内购买)确实做了什么。也就是说,这个过程的哪个部分被改变了。我发现this list的黑客运行的应用程序,其中一些条目的日期可能在本月,也就是说尚未完全修复。我见过的回复是“在服务器上验证应用程序”,但是如果黑客修改了Java.Security的签名验证功能,所以它总是返回true,然后在服务器中添加我自己的签名不会帮助很大。
我不知道作者是否仍然关注这个话题。但是我花了一些时间来找出(搜索)自由的方式,以及如何防止它(直到他们更新自由的方式)在我的项目和它的工作方式。我的实现非常简单,您不需要通过向服务器发送请求来进行验证(这会影响性能,并需要付出更多努力才能实现)。
自由的当前实现是它会将java.security.Signature.verify(byte[])
的所有方法调用替换(重定向)到自由的jni方法,而该方法只是总是返回true (or 1)
。
看一看java.security.Signature.verify(byte[])
:
public final boolean verify(byte[] signature) throws SignatureException {
if (state != VERIFY) {
throw new SignatureException("Signature object is not initialized properly");
}
return engineVerify(signature);
}
这里engineVerify
方法是首先在java.security.SignatureSpi
(Signature extends SignatureSpi
)定义的abstract protected
方法。 好的,那够了,因为我不能相信java.security.Signature.verify(byte[])
方法了,我会直接使用engineVerify
方法。要做到这一点,我们需要使用反思。从修改的IABUtil/Security
的verify
方法:
public static boolean verify(PublicKey publicKey, String signedData, String signature) {
Signature sig;
try {
sig = Signature.getInstance(SIGNATURE_ALGORITHM);
sig.initVerify(publicKey);
sig.update(signedData.getBytes());
if (!sig.verify(Base64.decode(signature))) {
Log.e(TAG, "Signature verification failed.");
return false;
}
return true;
} catch (...) {
...
}
return false;
}
要:
public static boolean verify(PublicKey publicKey, String signedData, String signature) {
Signature sig;
try {
sig = Signature.getInstance(SIGNATURE_ALGORITHM);
sig.initVerify(publicKey);
sig.update(signedData.getBytes());
Method verify = java.security.SignatureSpi.class.getDeclaredMethod("engineVerify", byte[].class);
verify.setAccessible(true);
Object returnValue = verify.invoke(sig, Base64.decode(signature));
if (!(Boolean)returnValue) {
Log.e(TAG, "Signature verification failed.");
return false;
}
return true;
} catch (...) {
...
}
return false;
}
说起来很简单,但它与当前实现自由的工作,直到他们更新其未来的算法。
然后在服务器中添加我自己的签名没有多大帮助。
这是不正确的,“自由”使用的签名是无效的,并且订单ID也是无效的。
我做的事,以确保我的应用是安全的是:
发送isPurchaseValid(myPurchase.getSignature(), myPurchase.getOriginalJson())
到我的服务器,以验证那边它与真正的购买,但每次的自由失败。
在我检查,如果签名匹配
如果匹配我联系“谷歌API的谷歌Play Android开发者API> androidpublisher.inapppurchases.get”以验证购买所在的服务器,并返回我的开发人员负载
然后,我使用开发人员有效负载来确保此购买是针对该特定用户而不是其他某个用户,并且该用户正在向我发送他的数据。
P.S.开发人员有效负载是在您的Android应用程序购买之前设置的String
,它应该是您的用户唯一的东西。
这可能是很多工作,但它确保没有人会买你的东西与自由和成功。
我无法做的唯一的事情就是不要让自由对我的应用程序产生影响,例如Path中的人做了一些我不知道是什么让Freedom变得没有影响的东西! !
我正在使用类似这样的东西,我知道与远程服务器检查您的签名相比,这不是一个好的解决方案。我正在检查是否安装了Freedom应用程序,如果是这样,我不打开我的应用程序。
@Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
if(isHackerAppIsntalled())
finish();
}
private boolean isHackerAppInstalled() {
final PackageManager pm = getApplication().getPackageManager();
List<ApplicationInfo> packages = pm
.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo packageInfo : packages) {
String packageName = packageInfo.packageName;
if (packageName.contains("cc.madkite.freedom")
|| packageName.contains("madkite.freedom")) {
return true;
}
}
return false;
}
这是一个非常糟糕的主意。所有黑客需要做的就是改变他的包名(当然这很简单)。 – Asaf
是的,我也这么认为,每次你需要太更新软件包名称:( – nexx
和自由是不是唯一的黑客程序..寻找幸运修补程式 – JerryGoyal
检查是否存在Freedom Hack的软件包名称,如果是,请求用户删除该应用程序。 – Mdlc
但是,如果Freedom的包名称发生更改,则支票将不再起作用。此外,我知道,它掩盖自己,所以它不会被发现(我敢肯定它可以做到这一点) – Asaf
你需要检测自由服务,并且(据我所知),自由始终显示活动时发出通知,也许您可以检测到该情况。 – Mdlc