1 2class Region: 3 """ 4 A region of memory that is mapped in the object's file. 5 6 :ivar offset: The offset into the file the region starts. 7 :ivar vaddr: The virtual address. 8 :ivar filesize: The size of the region in the file. 9 :ivar memsize: The size of the region when loaded into memory. 10 11 The prefix `v-` on a variable or parameter name indicates that it refers to the virtual, loaded memory space, 12 while a corresponding variable without the `v-` refers to the flat zero-based memory of the file. 13 14 When used next to each other, `addr` and `offset` refer to virtual memory address and file offset, respectively. 15 """ 16 17 vaddr: int 18 memsize: int 19 filesize: int 20 21 def __init__(self, offset, vaddr, filesize, memsize): 22 self.vaddr = vaddr 23 self.memsize = memsize 24 self.filesize = filesize 25 self.offset = offset 26 27 def _rebase(self, delta): 28 """ 29 Does region rebasing to other base address. 30 Intended for usage by loader's add_object to reflect the rebasing. 31 32 :param int delta: Delta offset between an old and a new image bases 33 """ 34 self.vaddr += delta 35 36 def contains_addr(self, addr): 37 """ 38 Does this region contain this virtual address? 39 """ 40 return self.vaddr <= addr < self.vaddr + self.memsize 41 42 def contains_offset(self, offset): 43 """ 44 Does this region contain this offset into the file? 45 """ 46 return self.offset <= offset < self.offset + self.filesize 47 48 def addr_to_offset(self, addr): 49 """ 50 Convert a virtual memory address into a file offset 51 """ 52 offset = addr - self.vaddr + self.offset 53 if not self.contains_offset(offset): 54 return None 55 return offset 56 57 def offset_to_addr(self, offset): 58 """ 59 Convert a file offset into a virtual memory address 60 """ 61 addr = offset - self.offset + self.vaddr 62 if not self.contains_addr(addr): 63 return None 64 return addr 65 66 def __repr__(self): 67 return '<{} {}>'.format(self.__class__.__name__, ', '.join(['{}=0x{:x}'.format(k, v) for k, v in self.__dict__.items()])) 68 69 @property 70 def max_addr(self): 71 """ 72 The maximum virtual address of this region 73 """ 74 return self.vaddr + self.memsize - 1 75 76 @property 77 def min_addr(self): 78 """ 79 The minimum virtual address of this region 80 """ 81 return self.vaddr 82 83 @property 84 def max_offset(self): 85 """ 86 The maximum file offset of this region 87 """ 88 return self.offset + self.filesize - 1 89 90 def min_offset(self): 91 """ 92 The minimum file offset of this region 93 """ 94 return self.offset 95 96 # EDG says: Blobs now have segments, and SimOS will get upset if these don't exist. See simos.py line 107 for 97 # some code you should probably fix if you don't like it. 98 def is_readable(self): 99 # pylint: disable=no-self-use 100 return True 101 102 def is_writable(self): 103 # pylint: disable=no-self-use 104 return True 105 106 def is_executable(self): 107 # pylint: disable=no-self-use 108 return True 109 110class Segment(Region): 111 pass 112 113 114class EmptySegment(Segment): 115 """ 116 A segment with no static content, and permissions 117 """ 118 119 def __init__(self, vaddr, memsize, is_readable=True, is_writable=True, is_executable=False): 120 super().__init__(0, vaddr, 0, memsize) 121 self._is_readable = is_readable 122 self._is_writable = is_writable 123 self._is_executable = is_executable 124 125 @property 126 def is_executable(self): 127 return self._is_executable 128 129 @property 130 def is_writable(self): 131 return self._is_writable 132 133 @property 134 def is_readable(self): 135 return self._is_readable 136 137 @property 138 def only_contains_uninitialized_data(self): 139 """ 140 Whether this section is initialized to zero after the executable is loaded. 141 """ 142 return True 143 144 145class Section(Region): 146 """ 147 Simple representation of a loaded section. 148 149 :ivar str name: The name of the section 150 """ 151 def __init__(self, name, offset, vaddr, size): 152 """ 153 :param str name: The name of the section 154 :param int offset: The offset into the binary file this section begins 155 :param int vaddr: The address in virtual memory this section begins 156 :param int size: How large this section is 157 """ 158 super().__init__(offset, vaddr, size, size) 159 self.name = name 160 161 @property 162 def is_readable(self): 163 """ 164 Whether this section has read permissions 165 """ 166 raise NotImplementedError() 167 168 @property 169 def is_writable(self): 170 """ 171 Whether this section has write permissions 172 """ 173 raise NotImplementedError() 174 175 @property 176 def is_executable(self): 177 """ 178 Whether this section has execute permissions 179 """ 180 raise NotImplementedError() 181 182 @property 183 def only_contains_uninitialized_data(self): 184 """ 185 Whether this section is initialized to zero after the executable is loaded. 186 """ 187 raise NotImplementedError() 188 189 def __repr__(self): 190 return "<%s | offset %#x, vaddr %#x, size %#x>" % ( 191 self.name if self.name else "Unnamed", 192 self.offset, 193 self.vaddr, 194 self.memsize 195 ) 196