iOS 安全攻防系列(五): nm 命令详解

来源:互联网 发布:图书在版编目数据查询 编辑:程序博客网 时间:2024/05/16 04:31

在学习iOS安全的时候,老是看到有个nm 命令,今天就来好好梳理下nm 这个命令。

符号表

先来说说符号表,符号表可以提供应用软件及其动态加载的苦衷引用的函数、类、方法等信息。通常,符号表中包含比类转储更多的信息,并且还包含了应用软件使用的C或者C++ 组件的信息。就好比你要去某个城市某个地方,首先你得需要一张地图才能找得到某个地方吧。符号表就是这张地图。

nm命令作用就是显示目标文件的符号表,文件对象可以是静态库、动态库、编译目标文件、可执行程序等任何包含符号信息的文件类型。

来看下面这个程序:helloworld.m

#import <Foundation/Foundation.h>@interface SaySomething : NSObject- (void)say:(NSString *)phrase;@end@implementation SaySomething- (void)say:(NSString *)phrase{        printf("%s",[phrase UTF8String]);}@endint main(int argc,const char * argv[]){        @autoreleasepool{        Class myClass = NSClassFromString(@"SaySomething");        id saysomething = [[myClass alloc]init];        SEL selector = NSSelectorFromString(@"say:");        [saysomething performSelector: selector withObject: @"hello world!!"];          }        return 0;}

然后编译

clang -arch armv7 -isysroot `xcrun --sdk iphoneos --show-sdk-path` -o helloworld helloworld.m -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk -framework Foundation -lobjc


$ file helloworld

helloworld: Mach-O executable arm


当然这个程序是没法在计算机中运行的,可以进行签名和安装到iOS设备就可以运行了。

$ 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



好吧,先来看看这些都是什么意思。

nm 显示的信息有三列,第一列是符号在内存地址控件的地址,第二列是符号类型,第三列是符号名称。

第一列就是内存地址,没有什么好解释的。

第二列这些符号都什么意思呢

对于每一个富豪来说,其类型如果是小写的,则表明符号是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

表示位于0x0000be00 地址中,say 方法是在本文件有定义的,所以是小写的t,其次,由于OC 是种动态语言,在调用方法时,根据方法名称来确定方法的唯一性,因此类和方法的名称必须存放在一个定法 ,如上SaySomething 类和say 方法存放在代码区,因此,他们的符号为t。

NSClassFromString 和NSSelectorFromString 方法是从Objective-C 语言库中动态加载起来的。在这个文件中没有定义,所以他们的符号为U。

好了,就到这吧。





1 0
原创粉丝点击