系统方法解读

iOS应用完整性检查

2018-05-11  本文已影响227人  __Guan__

场景:在越狱手机中,直接替换资源文件,然后重新启动app,加载了被替换的资源,app没有作出警告。

通过网络调查,目前市面上的方法大致分为三种:

第一种方法:CodeResources文件是Xcode在对IPA包做签名时的产物。打包之后可以再ProjectName.app/_CodeSignature/CodeResources路径下找到。

CodeResources

该文件为plist文件,其中存储了资源文件在签名之后的加密值,最终以base64编码显示,但是解码之后得到的仍然是乱码

记得之前某位大神的帖子里说codesign的过程是将文件进行MD5->RSA->Base64的方法进行加密,链接找不到了,但是试过后发现结果不一样,有大神知道请指正)。

因此只能在打包后将此文件交给后端,app启动后通过网络请求下载该文件,然后与本地的文件中的值做比较。

第二种办法,由于通过App Store上架的应用,苹果会对IPA包做数字加密处理,通过比较cryptid可以来判断该应用是否为App Store下载的应用,但是对于直接替换资源文件,貌似(越狱手机变成砖,暂未尝试)不会对加密状态产生影响,因此该方法只能用于验证加密状态,是否下载自AppStore。

#if TARGET_IPHONE_SIMULATOR && !defined(LC_ENCRYPTION_INFO)
#define LC_ENCRYPTION_INFO 0x21

struct encryption_info_command {
    uint32_t cmd;
    uint32_t cmdsize;
    uint32_t cryptoff;
    uint32_t cryptsize;
    uint32_t cryptid;
};
#endif

int main (int argc, char *argv[]);
static BOOL isEncrypted () {
    const struct mach_header *header;
    Dl_info dlinfo;
    /* Fetch the dlinfo for main() */
    if (dladdr(main, &dlinfo) == 0 || dlinfo.dli_fbase == NULL) {
        //NSLog(@"Could not find main() symbol (very odd)");
        return NO;
    }
    header = dlinfo.dli_fbase;
    /* Compute the image size and search for a UUID */
    struct load_command *cmd = (struct load_command *) (header+1);
    for (uint32_t i = 0; cmd != NULL && i < header->ncmds; i++) {
        /* Encryption info segment */
        if (cmd->cmd == LC_ENCRYPTION_INFO) {
            struct encryption_info_command *crypt_cmd = (struct encryption_info_command *) cmd;
            /* Check if binary encryption is enabled */
            if (crypt_cmd->cryptid < 1) {
                /* Disabled, probably pirated */
                return NO;
            }
            /* Probably not pirated <-- can't say for certain, maybe theres a way around it */
            return YES;
        }
        cmd = (struct load_command *) ((uint8_t *) cmd + cmd->cmdsize);
    }
    /* Encryption info not found */
    return NO;
}

第三种办法,在编译期间,使用shell命令,遍历所有资源图片,并计算其MD5值,然后以图片名字为key,写入一个plist文件中,app启动后,遍历自身bundle资源图片,进行MD5计算与比较。但是由于Xcode默认开启PNG图片压缩处理,需要将其关闭

CompressPNG

打包之后对比IPA增量,貌似不是很多。

shell代码如下:

MD5File="$PROJECT_DIR/Resource/sources_encodes.plist"
function encodeFiles () {
    for file in `ls $1`
    do
    if [ -d $1"/"$file ]
    then
        encodeFiles $1"/"$file
    else
        file_name=`basename $file`
        if [[ $file_name =~ ".png" ]]
        then
        md5value=`md5 -q $1"/"$file`
        echo $file_name $md5value
        /usr/libexec/PlistBuddy -c "Add:$file_name string $md5value" $MD5File
        fi
    fi
    done
}

rm -f $MD5File

cat>$MD5File <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

<plist version="1.0">
<dict>

</dict>
</plist>
EOF

folder="$PROJECT_DIR/Resource/"
encodeFiles $folder

其实代码层面的check,都可以通过Hook方式,直接将方法返回值改掉,因此逆向攻防就是互相伤害的过程,在此记录下。

上一篇下一篇

猜你喜欢

热点阅读