|
|
按理来说只要解密so的rc4就能还原nop
详细参考https://bbs.kanxue.com/thread-285620.htm
DPT通过Hook DefineClass 函数来触发代码恢复流程:
Hook:在native层的.init_array节中,通过Dobby和bhook框架Hook关键函数
触发:当系统调用 DefineClass 加载类时,Hook函数会被触发
定位:利用 DefineClass 的参数获取 DexFile 和 ClassDef 结构,从而定位需要恢复的CodeItem
详细介绍
1.原始代码的加密
DPT使用RC4加密对原始代码进行加密
i.生成密钥
位于RC4Utils.java
- <p>public static byte[] generateRC4Key() {</p><p> byte[] rc4key = new byte[16];</p><p> SecureRandom secureRandom = new SecureRandom();</p><p> for(int i = 0;i < rc4key.length;i++) {</p><p> secureRandom.nextBytes(rc4key);</p><p> }</p><p> rc4key[3] = 0x20;</p><p> rc4key[9] = 0x74;</p><p> return rc4key;</p><p>}</p>
复制代码 ii.加密
- <p>public static byte[] crypt(byte[] key,byte[] in) {</p><p> try {</p><p> Cipher cipher = Cipher.getInstance(transform);</p><p> SecretKeySpec spec = new SecretKeySpec(key,transform);</p><p> cipher.init(Cipher.ENCRYPT_MODE,spec);</p><p> return cipher.doFinal(in);</p><p> } catch (Exception e) {</p><p> }</p><p> return null;</p><p>}</p>
复制代码 iii.加固时加密 :在AndroidPackage类中执行SO文件加密
- <p>public void encryptSoFiles(String packageOutDir, byte[] rc4Key){</p><p> // ...</p><p> encryptSoFile(soFile, rc4Key);</p><p> writeSoFileCryptKey(soFile, rc4Key);</p><p> // ...</p><p>}</p>
复制代码 位于AndroidPackage.java
iiii.运行解密
在运行时,DPT通过 decrypt_section 函数解密存储在SO文件特定section中的代码:
- <p>void decrypt_section(const char* section_name, int temp_prot, int target_prot) {</p><p> // ...获取section信息</p><p> struct rc4_state dec_state;</p><p> rc4_init(&dec_state, reinterpret_cast<const u_char *>(DPT_UNKNOWN_DATA), 16);</p><p> rc4_crypt(&dec_state, reinterpret_cast<const u_char *>(target),</p><p> reinterpret_cast<u_char *>(bitcode),</p><p> size);</p><p> // ...将解密后的数据写回</p><p>}</p>
复制代码 2.加密后文件的存储位置
原始代码存储
存储格式 :使用 MultiDexCode 结构存储所有被提取的代码
包含版本信息、DEX数量、DEX代码索引数组和所有CodeItem数据
每个CodeItem包含方法索引、指令大小和原始指令数据
存储位置 :以特定名称( CODE_ITEM_NAME_IN_ZIP )存储在APK的ZIP文件中
运行读取 :在 init_app 函数中从ZIP文件读取:
- auto entry_data = read_zip_file_entry(package_addr, package_size, AY_OBFUSCATE(CODE_ITEM_NAME_IN_ZIP));
复制代码 位于dpt.cpp
加密密钥存储
密钥符号 :加密密钥存储在SO文件的特定符号 DPT_UNKNOWN_DATA 中
- public static final String RC4_KEY_SYMBOL = "DPT_UNKNOWN_DATA";
复制代码 位于const.java
密钥写入
在 writeSoFileCryptKey 方法中将密钥写入SO文件:
- <p>private void writeSoFileCryptKey(File soFile, byte[] rc4key) {</p><p> ReadElf.Symbol symbol = readElf.getDynamicSymbol(Const.RC4_KEY_SYMBOL);</p><p> // ...</p><p> IoUtils.writeFile(soFile.getAbsolutePath(), rc4key, symbolDataOffset);</p><p>}</p>
复制代码 3.代码加载与恢复
初始化与数据加载
初始化流程 :在 JNI_OnLoad 中调用 init_dpt() ,解密关键代码段
- <p>void init_dpt() {</p><p>#ifdef DECRYPT_BITCODE</p><p> decrypt_bitcode();</p><p>#endif</p><p> // ...</p><p>}</p>
复制代码 代码数据解析 :通过 readCodeItem 函数解析 MultiDexCode 格式的数据
- <p>DPT_ENCRYPT void readCodeItem(uint8_t *data, size_t data_len) {</p><p> if (data != nullptr && data_len >= 0) {</p><p> data::MultiDexCode *dexCode = data::MultiDexCode::getInst();</p><p> dexCode->init(data, data_len);</p><p> // ...解析DEX代码索引和CodeItem</p><p> }</p><p>}</p>
复制代码
4.MultiDexCode结构解析
MultiDexCode 提供了读取加密代码数据的方法:
数据结构 :
版本号(2字节)
DEX数量(2字节)
DEX代码索引数组
CodeItem数据数组
读取方法 :
- <p>dpt::data::CodeItem* dpt::data::MultiDexCode::nextCodeItem(uint32_t* offset) {</p><p> uint32_t methodIdx = readUInt32(*offset);</p><p> uint32_t insnsSize = readUInt32(*offset + 4);</p><p> auto* insns = (uint8_t*)(m_buffer + *offset + 8);</p><p> *offset = (*offset + 8 + insnsSize);</p><p> auto* codeItem = new CodeItem(methodIdx, insnsSize, insns);</p><p> return codeItem;</p><p>}</p>
复制代码 5.内存操作与代码恢复
内存保护与修改
内存权限修改 :通过Hook mmap 函数为DEX内存区域添加 PROT_WRITE 权限
代码恢复 :在Hook的 DefineClass 函数中,找到对应的CodeItem并将原始代码写回NOP填充区域
DPT使用映射表( dexMap )管理所有的CodeItem,以便在运行时快速查找和恢复:
- <p>// 在readCodeItem函数中构建映射</p><p>for (int i = 0; i < indexCount; i++) {</p><p> // ...</p><p> auto codeItemVec = new std::vector<data::CodeItem *>(65536);</p><p> // ...</p><p> for (int k = 0; k < methodCount; k++) {</p><p> data::CodeItem *codeItem = dexCode->nextCodeItem(&codeItemIndex);</p><p> uint32_t methodIdx = codeItem->getMethodIdx();</p><p> codeItemVec->at(methodIdx) = codeItem;</p><p> }</p><p> dexMap.emplace(i, codeItemVec);</p><p>}</p>
复制代码

|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|