发觉已然没有值得我兴奋的教程,真正的大佬们把自己的技术藏的严严实实[滑稽]便从研究MOD改个方向研究安全。寻思着一法通则万法通,本意是想写一个so层的c++签名检验,往hook框架进发。所以最近研究了一些关于签名检验的东西,从java层面,以及对lgl菜单的一个兼容,写了一个java层次的签名检验代码
由于我们经常需要对游戏进行去签,一些检验方式可能不是很适合,可能把自己的也防了。所以就从md5值方向出发。
实现功能比较简单,检验md5值,正确就正确运行,错误就弹出对话框,对话框的构造函数是默认的安卓对话框方式,实现功能为可以跳转链接。。。如果你有一定开发基础,也可以根据这个方向进行一定美化以及,对检验强度进行一个加强,这是我在so层检验的一个小产物。。
主要部分都有注释,复制全文提取代码部分粘贴到你的菜单项目,文件路径为:
我的菜单/app/src/main/java/com/android/support/main.java
建议是在完成植入与编译后,通过dex2c将代码抽取,提高安全程度。。。
package com.android.support;
import android.app.AlertDialog;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import java.security.NoSuchAlgorithmException;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.content.DialogInterface;
import android.graphics.drawable.GradientDrawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Looper;
import android.os.Process;
import android.provider.Settings;
import android.view.Gravity;
import android.view.SurfaceHolder;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.NetworkInterface;
import java.net.URL;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.UUID;
import org.json.JSONException;
import org.json.JSONObject;
import static android.graphics.Typeface.BOLD;
import android.app.Activity;
public class Main {
private static native void CheckOverlayPermission(Context context);
static {
//你所用so库的名字
System.loadLibrary("mylibname");
}
public static interface callbackSwitch {
void newMenu(Context context);
}
//获取应用签名 MD5 值
private static String getAppSignatureMD5(Context context) {
try {
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES);
Signature[] signatures = packageInfo.signatures;
byte[] signatureBytes = signatures[0].toByteArray();
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(signatureBytes);
byte[] digest = md.digest();
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
sb.append(String.format("%02X", b));
}
return sb.toString();
} catch (PackageManager.NameNotFoundException | NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
public static void Start(Context context) {
CrashHandler.init(context, false);
// 检查签名 MD5 值
String appSignatureMD5 = getAppSignatureMD5(context);
String expectedMD5 = "123456"; // 请将此处替换为您期望的 MD5 值
if (appSignatureMD5 != null && appSignatureMD5.equals(expectedMD5)) {
CheckOverlayPermission(context);
} else {
// 签名错误,退出程序
showErrorDialog(context);
}
}
private static void showErrorDialog(final Context context) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("错误");//对话框标题
builder.setMessage("签名错误,退出程序");
builder.setPositiveButton("打开链接", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.example.com"));
context.startActivity(browserIntent);
}
});
builder.setCancelable(false);
builder.show();
}
}
THE END