file
查看文件的基础信息,是否是fat文件,以及是动态库还是静态库。不限于库文件,基本所有的文件都可以用这个命令了解文件信息,对于库文件来说,可以了解库文件是否是fat文件,支持的架构,以及库是静态库还是动态库。
[user@localhost]$file Foundation
Foundation: Mach-O 64-bit dynamically linked shared library arm64
lipo
用来创建和操作通用(universal)文件,可以用来合并、剔除、抽取不同架构的库文件,创建一个新的fat文件;当然也可以打印库的信息,此处只介绍信息读取。
- 打印信息
[user@localhost]$lipo -info Foundation
Non-fat file: Foundation is architecture: arm64
- 打印详细信息
[user@localhost]$lipo -detailed_info Foundation
input file Foundation is not a fat file
Non-fat file: Foundation is architecture: arm64
- 只打印架构信息,通常用于命令行
[user@localhost]$lipo -archs Foundation
arm64
nm
用来查询符号表
- -a 显示所有符号,包括调试符号。默认不添加任何选项时,就是这个效果
[user@localhost]$nm -a Foundation | head -3
00000001819c0364 t +[NSAddressCheckingResult supportsSecureCoding]
00000001818d124c t +[NSAffineTransform supportsSecureCoding]
00000001818d04f8 t +[NSAffineTransform transform]
- -g 显示所有全局(外部)符号
- -n 按照数字而非字母排序
-p 不要排序,按照符号表的顺序显示
-r 倒序。 - -u 只显示未定义的符号
-U 不显示未定义的符号 - -m 以(segment_name,section_name) [external | non-external] 的格式,
显示符号所在的段名(segment_name)和分区名(section_name)
[user@localhost]$nm -m Foundation | head -3
00000001819c0364 (__TEXT,__text) non-external +[NSAddressCheckingResult supportsSecureCoding]
00000001818d124c (__TEXT,__text) non-external +[NSAffineTransform supportsSecureCoding]
00000001818d04f8 (__TEXT,__text) non-external +[NSAffineTransform transform]
- -j 只显示符号名称,不显示地址和类型
[user@localhost]$nm -j Foundation | head -3
+[NSAddressCheckingResult supportsSecureCoding]
+[NSAffineTransform supportsSecureCoding]
+[NSAffineTransform transform]
- -s 显示特定的段名(segname)下,分区名(sectname)的符号
[user@localhost]$nm -s __TEXT __const Foundation | head -3
0000000181a7bf68 S _NSAffineTransformStructIdentity
0000000181a7ccc0 S _NSBundleResourceRequestLoadingPriorityUrgent
0000000181a7c038 S _NSDataDeallocatorNone
- -arch 指定查询符号表的架构,如果是一个通用(universal)文件,即fat文件时。all选项参数,指定操作所有包含架构。(举例的文件只有arm64,所以,没有使用到)
otool
用来查看对象文件或库文件的特定部分信息
-
显示文件头信息 -a 如果是归档文件(通常是.a静态库),显示归档头 -S 如果是归档文件,显示__.SYMDEF文件 -f 显示通用(universal),即fat文件头
-
-h 显示Mach-O文件头(原文件不可读,通常配合-v使用,转换为可读输出)
[user@localhost]$otool -h KWPlayer.decrypted
KWPlayer.decrypted:
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
0xfeedfacf 16777228 0 0x00 2 130 13064 0x00218085
[user@localhost]$otool -hv KWPlayer.decrypted
KWPlayer.decrypted:
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
MH_MAGIC_64 ARM64 ALL 0x00 EXECUTE 130 13064 NOUNDEFS DYLDLINK TWOLEVEL WEAK_DEFINES BINDS_TO_WEAK PIE
- -l 显示镜像加载命令,我们可以用来查看文件依赖的动态库信息
[user@localhost]$otool -l KWPlayer.decrypted | head -25
KWPlayer.decrypted:
Load command 0
cmd LC_SEGMENT_64
cmdsize 72
segname __PAGEZERO
vmaddr 0x0000000000000000
vmsize 0x0000000100000000
fileoff 0
filesize 0
maxprot 0x00000000
initprot 0x00000000
nsects 0
flags 0x0
Load command 1
cmd LC_SEGMENT_64
cmdsize 1032
segname __TEXT
vmaddr 0x0000000100000000
vmsize 0x00000000085f0000
fileoff 0
filesize 140443648
maxprot 0x00000005
initprot 0x00000005
nsects 12
flags 0x0
以及最重要的:镜像是否被加密。此处的文件已经进行了脱壳,所以,cryptid为0,表示未加密。如果为0,表示镜像加密。加密的镜像是无法被反汇编(disassemble)的。
[user@localhost]$otool -l KWPlayer.decrypted | grep crypt
KWPlayer.decrypted:
cryptoff 16384
cryptsize 140427264
cryptid 0[user@localhost]$otool -l KWPlayer.decrypted | grep crypt
KWPlayer.decrypted:
cryptoff 16384
cryptsize 140427264
cryptid 0
-
-s 显示指定段名(segment_name)和分区名(section_name)的内容。通常配合-v、-V使用,对信息进行反汇编和符号化。
-
-t 显示(__TEXT,__text)分区,即代码段内容,通常配合-v、-V使用,对信息进行反汇编和符号化
-x 功能类似于-t,显示所有__text分区,不仅限于__TEXT。主要针对一些特殊文件处理
[user@localhost]$otool -tv KWPlayer.decrypted | grep -20 KWPlayer
0000000105a7c4e8 ldr x22, [x19, #0x8]
0000000105a7c4ec cbnz x22, 0x105a7c51c
0000000105a7c4f0 adrp x8, 16512 ; 0x109afc000
0000000105a7c4f4 ldr x0, [x8, #0x6c8] ; Objc class ref: KWPlayerResource
0000000105a7c4f8 bl 0x106eceaa0 ; symbol stub for: _objc_alloc
0000000105a7c4fc adrp x8, 16213 ; 0x1099d1000
0000000105a7c500 ldr x1, [x8, #0xf98] ; Objc selector ref: init
0000000105a7c504 bl 0x106ecebcc ; Objc message: +[KWPlayerResource init]
0000000105a7c508 ldr x8, [x19, #0x8]
0000000105a7c50c str x0, [x19, #0x8]
0000000105a7c510 mov x0, x8
0000000105a7c514 bl 0x106ecebf0 ; symbol stub for: _objc_release
0000000105a7c518 ldr x22, [x19, #0x8]
0000000105a7c51c adrp x8, 16422 ; 0x109aa2000
0000000105a7c520 ldr x21, [x8, #0x9b8] ; Objc selector ref: mediaItem
0000000105a7c524 mov x0, x19
0000000105a7c528 mov x1, x21
0000000105a7c52c bl 0x106ecebcc ; Objc message: -[x0 mediaItem]
0000000105a7c530 mov x29, x29
0000000105a7c534 bl 0x106ecec2c ; symbol stub for: _objc_retainAutoreleasedReturnValue
0000000105a7c538 mov x23, x0
0000000105a7c53c adrp x25, 11124 ; 0x1085f0000
0000000105a7c540 ldr x25, [x25, #0xd20] ; literal pool symbol address: __NSConcreteStackBlock
0000000105a7c544 str x25, [sp, #0x28]
0000000105a7c548 adrp x8, 5213 ; 0x106ed9000
0000000105a7c54c ldr d8, [x8, #0x428]
0000000105a7c550 adr x8, #0x1e4
0000000105a7c554 nop
- -d 显示(__DATA,__data)段
- -o 显示__OBJC段,段内容会被OC运行时加载。
[user@localhost]$otool -ov KWPlayer.decrypted | grep -20 KWWeakProxy
entsize 24
count 1
name 0x10813eee1 shareIns
types 0x10830b73d @16@0:8
imp 0x106d5525c
baseProtocols 0x0
ivars 0x0
weakIvarLayout 0x0
baseProperties 0x0
00000001089e8ad8 0x109d1d220
isa 0x109d1d248
superclass 0x0 _OBJC_CLASS_$_NSObject
cache 0x0 __objc_empty_cache
vtable 0x0
data 0x10998b9f8
flags 0x194 RO_HAS_CXX_STRUCTORS
instanceStart 8
instanceSize 16
reserved 0x0
ivarLayout 0x0
name 0x108309915 KWWeakProxy
baseMethods 0x10998b818
entsize 24
count 17
name 0x107f669f4 initWithTarget:
types 0x10830b766 @24@0:8@16
imp 0x106d55bd4
name 0x107d626af forwardingTargetForSelector:
types 0x10830ba65 @24@0:8:16
imp 0x106d55c4c
name 0x108036edc forwardInvocation:
types 0x10830b745 v24@0:8@16
imp 0x106d55c60
name 0x107d248a3 methodSignatureForSelector:
types 0x10830ba65 @24@0:8:16
imp 0x106d55c90
name 0x107ccca41 respondsToSelector:
types 0x10830ba9a B24@0:8:16
imp 0x106d55cac
name 0x107ccbba0 isEqual:
types 0x10830ba52 B24@0:8@16
-
-v 显示详细(符号)信息,如果可能
-V 显示反汇编指令的参数符号,隐含-v选项,配合-s,-t,-x使用非常有效 -
-X 不显示反汇编的段起始地址或头信息。
dyld_info
显示程序或动态库包含的动态链接器(dyld) 使用的信息。
- -platform 显示文件工作的平台信息(macOS,iOS)
[user@localhost]$dyld_info -platform KWPlayer.decrypted
/Users/sensoro/Desktop/KWPlayer.decrypted [arm64]:
-platform:
platform minOS sdk
iOS 9.0 15.4
- -segements 显示段和分区信息,以及大小
[user@localhost]$dyld_info -segments KWPlayer.decrypted | head -20
/Users/sensoro/Desktop/KWPlayer.decrypted [arm64]:
-segments:
load-offset segment section sect-size seg-size perm
0x00000000 __TEXT 137152KB r.x
0x00004900 __text 116150792
0x06EC9B08 __stubs 25356
0x06ECFE14 __stub_helper 24780
0x06ED5EE0 __const 4259433
0x072E5D4C __gcc_except_tab 5837876
0x07877180 __cstring 4537945
0x07CCAFD9 __objc_methname 6100937
0x0829C7A2 __objc_classname 454536
0x0830B72A __objc_methtype 682090
0x083B1F94 __ustring 467168
0x08424074 __unwind_info 1734220
0x085CB6C0 __eh_frame 149788
0x085F0000 __DATA 29216KB rw.
0x085F0000 __got 25464
0x085F6378 __la_symbol_ptr 16904
0x085FA580 __mod_init_func 7072
- -dependents 显示文件链接的所有动态库
[user@localhost]$dyld_info -dependents KWPlayer.decrypted | head -20
/Users/sensoro/Desktop/KWPlayer.decrypted [arm64]:
-dependents:
attributes load path
/usr/lib/libbz2.1.0.dylib
/usr/lib/libSystem.B.dylib
/usr/lib/libc++.1.dylib
/usr/lib/libiconv.2.dylib
/usr/lib/libicucore.A.dylib
/usr/lib/libresolv.9.dylib
/usr/lib/libsqlite3.dylib
/usr/lib/libxml2.2.dylib
/usr/lib/libz.1.dylib
@rpath/AFNetworking.framework/AFNetworking
/System/Library/Frameworks/AVFoundation.framework/AVFoundation
weak_import /System/Library/Frameworks/AVKit.framework/AVKit
/System/Library/Frameworks/Accelerate.framework/Accelerate
/System/Library/Frameworks/AdSupport.framework/AdSupport
@rpath/App.framework/App
weak_import /System/Library/Frameworks/AppTrackingTransparency.framework/AppTrackingTransparency
@rpath/Aspects.framework/Aspects
- -inits 显示所有的静态初始化器和OC +load方法
[user@localhost]$dyld_info -inits KWPlayer.decrypted | head -20
/Users/sensoro/Desktop/KWPlayer.decrypted [arm64]:
-inits:
0x000111C0 __mh_execute_header + 0x111C0
0x00011DF8 __ZN6Thread7cleanupEPv + 0x110
0x00018FBC __ZN6Thread19start_routine_afterEPv + 0x15D8
0x0001B470 __ZN6Thread19start_routine_afterEPv + 0x3A8C
0x0001D2A4 __ZN6Thread19start_routine_afterEPv + 0x58C0
0x00029710 __ZN6Thread19start_routine_afterEPv + 0x11D2C
0x00029740 __ZN6Thread19start_routine_afterEPv + 0x11D5C
0x00029770 __ZN6Thread19start_routine_afterEPv + 0x11D8C
0x000297A0 __ZN6Thread19start_routine_afterEPv + 0x11DBC
0x000297D0 __ZN6Thread19start_routine_afterEPv + 0x11DEC
0x00029800 __ZN6Thread19start_routine_afterEPv + 0x11E1C
0x00029830 __ZN6Thread19start_routine_afterEPv + 0x11E4C
0x00029860 __ZN6Thread19start_routine_afterEPv + 0x11E7C
0x0002D150 __ZN6Thread19start_routine_afterEPv + 0x1576C
0x0002D180 __ZN6Thread19start_routine_afterEPv + 0x1579C
0x0002D23C __ZN6Thread19start_routine_afterEPv + 0x15858
0x0002DE20 __ZN6Thread19start_routine_afterEPv + 0x1643C
0x00031D84 __ZN6Thread19start_routine_afterEPv + 0x1A3A0
[user@localhost]$dyld_info -inits KWPlayer.decrypted | tail -20
0x0943EEE0 +[BLYWCSessionDelegateInterceptor load]
0x094AE468 +[JVClientController load]
0x094B1B70 +[JVIntegrate load]
0x094C0838 +[JCommonServiceController load]
0x094C5D88 +[JPUSHReceivedPacketController load]
0x094CA3B8 +[JCORENetworkReachabilityManager load]
0x094EF7A0 +[TGGDTPODS_GDTCacheManager load]
0x094FFEF8 +[TGGDTPODS_GDataXMLNode load]
0x0956FC20 +[VLNLog load]
0x09645400 +[KWPAppDelegate load]
0x096BE588 +[LaunchMusic load]
0x096BE750 +[JXGlobalModuleRouter load]
0x0909CE50 +[(fxTouch) load]
0x0918BEB0 +[(Placeholder) load]
0x09316DA8 +[(MJRefresh) load]
0x09316E28 +[(MJRefresh) load]
0x0942DE78 +[(BuglyMartian) load]
0x0943ED88 +[(BUGLY_WCSessionRuntime) load]
0x094AAD10 +[(JVhook) load]
0x099A0C10 +[(SkinSupport) load]
- -exports 显示所有导出符号
-imports 显示所有导入符号
[user@localhost]dyld_info -imports KWPlayer.decrypted | tail -10
/Users/sensoro/Desktop/KWPlayer.decrypted [arm64]:
0x0000 0x002 __Block_copy
0x0001 0x002 __DefaultRuneLocale
[user@localhost]$dyld_info -exports KWPlayer.decrypted | tail -10
0x052CCA38 _cramer_solve [weak_def]
0x052CC8B4 _det [weak_def]
0x052CC9F0 _deinit_square_matrix [weak_def]
0x056AF194 _ABInputPortReceiveLive [weak_def]
0x056AF1A0 _ABInputPortIsConnected [weak_def]
0x056AF1C0 _ABOutputPortSendAudio [weak_def]
0x056AF1E0 _ABOutputPortIsConnected [weak_def]
0x056AF200 _ABOutputPortGetConnectedPortAttributes [weak_def]
0x056AF220 _ABOutputPortGetAverageLatency [weak_def]
0x09EAFF88 _ABConnectionsChangedNotification [weak_def]
- -objc 显示OC定义的类和分类信息
[sensoro@ninjia:~/Desktop]$dyld_info -objc /Users/sensoro/Desktop/KWPlayer.decrypted | head -20
/Users/sensoro/Desktop/KWPlayer.decrypted [arm64]:
-objc:
type vmaddr data-vmaddr name
class 0x109B79278 0x1089EF7B0 FANetCheckResultModel
method 0x1089EF608 status
method 0x1089EF620 setStatus:
method 0x1089EF638 score
method 0x1089EF650 setScore:
method 0x1089EF668 networkType
method 0x1089EF680 setNetworkType:
method 0x1089EF698 detailInfo
method 0x1089EF6B0 setDetailInfo:
method 0x1089EF6C8 .cxx_destruct
meta-class 0x109B792A0 0x1089EF5B8 FANetCheckResultModel
class 0x109B792C8 0x1089EF8C8 FANetCheck
method 0x1089EF868 init
method 0x1089EF880 startCheckWithHostList:
method 0x1089EF898 stopCheck
method 0x1089EF8B0 dealloc
meta-class 0x109B792F0 0x1089EF818 FANetCheck
- -fixups 显示一个简单的列表,包含动态链接器(dyld)修复的位置信息
-fixup_chains 如果文件使用了链式修复,显示链的格式和起始位置
-fixup_chain_details 显示一个列表,包含所有的修复链的原始位信息和意义
-symbolic_fixups 按照数据符号分组显示所有的修复
-validate_only 格式校验。如果文件是合法的,不显示任何信息,否则显示格式错误部分的信息。
libtool
用于从对象文件,创建库文件(动态库Mach-O或静态库ar),详细的使用方法可以使用man libtool
。