前言
首先我们确定目前我们已知的dyld有两种方式 1.直接插入动态库 2.附加在进程
前面我们对比Tweak前后的machO文件二进制没有被修改 那么Tweak的原理应该是附加到进程上
苹果开源了dyld源码 https://opensource.apple.com/tarballs/dyld/我们下载下来看下他的源码
源码解读
1.
首先大致查看下文目录 这么多如何看时看呢 我们前面推测Tweak是附加在进程上的 回顾我们之前脱壳的时候dumpdecrypted也是附加在进程上来脱壳的 那么 DYLD_INSERT_LIBRARIES = xxx.dylib
1)全局搜索DYLD_INSERT_LIBRARIES
因为我们的目的就是寻找DYLD的依附的逻辑 从而达到应用防止依附所以我们首先找一下关于DYLD_INSERT_LIBRARIES的条件判断
2)if (sEnv.DYLD_INSERT_LIBRARIES != NULL){
for(const char* const* lib = sEnv.DYLD_INSERT_LIBRARIES;*lib != NULL;++lib)
loadInsertedDylib(*lib);
}
这个大致看下含义如果sEnv.DYLD_INSERT_LIBRARIES不为空那么遍历sEnv.DYLD_INSERT_LIBRARIES这个环境变量的所有dylib然后去加载loadInsertedDylib(*lib);这个函数这个函数我们不可能去在判断里面直接注释或置空因为我们还有其他的动态库需要注入 我们也无法hook操作系统的库 所以我们要找到什么情况下不加载
3)我们往上查找代码 看有没有地方是可以拒绝插入的函数
if(!gLinkContext.allowEnvVarsPrint && !gLinkContext.allowEnvVarsPath && !gLinkContext.allowEnvVarsSharedCache){
pruneEnvironmentVariables(envp,&apple);
// set again because envp and apple may have changed or moved
setContext(mainExecutableMH,argc,argv,envp,apple);
}
当条件里面的参数满足时 那么就会移除我们的动态库
4)
现在找到if(issetugid()|| hasRestrictedSegment(mainExecutableMH)){
isRestricted = true;
}
issetugid大概意思是判断当前App的uid或者gid无法更改的我们只能hasRestrictedSegment(mainExecutableMH)看这个函数的实现
5)
我们现在来到了关键函数这个函数大致是在macho遍历command会查找有没有__RESTRICT段的__restrict
也就是说__RESTRICT段有__restrict 那么我们这个动态库就不会插入
6)修改RESTRICT来防护
在Build settings->Other Linker Flags添加-Wl,sectcreate,__RESTRICT,__restrict,/dev/null
这样macho文件就有了__RESTRICT,__restrict
在Build settings->Other Linker Flags添加-Wl,sectcreate,__RESTRICT,__restrict,/dev/null
这样macho文件就有了__RESTRICT,__restrict
接下来DYLD_INSERT_LIBRARIES再来Twesk的话就没有效果了这样就做到了Tweak的防护
7)破解__RESTRICT,__restrict 的防护
利用synalyze it !pro来修改RESTRICT段
将对应的二进制修改一个字段 达到修改RESTRICT段无效 继续hook