接触Ruby也有段时间了,一直没拿出来耍过,今天正好遇到个解crashlog的需求,本来打算用shell写,想想决定试试用ruby耍耍,重在练手,勿喷~
写这脚本的主要原因是针对需要解iOS的crashlog,而又没有对应的dSYM文件,所以需要手动利用符号表地址去查找对应方法名的需求。
首先明确下需求:
- 接收参数传入log文件和可执行文件
- 判断UUID是否一致
- 定位出log中未被解析出来的行
- 根据log文件中符号表地址找到对应符号表并替换
解题步骤:
- 读取给定可执行UUID(可能有多个)
- 读取Log文件UUID
- 判断第二个UUID是否包含在前一步得到的结果中
- 定位未来被解开的log行
- 读取符号表地址并去可执行文件中查找对应的符号表进行替换
最终得到代码如下:
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
#create ibcker 2014 04 15
crashFilePath = ARGV[0] #crashlog file path
binaryFilePath = ARGV[1] #binary file path
if crashFilePath.to_s=='' || crashFilePath=='-h' || crashFilePath=='-help'
puts '用于反解crashlog'
puts '> useage:'
puts ' hicrashlog xxx.crash xxx.dYMS'
puts ' or hicrashlog xxx.crash xxx.app/xxx'
exit
end
logUuid = `grep --after-context=1 "Binary Images:" #{crashFilePath} |tail -1|sed "s/.*<//"|sed "s/>.*//"`
logUuid = logUuid.to_s.chomp()
if logUuid.length<10
puts "Read CrashLog UUID ERROR :"+logUuid.to_s
exit
end
binaryUuid = `dwarfdump -u #{binaryFilePath}`
binaryUuid=binaryUuid.to_s.gsub(/[-]/,'').downcase;
if binaryUuid.length<10
puts "Read Binary UUID ERROR :"+binaryUuid.to_s
exit
end
if ! (binaryUuid.include?logUuid)
puts "UUID no match"
puts '-------------binary-------------'
puts binaryUuid
puts '------------crashlog-------------'
puts logUuid
exit
end
#p logUuid
#p binaryUuid
#exit
File.open(crashFilePath) do |file|
file.each_line(){ |line|
#puts "#{line.dump}"
reg = /0x[0-9a-f]{5,12} 0x[0-9a-f]{2,12} \+ [0-9]*/
if reg.match(line.to_s)
chips = line.split(' ')
# p chips
result = `atos -o #{binaryFilePath} -l #{chips[3]} #{chips[2]} 2>&1 |tail -1|sed "s/(in.*) (/(/"`
# p result
slc=' '
puts "#{chips[0]}#{slc}#{chips[1]} #{chips[2]} #{result}"
else
puts line
end
}
file.close();
end
hicrash xxx.crash xxx.dYMS
or
hicrash xxx.crash xxx.app/xxx
以上只是个demo,最新代码请移步github https://github.com/iBcker/hicrash