本期受害者 中国移动 12.0.5
第一步
先去dump 目标so libexec.so
第二步
我们可以使用frida Stalker定位被杀死的位置:
Interceptor.attach(JNI_OnLoad,{onEnter:function(){console.log("JNI_OnLoad 进入")constcurTid=Process.getCurrentThreadId();conststartBase=module.base;constname=module.name;constbase=module.base;constsize=module.size;Stalker.follow(curTid,{transform:function(iterator){letinstruction=iterator.next();constbaseFirstAddress=instruction.address;constisModuleCode=baseFirstAddress.compare(startBase)>=0&&baseFirstAddress.compare(startBase.add(size))<=0;do{constcurRealAddr=instruction.address;constcurOffset=curRealAddr.sub(base);constinstructionStr=instruction.toString()if(isModuleCode){log.push(curRealAddr+" <+"+curOffset+">: "+instructionStr);}iterator.keep();}while((instruction=iterator.next())!==null);}})},onLeave:function(){console.log("JNI_OnLoad 成功结束")}})直接定位到0x4a270
// 主要的 Frida 检测函数 - 综合检测多种反调试和脱壳工具 __int64 __fastcall sub_49D00(__int64 a1, __int64 a2, __int64 a3, __int64 a4, void *a5, void *a6, void *a7) { { atomic_store(1u, &dword_E8F70); decrypt_string(&unk_DFCF4, 13LL); } v9 = linux_eabi_syscall(48LL, 0xFFFFFFFFFFFFFF9CLL, &unk_DFCF4, 0LL, 0LL, a5, a6, a7);// 检测1: 检查 /data/dexname 文件是否存在(脱壳工具特征) if ( v9 < 0xFFFFFFFFFFFFF001LL ) { if ( v9 != -1 ) goto LABEL_21; } else { *MEMORY[0xD13D0]() = -v9; } v10 = atomic_load(&dword_E8F6C); if ( !v10 && !dword_E8F6C ) { atomic_store(1u, &dword_E8F6C); decrypt_string(&unk_DFCD0, 32LL); } v11 = linux_eabi_syscall(48LL, 0xFFFFFFFFFFFFFF9CLL, &unk_DFCD0, 0LL, 0LL, a5, a6, a7);// 检测2: 检查 /system/lib64/libxiaojianbang.so 是否存在(小肩膀脱壳工具) if ( v11 < 0xFFFFFFFFFFFFF001LL ) { if ( v11 != -1 ) goto LABEL_21; } else { *MEMORY[0xD13D0]() = -v11; } v12 = off_D9AE0; v13 = *(*off_D9AE0 + 16LL); v14 = *(*v13 + 48LL); v15 = atomic_load(&dword_E8F74); if ( !v15 && !dword_E8F74 ) { atomic_store(1u, &dword_E8F74); decrypt_string(&unk_DFD10, 18LL); } v16 = v14(v13, &unk_DFD10); // 检测3: 检查 cn/youlor/Unpacker 类是否存在(Unpacker 脱壳工具) (*(*(*v12 + 32) + 208LL))(*(*v12 + 16)); if ( v16 ) goto LABEL_21; v17 = atomic_load(&dword_E8F78); if ( !v17 && !dword_E8F78 ) { atomic_store(1u, &dword_E8F78); decrypt_string(&unk_DFD24, 13LL); } if ( MEMORY[0xD13A0](&unk_DFD24, 0LL) ) // 检测4: 检查 libsotweak.so 是否加载(SO 文件 hook 工具) goto LABEL_21; v22 = atomic_load(&dword_E8F08); if ( !v22 && !dword_E8F08 ) { atomic_store(1u, &dword_E8F08); decrypt_string(&unk_DFA00, 31LL); } v23 = linux_eabi_syscall(48LL, 0xFFFFFFFFFFFFFF9CLL, &unk_DFA00, 0LL, 0LL, v18, v19, v20);// 检测5: 检查 /data/local/tmp/unpacker.config 配置文件 if ( v23 < 0xFFFFFFFFFFFFF001LL ) { if ( v23 != -1 ) goto LABEL_21; } else { *MEMORY[0xD13D0]() = -v23; } v24 = atomic_load(&dword_E8F7C); if ( !v24 && !dword_E8F7C ) { atomic_store(1u, &dword_E8F7C); decrypt_string(&unk_DFD40, 27LL); } v25 = linux_eabi_syscall(48LL, 0xFFFFFFFFFFFFFF9CLL, &unk_DFD40, 0LL, 0LL, v18, v19, v20);// 检测6: 检查 /data/local/tmp/aupk.config 配置文件 if ( v25 < 0xFFFFFFFFFFFFF001LL ) { if ( v25 != -1 ) goto LABEL_21; } else { *MEMORY[0xD13D0]() = -v25; } v26 = atomic_load(&dword_E8F80); if ( !v26 && !dword_E8F80 ) { atomic_store(1u, &dword_E8F80); decrypt_string(&unk_DFD5C, 10LL); } v27 = linux_eabi_syscall(48LL, 0xFFFFFFFFFFFFFF9CLL, &unk_DFD5C, 0LL, 0LL, v18, v19, v20);// 检测7: 检查 /data/fart 目录(FART 脱壳工具) if ( v27 < 0xFFFFFFFFFFFFF001LL ) { if ( v27 != -1 ) goto LABEL_21; } else { *MEMORY[0xD13D0]() = -v27; } v28 = *(*v12 + 16); v29 = *(*v28 + 48LL); v30 = atomic_load(&dword_E8F84); if ( !v30 && !dword_E8F84 ) { atomic_store(1u, &dword_E8F84); decrypt_string(&unk_DFD68, 14LL); } v31 = v29(v28, &unk_DFD68); // 检测8: 检查 cn/mik/Fartext 类(Fartext 脱壳工具) v32 = (*(*(*v12 + 32) + 208LL))(*(*v12 + 16)); if ( v31 || sub_4B4F8(v32) ) goto LABEL_21; v36 = atomic_load(&dword_E8F88); if ( !v36 && !dword_E8F88 ) { atomic_store(1u, &dword_E8F88); decrypt_string(&unk_DFD80, 21LL); } v37 = linux_eabi_syscall(48LL, 0xFFFFFFFFFFFFFF9CLL, &unk_DFD80, 0LL, 0LL, v33, v34, v35);// 检测9: 检查 /data/system/mik.conf 配置文件 if ( v37 < 0xFFFFFFFFFFFFF001LL ) { if ( v37 != -1 ) goto LABEL_21; } else { *MEMORY[0xD13D0]() = -v37; } v38 = *v12; v143 = 0LL; v39 = *(v38 + 16); v40 = *(*v39 + 1336LL); v41 = atomic_load(&dword_E8F8C); if ( !v41 && !dword_E8F8C ) { atomic_store(1u, &dword_E8F8C); decrypt_string(&unk_DFD98, 6LL); } v42 = v40(v39, &unk_DFD98); // 检测10: 检查 mikrom 服务是否存在 v43 = *(*v12 + 16); v44 = *(*(*v12 + 32) + 128LL); v45 = atomic_load(&dword_E8F90); if ( !v45 && !dword_E8F90 ) { atomic_store(1u, &dword_E8F90); decrypt_string(&unk_DFDA0, 25LL); } v46 = atomic_load(&dword_E8F94); // read_string: android/os/ServiceManager if ( !v46 && !dword_E8F94 ) { atomic_store(1u, &dword_E8F94); decrypt_string(&unk_DFDC0, 40LL); } v47 = atomic_load(&dword_E8F98); // read_string: (Ljava/lang/String;)Landroid/os/IBinder; if ( !v47 && !dword_E8F98 ) { atomic_store(1u, &dword_E8F98); decrypt_string(&unk_DFDEC, 10LL); } v44(v43, &v143, &unk_DFDA0, &unk_DFDC0, &unk_DFDEC, v42);// 检测11: 通过 ServiceManager.getService 检查系统服务 (*(**(*v12 + 16) + 184LL))(*(*v12 + 16), v42); if ( v143 ) goto LABEL_21; v48 = atomic_load(&dword_E8F9C); if ( !v48 && !dword_E8F9C ) { atomic_store(1u, &dword_E8F9C); decrypt_string(&unk_DFE00, 31LL); } v49 = atomic_load(&dword_E8FA0); // read_string: /data/local/tmp/re.frida.server if ( !v49 && !dword_E8FA0 ) { atomic_store(1u, &dword_E8FA0); decrypt_string(&unk_DFE20, 15LL); } if ( !MEMORY[0xD1320](&unk_DFE00, &unk_DFE20) )// 检测12: 检查 re.frida.server 进程是否运行 goto LABEL_21; v50 = *v12; v51 = *(*v12 + 220); if ( v51 >= 23 ) { v52 = sub_4B6D8(v147); // 检测13: 开始读取 /proc/self/maps 进行内存映射分析 v146 = 0LL; if ( v52 ) { v53 = v51 + 45; v54 = v51 + 2; v55 = v51 - 81; if ( v51 - 82 >= 0 ) v53 = v51 - 82; v56 = v51 - 66; if ( v54 >= 0 ) v57 = v51 + 2; else v57 = v51 + 33; v58 = v51 - 32; if ( v55 >= 0 ) v56 = v51 - 81; v59 = v51 + 55; v60 = v57 & 0xFFFFFFE0; if ( v58 >= 0 ) v61 = v51 - 32; else v61 = v51 + 991; v62 = v54 - v60; if ( v59 >= 0 ) v63 = v51 + 55; else v63 = v51 + 86; v64 = v55 - (v56 & 0xFFFFFFF0); v65 = v58 - (v61 & 0xFFFFFC00); v66 = v59 - (v63 & 0xFFFFFFE0); v67 = v51 - 15; v68 = (v62 + 1) * v62 * (v62 + 2) * (v62 + 3) * (v62 + 4) * (v62 + 5); v69 = v66 * v66 * v66 * v66 * (6 * v66 + 2 * v66 * v66 + 5) - v66 * v66; v70 = (2 * v65) | 1; v71 = (v65 + 1) * v65; if ( v51 + 34 >= 0 ) v72 = v51 + 34; else v72 = v51 - 95; v73 = v71 * v70; if ( v67 >= 0 ) v74 = v51 - 15; else v74 = v51; v75 = v51 - 37; v76 = v67 - (v74 & 0xFFFFFFF0); if ( v51 - 68 >= 0 ) v75 = v51 - 68; v77 = v51 - 68 - (v75 & 0xFFFFFFE0); v78 = v68 % 20; v136 = ((v77 + 1) * v77 * (v77 + 2) * (v77 + 3) * (v77 + 4) * (v77 + 5)) % 20; v79 = v69 % 12; v138 = v73 % 6; v80 = v51 - 80; if ( v51 - 93 >= 0 ) v81 = v51 - 93; else v81 = v51 + 930; v82 = v51 + 943; if ( v80 >= 0 ) v82 = v51 - 80; v83 = ((v80 - (v82 & 0xFFFFFC00) + 1) * (v80 - (v82 & 0xFFFFFC00)) * ((2 * (v80 - (v82 & 0xFFFFFC00))) | 1)) % 6; v139 = ((v64 + 1) * v64 * (v64 + 2) * (v64 + 3) * (v64 + 4) * (v64 + 5) * (v64 + 6)) % 30; v134 = ((v76 + 1) * v76 * (v76 + 2) * (v76 + 3) * (v76 + 4) * (v76 + 5) * (v76 + 6)) % 30; v141 = (v83 | (((v51 - 93 - (v81 & 0xFFFFFC00) + 1) * (v51 - 93 - (v81 & 0xFFFFFC00)) * ((2 * (v51 - 93 - (v81 & 0xFFFFFC00))) | 1)) % 6)) == 0 || v83 == 0; v84 = 0; v142 = ((v51 - 82 - (v53 & 0x80) + 1) * (v51 - 82 - (v53 & 0x80)) * (v51 - 82 - (v53 & 0x80) + 2) * (v51 - 82 - (v53 & 0x80) + 3)) & 7; v85 = v52; v135 = ((v51 + 34 - (v72 & 0x80) + 1) * (v51 + 34 - (v72 & 0x80)) * (v51 + 34 - (v72 & 0x80) + 2) * (v51 + 34 - (v72 & 0x80) + 3)) & 7; v137 = v52; while ( 1 ) { v86 = sub_6C3D4(v85, "\n", &v146); if ( !v86 ) goto LABEL_183; v87 = v86; if ( v142 ) { LABEL_108: v90 = atomic_load(&dword_E8FC4); if ( !v90 && !dword_E8FC4 ) { atomic_store(1u, &dword_E8FC4); decrypt_string(&unk_DFEF0, 17LL); } strstr_1(v87, &unk_DFEF0); } v88 = atomic_load(&dword_E8FC4); if ( !v88 && !dword_E8FC4 ) { atomic_store(1u, &dword_E8FC4); decrypt_string(&unk_DFEF0, 17LL); } v89 = strstr_1(v87, &unk_DFEF0); // 检测14: 在内存映射中搜索 frida-agent-64.so if ( v78 ) goto LABEL_108; if ( v89 ) goto LABEL_117; v91 = atomic_load(&dword_E8FA0); if ( !v91 && !dword_E8FA0 ) { atomic_store(1u, &dword_E8FA0); decrypt_string(&unk_DFE20, 15LL); } if ( strstr_1(v87, &unk_DFE20) ) goto LABEL_117; if ( v139 ) { LABEL_126: v95 = atomic_load(&dword_E8FC8); if ( !v95 && !dword_E8FC8 ) { atomic_store(1u, &dword_E8FC8); decrypt_string(&unk_DFF04, 7LL); } strstr_1(v87, &unk_DFF04); } v93 = atomic_load(&dword_E8FC8); if ( !v93 && !dword_E8FC8 ) { atomic_store(1u, &dword_E8FC8); decrypt_string(&unk_DFF04, 7LL); } v94 = strstr_1(v87, &unk_DFF04); // 检测15: 在内存映射中搜索 /memfd: (匿名内存文件,Frida 常用) if ( (((v51 - 26) * (v51 - 27) * (v51 - 26) * (v51 - 27)) & 3) != 0 ) goto LABEL_126; if ( v94 ) { v154 = 0u; v155 = 0u; v152 = 0u; v153 = 0u; v150 = 0u; v151 = 0u; v148 = 0u; v149 = 0u; v96 = atomic_load(&dword_E8FCC); if ( !v96 && !dword_E8FCC ) { atomic_store(1u, &dword_E8FCC); decrypt_string(&unk_DFF0C, 10LL); } MEMORY[0xD1450](v87, &unk_DFF0C, &v145, &v144, &v148);// 解析内存映射行: 格式 %lx-%lx %s (起始地址-结束地址 路径) if ( (v144 - v145) > 0x200000 ) // 检测16: 检查内存区域大小是否大于 2MB(可疑的大内存区域) { v140 = v84; if ( v138 ) strstr_1(&v148, "r"); do v97 = strstr_1(&v148, "r"); while ( v79 ); if ( v97 ) { if ( v138 ) strstr_1(&v148, "p"); do v98 = strstr_1(&v148, "p"); while ( v135 ); if ( v98 ) { v99 = v145; if ( *v145 == 127 && v145[1] == 69 )// 检测17: 检查 ELF 魔数 (0x7F 'E') - 识别动态加载的 SO 文件 { v100 = v144; v101 = atomic_load(&dword_E8FD4); if ( !v101 && !dword_E8FD4 ) { atomic_store(1u, &dword_E8FD4); decrypt_string(byte_DFF30, 20LL); } v102 = v99 + 0x200000; // 检测18: 在内存中搜索 FridaAgentStopReason 字符串(Frida 特征字符串) if ( v99 + 0x200000 >= v100 ) v102 = v100; if ( v102 - 20 > v99 ) { v103 = v99; while ( 1 ) { if ( *v103 == byte_DFF30[0] ) { v104 = 1LL; do { v105 = v104 + 1; if ( v103[v104] != byte_DFF30[v104] ) break; } while ( v102 > v99 + v104++ ); if ( (v105 - 1) > 0x13 ) break; } ++v103; ++v99; if ( v102 - 20 <= v103 ) goto LABEL_159; } v92 = ((v51 - 11) * (v51 - 12) * (v51 - 11) * (v51 - 12)) & 3; v79 = 0; if ( v92 ) goto LABEL_181; goto LABEL_118; } } LABEL_159: if ( v134 ) { while ( 1 ) ; } v84 = v140; v79 = 0; if ( (((v51 - 11) * (v51 - 12) * (v51 - 11) * (v51 - 12)) & 3) != 0 ) { while ( 1 ) LABEL_181: ; } } } } } if ( !*(*v12 + 463) ) goto LABEL_179; v107 = atomic_load(&dword_E8FD0); if ( !v107 && !dword_E8FD0 ) { atomic_store(1u, &dword_E8FD0); decrypt_string(&unk_DFF18, 12LL); } if ( !strstr_1(v87, &unk_DFF18) ) // 检测19: 检查内存映射路径是否包含 /data/local/ { if ( v136 ) goto LABEL_174; while ( 1 ) { v108 = atomic_load(&dword_E8FD8); if ( !v108 && !dword_E8FD8 ) { atomic_store(1u, &dword_E8FD8); decrypt_string(&unk_DFF48, 10LL); } v109 = strstr_1(v87, &unk_DFF48); // 检测20: 检查内存映射路径是否包含 /data/adb/ (Magisk 模块路径) if ( (((v51 - 49) * (v51 - 50) * (v51 - 49) * (v51 - 50)) & 3) == 0 ) { if ( !v109 ) { LABEL_179: v85 = 0LL; v92 = 1; if ( !v141 ) { while ( 1 ) LABEL_180: ; } goto LABEL_119; } break; } LABEL_174: v110 = atomic_load(&dword_E8FD8); if ( !v110 && !dword_E8FD8 ) { atomic_store(1u, &dword_E8FD8); decrypt_string(&unk_DFF48, 10LL); } strstr_1(v87, &unk_DFF48); } } LABEL_117: v92 = 0; LABEL_118: v84 = 1; if ( !v141 ) goto LABEL_180; LABEL_119: if ( (v92 & 1) == 0 ) { LABEL_183: MEMORY[0xD1300](v137); goto LABEL_185; } } } LOBYTE(v84) = 0; LABEL_185: v111 = v51 + 33; if ( v51 - 30 >= 0 ) v111 = v51 - 30; while ( ((v51 - 30 - (v111 & 0xFFFFFFC0) + 1) * (v51 - 30 - (v111 & 0xFFFFFFC0)) * (v51 - 30 - (v111 & 0xFFFFFFC0) + 2) * (v51 - 30 - (v111 & 0xFFFFFFC0) + 3) * (v51 - 30 - (v111 & 0xFFFFFFC0) + 4)) % 10 ) ; if ( !v84 && *(*v12 + 457) ) { v112 = *(**v12 + 40LL); v113 = atomic_load(&dword_E8F14); if ( !v113 && !dword_E8F14 ) { atomic_store(1u, &dword_E8F14); decrypt_string(&unk_DFA48, 7LL); } v114 = atomic_load(&dword_E8FC0); if ( !v114 && !dword_E8FC0 ) { atomic_store(1u, &dword_E8FC0); decrypt_string(&unk_DFEE0, 4LL); } v115 = v112(&unk_DFA48, &unk_DFEE0); v116 = *(**v12 + 40LL); v117 = atomic_load(&dword_E8F14); if ( !v117 && !dword_E8F14 ) { atomic_store(1u, &dword_E8F14); decrypt_string(&unk_DFA48, 7LL); } v118 = atomic_load(&dword_E8FE0); if ( !v118 && !dword_E8FE0 ) { atomic_store(1u, &dword_E8FE0); decrypt_string(&unk_DFF88, 14LL); } LOBYTE(v84) = (v116(&unk_DFA48, &unk_DFF88) | v115) != 0; } if ( v84 ) goto LABEL_21; v50 = *v12; } if ( *(v50 + 463) ) { v119 = *(*v50 + 24LL); v120 = atomic_load(&dword_E8F28); if ( !v120 && !dword_E8F28 ) { atomic_store(1u, &dword_E8F28); decrypt_string(&unk_DFAD0, 18LL); } v121 = atomic_load(&dword_E8F2C); if ( !v121 && !dword_E8F2C ) { atomic_store(1u, &dword_E8F2C); decrypt_string(&unk_DFAF0, 17LL); } v122 = v119(&unk_DFAD0, &unk_DFAF0, 0LL); if ( !v122 ) { v123 = *(**v12 + 24LL); v124 = atomic_load(&dword_E8F28); if ( !v124 && !dword_E8F28 ) { atomic_store(1u, &dword_E8F28); decrypt_string(&unk_DFAD0, 18LL); } v125 = atomic_load(&dword_E8F30); if ( !v125 && !dword_E8F30 ) { atomic_store(1u, &dword_E8F30); decrypt_string(&unk_DFB10, 32LL); } v122 = v123(&unk_DFAD0, &unk_DFB10, 0LL); if ( !v122 ) goto LABEL_240; } if ( !v122() ) { LABEL_240: v154 = 0u; v155 = 0u; v152 = 0u; v153 = 0u; v150 = 0u; v151 = 0u; v148 = 0u; v149 = 0u; v126 = atomic_load(&dword_E8FA8); if ( !v126 && !dword_E8FA8 ) { atomic_store(1u, &dword_E8FA8); decrypt_string(&unk_DFE50, 26LL); } if ( sub_499B8(&unk_DFE50, &v148) < 1 ) goto LABEL_235; v127 = atomic_load(&dword_E8FAC); if ( !v127 && !dword_E8FAC ) { atomic_store(1u, &dword_E8FAC); decrypt_string(&byte_DFE70, 16LL); } if ( !strstr_1(&v148, &byte_DFE70) ) { v131 = atomic_load(&dword_E8FB0); if ( !v131 && !dword_E8FB0 ) { atomic_store(1u, &dword_E8FB0); decrypt_string(&unk_DFE90, 28LL); } v132 = linux_eabi_syscall(48LL, 0xFFFFFFFFFFFFFF9CLL, &unk_DFE90, 0LL, 0LL, v128, v129, v130); if ( v132 >= 0xFFFFFFFFFFFFF001LL ) { *MEMORY[0xD13D0]() = -v132; LABEL_235: (**(*v12 + 776))(v147, 0LL, sub_4B03C, 0LL); v50 = *v12; goto LABEL_236; } if ( v132 == -1 ) goto LABEL_235; } } LABEL_21: result = 1LL; // 检测到威胁: 返回 1 表示发现 Frida 或其他调试工具 goto LABEL_22; } LABEL_236: (**(v50 + 776))(v147, 0LL, check_art_unpacker_symbols, 0LL); result = 0LL; // 未检测到威胁: 返回 0 表示环境安全 LABEL_22: if ( *(StatusReg + 40) != v156 ) { v133 = MEMORY[0xD1310](result); return sub_4B03C(v133); } return result; }这个函数还检测了其他 20 多个 Frida 特征:
frida-agent-64.so内存映射(第 441 行)re.frida.server进程(第 331 行)FridaAgentStopReason字符串(第 518 行)/data/local/和/data/adb/路径(第 577、589 行)- ELF 魔数检测(第 509 行)
- 大于 2MB 的可疑内存区域(第 491 行)
第三步
发现字符串解密函数
decrypt_string 0x54428 hook他看下都有什么字符串
0x54428 read_string libart.so this.lr: 0x541ac 0x54428 read_string _ZN3art3Dbg8GoActiveEv this.lr: 0x541e0 0x54428 read_string _ZN3art3Dbg12DdmConnectedEv this.lr: 0x54280 0x54428 read_string isDebuggerConnected this.lr: 0x50fcc 0x54428 read_string android/os/Debug this.lr: 0x51000 0x54428 read_string ()Z this.lr: 0x51034 0x54428 read_string /system/bin/su this.lr: 0x532b4 0x54428 read_string /system/xbin/su this.lr: 0x532e8 0x54428 read_string /system/sbin/su this.lr: 0x5331c 0x54428 read_string /sbin/su this.lr: 0x53350 0x54428 read_string /vendor/bin/su this.lr: 0x53384 0x54428 read_string /su/bin/su this.lr: 0x533b8 0x54428 read_string /sbin/.magisk this.lr: 0x49c34 0x54428 read_string /system/bin/magisk this.lr: 0x49ca4 0x54428 read_string /data/data/com.topjohnwu.magisk this.lr: 0x4953c 0x54428 read_string /data/data/me.weishu.kernelsu this.lr: 0x495ac 0x54428 read_string /data/data/me.bmax.apatch this.lr: 0x49624 0x54428 read_string /data/dexname this.lr: 0x49d60 0x54428 read_string /system/lib64/libxiaojianbang.so this.lr: 0x49dd0 0x54428 read_string cn/youlor/Unpacker this.lr: 0x49e58 0x54428 read_string libsotweak.so this.lr: 0x49ebc 0x54428 read_string /data/local/tmp/unpacker.config this.lr: 0x49f38 0x54428 read_string /data/local/tmp/aupk.config this.lr: 0x49fa8 0x54428 read_string /data/fart this.lr: 0x4a018 0x54428 read_string cn/mik/Fartext this.lr: 0x4a098 0x54428 read_string ro.build.version.incremental this.lr: 0x4b574 0x54428 read_string libc.so this.lr: 0x49a10 0x54428 read_string __system_property_get this.lr: 0x49a5c 0x54428 read_string FART14. this.lr: 0x4b5d0 0x54428 read_string FART12. this.lr: 0x4b61c 0x54428 read_string /data/system/mik.conf this.lr: 0x4a108 0x54428 read_string mikrom this.lr: 0x4a18c 0x54428 read_string android/os/ServiceManager this.lr: 0x4a1e4 0x54428 read_string (Ljava/lang/String;)Landroid/os/IBinder; this.lr: 0x4a218 0x54428 read_string getService this.lr: 0x4a24c 0x54428 read_string /data/local/tmp/re.frida.server this.lr: 0x4a2c8 0x54428 read_string re.frida.server this.lr: 0x4a304 0x54428 read_string /proc/self/maps this.lr: 0x4b724 0x54428 read_string frida-agent-64.so this.lr: 0x4a764 0x54428 read_string /memfd: this.lr: 0x4a85c 0x54428 read_string /data/local/ this.lr: 0x4ab08 0x54428 read_string /data/adb/ this.lr: 0x4ab74 0x54428 read_string %lx-%lx %s this.lr: 0x4a91c 0x54428 read_string FridaAgentStopReason this.lr: 0x4aa24信息还是蛮多的 mikrom FART14 啥的都检测了
第四步
直接跳到 0x54428 read_string FridaAgentStopReason this.lr: 0x4aa24 这个位置 往上看
我们发现其实重点检测了 /memfd的东西 导致我们在0x4aa24 作用死掉了 那我们直接hook strstr_1函数 (当然这个是我重命名的)
直接不让他检测 /memfd: 梭哈完结
拓展
frida 为什么 会 扫描 /memfd: 问问ai:
1.Frida 的注入机制
Frida 需要将自己的 agent 代码(frida-agent-64.so)注入到目标进程中,它有几种方式:
传统方式(容易被检测):
/data/local/tmp/frida-agent-64.so ← 文件存在于磁盘/system/lib64/frida-agent-64.so ← 可以被扫描到Frida 的现代方式(使用 memfd):
/memfd:frida-agent(deleted)← 只存在于内存,不在磁盘2.memfd_create 系统调用
Frida 使用 Linux 的memfd_create()系统调用来创建匿名内存文件:
// Frida 内部的操作(简化版)intfd=memfd_create("frida-agent",MFD_CLOEXEC);write(fd,agent_code,agent_size);// 将 SO 库写入内存dlopen("/proc/self/fd/XXX",RTLD_NOW);// 从内存加载 SO3.为什么 Frida 要这样做?
优势:
- ✅无文件注入:不在磁盘留下痕迹,难以被文件扫描检测
- ✅绕过文件权限检查:不需要写入
/data/local/tmp等目录 - ✅动态加载:可以随时修改内存中的代码
- ✅隐蔽性强:普通的文件扫描工具找不到
在/proc/self/maps中的表现:
# 传统方式(容易检测)7f1234567000-7f1234890000 r-xp 00000000103:0612345/data/local/tmp/frida-agent-64.so# memfd 方式(Frida 使用)7f1234567000-7f1234890000 r-xp 00000000 00:000/memfd:frida-agent(deleted)^^^^^ 注意:设备号为 00:00,表示不是真实文件4.反调试代码为什么要扫描/memfd:?
因为这是 Frida 的核心特征之一:
// 反调试逻辑FILE*maps=fopen("/proc/self/maps","r");while(fgets(line,sizeof(line),maps)){if(strstr(line,"/memfd:")){// 发现了 memfd,很可能是 Frida 注入returnDETECTED;}}检测原理:
正常 Android 应用几乎不会使用
memfd_create如果在内存映射中看到
/memfd:,大概率是:
- Frida 注入
- 其他动态注入工具(如 Xposed、Magisk 模块)
- 恶意代码注入
5.完整的检测链
从你的日志可以看到,反调试代码按顺序检测:
1.frida-agent-64.so ← 直接检测 Frida 的SO文件名2./memfd:← 检测匿名内存文件(Frida 的核心特征)3./data/local/← 检测常见的 Frida 服务器路径4./data/adb/← 检测 Magisk 模块路径5.FridaAgentStopReason ← 检测 Frida 内部字符串6.实际例子
当 Frida 注入后,/proc/self/maps会显示:
# 查看当前进程的内存映射cat/proc/self/maps# 输出示例(Frida 注入后)7f8a2c000000-7f8a2c400000 r-xp 00000000 00:000/memfd:frida-agent(deleted)7f8a2c400000-7f8a2c600000 r--p 00400000 00:000/memfd:frida-agent(deleted)7f8a2c600000-7f8a2c800000 rw-p 00600000 00:000/memfd:frida-agent(deleted)关键特征:
- 路径以
/memfd:开头 - 设备号是
00:00(不是真实设备) - 通常标记为
(deleted)
总结
Frida 使用/memfd:的原因:
- 实现无文件注入,提高隐蔽性
- 绕过文件系统权限和扫描
- 动态加载代码到内存
反调试代码扫描/memfd:的原因:
- 这是 Frida 注入的明显特征
- 正常应用很少使用 memfd
- 可以有效检测到 Frida 和其他注入工具
你的 Hook 绕过原理:
- 拦截
strstr函数 - 当检测到查找
/memfd:时,返回 NULL(未找到) - 让反调试代码误以为没有 Frida 注入
测匿名内存文件(Frida 的核心特征)
3. /data/local/ ← 检测常见的 Frida 服务器路径
4. /data/adb/ ← 检测 Magisk 模块路径
5. FridaAgentStopReason ← 检测 Frida 内部字符串
### 6. **实际例子** 当 Frida 注入后,`/proc/self/maps` 会显示: ```bash # 查看当前进程的内存映射 cat /proc/self/maps # 输出示例(Frida 注入后) 7f8a2c000000-7f8a2c400000 r-xp 00000000 00:00 0 /memfd:frida-agent (deleted) 7f8a2c400000-7f8a2c600000 r--p 00400000 00:00 0 /memfd:frida-agent (deleted) 7f8a2c600000-7f8a2c800000 rw-p 00600000 00:00 0 /memfd:frida-agent (deleted)关键特征:
- 路径以
/memfd:开头 - 设备号是
00:00(不是真实设备) - 通常标记为
(deleted)
总结
Frida 使用/memfd:的原因:
- 实现无文件注入,提高隐蔽性
- 绕过文件系统权限和扫描
- 动态加载代码到内存
反调试代码扫描/memfd:的原因:
- 这是 Frida 注入的明显特征
- 正常应用很少使用 memfd
- 可以有效检测到 Frida 和其他注入工具
你的 Hook 绕过原理:
- 拦截
strstr函数 - 当检测到查找
/memfd:时,返回 NULL(未找到) - 让反调试代码误以为没有 Frida 注入