iOS 关于符号该知道的事儿

符号表是什么

符号表 debugger Symbols,是Xcode编译项目生成的.dSYM文件

浅显点说,咱们定义的方法和变量都有称号,保存这些称号的表便是符号表。

符号绑定及其过程

ASLD和重定向

image镜像,本地编译完的可执行文件运转到内存后便是镜像。UIKitFoundation等动态库的可执行文件拷贝到内存便是镜像文件。

断点输出image list指令能够检查项目可执行文件的首地Swift

iOS 关于符号该知道的事儿

每次machO运转的时分,这个首地址方位都不相同,原因是体系会在虚拟地址前增加一个随机偏移量(ASLR安全模式

经过符号的地址和这个首地址相减,能够得到一个偏移,这个偏移值不管从头运转多少次不会改动。

接下来咱们来说一下什么是重定向:ASLR + 偏移值 = 内存值

  • 内部函数地址经过重定向能够计算

  • 外部函数(NSLog等动态库函数)无法计算函数地址

符号的加载时机

DYLswift是什么组织缩写D动态链接器加载imageMachOview里边看到的Load Commands便是工程依靠库的基本信息,里边能看到很多体系库。加载完依靠库以后才会加载运用。

符号表运用了PIC技能,便是方位代码独立。初次发动运用但还未调用NSLog方法时,咱们依旧能够在Dynamic Symbol tableIndirect Symbols里边能看到NSLog及其一些信息,可是这个时分其实还未进行符号绑定,里边记载的也不是实在的函数地址。

直到初次运用该方法二进制亡者列车DYLD才会去做符号绑定源码中的图片(告诉当前运用这个函数的实在地址二进制转化为十进制),下次就能够直接访问符号表进行调用。

这个便是符号的懒加安全教育平台作业登录

符号绑定的流程

每个外部方法调用,首先要找到外部符号的桩。便是在symbol pointer stubs表找到存储的数据,这里存储的是跳转指令及传参。

接下来就需求去懒加载表(Lazy Symbol Pointers)里查找方法的相关信息。

假如是初次调用该方安全法,懒加载表记载的是Non Lazy Symb镜像ol Pointersdyld_stub_binder的方法地及榜首步的传参。

dyld_stub_binder会到动态库里获取实在的方法地址,替换掉懒加载二进制怎么算表的数据然后调用。

后续的每次调用就能够直接经过已绑定成功的函数地swifter址调用函数,不需求再次绑定。

怎样去除符号

为什么要去除符号

去除符号后安装包会变小,运用更加安全

符号分几种

  • 大局符号(导出符镜像画面什么梗号),一般供给给外部用,做为动态库用。所以安全动态库不能悉数去源码编程器掉符号。
  • 直接符号(导入符号),从Foundation等动态库过来的函数,需求做符号绑定的,所以不能够去掉

APP自己的方法一般不需求供给外部运用,所以除了直接符号,其他符号能够去除。

作用于本文件,static润饰函数镜像文件的符号是本地符号。

作用于本文件,没有static的函数,能够供给给其他文件调用的,便是大局符号。

本地符号假如不运用,符号不swiftly会生成。

大局符号不运用也会生成符号。

经过二进制换成十进制算法objcdump –macho -t symboldemo1指令能够检查符号表

  • 前缀 l = local,本地符号

  • 前缀 g = gobal,大局符号

Xcode相关的配置

经过Xco安全期计算器de的设置能够控制咱们需求保存在符号表的符号

Build Se镜像图片怎么弄ttiswift是什么组织缩写ng -> Target -> Deploym二进制换成十进制算法ent pos源码之家tprocessing 设置为NO编译时保存符号,打包的时分才去除。

Build Setting -> strip Sty源码交易平台le

  • All Symbol 一般APP用,只剩下直接符号
  • Non-Global Symbol,一般给动态库用,只剩大局符号
  • Debugging Symbol,编译时会做去符号操作,此刻debug也无法断点

怎样康复符号

逆向工程会有康复符号的技能,什么能康复符号呢?

OC有动态言语的特性,runtime能够经过字符串取得类、方法……

上述变量明即使设置了去除符号,在MachO文件中依旧会以字符串方式保存。

运用restore_symbol东西(镜像人生搜索下载,找不到留言),能够康复OCswift的本地符号。

  • s源码交易平台wift归于动态派发所以能够康复

  • OC有动态言语特性,所以能够康复

  • C函数没有动态特性所以二进制不能够康复

怎样修正符安全工程师

fishhook结构

fishHookFacebook 供给的一个动态修正链接 mach-O 文件的东西

经过 修正符号表的指向 完成 勾起方法 的作用

代码很简单,fishHook 供给了两个钩子方法及一个钩子结构体,

一般如下构建r二进制计算器ebinding结构体传入rebin源码1688d_symbols函数即可

- (void)viewDidLoad {
    [super viewDidLoad];
    // hook NSLog
    struct rebinding nslog = {};
    // 方法名
    nslog.name = "NSLog";
    // 替换进去的方法
    nslog.replacement = new_NSLog;
    // 被替换的方法指针
    nslog.replaced = (void *)&sys_NSlog;
    // 创立结构体数组
    struct rebinding rbs[1] = {nslog};
    // hook
    rebind_symbols(rbs, 1);
}
// 体系NSLog的函数地址
static void (*sys_NSlog)(NSString *format, ...);
// 定义新的NSLog
void new_NSLog(NSString *format, ...) {
    format = [format stringByAppendingString:@"n hook Succ"];
    sys_NSlog(format);
}
//点击一下 就输出
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSLog(@"test");
}

fishhook的流程

fishhook 是经过从头绑定符号完成功能的,首先咱们看一下怎样运用符号找到方法的名字

懒加载符号表(Lazy Symbol Pointer镜像图片怎么弄s)和直接符号表(Indirect Symbols)的记载顺序是一致的。

在直接符号表(Lazy Symbol Pointers)的Data段,记载着这个符号在总符号表(Symbolswift翻译s)的编号。

依据编号查找总符号表,能够看到方法源码编辑器下载所属的库(Lib安全教育平台登录rary)以及在字符串表(String Table)记载的偏移(string table index)。

到字符串表里边运用string table index加上字符串表榜首行的pFile地址得出对应行,就能找到对应函数名。

那么其实只要反向操作上述镜像干部过程,就能够经过方法名找到符号所在方位!

  • 1、fis镜像干部hhook在字符串表(String Table)运用.分割字符串,比照传入的方法名找出所内行,再用所内行减去首行pFile算出string table indeswiftlyx

  • 2、在总符号表(String Table)遍历比照源码string table index 查出符号在总符号表的方位(symbols index

  • 3、在直接符号表(Indirect Symbols)用symbols index 查找该符号偏移值(indirect安全教育平台 symbols index

  • 4、经过符号在懒加载符号表(Lazy Symbol Pointers)和直接符号表(Indi安全教育平台rect Symbols)方安全位一一对应的联系就能够就找到符号在懒加载符号表的方位。

  • 5、最终修正镜像画面什么梗的值是懒加载符号表(Lazy Symbol Pointers)里记载的值

后续调用二进制方法的时分先二进制怎么算找桩,找到桩就会找lazy symbol pointer执行,此刻找到的便是swift是什么组织缩写修正后的方镜像画面法地址了。

处理第三方库的符号抵触

动态库的状况

当两个动态库都有同名方法的时分,动态库方法的调用是先找到方法所在库,再去找方法符号。

所以找到了源码1688A库就不会到B库找符号。动态库之间不存在符号抵触

静态库二进制换成十进制算法的状况

两个静态库都有同镜像干部名方法的时分

  • 1、假如静态库没有被运用到,就不会被链接,其链接的最小单位是类
  • 2、链接器链接到A符号之后就不会再链接同二进制怎么算名的A符号了

假如静态库里边增加分类,那状况就会不相同了。分类是动态增加的,分类在编译时不会被链接。

静态库链接的时分也不确定动态库是否swift国际结算系统运用分类代码,所以不会链接分类,运转就会崩溃找不到该方法。

二进制换成十进制算法以免除上述问题的方法便是增加Other Link Flags增加-ObjC参数,这样编译的时分就会连同分类里边的代码把一切OC代码编译进去。

两个静态库都有二进制的运算规则分类的时源码编辑器分,能够经过Build Setting -> Otswifterher Link Flags参数运用-forceload指定库加安全教育平台载代码,以处理抵触。

碰到两个静态库都二进制有动态代码需求链接的时分,又不供给源码的时分,运用llvmobjcopy修正库的二进制文件增加前缀以处理抵触。

发表回复

提供最优质的资源集合

立即查看 了解详情