※需求:
实现注入防护,如:frida,cycript等。
※当前方案:
1.遍历const char * dyld = _dyld_get_image_name(i)中所有的image_name
2.基于《iOS应用逆向与安全》8.3源码:MachOParser实现。
like:
//获取加载的动态库
NSArray* MachOParser::find_load_dylib(){
NSMutableArray* array = [[NSMutableArray alloc] init];
mach_header_t *header = (mach_header_t*)base;
segment_command_t *cur_seg_cmd;
uintptr_t cur = (uintptr_t)this->base + sizeof(mach_header_t);
for (uint i = 0; i < header->ncmds; i++,cur += cur_seg_cmd->cmdsize) {
cur_seg_cmd = (segment_command_t*)cur;
if(cur_seg_cmd->cmd == LC_LOAD_DYLIB || cur_seg_cmd->cmd == LC_LOAD_WEAK_DYLIB){
dylib_command *dylib = (dylib_command*)cur_seg_cmd;
char* name = (char*)((uintptr_t)dylib + dylib->dylib.name.offset);
NSString* dylibName = [NSString stringWithUTF8String:name];
[array addObject:dylibName];
}
}
return [array copy];
}
※目前问题:
iOS15版本系统无法像其他低版本系统一样返回完整的动态库列表。
方案1不再返回第三方动态库,方案2仅仅返回“ /usr/lib/libSystem.B.dylib ”
※优化方案与存在的问题。
我的方案:
将find_load_dylib方法 mach_header_t header = (mach_header_t )base;改为: mach_header_64 *header = (mach_header_64 *)&_mh_execute_header;可行。
问题:
该方案无法在动态库中实现。
通过增加“_mh_execute_header”以得到完成动态库加载列表的方法,在APP或静态库static library工程中没有问题。(至于为什么加这么一个就行了,我也是不知其所以然~)
但是在我的动态库.dylib工程中无法使用,存在报错: Showing Recent Messages Undefined symbol: __mh_execute_header
请大家帮助,指点,谢谢。
Zhang
2021 年11 月 18 日 08:16
3
// add must preserve symbols from compiler_rt input.
for ( auto &f : _state.filesFromCompilerRT ) {
std::vector<const char*> symbols;
if ( f->fileContent() && mach_o::relocatable::getNonLocalSymbols(f->fileContent(), symbols) ) {
for ( auto &sym : symbols)
obfuscator->addMustPreserveSymbols(sym);
}
}
// special symbols supplied by linker
obfuscator->addMustPreserveSymbols("___dso_handle");
obfuscator->addMustPreserveSymbols("__mh_execute_header");
obfuscator->addMustPreserveSymbols("__mh_dylib_header");
obfuscator->addMustPreserveSymbols("__mh_bundle_header");
obfuscator->addMustPreserveSymbols("__mh_dylinker_header");
obfuscator->addMustPreserveSymbols("__mh_object_header");
obfuscator->addMustPreserveSymbols("__mh_preload_header");
// add all the Proxy Atom linker ever created and all the undefs that are possibily dead-stripped.
for (auto sym : _state.allUndefProxies)
obfuscator->addMustPreserveSymbols(sym);
obfuscator->addMustPreserveSymbols("___dso_handle");
obfuscator->addMustPreserveSymbols("__mh_execute_header");
obfuscator->addMustPreserveSymbols("__mh_dylib_header");
obfuscator->addMustPreserveSymbols("__mh_bundle_header");
obfuscator->addMustPreserveSymbols("__mh_dylinker_header");
obfuscator->addMustPreserveSymbols("__mh_object_header");
obfuscator->addMustPreserveSymbols("__mh_preload_header");
官方的定义在 <mach-o/ldsyms.h>
1 个赞
那咋办?动态库工程里没法用这个方案,我该换个思路。
Zhang
2021 年11 月 18 日 10:03
6
不用啊 dyld get vm slide0能拿到主程序的内存地址。【不太确定需不需要随机加个小偏移】然后用这个地址加dladdr还是哪个API就能拿到主程序的mh execute header了。
太久不做蓝方忘了(
嗯嗯,这次iOS15版本更新对MachO读取这块影响还是挺大的。
不光是读动态库加载列表的问题,有些重签名工具的签名IPA包在15版本上也不能通过验证了。
iOS实现注入防护,如:frida,cycript等。
iOS15你是怎么验证frida? 注入FridaGadget.dylib验证的还是iOS15能越狱了?_dyld_get_image_name还是能获取第3方库;
验证macho文件的动态库加载项“LC_LOAD_DYLIB”和“LC_LOAD_WEAK_DYLIB”里面有没有“FridaGadget.dylib”字段。
该功能在iOS15上不能像低版本一样如实输出,并不是iOS15能越狱了。
_dyld_get_image_name在iOS15上也是一样的问题,输出一大堆系统框架,不再输出第三方的了。
多谢您的提点
出现问题的原因是:iOS15中_dyld_get_image_vmaddr_slide(0)拿到的不是主程序地址,而是在_dyld_get_image_vmaddr_slide(3)中(多个工程验证,iOS15主程序都是在index-3位置,但没有官方文档,妄加猜测)。
低于iOS15版本的设备确实是dyld get vm slide0能拿到主程序的内存地址,这一变动造成了获取header失败,以至接下来的操作无法进行。
iOS15如图:
iOS13如图:
《iOS应用逆向与安全》8.3源码:MachOParser的调用方案:
Zhang
2021 年11 月 23 日 02:03
13
前两个是Xcode调试才注入的应该。 你离开Xcode跑起来试试
wwpp3399
(Metros)
2022 年12 月 10 日 22:28
14
yangyan888:
iOS应用逆向与安全
求助,machOParser的相关源码可否共享一下