fence 防护机制

混淆

安全防护 减小包大小

代码混淆

  • classes.dex + dex2jar -> jar-> jd-gui
  • apktool -> smali

资源混淆

AndResGuard

类似Java Proguard,但是只针对资源,将原本冗长的资源路径变短

签名

没有签名apk不能安装,每个app都有一个唯一签名。同一包名不同签名不允许。

debug有个默认签名文件进行签名。

为了防止二次打包,检查签名。都二次打包改代码了,干掉检查很难?

APK签名机制

数字签名

  • 确保消息来源
  • 确保消息不被篡改

S : 发送者 R : 接收者

\[S\xrightarrow{\mathrm{公钥}}R\] \[S\xrightarrow{\mathrm{原始消息}\;+\;\mathrm{私钥加密}(\mathrm{消息摘要})\;}R\] \[R\;\left\{\begin{array}{l}\mathrm{原始消息}\;\xrightarrow[{}]{}\mathrm{摘要}A\\\mathrm{加密摘要}\xrightarrow[\mathrm{公钥解密}]{}\mathrm{摘要}B\end{array}\right.\]

对比摘要A 和摘要B是否一致 不能确保正确的公钥->数字证书

sign

jarsign , signapk

keytool生成keystore 使用 jarsign 进行签名

签名检查

class.dex CRC

反调试

反IDA

TracerPid > 0

反Android

xml android:debuggable=True

调试器

模拟器

Android组件安全

Activity

串谋权限攻击

防止被外部利用

劫持

Broadcast Receiver

发送安全

Service

Content Provider

数据安全

外部存储

权限

solve

内部存储

MODE_PRIVATE linux 权限 通过root/等更高权限可以破解

MODE_WORLD_READABLE

其他

apk 加固

合并

脱壳流程

summary

  • 源APK
  • 脱壳APK = 壳dex + 壳rest
  • 加密解密程序encrypt/decrypt(可以使用native来做)

加壳 classes.dex = encrypt(源APK) + 壳dex APK = sign(classes.dex + 壳rest)

脱壳 run : APK-> classes.dex -> decrypt(加密源APK) -> 加载源APK

so

好难弄懂

so加载过程

init_array段是在so加载的时候执行的 执行顺序要优先于 JNI_OnLoad 所以这里是最早被执行的函数 把反调试和so的解密放到这里是比较好的选择。 JNI_OnLoad

apk 签名检验

1
2
3
4
5
6
7
8
public class myJNI {
  //加载so库
    static {
        System.loadLibrary("JniTest");
    }
  //native方法
    public static native String sayHello();
}

调用

1
myJNI.sayHello();

动态注册

section 加固

原理

实现

summary

函数加密