1""" 2 XNU Triage commands 3""" 4from __future__ import absolute_import, print_function 5 6from xnu import * 7import sys, shlex 8from utils import * 9import xnudefines 10import re 11import os.path 12 13# Macro: xi 14def OutputAddress(cmd_args=None): 15 """ Returns out address and symbol corresponding to it without newline 16 Parameters: <address whose symbol is needed> 17 """ 18 if not cmd_args: 19 print("No arguments passed") 20 print(OutputAddress.__doc__) 21 return False 22 a = unsigned(cmd_args[0]) 23 cmd_str = "image lookup -a {:#x}".format(a) 24 cmd_out = lldb_run_command(cmd_str) 25 if len(cmd_out) != 0 and cmd_out != "ERROR:": 26 cmd_out1 = cmd_out.split('\n') 27 if len(cmd_out1) != 0: 28 cmd_out2 = cmd_out1[1].split('`') 29 if cmd_out2 != 0: 30 cmd_out3 = cmd_out2[1].split(' at') 31 if len(cmd_out3) != 0: 32 symbol_str = "{:#x} <{:s}>".format(unsigned(a), cmd_out3[0]) 33 return symbol_str 34 return "" 35 36@lldb_command('xi') 37def SymbolicateWithInstruction(cmd_args=None): 38 """ Prints out address and symbol similar to x/i 39 Usage: xi <address whose symbol is needed> 40 """ 41 if not cmd_args: 42 print("No arguments passed") 43 print(SymbolicateWithInstruction.__doc__) 44 return False 45 a = ArgumentStringToInt(cmd_args[0]) 46 print(OutputAddress([a])) 47 48# Macro: xi 49 50# Macro: newbt 51@lldb_command('newbt') 52def NewBt(cmd_args=None): 53 """ Prints all the instructions by walking the given stack pointer 54 """ 55 if not cmd_args: 56 print("No arguments passed") 57 print(NewBt.__doc__) 58 return False 59 a = ArgumentStringToInt(cmd_args[0]) 60 while a != 0: 61 if kern.arch == "x86_64" or kern.arch.startswith("arm64"): 62 offset = 8 63 else: 64 offset = 4 65 link_register = dereference(kern.GetValueFromAddress(a + offset, 'uintptr_t *')) 66 cmd_str = "di -s {:#x} -c 1".format(link_register) 67 cmd_out = lldb_run_command(cmd_str) 68 if len(cmd_out) != 0: 69 cmd_out1 = cmd_out.split('\n') 70 if len(cmd_out1) != 0: 71 address = OutputAddress([unsigned(link_register)]) 72 if address is None: 73 address = '0x%x <???>' % unsigned(link_register) 74 print(address + ": " + cmd_out1[1].split(':', 1)[1]) 75 a = dereference(kern.GetValueFromAddress(unsigned(a), 'uintptr_t *')) 76 77# EndMacro: newbt 78 79# Macro: parseLR 80@lldb_command('parseLR') 81def parseLR(cmd_args=None): 82 """ Decode the LR value from panic log into source code location 83 """ 84 global paniclog_data 85 panic_found = 1 86 87 if not paniclog_data: 88 if kern.arch == "x86_64": 89 paniclog_data += returnfunc("\n(lldb) paniclog\n", "paniclog -v") 90 else: 91 paniclog_data += returnfunc("\n(lldb) paniclog\n", "paniclog") 92 93 if panic_found == 1: 94 srch_string = "lr:\s+0x[a-fA-F0-9]+\s" 95 lr_pc_srch = re.findall(srch_string, paniclog_data) 96 if lr_pc_srch: 97 print(paniclog_data, lr_pc_srch) 98 for match in lr_pc_srch: 99 sp=match.strip("lr: ") 100 print(sp) 101 print("(lldb) list *{:s}".format(sp)) 102 print(lldb_run_command("list *{:s}".format(sp))) 103 104 else: 105 print("Currently unsupported on x86_64 architecture") 106#EndMacro: parseLR 107 108# Macro: parseLRfromfile 109@lldb_command('parseLRfromfile') 110def parseLRfromfile(cmd_args=None): 111 """ Decode the LR value from file into source code location 112 """ 113 f = open('/tmp/lrparsefile', 'r') 114 parse_data= f.read() 115 srch_string = "lr:\s+0x[a-fA-F0-9]+\s" 116 lr_pc_srch = re.findall(srch_string, parse_data) 117 if lr_pc_srch: 118 print(paniclog_data, lr_pc_srch) 119 for match in lr_pc_srch: 120 sp=match.strip("lr: ") 121 print(sp) 122 print("(lldb) list *{:s}".format(sp)) 123 print(lldb_run_command("list *{:s}".format(sp))) 124 125#EndMacro: parseLRfromfile 126 127