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""" 13 14# The value class is designed to be Python 2/3 compatible. Pulling in more 15# builtins classes may break it. 16import numbers 17 18import lldb 19import re 20from .caching import ( 21 cache_statically, 22) 23from .pointer import PointerPolicy 24 25_CSTRING_REX = re.compile(r"((?:\s*|const\s+)\s*char(?:\s+\*|\s+[A-Za-z_0-9]*\s*\[|)\s*)", re.MULTILINE | re.DOTALL) 26 27 28# pragma pylint: disable=hex-method, div-method, rdiv-method, idiv-method, oct-method, nonzero-method 29class value(object): 30 """A class designed to wrap lldb.SBValue() objects so the resulting object 31 can be used as a variable would be in code. So if you have a Point structure 32 variable in your code in the current frame named "pt", you can initialize an instance 33 of this class with it: 34 35 pt = lldb.value(lldb.frame.FindVariable("pt")) 36 print pt 37 print pt.x 38 print pt.y 39 40 pt = lldb.value(lldb.frame.FindVariable("rectangle_array")) 41 print rectangle_array[12] 42 print rectangle_array[5].origin.x 43 """ 44 45 __slots__ = ('__sbval', '__ptr') 46 47 def __init__(self, sbvalue, usePtrPolicy=True): 48 # Using a double `__` means this will be hidden from getattr() 49 # and can't conflict with C/C++ type field names. 50 self.__sbval = sbvalue 51 self.__ptr = PointerPolicy.match(sbvalue) if usePtrPolicy else None 52 53 @property 54 def sbvalue(self): 55 """backward compability for the old .sbvalue property""" 56 return self.GetSBValue() 57 58 @property 59 def ptrpolicy(self): 60 return self.__ptr 61 62 @ptrpolicy.setter 63 def ptrpolicy(self, policy): 64 self.__ptr = policy 65 66 def __bool__(self): 67 return self.__sbval.__bool__() and self._GetValueAsUnsigned() != 0 68 69 def __nonzero__(self): 70 return self.__sbval.__nonzero__() and self._GetValueAsUnsigned() != 0 71 72 def __repr__(self): 73 return self.__sbval.__str__() 74 75 # 76 # Compare operators 77 # 78 79 def __eq__(self, other): 80 self_val = self._GetValueAsUnsigned() 81 if isinstance(other, value): 82 other_val = other._GetValueAsUnsigned() 83 return self_val == other_val 84 if isinstance(other, numbers.Integral): 85 return int(self) == other 86 raise TypeError("EQ operator is not defined for this type.") 87 88 def __ne__(self, other): 89 return not self == other 90 91 def __lt__(self, other): 92 self_val = self._GetValueAsUnsigned() 93 if isinstance(other, value): 94 other_val = other._GetValueAsUnsigned() 95 return self_val < other_val 96 if isinstance(other, numbers.Integral): 97 return int(self) < int(other) 98 raise TypeError("LT operator is not defined for this type") 99 100 def __le__(self, other): 101 return self < other or self == other 102 103 def __gt__(self, other): 104 return not self <= other 105 106 def __ge__(self, other): 107 return not self < other 108 109 def __str__(self): 110 global _CSTRING_REX 111 sbv = self.__sbval 112 type_name = sbv.GetType().GetCanonicalType().GetName() 113 if len(_CSTRING_REX.findall(type_name)) > 0: 114 return self._GetValueAsString() 115 summary = sbv.GetSummary() 116 if summary: 117 return summary.strip('"') 118 return sbv.__str__() 119 120 def __getitem__(self, key): 121 # Allow array access if this value has children... 122 if type(key) is slice: 123 _start = int(key.start) 124 _end = int(key.stop) 125 _step = 1 126 if key.step is not None: 127 _step = int(key.step) 128 retval = [] 129 while _start < _end: 130 retval.append(self[_start]) 131 _start += _step 132 return retval 133 if type(key) is value: 134 key = int(key) 135 if isinstance(key, numbers.Integral): 136 sbv = self.__sbval 137 if self.__ptr: 138 sbv = self.__ptr.GetPointerSBValue(sbv) 139 child_sbvalue = sbv.GetValueForExpressionPath("[%i]" % key) 140 if child_sbvalue and child_sbvalue.IsValid(): 141 return value(child_sbvalue) 142 raise IndexError("Index '%d' is out of range" % key) 143 raise TypeError("Cannot fetch array item for key of type {}".format(str(type(key)))) 144 145 def __getattr__(self, name): 146 sbv = self.__sbval 147 if self.__ptr: 148 sbv = self.__ptr.GetPointerSBValue(sbv) 149 child_sbvalue = sbv.GetChildMemberWithName(name) 150 if child_sbvalue and child_sbvalue.IsValid(): 151 return value(child_sbvalue) 152 raise AttributeError("No field by name: " + name) 153 154 def __add__(self, other): 155 return int(self) + int(other) 156 157 def __radd__(self, other): 158 return int(self) + int(other) 159 160 def __sub__(self, other): 161 return int(self) - int(other) 162 163 def __rsub__(self, other): 164 return int(other) - int(self) 165 166 def __mul__(self, other): 167 return int(self) * int(other) 168 169 def __rmul__(self, other): 170 return int(self) * int(other) 171 172 def __floordiv__(self, other): 173 return int(self) // int(other) 174 175 def __rfloordiv__(self, other): 176 return int(other) // int(self) 177 178 def __mod__(self, other): 179 return int(self) % int(other) 180 181 def __rmod__(self, other): 182 return int(other) % int(self) 183 184 def __divmod__(self, other): 185 return divmod(int(self), int(other)) 186 187 def __rdivmod__(self, other): 188 return divmod(int(other), int(self)) 189 190 def __pow__(self, other): 191 return int(self) ** int(other) 192 193 def __lshift__(self, other): 194 return int(self) << int(other) 195 196 def __rshift__(self, other): 197 return int(self) >> int(other) 198 199 def __and__(self, other): 200 return int(self) & int(other) 201 202 def __rand__(self, other): 203 return int(other) & int(self) 204 205 def __xor__(self, other): 206 return int(self) ^ int(other) 207 208 def __or__(self, other): 209 return int(self) | int(other) 210 211 def __truediv__(self, other): 212 return int(self) / int(other) 213 214 def __rtruediv__(self, other): 215 return int(other) / int(self) 216 217 def __iadd__(self, other): 218 result = self.__add__(other) 219 self.__sbval.SetValueFromCString(str(result)) 220 return result 221 222 def __isub__(self, other): 223 result = self.__sub__(other) 224 self.__sbval.SetValueFromCString(str(result)) 225 return result 226 227 def __imul__(self, other): 228 result = self.__mul__(other) 229 self.__sbval.SetValueFromCString(str(result)) 230 return result 231 232 def __idiv__(self, other): 233 result = self.__div__(other) 234 self.__sbval.SetValueFromCString(str(result)) 235 return result 236 237 def __itruediv__(self, other): 238 result = self.__truediv__(other) 239 self.__sbval.SetValueFromCString(str(result)) 240 return result 241 242 def __ifloordiv__(self, other): 243 result = self.__floordiv__(other) 244 self.__sbval.SetValueFromCString(str(result)) 245 return result 246 247 def __imod__(self, other): 248 result = self.__mod__(other) 249 self.__sbval.SetValueFromCString(str(result)) 250 return result 251 252 def __ipow__(self, other): 253 result = self.__pow__(other) 254 self.__sbval.SetValueFromCString(str(result)) 255 return result 256 257 def __ilshift__(self, other): 258 result = self.__lshift__(other) 259 self.__sbval.SetValueFromCString(str(result)) 260 return result 261 262 def __irshift__(self, other): 263 result = self.__rshift__(other) 264 self.__sbval.SetValueFromCString(str(result)) 265 return result 266 267 def __iand__(self, other): 268 result = self.__and__(other) 269 self.__sbval.SetValueFromCString(str(result)) 270 return result 271 272 def __ixor__(self, other): 273 result = self.__xor__(other) 274 self.__sbval.SetValueFromCString(str(result)) 275 return result 276 277 def __ior__(self, other): 278 result = self.__or__(other) 279 self.__sbval.SetValueFromCString(str(result)) 280 return result 281 282 def __neg__(self): 283 return -int(self) 284 285 def __pos__(self): 286 return +int(self) 287 288 def __abs__(self): 289 return abs(int(self)) 290 291 def __invert__(self): 292 return ~int(self) 293 294 def __complex__(self): 295 return complex(int(self)) 296 297 def __int__(self): 298 sbv = self.__sbval 299 if self.__ptr: 300 sbv = self.__ptr.GetPointerSBValue(sbv) 301 302 flags = sbv.GetType().GetTypeFlags() 303 if flags & lldb.eTypeIsPointer: 304 return sbv.GetValueAsAddress() 305 if not flags & lldb.eTypeIsSigned: 306 return self._GetValueAsUnsigned() 307 308 return sbv.GetValueAsSigned() 309 310 # Python 3 conversion to int calls this. 311 def __index__(self): 312 return self.__int__() 313 314 def __long__(self): 315 sbv = self.__sbval 316 if self.__ptr: 317 sbv = self.__ptr.GetPointerSBValue(sbv) 318 319 flags = sbv.GetType().GetTypeFlags() 320 if flags & lldb.eTypeIsPointer: 321 return sbv.GetValueAsAddress() 322 if not flags & lldb.eTypeIsSigned: 323 return self._GetValueAsUnsigned() 324 325 return sbv.GetValueAsSigned() 326 327 def __float__(self): 328 return float(self.__sbval.GetValueAsSigned()) 329 330 # Python 2 must return native string. 331 def __oct__(self): 332 return '0%o' % self._GetValueAsUnsigned() 333 334 # Python 2 must return native string. 335 def __hex__(self): 336 return '0x%x' % self._GetValueAsUnsigned() 337 338 def __hash__(self): 339 return hash(self.__sbval) 340 341 def GetRawSBValue(self): 342 return self.__sbval 343 344 def GetSBValue(self): 345 sbv = self.__sbval 346 if self.__ptr: 347 sbv = self.__ptr.GetPointerSBValue(sbv) 348 349 return sbv 350 351 def __getstate__(self): 352 err = lldb.SBError() 353 sbv = self.__sbval 354 if self.__ptr: 355 sbv = self.__ptr.GetPointerSBValue(sbv) 356 addr = sbv.GetValueAsAddress() 357 size = sbv.GetType().GetPointeeType().GetByteSize() 358 else: 359 addr = sbv.GetLoadAddress() 360 size = sbv.GetType().GetByteSize() 361 362 content = sbv.GetProcess().ReadMemory(addr, size, err) 363 if err.fail: 364 content = '' 365 return content 366 367 def _GetValueAsSigned(self): 368 sbv = self.__sbval 369 if self.__ptr: 370 print("ERROR: You cannot get 'int' from pointer type %s, please use unsigned(obj) for such purposes." % sbv.GetType().GetDisplayTypeName()) 371 raise ValueError("Cannot get signed int for pointer data.") 372 serr = lldb.SBError() 373 retval = sbv.GetValueAsSigned(serr) 374 if serr.success: 375 return retval 376 raise ValueError("Failed to read signed data. {} (type = {}) Error description: {}".format( 377 str(sbv), sbv.GetType().GetDisplayTypeName(), serr.GetCString())) 378 379 def _GetValueAsCast(self, dest_type): 380 if not isinstance(dest_type, lldb.SBType): 381 raise ValueError("Invalid type for dest_type: {}".format(type(dest_type))) 382 addr = self._GetValueAsUnsigned() 383 sbval = self.__sbval.target.CreateValueFromExpression("newname", "(void *)"+str(addr)) 384 val = value(sbval.Cast(dest_type)) 385 return val 386 387 def _GetValueAsUnsigned(self): 388 sbv = self.__sbval 389 if self.__ptr: 390 sbv = self.__ptr.GetPointerSBValue(sbv) 391 return sbv.GetValueAsAddress() 392 serr = lldb.SBError() 393 retval = sbv.GetValueAsUnsigned(serr) 394 if serr.success: 395 return retval 396 raise ValueError("Failed to read unsigned data. {} (type = {}) Error description: {}".format( 397 str(sbv), sbv.GetType().GetDisplayTypeName(), serr.GetCString())) 398 399 def _GetValueAsString(self, offset=0, maxlen=1024): 400 sbv = self.__sbval 401 serr = lldb.SBError() 402 sbdata = None 403 if self.__ptr: 404 sbv = self.__ptr.GetPointerSBValue(sbv) 405 sbdata = sbv.GetPointeeData(offset, maxlen) 406 else: 407 sbdata = sbv.GetData() 408 409 retval = '' 410 bytesize = sbdata.GetByteSize() 411 if bytesize == 0: 412 # raise ValueError('Unable to read value as string') 413 return '' 414 for i in range(0, bytesize): 415 serr.Clear() 416 ch = chr(sbdata.GetUnsignedInt8(serr, i)) 417 if serr.fail: 418 raise ValueError("Unable to read string data: " + serr.GetCString()) 419 if ch == '\0': 420 break 421 retval += ch 422 return retval 423 424 def __format__(self, format_spec): 425 # typechar is last char. see http://www.python.org/dev/peps/pep-3101/ 426 typechar = format_spec[-1] if len(format_spec) else '' 427 428 if typechar in 'bcdoxX': # requires integral conversion 429 return format(int(self), format_spec) 430 431 if typechar in 'eEfFgG%': # requires float conversion 432 return format(float(self), format_spec) 433 434 if typechar in 's': # requires string conversion 435 return format(str(self), format_spec) 436 437 # 'n' or '' mean "whatever you got for me" 438 flags = self.__sbval.GetType().GetTypeFlags() 439 if flags & lldb.eTypeIsFloat: 440 return format(float(self), format_spec) 441 elif flags & lldb.eTypeIsScalar: 442 return format(int(self), format_spec) 443 else: 444 return format(str(self), format_spec) 445 446def unsigned(val): 447 """ Helper function to get unsigned value from core.value 448 params: val - value (see value class above) representation of an integer type 449 returns: int which is unsigned. 450 raises : ValueError if the type cannot be represented as unsigned int. 451 """ 452 if type(val) is value: 453 return int(val._GetValueAsUnsigned()) 454 return int(val) 455 456 457def signed(val): 458 """ Helper function to get signed value from core.value 459 params: val - value (see value class above) representation of an integer type 460 returns: int which is signed. 461 raises: ValueError if the type cannot be represented as signed int. 462 """ 463 if type(val) is value: 464 return val.GetSBValue().GetValueAsSigned() 465 return int(val) 466 467 468def sizeof(t): 469 """ Find the byte size of a type. 470 params: t - str : ex 'time_spec' returns equivalent of sizeof(time_spec) in C 471 t - value: ex a value object. returns size of the object 472 returns: int - byte size length 473 """ 474 if type(t) is value: 475 return t.GetSBValue().GetByteSize() 476 if isinstance(t, str): 477 return gettype(t).GetByteSize() 478 raise ValueError("Cannot get sizeof. Invalid argument") 479 480 481def dereference(val): 482 """ Get a dereferenced obj for a pointer type obj 483 params: val - value object representing a pointer type C construct in lldb 484 returns: value - value 485 ex. val = dereference(ptr_obj) #python 486 is same as 487 obj_ptr = (int *)0x1234 #C 488 val = *obj_ptr #C 489 """ 490 if type(val) is value: 491 sbv = val.GetSBValue() 492 return value(sbv.Dereference()) 493 raise TypeError('Cannot dereference this type.') 494 495 496def wrapped(val): 497 """ Get original pointer value without aplying pointer policy. 498 param: val - value object representing a pointer 499 returns: value - value 500 """ 501 if isinstance(val, value): 502 policy = val.ptrpolicy 503 val.ptrpolicy = None 504 newval = value(val.GetSBValue(), False) 505 val.ptrpolicy = policy 506 return newval 507 raise TypeError("Cannot do wrapped for non-value type objects") 508 509 510def addressof(val): 511 """ Get address of a core.value object. 512 params: val - value object representing a C construct in lldb 513 returns: value - value object referring to 'type(val) *' type 514 ex. addr = addressof(hello_obj) #python 515 is same as 516 uintptr_t addr = (uintptr_t)&hello_obj #C 517 """ 518 if type(val) is value: 519 return value(val.GetSBValue().AddressOf()) 520 raise TypeError("Cannot do addressof for non-value type objects") 521 522 523def cast(obj, target_type): 524 """ Type cast an object to another C type. 525 params: 526 obj - core.value object representing some C construct in lldb 527 target_type - str : ex 'char *' 528 - lldb.SBType : 529 """ 530 dest_type = target_type 531 if isinstance(target_type, str): 532 dest_type = gettype(target_type) 533 elif type(target_type) is value: 534 dest_type = target_type.GetSBValue().GetType() 535 536 if type(obj) is value: 537 return obj._GetValueAsCast(dest_type) 538 elif type(obj) is int: 539 print("ERROR: You cannot cast an 'int' to %s, please use kern.GetValueFromAddress() for such purposes." % str(target_type)) 540 raise TypeError("object of type %s cannot be casted to %s" % (str(type(obj)), str(target_type))) 541 542 543def containerof(obj, target_type, field_name): 544 """ Type cast an object to another C type from a pointer to a field. 545 params: 546 obj - core.value object representing some C construct in lldb 547 target_type - str : ex 'struct thread' 548 - lldb.SBType : 549 field_name - the field name within the target_type obj is a pointer to 550 """ 551 addr = int(obj) - getfieldoffset(target_type, field_name) 552 sbv = obj.GetSBValue() 553 sbv = sbv.chkCreateValueFromAddress(None, addr, gettype(target_type)) 554 return value(sbv.AddressOf()) 555 556 557@cache_statically 558def gettype(target_type, target=None): 559 """ Returns lldb.SBType of the given target_type 560 params: 561 target_type - str, ex. 'char', 'uint32_t' etc 562 returns: 563 lldb.SBType - SBType corresponding to the given target_type 564 raises: 565 NameError - Incase the type is not identified 566 """ 567 568 # 569 # If the type was qualified with a `struct` or `class`, ... 570 # make sure we pick up the proper definition in case of clashes. 571 # 572 want = 0 573 name = str(target_type).strip() 574 575 if name.startswith("struct"): 576 want = lldb.eTypeClassStruct 577 elif name.startswith("union"): 578 want = lldb.eTypeClassUnion 579 elif name.startswith("class"): 580 want = lldb.eTypeClassClass 581 elif name.startswith("enum"): 582 want = lldb.eTypeClassEnumeration 583 elif name.startswith("typedef"): 584 want = lldb.eTypeClassTypedef 585 586 # 587 # Now remove constness and speficiers, and pointers 588 # 589 tmpname = re.sub(r'\bconst\b', '', name).strip(" ") 590 tmpname = re.sub(r'^(struct|class|union|enum|typedef) ', '', tmpname) 591 basename = tmpname.rstrip(" *") 592 ptrlevel = tmpname.count('*', len(basename)) 593 594 def resolve_pointee_type(t: lldb.SBType): 595 while t.IsPointerType(): 596 t = t.GetPointeeType() 597 return t 598 599 def type_sort_heuristic(t: lldb.SBType) -> int: 600 """ prioritizes types with more fields, and prefers fields with complete 601 types 602 params: 603 t - lldb.SBType, type to score 604 returns: 605 int - heuristic score 606 """ 607 # we care about the underlying type, not the pointer 608 resolved_type: lldb.SBType = resolve_pointee_type(t) 609 610 # heuristic score 611 score = 0 612 for field in resolved_type.fields: 613 resolved_field_type = resolve_pointee_type(field.GetType()) 614 score += 3 if resolved_field_type.IsTypeComplete() else 1 615 616 return score 617 618 type_arr = [t for t in target.chkFindTypes(basename)] 619 # After the sort, the best matching struct will be at index [0]. 620 # This heuristic selects a struct type with more fields (with complete types) 621 # compared to ones with "opaque" members 622 type_arr.sort(reverse=True, key=type_sort_heuristic) 623 624 for tyobj in type_arr: 625 if want and tyobj.GetTypeClass() != want: 626 continue 627 628 for _ in range(ptrlevel): 629 tyobj = tyobj.GetPointerType() 630 631 return tyobj 632 633 raise NameError('Unable to find type {}'.format(target_type)) 634 635 636@cache_statically 637def getfieldoffset(struct_type, field_name_or_path, target=None): 638 """ Returns the byte offset of a field inside a given struct 639 Understands anonymous unions and field names in sub-structs 640 params: 641 field_name_or_path - str, name or path to the field inside the struct ex. 'ip_messages' 642 returns: 643 int - byte offset of the field_name inside the struct_type 644 """ 645 646 return gettype(struct_type).xGetFieldOffset(field_name_or_path) 647 648 649def islong(x): 650 """ Returns True if a string represents a long integer, False otherwise 651 """ 652 try: 653 int(x, 16) 654 except ValueError: 655 try: 656 int(x) 657 except ValueError: 658 return False 659 return True 660 661 662def readmemory(val): 663 """ Returns a string of hex data that is referenced by the value. 664 params: val - a value object. 665 return: str - string of hex bytes. 666 raises: TypeError if val is not a valid type 667 """ 668 if not type(val) is value: 669 raise TypeError('%s is not of type value' % str(type(val))) 670 return val.__getstate__() 671 672 673def getOSPtr(cpp_obj): 674 """ Returns a core.value created from an intrusive_shared_ptr or itself, cpp_obj 675 params: cpp_obj - core.value object representing a C construct in lldb 676 return: core.value - newly created core.value or cpp_obj 677 """ 678 child = cpp_obj.GetSBValue().GetChildAtIndex(0) 679 if 'intrusive_shared_ptr' in str(child): 680 return value(child.GetChildMemberWithName('ptr_')) 681 return cpp_obj 682