来自NDK / JNI的Android APK篡改检测

时间:2016-02-19 19:25:55

标签: android security android-ndk apk dex

问题

我有一些钥匙,我想保证它的安全。目前,本机共享库按需生成它们。我的apk使用这个共享库来获取密钥。当前实现的问题是攻击者可能提取apk,复制共享库并调用生成密钥的函数并获取密钥。因此,我想确保共享库仅在我的apk调用时生成有效密钥。

解决此问题的方法

解决此问题的方法涉及NDK侧的apk篡改检测。基本思想是在运行时从JNI获取调用APK的签名。如果签名有效,则库生成有效密钥,否则生成无效密钥。

此方法的已知限制

  • 据了解,这不是100%万无一失。
  • 由于密钥位于客户端设备中且客户端拥有硬件,因此专用攻击者可以访问生成的密钥。

到目前为止我做了什么 到目前为止,实施基于此stackoverflow post

中提到的想法
  • 读取存储在/ proc / self / maps
  • 中的进程内存
  • 找到包含文字'.dex'的行。
  • 获取DEX文件区域的起始和结束地址

    FILE *fp;    
    fp = fopen("/proc/self/maps", "r");    
    if(fp!=NULL){
        char line [ 2048 ];
        while ( fgets ( line, sizeof line, fp ) != NULL ) /* read a line */
        {
            if (strstr(line, ".dex") != NULL) {
    
                //This is the line we want
                __android_log_write(ANDROID_LOG_INFO,"DexFile",line);
                char * startingAddress;
                char * endingAddress;
                startingAddress = strtok (line," ,.-");
                endingAddress = strtok (NULL," ,.-");
                if(startingAddress!=NULL){
                    __android_log_write(ANDROID_LOG_INFO,"DexStart",startingAddress);
                }
                if(endingAddress!=NULL){
                __android_log_write(ANDROID_LOG_INFO,"DexEnd",endingAddress);
                }
                //Now, we have the starting and ending address
            }
    
        }
        fclose ( fp);
    }
    

我还没有理解

  • 现在我有了dex文件区域的起始地址和结束地址, 我如何获得签名?
  • 我不确定为什么签名需要首先阅读。我认为你需要在dex文件区域dex file format中读取apk的校验和,如果校验和不符合你的预期,则认为apk已被篡改。

  • 如何以可移植的方式实现我想要做的事情(因为它涉及本机代码)?

注意:如果你能提供示例实现,那就太棒了,因为我一直在寻找这个特定的答案而且我只找到了抽象的答案。提前谢谢。

0 个答案:

没有答案