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