内容简介:对 Dex 文件的局部(可以是头部、代码段等等)求MD5值,并将MD5写入dex文件的末尾或其他不影响dex文件加载运行的位置(本人暂时还没碰到)
一、静态完整性校验
1、对Dex文件进行完整性校验
由于 Android 稍高版本在安装 APK 的过程中会把 classes.dex 抠出来转化为odex或者 vdex 等其他格式的优化文件,原 APK 中无 classes.dex ,但是会存在除 classes.dex 外的其他多dex文件(比如 classes2.dex 、 classes3.dex 等),故 无法校验 classes.dex ,也无法校验整个 APK 文件哈希值。
通过读取 APK 包中的除 classes.dex 外的其他 dex 文件,并计算其 CRC 的值,将得到的 CRC 与原始 CRC 进行比较,判断是否被修改过,原始 CRC 值保存在资源文件或其他自定义文件中相关代码:
String apkPath=context.getPackageCodePath();//获取Apk的路径 ZipFile zipFile=new ZipFile(apkPath); ZipEntry dexEntry=ZipFile.getEntry("classes.dex");//读取zip包中的classes.dex文件 String dexCRC=dexEntry.getCrc().toString();//计算dex的CRC文件值
对 Dex 文件的局部(可以是头部、代码段等等)求MD5值,并将MD5写入dex文件的末尾或其他不影响dex文件加载运行的位置(本人暂时还没碰到)
相关代码:
MessageDigest digest=MessageDigest.getInstance("MD5"); byte[] bytes=new byte[1024]; FileInputStream fileinputStream=new FileInputStream(new File(dexPath)); int byteCount; while(fileinputStream.read(bytes)!=-1){ digest.update(bytes,0,byteCount); } BigInteger bigInteger=new BigInteger(1,digest.digest());//计算dex的哈希 String MD5=bigInteger.toString();//dex的哈希值
2、对Apk文件进行完整性校验(Android 5.0以下)
通过 APK 包的 MD5 摘要进行判断文件是否被修改过,这里需要计算 APK 的 MD5 值,然后将 MD5 上传到服务器进行判断,或者等待服务器下发原始文件的 MD5 值,进行比较判断。
相关代码:
String apkPath=context.getPackageCodePath();//获取Apk的路径 MessageDigest digest=MessageDigest.getInstance("MD5"); byte[] bytes=new byte[1024]; FileInputStream fileinputStream=new FileInputStream(new File(apkPath));//读取apk文件 int byteCount; while(fileinputStream.read(bytes)!=-1){ digest.update(bytes,0,byteCount); } BigInteger bigInteger=new BigInteger(1,digest.digest());//计算apk的哈希 String MD5=bigInteger.toString();//apk的哈希值
3、签名信息校验
(1)通过 A ndroid.content.pm.PackageInfo.getPacketInfo() 函数获取包信息,然后拿到签名信息。
(2)该签名信息为一个 byte 数组,可以转换成 X.509 格式的证书信息,或者直接对该签名信息求哈希。
(3)现阶段为了增加分析的难度,通常都会将部分代码放到.so文件中。
相关代码:
PackageInfo packageInfo=content.getPackageManager() .getPackageInfo(content.getPackageName() PackageManager.GET_SIGNATURES);//获取包信息 Signature[] signature=packageInfo.signatures; Signature sign=signature[0]; MessageDigest digest=MessageDigest.getInstance("MD5"); digest.update(sign);
二、静态完整性校验apk的一些逆向思路
1、获取apk签名需要获取APK的路径
我们可以在获取APK路径的地方下断点。这样可以定位到相关校验代码。通过修改参数,传入一个官方APK路径,也可以绕过校验。
Context.getPackageCodePath() 用来获得当前应用程序对应的 apk 文件的路径:/data/app/包名/xxx.apk Context.getPackageResourcePath() 获取该程序的安装包路径 : /data/app/包名/xxx.apk packageInfo.applicationInfo.sourceDir 这里面也可以获取apk路径
2、在相关API下断
大部分应用在获取签名信息时都会调用系统API,我们可以在相关的API下断:
V1签名( Android 7.0 以下):
android.content.pm.PackageInfo.getPacketInfo(ClassName,flags).signatures
这里需要注意 当 flags 为64的时候,该函数会获取签名信息。 所以需要在 getpackageinfo 下断点,当flags为64的时候,就是获取签名信息。
V2签名( Android 7-9 ):
// 1.反射实例化PackageParser对象 Object packageParser = getPackageParser(path); // 2.反射获取parsePackage方法 Object packageObject = getPackageInfo(path,packageParser); // 3.调用collectCertificates方法 Method collectCertificatesMethod = packageParser.getClass(). getDeclaredMethod("collectCertificates",packageObject.getClass(),int.class); collectCertificatesMethod.invoke(packageParser,packageObject,0); // 4.获取mSignatures属性 Field signaturesField = packageObject.getClass().getDeclaredField("mSignatures"); signaturesField.setAccessible(true); Signature[] mSignatures = (Signature[]) signaturesField.get(packageObject);
V3签名( Android 9 及以上):
这几个是v3签名的系统验证函数
PackageManagerService.InstallPackageLI() PackageParser.collectCertificates() ApkSignatureVerifier.verify() ApkSignatureSchemeV3Verifier.verify() ApkSigningBlockUtils.findSignature() ApkSigningBlockUtils.findApkSigningBlock() ApkSigningBlockUtils.findApkSignatureSchemeBlock() SignatureInfo.SignatureInfo() ApkSignatureSchemeV3Verifier.verify() ApkSignatureSchemeV3Verifier.verifySigner() ApkSignatureSchemeV3Verifier.verifyAdditionalAttributes() ApkSignatureSchemeV3Verifier.verifyProofOfRotationStruct() ApkSignatureSchemeV3Verifier.VerifiedProofOfRotation()
3、可以在获取哈希相关的API处下断。
4、可以通过弹出窗口或者toast提示进行代码回溯,定位到签名校验的附近。
三、动态完整性
1、Xpose Hook 检测
(1)检测关键字
de.robv.android.xposed.XposedHelpers类的 静态fieldCache字段 保存被hook的字段信息 静态methodCache字段 保存被hook的方法信息 静态constructorCache字段 保存被hook的类信息
(2)检测内存
检测内存映射列表中是否包含如下文件:
XposedBridge.so XposedBridge.jar
(3)检测方法的调用栈
handleHookMethod invokeOriginalMethodNative
注:
(1)在 dalvik.system.NativeStart.main 方法后出现 de.robv.android.xposed.XposedBridge.main 的方法调用
(2)如果Xposed hook了调用栈里的一个方法, 还会有 de.robv.android.xposed.XposedBridge.handleHookedMethod 和 de.robv.android.xposed.XposedBridge.invokeOriginalMethodNative 调用
(3)检测标记位
d e.robv.android.xposed.XposedBridge 类, 静态 disableHooks 成员变量, 这个字段表示是否对当前应用进行hook操作。
2、Frida Hook 检测
(1)检测进程
FridaServer 通过 TCP 与 PC 上的 Frida 进行通信,所以可以检测进程中是否存在 FridaServer 进程
(2)检测端口
默认端口: 2704 7
非默认端口:
A. 用 nmap -sV 来找到开放端口
B. 对每个开放端口发送 D-Bus 认证协议
C. 哪个端口回复了哪个就是 FridaServer 进程的端口
(3)检测内存
搜索内存是否存在以下两个文件
frida-gadget.so
frida-agent.so`
(4)暴力扫描
在映射的s o 文件中扫描Frida的库特征,例如:“ gadgets ”,“ LIBFRIDA ”等等,这 两个在Frida的所有版本中都有存在
3、Cydia Substrate Hook检测
(1)检测包名
检测设备安装目录是否存在 com.saurik.substrate
(2)检测调用栈
com.android.internal.os.ZygoteInit
com.saurik.substrate.MS$2
注:
(1) 在dalvik.system.NativeStart.main 调用后会出现2次
com.android.internal.os.ZygoteInit.main ,而不是一次。
(2) 如果Substrate hook了调用栈里的一个方法,还会出现 com.saurik.substrate.MS$2.invoked、
com.saurik.substrate.MS$MethodPointer.invok e和跟S ubstrat e扩展相关的方法。
(3)检测内存
检测内存映射中是否存在 com.saurik.substrate 文件
4、动态完整性校验的一些逆向思路
(1)搜索字符串
例如:搜索 d e.robv.android.xposed.XposedBridge 或者搜索上述字符串的base64编码后的值。
(2)获取堆栈的函数下断
大部分应用都是主动触发异常,然后获取堆栈信息,判断里面是否有相关hook的关键字, 可以对 getStackTrace() 下断,这个是获取堆栈的API。
(3)对文件读取函数下断
如果获取内存,需要打开当前进程的 / proc 文件,可以对文件读取相关的 API 下断, 例如: new file 、new FildeReader。
(4)对相关的获取包名下断
函数 getPackageName() 获取相关的包名信息,判断参数里是否包含 hook 工具的包名。
- End -
看雪ID: 陌殇
https://bbs.pediy.com/user-759951.htm
本文由看雪论坛 陌殇 原创
转载请注明来自看雪社区
:warning: 注意
2019 看雪安全开发者峰会门票正在热售中!
长按识别下方 二维码 , 即可享受 2.5折 优惠!
﹀
﹀
﹀
公众号ID:ikanxue
官方微博:看雪安全
商务合作:wsc@kanxue.com
↙ 点击下方“阅读原文”,查看更多干货
以上所述就是小编给大家介绍的《Android应用完整性保护总结》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
谷歌和亚马逊如何做产品
梅 (Chris Vander Mey) / 刘亦舟 / 人民邮电出版社 / 2014-6-1 / CNY 49.00
软件在交付之前,面临产品、方案、项目和工程管理等诸多挑战,如何做到游刃有余并打造出极致产品?本书作者曾任谷歌和亚马逊高级产品经理、现任Facebook产品经理,他将自己在达特茅斯学院钻研的理论知识和在领先的互联网公司十年的工作经验尽数总结在此,从定义产品开始,一步步指导你完成管理项目、迭代、发布、市场推广等交付流程,让你身临其境地体验到极致产品如何取得成功。 本书主要内容: 如何清晰定......一起来看看 《谷歌和亚马逊如何做产品》 这本书的介绍吧!