Mach-O初探和链接

2021-03-08  本文已影响0人  雾中探雪
Mach-O初探和链接
1、Mach-O定义
1. 调⽤`fork`函数,创建⼀个`process`
2. 调⽤`execve`或其衍⽣函数,在该进程上加载,执⾏我们的`Mach-O`⽂件
// 注:当我们调⽤时`execve`(程序加载器),内核实际上在执⾏以下操作:1. 将⽂件加载到内存 2. 开始分析`Mach-O`中的`mach_header`,以确认它是有效的`Mach-O`⽂件
objdump --macho --private-headers /users/zengca/..(Mach-o文件路径)
2、 链接
3、Symbol Table(符号表)
Symbol Table:就是⽤来保存符号。
String Table:就是⽤来保存符号的名称。
Indirect Symbol Table:间接符号表。保存使⽤的外部符号。更准确⼀点就是使⽤的外部动态库的符号。是Symbol Table的⼦集。
$ nm helloworld
0000bf08 s  stub helpers
0000be00 t -[SaySomething say:]
         U _NSClassFromString
         U _NSSelectorFromString
0000c110 S _NXArgc
0000c114 S _NXArgv
         U _OBJC_CLASS_$_NSObject
0000c0fc S _OBJC_CLASS_$_SaySomething
         U _OBJC_METACLASS_$_NSObject
0000c0e8 S _OBJC_METACLASS_$_SaySomething
         U ___CFConstantStringClassReference
0000c11c S ___progname
00004000 T __mh_execute_header
         U __objc_empty_cache
0000c118 S _environ
         U _exit
0000be44 T _main
         U _objc_autoreleasePoolPop
         U _objc_autoreleasePoolPush
         U _objc_msgSend
         U _printf
0000c018 s _pvars
         U dyld_stub_binder
0000bdd4 T start
第一列就是内存地址,没有什么好解释的。
第二列这些符号都什么意思呢?
对于每一个富豪来说,其类型如果是小写的,则表明符号是local的;大写则表明符号是global 的。
A  该符号的值是绝对的,在以后的链接过程中,不允许进行改变,这样的符号之,尝尝出现在中断向量(终端服务程序的入口地址)中,列入用符号来表示中断向量函数在中断 向量表中的位置。
B  该符号的值出现在非初始化数据段中(bss)。例如,在一个文件中定义全局static int  a。则该响亮符号 a  的类型为b,位于bss section 中。
C  该符号为common。common symbol 是未初始化数据段。该符号没有包含于一个普通section 中。只有在连接过程中才进行分配。符号的指标是该符号的字节数。
D  该符号位于初始化数据段中。一般来说。分配到data section 中。例如,定义 int  arr[5] = {9600,19200,28400,57600,115200},会分配到初始化数据段中。
G  该符号也位于初始化数据段中。主要用于small Object 提高访问small Object 的一种方式。
I  该符号是对另一个符号的间接引用。
N  该符号位于只读数据区,例如定义全局const int test[] = {123,123};则test 就是一个只读数据区的符号。
S  该符号位于非初始化数据区,用于small Object。
T  该符号位于代码区 text  section 。
U  该符号在当前文件中是未定义的,即该符号的定义在别的文件中。
V  该符号是一个weak Object 。

好了,现在来解释一下上边的一个具体信息。
0000be00 t -[SaySomething say:]
         U _NSClassFromString
         U _NSSelectorFromString

1、表示位于0x0000be00 地址中,say 方法是在本文件有定义的,所以是小写的t,其次,由于OC 是种动态语言,在调用方法时,根据方法名称来确定方法的唯一性,因此类和方法的名称必须存放在一个定法 ,如上SaySomething 类和say 方法存放在代码区,因此,他们的符号为t。
2、NSClassFromString 和NSSelectorFromString 方法是从Objective-C 语言库中动态加载起来的。在这个文件中没有定义,所以他们的符号为U。
4、重定向

Target—>Build Phases—>Run Script—>echo "hello" >/dev/ttys000

重定向.png
注:/dev/ttys000 是当前终端的名称,在终端中执行tty就可以看到当前终端名称
5、使用脚本运行命令
#!/bin/sh


RunCommand() {
  #判断全局字符串VERBOSE_SCRIPT_LOGGING是否为空。-n string判断字符串是否非空
  #[[是 bash 程序语言的关键字。用于判断
  if [[ -n "$VERBOSE_SCRIPT_LOGGING" ]]; then
    #作为一个字符串输出所有参数。使用时加引号"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数
      if [[ -n "$TTY" ]]; then
          echo "♦ $@" 1>$TTY
      else
          echo "♦ $*"
      fi
      echo "------------------------------------------------------------------------------" 1>$TTY
  fi
  #与$*相同。但是使用时加引号,并在引号中返回每个参数。"$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数
  if [[ -n "$TTY" ]]; then
      echo `$@ &>$TTY`
  else
      "$@"
  fi
  #显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
  return $?
}

EchoError() {
    #在shell脚本中,默认情况下,总是有三个文件处于打开状态,标准输入(键盘输入)、标准输出(输出到屏幕)、标准错误(也是输出到屏幕),它们分别对应的文件描述符是0,1,2
    # >  默认为标准输出重定向,与 1> 相同
    # 2>&1  意思是把 标准错误输出 重定向到 标准输出.
    # &>file  意思是把标准输出 和 标准错误输出 都重定向到文件file中
    # 1>&2 将标准输出重定向到标准错误输出。实际上就是打印所有参数已标准错误格式
    if [[ -n "$TTY" ]]; then
        echo "$@" 1>&2>$TTY
    else
        echo "$@" 1>&2
    fi
    
}

RunCMDToTTY() {
    if [[ ! -e "$TTY" ]]; then
        EchoError "=========================================="
        EchoError "ERROR: Not Config tty to output."
        exit -1
    fi
    
    if [[ -n "$CMD" ]]; then
        RunCommand "$CMD" ${CMD_FLAG}
    else
        EchoError "=========================================="
        EchoError "ERROR:Failed to run CMD. THE CMD must not null"
    fi
}


RunCMDToTTY

//  TTY = 终端
//  CMD = 运行的命令
//  CMD_FLAG = 运行命令的参数

CMD = nm
CMD_FLAG = -pa ${MACHO_PATH}
TTY = /dev/ttys000
MACHO_PATH=${BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/*

// nm
// -p: 不排序
// -a: 显示所有符号,除了调试符号
// -m:显示(N_SECT)符号,格式(seg-ment_name, section_name) (external non-
// external) (undefined), (common), (absolute) (indirect)

// objdump
// --macho --syms
// --exports-trie :导出符号

// -Xlinker  在GCC中用来给连接器传递参数,每次只能传递一个参数(如:-Xlinker -S ),如果传递多个参数需多次传递(如:-Xlinker -S -Xlinker _cat_NSLog或可简写为-Xlinker -S=_cat_NSLog)。
// -Wl 在GCC中用来给连接器传递参数,可以传递多个参数(如:-Wl,-Map,output.map)。
// -S 去除输出文件中的调试信息

// -O1 -Oz 生成目标文件  编译时优化
// 后面两步就是在操作符号
// dead code strip  死代码剥离实际上也是在剥离符号  链接时
// strip 剥离符号  修改已经生成的Mach-O文件

运行结果:

Last login: Mon Jan 18 13:42:42 on ttys000
zengcai@Mac-mini ~ % 0000000100003f40 t _weak_hidden_function
0000000100008008 d __dyld_private
0000000100008014 d _static_init_value
0000000100008018 d _hidden_y
0000000100008030 b _static_uninit_value
0000000100008040 s _default_x
0000000000000000 - 00 0000    SO /Users/zengcai/Downloads/逻辑学习/强化班第一节课资料/完成代码/MachOAndSymbol/
0000000000000000 - 00 0000    SO main.m
0000000060050b13 - 03 0001   OSO /Users/zengcai/Library/Developer/Xcode/DerivedData/MachOAndSymbol-aiyqlpfqaarxnvcresdhogckdoqi/Build/Intermediates.noindex/MachOAndSymbol.build/Debug/MachOAndSymbol.build/Objects-normal/x86_64/main.o
0000000100003ec0 - 01 0000 BNSYM
0000000100003ec0 - 01 0000   FUN _main
000000000000003f - 00 0000   FUN
000000000000003f - 01 0000 ENSYM
0000000000000000 - 00 0000  GSYM _global_init_value
0000000100008014 - 0a 0000 STSYM _static_init_value
0000000100008030 - 0b 0000 STSYM _static_uninit_value
0000000000000000 - 00 0000  GSYM _global_uninit_value
0000000000000000 - 00 0000  GSYM _default_x
0000000000000000 - 01 0000    SO
0000000000000000 - 00 0000    SO /Users/zengcai/Downloads/逻辑学习/强化班第一节课资料/完成代码/MachOAndSymbol/
0000000000000000 - 00 0000    SO WeakImportSymbol.m
0000000060052666 - 03 0001   OSO /Users/zengcai/Library/Developer/Xcode/DerivedData/MachOAndSymbol-aiyqlpfqaarxnvcresdhogckdoqi/Build/Intermediates.noindex/MachOAndSymbol.build/Debug/MachOAndSymbol.build/Objects-normal/x86_64/WeakImportSymbol.o
0000000100003f00 - 01 0000 BNSYM
0000000100003f00 - 01 0000   FUN _weak_import_function
0000000000000017 - 00 0000   FUN
0000000000000017 - 01 0000 ENSYM
0000000000000000 - 01 0000    SO
0000000000000000 - 00 0000    SO /Users/zengcai/Downloads/逻辑学习/强化班第一节课资料/完成代码/MachOAndSymbol/
0000000000000000 - 00 0000    SO WeakSymbol.m
0000000060050b12 - 03 0001   OSO /Users/zengcai/Library/Developer/Xcode/DerivedData/MachOAndSymbol-aiyqlpfqaarxnvcresdhogckdoqi/Build/Intermediates.noindex/MachOAndSymbol.build/Debug/MachOAndSymbol.build/Objects-normal/x86_64/WeakSymbol.o
0000000100003f20 - 01 0000 BNSYM
0000000100003f20 - 01 0000   FUN _weak_function
0000000000000020 - 00 0000   FUN
0000000000000020 - 01 0000 ENSYM
0000000100003f40 - 01 0000 BNSYM
0000000100003f40 - 01 0000   FUN _weak_hidden_function
0000000000000017 - 00 0000   FUN
0000000000000017 - 01 0000 ENSYM
0000000000000000 - 01 0000    SO
0000000000000000 - 00 0000    SO /Users/zengcai/Downloads/逻辑学习/强化班第一节课资料/完成代码/MachOAndSymbol/
0000000000000000 - 00 0000    SO VisibilitySymbol.m
0000000060050b0f - 03 0001   OSO /Users/zengcai/Library/Developer/Xcode/DerivedData/MachOAndSymbol-aiyqlpfqaarxnvcresdhogckdoqi/Build/Intermediates.noindex/MachOAndSymbol.build/Debug/MachOAndSymbol.build/Objects-normal/x86_64/VisibilitySymbol.o
0000000000000000 - 00 0000  GSYM _hidden_y
0000000000000000 - 00 0000  GSYM _default_y
0000000000000000 - 00 0000  GSYM _protected_y
0000000000000000 - 01 0000    SO
0000000100000000 T __mh_execute_header
0000000100008020 D _default_y
0000000100008010 D _global_init_value
0000000100008038 S _global_uninit_value
0000000100003ec0 T _main
0000000100008028 D _protected_y
0000000100003f20 T _weak_function
0000000100003f00 T _weak_import_function
                 U _NSLog
                 U ___CFConstantStringClassReference
                 U dyld_stub_binder
0000000100003f40 t _weak_hidden_function
0000000100008008 d __dyld_private
0000000100008014 d _static_init_value
0000000100008018 d _hidden_y
0000000100008030 b _static_uninit_value
0000000100008040 s _default_x
0000000000000000 - 00 0000    SO /Users/zengcai/Downloads/逻辑学习/强化班第一节课资料/完成代码/MachOAndSymbol/
0000000000000000 - 00 0000    SO main.m
000000006005268b - 03 0001   OSO /Users/zengcai/Library/Developer/Xcode/DerivedData/MachOAndSymbol-aiyqlpfqaarxnvcresdhogckdoqi/Build/Intermediates.noindex/MachOAndSymbol.build/Debug/MachOAndSymbol.build/Objects-normal/x86_64/main.o
0000000100003ec0 - 01 0000 BNSYM
0000000100003ec0 - 01 0000   FUN _main
000000000000003f - 00 0000   FUN
000000000000003f - 01 0000 ENSYM
0000000000000000 - 00 0000  GSYM _global_init_value
0000000100008014 - 0a 0000 STSYM _static_init_value
0000000100008030 - 0b 0000 STSYM _static_uninit_value
0000000000000000 - 00 0000  GSYM _global_uninit_value
0000000000000000 - 00 0000  GSYM _default_x
0000000000000000 - 01 0000    SO
0000000000000000 - 00 0000    SO /Users/zengcai/Downloads/逻辑学习/强化班第一节课资料/完成代码/MachOAndSymbol/
0000000000000000 - 00 0000    SO WeakImportSymbol.m
000000006005268b - 03 0001   OSO /Users/zengcai/Library/Developer/Xcode/DerivedData/MachOAndSymbol-aiyqlpfqaarxnvcresdhogckdoqi/Build/Intermediates.noindex/MachOAndSymbol.build/Debug/MachOAndSymbol.build/Objects-normal/x86_64/WeakImportSymbol.o
0000000100003f00 - 01 0000 BNSYM
0000000100003f00 - 01 0000   FUN _weak_import_function
0000000000000017 - 00 0000   FUN
0000000000000017 - 01 0000 ENSYM
0000000000000000 - 01 0000    SO
0000000000000000 - 00 0000    SO /Users/zengcai/Downloads/逻辑学习/强化班第一节课资料/完成代码/MachOAndSymbol/
0000000000000000 - 00 0000    SO WeakSymbol.m
000000006005268b - 03 0001   OSO /Users/zengcai/Library/Developer/Xcode/DerivedData/MachOAndSymbol-aiyqlpfqaarxnvcresdhogckdoqi/Build/Intermediates.noindex/MachOAndSymbol.build/Debug/MachOAndSymbol.build/Objects-normal/x86_64/WeakSymbol.o
0000000100003f20 - 01 0000 BNSYM
0000000100003f20 - 01 0000   FUN _weak_function
0000000000000020 - 00 0000   FUN
0000000000000020 - 01 0000 ENSYM
0000000100003f40 - 01 0000 BNSYM
0000000100003f40 - 01 0000   FUN _weak_hidden_function
0000000000000017 - 00 0000   FUN
0000000000000017 - 01 0000 ENSYM
0000000000000000 - 01 0000    SO
0000000000000000 - 00 0000    SO /Users/zengcai/Downloads/逻辑学习/强化班第一节课资料/完成代码/MachOAndSymbol/
0000000000000000 - 00 0000    SO VisibilitySymbol.m
000000006005268b - 03 0001   OSO /Users/zengcai/Library/Developer/Xcode/DerivedData/MachOAndSymbol-aiyqlpfqaarxnvcresdhogckdoqi/Build/Intermediates.noindex/MachOAndSymbol.build/Debug/MachOAndSymbol.build/Objects-normal/x86_64/VisibilitySymbol.o
0000000000000000 - 00 0000  GSYM _hidden_y
0000000000000000 - 00 0000  GSYM _default_y
0000000000000000 - 00 0000  GSYM _protected_y
0000000000000000 - 01 0000    SO
0000000100000000 T __mh_execute_header
0000000100008020 D _default_y
0000000100008010 D _global_init_value
0000000100008038 S _global_uninit_value
0000000100003ec0 T _main
0000000100008028 D _protected_y
0000000100003f20 T _weak_function
0000000100003f00 T _weak_import_function
                 U _NSLog
                 U ___CFConstantStringClassReference
                 U dyld_stub_binder
CMD = nm
CMD_FLAG = -pa ${MACHO_PATH}
TTY = /dev/ttys000
OTHER_LDFLAGS = -Xlinker -S
MACHO_PATH=${BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/*

运行结果:

0000000100003f40 t _weak_hidden_function
0000000100008008 d __dyld_private
0000000100008014 d _static_init_value
0000000100008018 d _hidden_y
0000000100008030 b _static_uninit_value
0000000100008040 s _default_x
0000000100000000 T __mh_execute_header
0000000100008020 D _default_y
0000000100008010 D _global_init_value
0000000100008038 S _global_uninit_value
0000000100003ec0 T _main
0000000100008028 D _protected_y
0000000100003f20 T _weak_function
0000000100003f00 T _weak_import_function
                 U _NSLog
                 U ___CFConstantStringClassReference
                 U dyld_stub_binder
上一篇下一篇

猜你喜欢

热点阅读