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