app逆向-frida定位签名校验

本文介绍了应用签名校验的概念,包括其在确保应用安全中的作用,以及通过SHA1值和签名验证的实现方法。还探讨了如何通过反编译和Hook内置API进行签名校验的绕过,以及一个实际案例演示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、前言

当我们说应用签名校验时,实际上是一种安全机制,用于确保移动应用在被安装和运行时没有被篡改或修改。这个机制通过在应用程序文件上附加一种数字签名的方式来实现。

想象一下,你制作了一个应用,并且你希望用户下载并安装这个应用。在你发布应用之前,你对这个应用进行了签名,就好像你在应用上盖了一个印章一样。这个印章是使用你的私钥生成的,只有你才有这个私钥。

现在,当用户下载你的应用时,操作系统会检查这个印章。它会使用你公开的公钥来验证这个印章是否与应用的内容匹配。如果匹配,就说明应用是原始未经修改的版本,因为只有你拥有私钥,其他人无法伪造相同的印章。

这个过程的目的是确保用户安装的应用是来自可信的源,并且没有被黑客篡改过。这对于防止应用被恶意修改、插入广告或其他不良行为非常重要。这就是应用签名校验的基本概念。

二、如何实现签名校验

通过反编译软件可以看到app签名信息
在这里插入图片描述
那么在app内可以通过对比SHA1值进行校验

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.util.Base64;
import android.util.Log;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class AppSignatureVerifier {

    // 获取应用签名的方法
    public static String getAppSignature(Context context) {
        try {
            PackageInfo packageInfo = context.getPackageManager().getPackageInfo(
                    context.getPackageName(),
                    PackageManager.GET_SIGNATURES
            );

            // 获取第一个签名(通常应用只有一个签名)
            Signature signature = packageInfo.signatures[0];

            // 计算 SHA1 哈希值
            MessageDigest md = MessageDigest.getInstance("SHA1");
            byte[] signatureBytes = md.digest(signature.toByteArray());

            // 将字节数组转换为 Base64 编码的字符串
            return Base64.encodeToString(signatureBytes, Base64.NO_WRAP);
        } catch (PackageManager.NameNotFoundException | NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        return null;
    }

    // 校验应用签名的方法
    public static boolean verifySignature(Context context, String expectedSignature) {
        String appSignature = getAppSignature(context);

        // 对比期望的签名和实际的签名
        return (appSignature != null && appSignature.equals(expectedSignature));
    }

    // 示例用法
    public static void main(String[] args) {
        Context context = /* 获取Android应用的上下文 */;
        String expectedSignature = /* 期望的应用签名 */;
        
        if (verifySignature(context, expectedSignature)) {
            Log.d("AppSignatureVerifier", "应用签名校验通过");
        } else {
            Log.e("AppSignatureVerifier", "应用签名校验失败");
        }
    }
}

也存在其他的校验方法如对比hashcode

if(-19423432442 == context.getPackageManager().getPackageInfo(context.getPackageName(),64).signatures[0].hashCode(){
	return true;
})
Process.killProcess(Process.myPid());
return true;

三、案例:定位签名校验

案例app下载

链接:https://pan.baidu.com/s/1lZ2Umucc0wgglDlSEuFK9w 提取码:9r9w

先反编译apk,再重新打包成apk

# 反编译apk
apktool d E:\apk\lesson3-com.chaozhuo.texteditor.apk
# 重新打包成apk
apktool b E:\apk\lesson3-com.chaozhuo.texteditor\
# 签名
keytool -genkey -keystore my-release-key.keystore -alias my_alias -keyalg RSA -keysize 4096 -validity 10000
jarsigner -sigalg MD5withRSA -digestalg SHA1 -keystore my-release-key.keystore -signedjar E:\apk\2.apk E:\apk\1.apk my_alias
# 安装重新打包好的apk
adb install E:\apk\2.apk

再次打开app,发现被检测,无法正常使用app如下:
在这里插入图片描述
通过java内置库android.content.pm.Signature可以hook与签名相关的函数

# hook 内置类android.content.pm.Signature
var Signature = Java.use('android.content.pm.Signature')

# hook 内置类的hashCode方法
Signature.hashCode.implementation = function() {
    console.log('hashCode')
    return this.hashCode()
}

# hook 内置类的toByteArray方法
Signature.toByteArray.implementation = function() {
    console.log('toByteArray')
    return this.toByteArray()
}

并打印出堆栈

# hook 内置类的toByteArray方法
Signature.toByteArray.implementation = function() {
    console.log('toByteArray')
    printstack()
    return this.toByteArray()
}
# 打印调用堆栈
function printstack() {
    console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
}

完整代码:github

<think>嗯,用户想知道如何绕过APK的签名校验机制。首先,我得回忆一下APK签名的作用。APK签名主要是为了验证应用在发布后没有被篡改,确保应用的完整性。如果用户想绕过这个机制,可能有几种方法,比如修改APK后重新签名,但系统会检测到签名不一致,导致安装失败或者运行时校验失败。 根据提供的引用内容,引用[1]提到verifiedEntries找不到新添加的文件,导致返回null。这可能涉及到在签名后添加文件,从而绕过签名检查。另外,引用[2]和[3]提到了替换public_key的方法,可能是在反编译后的代码中找到签名相关的部分,替换正确的公钥,或者通过抓包修改网络请求中的验证信息。引用[4]和[5]则涉及重打包和修改返回值,比如hook方法返回特定的路径,欺骗签名检查。 首先,我需要整理这些方法。可能的方法包括:重打包时处理签名校验逻辑、修改验证相关的代码或资源、网络验证的中间人攻击、动态Hook技术,以及通过注入文件来绕过校验。每种方法的具体步骤需要详细说明,比如反编译APK、定位签名校验代码、修改smali代码或资源文件,然后重新打包签名。同时,需要注意这些方法的实现细节,比如如何找到关键代码位置,如何处理签名后的文件添加,或者如何Hook系统方法返回伪造的信息。 另外,用户可能需要了解这些方法的原理和潜在风险,比如可能违反法律法规,或导致应用不稳定。因此,在回答中需要强调这些注意事项,并建议仅用于合法授权的研究。同时,要确保步骤清晰,比如分步骤说明如何反编译、修改、重打包,以及可能用到的工具如apktool、Frida等。 还需要考虑用户的实际操作中可能遇到的问题,比如如何定位签名校验的代码位置,如何正确替换公钥,或者如何配置抓包工具来拦截和修改网络请求。引用中的例子提供了具体的代码修改点,比如修改getPackageCodePath的返回值,这需要用户具备一定的逆向工程和编程能力。 总结起来,回答需要分步骤介绍不同方法,结合引用中的具体案例,说明每种方法的操作流程,并提醒用户注意法律和安全问题。同时,生成的相关问题要围绕这些方法的应用、检测和防御展开,帮助用户进一步理解相关技术。</think>### 绕过APK签名校验的常见方法 #### 1. **修改签名校验逻辑(代码层绕过)** - **原理**:APK签名校验通常通过对比当前APK的签名与预置的合法签名是否一致来实现。若直接修改校验逻辑(例如强制返回`true`),可绕过检测。 - **步骤**: 1. 使用反编译工具(如`apktool`)解包APK,定位签名校验代码。通常搜索关键词如`signatures`、`getPackageInfo`、`verify`等[^2]。 2. 修改`smali`代码或`Java`逻辑,使校验函数直接返回合法值。例如: ```smali # 原代码:if-eqz v0, :cond_0 (检查签名是否为空) # 修改为:if-nez v0, :cond_0 (反向条件) ``` - **风险**:部分应用会在多个位置校验签名,需全面覆盖。 #### 2. **注入合法公钥(资源替换)** - **原理**:若应用使用预埋的公钥验证签名,可通过反编译替换合法公钥。 - **步骤**: 1. 反编译APK后,搜索`public_key`或`signature`相关资源文件。 2. 将合法APK的公钥替换到目标APK中,确保验证逻辑匹配[^3]。 - **案例**:通过抓包对比正常APK与篡改APK的`public_key`差异,替换后绕过网络验证[^3]。 #### 3. **动态Hook绕过(运行时拦截)** - **原理**:使用`Frida`或`Xposed`等工具,在运行时修改关键函数返回值。 - **步骤**: 1. Hook签名校验函数(如`getPackageCodePath`),强制返回合法APK路径: ```javascript // Frida脚本示例[^5] Java.perform(function () { Java.use("android.content.ContextWrapper").getPackageCodePath.implementation = function () { return "/data/app/合法APK路径/base.apk"; }; }); ``` 2. 绕过校验后加载篡改后的APK。 #### 4. **签名后注入文件(Jar漏洞利用)** - **原理**:Android的`JarVerifier`在校验时依赖`verifiedEntries`列表。若在签名后添加新文件,该校验会失败但可能被忽略[^1]。 - **步骤**: 1. 对已签名APK追加新文件(如`assets/`目录下的资源)。 2. 修改代码逻辑,使应用加载新增文件时不触发校验。 #### 5. **网络验证中间人攻击** - **原理**:若签名校验依赖服务端验证,可通过抓包篡改响应。 - **步骤**: 1. 使用抓包工具(如`Charles`)拦截验证请求。 2. 替换响应中的签名验证结果字段(如`"valid": true`)[^3]。 --- ### 注意事项 1. **法律风险**:绕过签名校验可能违反《计算机软件保护条例》,仅限合法授权场景使用。 2. **兼容性问题**:修改后的APK可能因签名失效导致部分功能异常(如支付、地图SDK)。 3. **对抗加固**:若APK被混淆或加固(如360加固),需先脱壳再修改。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是花臂不花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值