应用安全 --- 安卓安全 之 加密入口
由于分析时我们要找到so文件的所有导出函数,为了不被反编译出导出函数暴露关键处理逻辑,我们可以通过动态注册函数加字符串加密的方法隐藏导出函数。
对抗方法:
解密字符串后找到映射的真实的函数地址和函数名称字符串
有些加密强度非常高,只会在运行时解密这些字符串,我这里提供一个方法,就是反编译所有的函数,并比对java和c函数的函数参数个数和类型,并分析处理逻辑可以大致找到这个匿名函数
比如有这样一个入口加密函数
// 模拟这个函数的工作流程 unsigned int decrypt_and_process_string( StringBuffer* output_buffer, // 输出缓冲区 CryptoObject* crypto_obj, // 加密对象 EncryptedData* encrypted_param // 加密参数 ) { if (encrypted_param != NULL) { // 步骤1: 调用解密函数(虚函数表偏移676) const char* decrypted_text = crypto_obj->vtable->decrypt_function( crypto_obj, encrypted_param, 0 // 解密标志 ); if (decrypted_text != NULL) { // 步骤2: 保存解密后的字符串 copy_string(output_buffer, decrypted_text); // 步骤3: 调用清理函数(虚函数表偏移680) return crypto_obj->vtable->cleanup_function( crypto_obj, encrypted_param, decrypted_text ); } } // 失败情况:使用默认字符串 copy_string(output_buffer, DEFAULT_ERROR_STRING); return 0; }
这个加密函数的好处有
1.内存不保留用完就销毁。防止内存dump
2.加密方法和加密数据是动态获取的。防止ida静态反编译分析。
3.字符串数据与解密逻辑分离
// 需要同时获取:
// 1. 加密数据 (encrypted_param)
// 2. 解密算法 (crypto_obj)
// 3. 可能的密钥材料