1""" 2Defines a class value which encapsulates the basic lldb Scripting Bridge APIs. This provides an easy 3wrapper to extract information from C based constructs. 4 5 |------- core.value------------| 6 | |--lldb Scripting Bridge--| | 7 | | |--lldb core--| | | 8 | |-------------------------| | 9 |------------------------------| 10 11Use the member function GetSBValue() to access the base Scripting Bridge value. 12""" 13from __future__ import absolute_import, division, print_function 14 15# The value class is designed to be Python 2/3 compatible. Pulling in more 16# builtins classes may break it. 17from builtins import range 18import numbers 19 20# Override int with valueint so we get the desired behavior. 21from .compat import valueint as int 22 23from past.utils import old_div 24import lldb 25import re 26from .lazytarget import LazyTarget 27import six 28 29_CSTRING_REX = re.compile(r"((?:\s*|const\s+)\s*char(?:\s+\*|\s+[A-Za-z_0-9]*\s*\[|)\s*)", re.MULTILINE | re.DOTALL) 30 31 32# pragma pylint: disable=hex-method, div-method, rdiv-method, idiv-method, oct-method, nonzero-method 33class value(object): 34 """A class designed to wrap lldb.SBValue() objects so the resulting object 35 can be used as a variable would be in code. So if you have a Point structure 36 variable in your code in the current frame named "pt", you can initialize an instance 37 of this class with it: 38 39 pt = lldb.value(lldb.frame.FindVariable("pt")) 40 print pt 41 print pt.x 42 print pt.y 43 44 pt = lldb.value(lldb.frame.FindVariable("rectangle_array")) 45 print rectangle_array[12] 46 print rectangle_array[5].origin.x 47 """ 48 _kasan_tbi_build = None 49 50 def __init__(self, sbvalue): 51 # _sbval19k84obscure747 is specifically chosen to be obscure. 52 # This avoids conflicts when attributes could mean any field value in code. 53 self.sbvalue = sbvalue 54 self._sbval19k84obscure747 = self.sbvalue 55 self._sbval19k84obscure747_type = self.sbvalue.GetType() 56 self._sbval19k84obscure747_is_ptr = self.sbvalue.GetType().GetTypeFlags() & lldb.eTypeIsPointer 57 58 """Pointers need to have their TBI byte stripped if in use. TBI KASan, 59 for instance, tags pointers to detect improper memory accesses. Reading 60 values from such tagged pointers fails. 61 62 Stripping the pointers requires to learn whether TBI is in use or not. 63 We do that by checking presence of 'kasan_tbi_enabled' symbol which only 64 exists on the TBI KASan variant. Since KASan is one of more TBI 65 consumers (along with PAC or Sandbox) this is not an ideal approach. 66 Inspecting respective CPU state would be more appropriate. 67 68 Missing uniform TBI support in macros led to storing the TBI indication 69 in the 'value' class since it represents memory objects. In reality, it 70 is a property of the target itself where it rather belongs. 71 """ 72 if value._IsKASanTBIBuild(): 73 self._StripTBI() 74 75 @classmethod 76 def _IsKASanTBIBuild(cls): 77 """Returns true on TBI KASan targets, false otherwise.""" 78 if cls._kasan_tbi_build is None: 79 if LazyTarget.GetTarget().FindGlobalVariables('kasan_tbi_enabled', 1): 80 cls._kasan_tbi_build = True 81 else: 82 cls._kasan_tbi_build = False 83 return cls._kasan_tbi_build 84 85 def __bool__(self): 86 return self._sbval19k84obscure747.__bool__() and self._GetValueAsUnsigned() != 0 87 88 def __nonzero__(self): 89 return self._sbval19k84obscure747.__nonzero__() and self._GetValueAsUnsigned() != 0 90 91 def __repr__(self): 92 return self._sbval19k84obscure747.__str__() 93 94 # 95 # Compare operators 96 # 97 98 def __eq__(self, other): 99 self_val = self._GetValueAsUnsigned() 100 if isinstance(other, value): 101 other_val = other._GetValueAsUnsigned() 102 return self_val == other_val 103 if isinstance(other, numbers.Integral): 104 return int(self) == other 105 raise TypeError("EQ operator is not defined for this type.") 106 107 def __ne__(self, other): 108 return not self == other 109 110 def __lt__(self, other): 111 self_val = self._GetValueAsUnsigned() 112 if isinstance(other, value): 113 other_val = other._GetValueAsUnsigned() 114 return self_val < other_val 115 if isinstance(other, numbers.Integral): 116 return int(self) < int(other) 117 raise TypeError("LT operator is not defined for this type") 118 119 def __le__(self, other): 120 return self < other or self == other 121 122 def __gt__(self, other): 123 return not self <= other 124 125 def __ge__(self, other): 126 return not self < other 127 128 def __str__(self): 129 global _CSTRING_REX 130 type_name = self._sbval19k84obscure747_type.GetCanonicalType().GetName() 131 if len(_CSTRING_REX.findall(type_name)) > 0: 132 return self._GetValueAsString() 133 summary = self._sbval19k84obscure747.GetSummary() 134 if summary: 135 return summary.strip('"') 136 return self._sbval19k84obscure747.__str__() 137 138 def __getitem__(self, key): 139 # Allow array access if this value has children... 140 if type(key) is slice: 141 _start = int(key.start) 142 _end = int(key.stop) 143 _step = 1 144 if key.step is not None: 145 _step = int(key.step) 146 retval = [] 147 while _start < _end: 148 retval.append(self[_start]) 149 _start += _step 150 return retval 151 if isinstance(key, numbers.Integral): 152 return value(self._sbval19k84obscure747.GetValueForExpressionPath("[%i]" % key)) 153 if type(key) is value: 154 return value(self._sbval19k84obscure747.GetValueForExpressionPath("[%i]" % int(key))) 155 raise TypeError("Cannot fetch Array item for this type") 156 157 def __getattr__(self, name): 158 child_sbvalue = self._sbval19k84obscure747.GetChildMemberWithName(name) 159 if child_sbvalue: 160 return value(child_sbvalue) 161 raise AttributeError("No field by name: " + name) 162 163 def __add__(self, other): 164 return int(self) + int(other) 165 166 def __radd__(self, other): 167 return int(self) + int(other) 168 169 def __sub__(self, other): 170 return int(self) - int(other) 171 172 def __rsub__(self, other): 173 return int(other) - int(self) 174 175 def __mul__(self, other): 176 return int(self) * int(other) 177 178 def __rmul__(self, other): 179 return int(self) * int(other) 180 181 def __floordiv__(self, other): 182 return int(self) // int(other) 183 184 def __rfloordiv__(self, other): 185 return int(other) // int(self) 186 187 def __mod__(self, other): 188 return int(self) % int(other) 189 190 def __rmod__(self, other): 191 return int(other) % int(self) 192 193 def __divmod__(self, other): 194 return divmod(int(self), int(other)) 195 196 def __rdivmod__(self, other): 197 return divmod(int(other), int(self)) 198 199 def __pow__(self, other): 200 return int(self) ** int(other) 201 202 def __lshift__(self, other): 203 return int(self) << int(other) 204 205 def __rshift__(self, other): 206 return int(self) >> int(other) 207 208 def __and__(self, other): 209 return int(self) & int(other) 210 211 def __rand__(self, other): 212 return int(other) & int(self) 213 214 def __xor__(self, other): 215 return int(self) ^ int(other) 216 217 def __or__(self, other): 218 return int(self) | int(other) 219 220 def __div__(self, other): 221 return old_div(int(self), int(other)) 222 223 def __rdiv__(self, other): 224 return old_div(int(other), int(self)) 225 226 def __truediv__(self, other): 227 return int(self) / int(other) 228 229 def __rtruediv__(self, other): 230 return int(other) / int(self) 231 232 def __iadd__(self, other): 233 result = self.__add__(other) 234 self._sbval19k84obscure747.SetValueFromCString(str(result)) 235 return result 236 237 def __isub__(self, other): 238 result = self.__sub__(other) 239 self._sbval19k84obscure747.SetValueFromCString(str(result)) 240 return result 241 242 def __imul__(self, other): 243 result = self.__mul__(other) 244 self._sbval19k84obscure747.SetValueFromCString(str(result)) 245 return result 246 247 def __idiv__(self, other): 248 result = self.__div__(other) 249 self._sbval19k84obscure747.SetValueFromCString(str(result)) 250 return result 251 252 def __itruediv__(self, other): 253 result = self.__truediv__(other) 254 self._sbval19k84obscure747.SetValueFromCString(str(result)) 255 return result 256 257 def __ifloordiv__(self, other): 258 result = self.__floordiv__(other) 259 self._sbval19k84obscure747.SetValueFromCString(str(result)) 260 return result 261 262 def __imod__(self, other): 263 result = self.__mod__(other) 264 self._sbval19k84obscure747.SetValueFromCString(str(result)) 265 return result 266 267 def __ipow__(self, other): 268 result = self.__pow__(other) 269 self._sbval19k84obscure747.SetValueFromCString(str(result)) 270 return result 271 272 def __ilshift__(self, other): 273 result = self.__lshift__(other) 274 self._sbval19k84obscure747.SetValueFromCString(str(result)) 275 return result 276 277 def __irshift__(self, other): 278 result = self.__rshift__(other) 279 self._sbval19k84obscure747.SetValueFromCString(str(result)) 280 return result 281 282 def __iand__(self, other): 283 result = self.__and__(other) 284 self._sbval19k84obscure747.SetValueFromCString(str(result)) 285 return result 286 287 def __ixor__(self, other): 288 result = self.__xor__(other) 289 self._sbval19k84obscure747.SetValueFromCString(str(result)) 290 return result 291 292 def __ior__(self, other): 293 result = self.__or__(other) 294 self._sbval19k84obscure747.SetValueFromCString(str(result)) 295 return result 296 297 def __neg__(self): 298 return -int(self) 299 300 def __pos__(self): 301 return +int(self) 302 303 def __abs__(self): 304 return abs(int(self)) 305 306 def __invert__(self): 307 return ~int(self) 308 309 def __complex__(self): 310 return complex(int(self)) 311 312 def __int__(self): 313 flags = self._sbval19k84obscure747_type.GetTypeFlags() 314 if flags & lldb.eTypeIsPointer: 315 return self._GetValueAsUnsigned() 316 if not flags & lldb.eTypeIsSigned: 317 return self._GetValueAsUnsigned() 318 return int(self._sbval19k84obscure747.GetValueAsSigned()) 319 320 # Python 3 conversion to int calls this. 321 def __index__(self): 322 return self.__int__() 323 324 def __long__(self): 325 flags = self._sbval19k84obscure747_type.GetTypeFlags() 326 if flags & lldb.eTypeIsPointer: 327 return self._GetValueAsUnsigned() 328 if not flags & lldb.eTypeIsSigned: 329 return self._GetValueAsUnsigned() 330 return int(self._sbval19k84obscure747.GetValueAsSigned()) 331 332 def __float__(self): 333 return float(self._sbval19k84obscure747.GetValueAsSigned()) 334 335 # Python 2 must return native string. 336 def __oct__(self): 337 return '0%o' % self._GetValueAsUnsigned() 338 339 # Python 2 must return native string. 340 def __hex__(self): 341 return '0x%x' % self._GetValueAsUnsigned() 342 343 def __hash__(self): 344 return hash(self._sbval19k84obscure747) 345 346 def GetSBValue(self): 347 return self._sbval19k84obscure747 348 349 def __getstate__(self): 350 err = lldb.SBError() 351 if self._sbval19k84obscure747_is_ptr: 352 addr = self._sbval19k84obscure747.GetValueAsAddress() 353 size = self._sbval19k84obscure747_type.GetPointeeType().GetByteSize() 354 else: 355 addr = self._sbval19k84obscure747.AddressOf().GetValueAsAddress() 356 size = self._sbval19k84obscure747_type.GetByteSize() 357 358 content = LazyTarget.GetProcess().ReadMemory(addr, size, err) 359 if err.fail: 360 content = '' 361 return content 362 363 def _GetValueAsSigned(self): 364 if self._sbval19k84obscure747_is_ptr: 365 print("ERROR: You cannot get 'int' from pointer type %s, please use unsigned(obj) for such purposes." % str(self._sbval19k84obscure747_type)) 366 raise ValueError("Cannot get signed int for pointer data.") 367 serr = lldb.SBError() 368 retval = self._sbval19k84obscure747.GetValueAsSigned(serr) 369 if serr.success: 370 return retval 371 raise ValueError("Failed to read signed data. " + str(self._sbval19k84obscure747) + "(type =" + str(self._sbval19k84obscure747_type) + ") Error description: " + serr.GetCString()) 372 373 def _GetValueAsCast(self, dest_type): 374 if type(dest_type) is not lldb.SBType: 375 raise ValueError("Invalid type for dest_type: {}".format(type(dest_type))) 376 addr = self._GetValueAsUnsigned() 377 sbval = self._sbval19k84obscure747.target.CreateValueFromExpression("newname", "(void *)"+str(addr)) 378 val = value(sbval.Cast(dest_type)) 379 return val 380 381 def _GetValueAsUnsigned(self): 382 serr = lldb.SBError() 383 if self._sbval19k84obscure747_is_ptr: 384 retval = self._sbval19k84obscure747.GetValueAsAddress() 385 else: 386 retval = self._sbval19k84obscure747.GetValueAsUnsigned(serr) 387 if serr.success: 388 return int(retval) 389 raise ValueError("Failed to read unsigned data. " + str(self._sbval19k84obscure747) + "(type =" + str(self._sbval19k84obscure747_type) + ") Error description: " + serr.GetCString()) 390 391 def _GetValueAsString(self, offset=0, maxlen=1024): 392 serr = lldb.SBError() 393 sbdata = None 394 if self._sbval19k84obscure747_is_ptr: 395 sbdata = self._sbval19k84obscure747.GetPointeeData(offset, maxlen) 396 else: 397 sbdata = self._sbval19k84obscure747.GetData() 398 399 retval = '' 400 bytesize = sbdata.GetByteSize() 401 if bytesize == 0: 402 # raise ValueError('Unable to read value as string') 403 return '' 404 for i in range(0, bytesize): 405 serr.Clear() 406 ch = chr(sbdata.GetUnsignedInt8(serr, i)) 407 if serr.fail: 408 raise ValueError("Unable to read string data: " + serr.GetCString()) 409 if ch == '\0': 410 break 411 retval += ch 412 return retval 413 414 def __format__(self, format_spec): 415 ret_format = "{0:"+format_spec+"}" 416 # typechar is last char. see http://www.python.org/dev/peps/pep-3101/ 417 type_spec = format_spec.strip().lower()[-1] 418 if type_spec == 'x': 419 return ret_format.format(int(self)) 420 if type_spec == 'd': 421 return ret_format.format(int(self)) 422 if type_spec == 's': 423 return ret_format.format(str(self)) 424 if type_spec == 'o': 425 return ret_format.format(int(oct(self), 8)) 426 if type_spec == 'c': 427 return ret_format.format(int(self)) 428 429 raise TypeError("Unsupported value format") 430 431 def _StripTBI(self): 432 """Strips the TBI byte value. Since the value is not a plain value but 433 represents a value of a variable, a register or an expression the 434 conversion is performed by (re-)creating the value through expression. 435 """ 436 if not self._sbval19k84obscure747_is_ptr: 437 return 438 addr = self._sbval19k84obscure747.GetValueAsAddress() 439 sbv_new = self._sbval19k84obscure747.CreateValueFromExpression(None,'(void *)' + str(addr)) 440 self._sbval19k84obscure747 = sbv_new.Cast(self._sbval19k84obscure747_type) 441 442def unsigned(val): 443 """ Helper function to get unsigned value from core.value 444 params: val - value (see value class above) representation of an integer type 445 returns: int which is unsigned. 446 raises : ValueError if the type cannot be represented as unsigned int. 447 """ 448 if type(val) is value: 449 return int(val._GetValueAsUnsigned()) 450 return int(val) 451 452 453def signed(val): 454 """ Helper function to get signed value from core.value 455 params: val - value (see value class above) representation of an integer type 456 returns: int which is signed. 457 raises: ValueError if the type cannot be represented as signed int. 458 """ 459 if type(val) is value: 460 return val._sbval19k84obscure747.GetValueAsSigned() 461 return int(val) 462 463 464def sizeof(t): 465 """ Find the byte size of a type. 466 params: t - str : ex 'time_spec' returns equivalent of sizeof(time_spec) in C 467 t - value: ex a value object. returns size of the object 468 returns: int - byte size length 469 """ 470 if type(t) is value: 471 return t.GetSBValue().GetByteSize() 472 if isinstance(t, six.string_types): 473 return gettype(t).GetByteSize() 474 raise ValueError("Cannot get sizeof. Invalid argument") 475 476 477def dereference(val): 478 """ Get a dereferenced obj for a pointer type obj 479 params: val - value object representing a pointer type C construct in lldb 480 returns: value - value 481 ex. val = dereference(ptr_obj) #python 482 is same as 483 obj_ptr = (int *)0x1234 #C 484 val = *obj_ptr #C 485 """ 486 if type(val) is value and val._sbval19k84obscure747_is_ptr: 487 return value(val.GetSBValue().Dereference()) 488 raise TypeError('Cannot dereference this type.') 489 490 491def addressof(val): 492 """ Get address of a core.value object. 493 params: val - value object representing a C construct in lldb 494 returns: value - value object referring to 'type(val) *' type 495 ex. addr = addressof(hello_obj) #python 496 is same as 497 uintptr_t addr = (uintptr_t)&hello_obj #C 498 """ 499 if type(val) is value: 500 return value(val.GetSBValue().AddressOf()) 501 raise TypeError("Cannot do addressof for non-value type objects") 502 503 504def cast(obj, target_type): 505 """ Type cast an object to another C type. 506 params: 507 obj - core.value object representing some C construct in lldb 508 target_type - str : ex 'char *' 509 - lldb.SBType : 510 """ 511 dest_type = target_type 512 if isinstance(target_type, six.string_types): 513 dest_type = gettype(target_type) 514 elif type(target_type) is value: 515 dest_type = target_type.GetSBValue().GetType() 516 517 if type(obj) is value: 518 return obj._GetValueAsCast(dest_type) 519 elif type(obj) is int: 520 print("ERROR: You cannot cast an 'int' to %s, please use kern.GetValueFromAddress() for such purposes." % str(target_type)) 521 raise TypeError("object of type %s cannot be casted to %s" % (str(type(obj)), str(target_type))) 522 523 524def containerof(obj, target_type, field_name): 525 """ Type cast an object to another C type from a pointer to a field. 526 params: 527 obj - core.value object representing some C construct in lldb 528 target_type - str : ex 'struct thread' 529 - lldb.SBType : 530 field_name - the field name within the target_type obj is a pointer to 531 """ 532 addr = int(obj) - getfieldoffset(target_type, field_name) 533 obj = value(obj.GetSBValue().CreateValueFromExpression(None, '(void *)' + str(addr))) 534 return cast(obj, target_type + " *") 535 536 537_value_types_cache = {} 538 539 540def gettype(target_type): 541 """ Returns lldb.SBType of the given target_type 542 params: 543 target_type - str, ex. 'char', 'uint32_t' etc 544 returns: 545 lldb.SBType - SBType corresponding to the given target_type 546 raises: 547 NameError - Incase the type is not identified 548 """ 549 global _value_types_cache 550 target_type = str(target_type).strip() 551 if target_type in _value_types_cache: 552 return _value_types_cache[target_type] 553 554 target_type = target_type.strip() 555 556 requested_type_is_struct = False 557 m = re.match(r'\s*struct\s*(.*)$', target_type) 558 if m: 559 requested_type_is_struct = True 560 target_type = m.group(1) 561 562 tmp_type = None 563 requested_type_is_pointer = False 564 if target_type.endswith('*'): 565 requested_type_is_pointer = True 566 567 # tmp_type = LazyTarget.GetTarget().FindFirstType(target_type.rstrip('*').strip()) 568 search_type = target_type.rstrip('*').strip() 569 type_arr = [t for t in LazyTarget.GetTarget().FindTypes(search_type)] 570 571 if requested_type_is_struct: 572 type_arr = [t for t in type_arr if t.type == lldb.eTypeClassStruct] 573 574 # After the sort, the struct type with more fields will be at index [0]. 575 # This hueristic helps selecting struct type with more fields compared to ones with "opaque" members 576 type_arr.sort(reverse=True, key=lambda x: x.GetNumberOfFields()) 577 if len(type_arr) > 0: 578 tmp_type = type_arr[0] 579 else: 580 raise NameError('Unable to find type '+target_type) 581 582 if not tmp_type.IsValid(): 583 raise NameError('Unable to Cast to type '+target_type) 584 585 if requested_type_is_pointer: 586 tmp_type = tmp_type.GetPointerType() 587 _value_types_cache[target_type] = tmp_type 588 589 return _value_types_cache[target_type] 590 591 592def getfieldoffset(struct_type, field_name): 593 """ Returns the byte offset of a field inside a given struct 594 Understands anonymous unions and field names in sub-structs 595 params: 596 struct_type - str or lldb.SBType, ex. 'struct ipc_port *' or port.gettype() 597 field_name - str, name of the field inside the struct ex. 'ip_messages' 598 returns: 599 int - byte offset of the field_name inside the struct_type 600 raises: 601 TypeError - - In case the struct_type has no field with the name field_name 602 """ 603 604 if isinstance(struct_type, six.string_types): 605 struct_type = gettype(struct_type) 606 607 if '.' in field_name: 608 # Handle recursive fields in sub-structs 609 components = field_name.split('.', 1) 610 for field in struct_type.get_fields_array(): 611 if str(field.GetName()) == components[0]: 612 return getfieldoffset(struct_type, components[0]) + getfieldoffset(field.GetType(), components[1]) 613 raise TypeError('Field name "%s" not found in type "%s"' % (components[0], str(struct_type))) 614 615 for field in struct_type.get_fields_array(): 616 if str(field.GetName()) == field_name: 617 return field.GetOffsetInBytes() 618 619 # Hack for anonymous unions - the compiler does this, so cvalue should too 620 if field.GetName() is None and field.GetType().GetTypeClass() == lldb.eTypeClassUnion: 621 for union_field in field.GetType().get_fields_array(): 622 if str(union_field.GetName()) == field_name: 623 return union_field.GetOffsetInBytes() + field.GetOffsetInBytes() 624 raise TypeError('Field name "%s" not found in type "%s"' % (field_name, str(struct_type))) 625 626 627def islong(x): 628 """ Returns True if a string represents a long integer, False otherwise 629 """ 630 try: 631 int(x, 16) 632 except ValueError: 633 try: 634 int(x) 635 except ValueError: 636 return False 637 return True 638 639 640def readmemory(val): 641 """ Returns a string of hex data that is referenced by the value. 642 params: val - a value object. 643 return: str - string of hex bytes. 644 raises: TypeError if val is not a valid type 645 """ 646 if not type(val) is value: 647 raise TypeError('%s is not of type value' % str(type(val))) 648 return val.__getstate__() 649 650 651def getOSPtr(cpp_obj): 652 """ Returns a core.value created from an intrusive_shared_ptr or itself, cpp_obj 653 params: cpp_obj - core.value object representing a C construct in lldb 654 return: core.value - newly created core.value or cpp_obj 655 """ 656 child = cpp_obj._sbval19k84obscure747.GetChildAtIndex(0) 657 if 'intrusive_shared_ptr' in str(child): 658 return value(child.GetChildMemberWithName('ptr_')) 659 return cpp_obj