作者 | yuec
来源 :
https://juejin.im/user/5d02fe565188255a70479721
#binary_file_arch: distinguish Big-Endian and Little-Endian
#file -b output example: Mach-O 64-bit executable arm64
binary_file_arch = os.popen('file -b ' + path).read().split(' ')[-1].strip()
def pointers_from_binary(line, binary_file_arch):
line = line[16:].strip().split(' ')
pointers = set()
if binary_file_arch == 'x86_64':
#untreated line example:00000001030cec80 d8 75 15 03 01 00 00 00 68 77 15 03 01 00 00 00
pointers.add(''.join(line[4:8][::-1] + line[0:4][::-1]))
pointers.add(''.join(line[12:16][::-1] + line[8:12][::-1]))
return pointers
#arm64 confirmed,armv7 arm7s unconfirmed
if binary_file_arch.startswith('arm'):
#untreated line example:00000001030bcd20 03138580 00000001 03138878 00000001
pointers.add(line[1] + line[0])
pointers.add(line[3] + line[2])
return pointers
return None
def class_ref_pointers(path, binary_file_arch):
ref_pointers = set()
lines = os.popen('/usr/bin/otool -v -s __DATA __objc_classrefs %s' % path).readlines()
for line in lines:
pointers = pointers_from_binary(line, binary_file_arch)
ref_pointers = ref_pointers.union(pointers)
return ref_pointers
def class_list_pointers(path, binary_file_arch):
list_pointers = set()
lines = os.popen('/usr/bin/otool -v -s __DATA __objc_classlist %s' % path).readlines()
for line in lines:
pointers = pointers_from_binary(line, binary_file_arch)
list_pointers = list_pointers.union(pointers)
return list_pointers
unref_pointers = class_list_pointers(path, binary_file_arch) - class_ref_pointers(path, binary_file_arch)
def class_symbols(path):
symbols = {}
#class symbol format from nm: 0000000103113f68 (__DATA,__objc_data) external _OBJC_CLASS_$_EpisodeStatusDetailItemView
re_class_name = re.compile('(w{16}) .* _OBJC_CLASS_$_(.+)')
lines = os.popen('nm -nm %s' % path).readlines()
for line in lines:
result = re_class_name.findall(line)
if result:
(address, symbol) = result[0]
symbols[address] = symbol
return symbols
def filter_super_class(unref_symbols):
re_subclass_name = re.compile("w{16} 0xw{9} _OBJC_CLASS_$_(.+)")
re_superclass_name = re.compile("s*superclass 0xw{9} _OBJC_CLASS_$_(.+)")
#subclass example: 0000000102bd8070 0x103113f68 _OBJC_CLASS_$_TTEpisodeStatusDetailItemView
#superclass example: superclass 0x10313bb80 _OBJC_CLASS_$_TTBaseControl
lines = os.popen("/usr/bin/otool -oV %s" % path).readlines()
subclass_name = ""
superclass_name = ""
for line in lines:
subclass_match_result = re_subclass_name.findall(line)
if subclass_match_result:
subclass_name = subclass_match_result[0]
superclass_match_result = re_superclass_name.findall(line)
if superclass_match_result:
superclass_name = superclass_match_result[0]
if len(subclass_name) > 0 and len(superclass_name) > 0:
if superclass_name in unref_symbols and subclass_name not in unref_symbols:
unref_symbols.remove(superclass_name)
superclass_name = ""
subclass_name = ""
return unref_symbols
for unref_pointer in unref_pointers:
if unref_pointer in symbols:
unref_symbol = symbols[unref_pointer]
if len(reserved_prefix) > 0 and not unref_symbol.startswith(reserved_prefix):
continue
if len(filter_prefix) > 0 and unref_symbol.startswith(filter_prefix):
continue
unref_symbols.add(unref_symbol)
script_path = sys.path[0].strip()
f = open(script_path+"/result.txt","w")
f.write( "unref class number: %d
" % len(unref_symbles))
f.write("
")
for unref_symble in unref_symbles:
f.write(unref_symble+"
")
f.close()
推荐↓↓↓
长
按
关
注
?【16个技术公众号】都在这里!
涵盖:程序员大咖、源码共读、程序员共读、数据结构与算法、黑客技术和网络安全、大数据科技、编程前端、Java、Python、Web编程开发、Android、iOS开发、Linux、数据库研发、幽默程序员等。
本文地址:https://blog.csdn.net/olsQ93038o99S/article/details/100680143
如对本文有疑问, 点击进行留言回复!!
springcloud中feign调用处理mybatis-plus Ipage反序列化问题。
Flume 史上最全面的大数据学习第十篇(一) 别再说不知道flume是什么了
网友评论