示例#1
0
 def crunch_entry_push(self, op):
     """Crunch amd64/ia32 push directives from given line listing."""
     lst = self.want_label(op)
     if not lst:
         return
     ii = lst[0] + 1
     jj = ii
     stack_decrement = 0
     reinstated_lines = []
     while True:
         current_line = self.__content[jj]
         match = re.match(r'\s*(push\w).*%(\w+)', current_line,
                          re.IGNORECASE)
         if match:
             stack_decrement += get_push_size(match.group(1))
             jj += 1
             continue
         # Preserve comment lines as they are.
         match = re.match(r'^\s*[#;].*', current_line, re.IGNORECASE)
         if match:
             reinstated_lines += [current_line]
             jj += 1
             continue
         # Some types of lines can be in the middle of pushing.
         if is_reinstate_line(current_line):
             reinstated_lines += [current_line]
             jj += 1
             continue
         # Stop at stack decrement.
         match = re.match(r'\s*sub.*\s+[^\d]*(\d+),\s*%(rsp|esp)',
                          current_line, re.IGNORECASE)
         if match:
             # Align to 16 bytes if necessary.
             if osname_is_linux() and osarch_is_64_bit():
                 if osarch_is_amd64():
                     # Just ignore increment, there's probably enough stack.
                     self.__content[jj] = re.sub(
                         r'subq(\s*).*',
                         r'andq\g<1>$0xFFFFFFFFFFFFFFF0, %rsp',
                         current_line)
                 else:
                     raise RuntimeError(
                         "no stack alignment instruction for current architecture"
                     )
             else:
                 total_decrement = int(match.group(1)) + stack_decrement
                 self.__content[jj] = re.sub(r'\d+', str(total_decrement),
                                             current_line)
             break
         # Do nothing if suspicious instruction is found.
         if is_verbose():
             print(
                 "Unknown header instruction found, aborting erase: '%s'" %
                 (current_line.strip()))
         break
     if is_verbose():
         print("Erasing function header from '%s': %i lines" %
               (op, jj - ii - len(reinstated_lines)))
     self.__content[ii:jj] = reinstated_lines
示例#2
0
 def add_symbol_empty(self):
     """Add an empty symbol."""
     if osarch_is_32_bit():
         self.add_data(("empty symbol", 4, (0, 0, 0, 0)))
     elif osarch_is_64_bit():
         self.add_data(("empty symbol", 4, (0, 0)))
         self.add_data(("empty symbol", PlatformVar("addr"), (0, 0)))
     else:
         raise_unknown_address_size()
示例#3
0
 def add_symbol_empty(self):
   """Add an empty symbol."""
   if osarch_is_32_bit():
     self.add_data(("empty symbol", 4, (0, 0, 0, 0)))
   elif osarch_is_64_bit():
     self.add_data(("empty symbol", 4, (0, 0)))
     self.add_data(("empty symbol", PlatformVar("addr"), (0, 0)))
   else:
     raise_unknown_address_size()
示例#4
0
 def crunch_entry_push(self, op):
     """Crunch amd64/ia32 push directives from given line listing."""
     lst = self.want_label(op)
     if not lst:
         return
     ii = lst[0] + 1
     jj = ii
     stack_decrement = 0
     reinstated_lines = []
     while True:
         current_line = self.__content[jj]
         match = re.match(r'\s*(push\w).*%(\w+)', current_line, re.IGNORECASE)
         if match:
             stack_decrement += get_push_size(match.group(1))
             jj += 1
             continue
         # Preserve comment lines as they are.
         match = re.match(r'^\s*[#;].*', current_line, re.IGNORECASE)
         if match:
             reinstated_lines += [current_line]
             jj += 1
             continue
         # Some types of lines can be in the middle of pushing.
         if is_reinstate_line(current_line):
             reinstated_lines += [current_line]
             jj += 1
             continue
         # Stop at stack decrement.
         match = re.match(r'\s*sub.*\s+[^\d]*(\d+),\s*%(rsp|esp)', current_line, re.IGNORECASE)
         if match:
             total_decrement = int(match.group(1)) + stack_decrement
             # As per gcc ABI, align to 16 bytes on 64-bit architectures.
             if osarch_is_64_bit() and ((total_decrement & 0xF) != 0):
                 total_decrement += 0x10 - (total_decrement & 0xF)
             self.__content[jj] = re.sub(r'\d+', str(total_decrement), current_line)
             break
         # Do nothing if suspicious instruction is found.
         if is_verbose():
             print("Unknown header instruction found, aborting erase: '%s'" % (current_line.strip()))
         break
     if is_verbose():
         print("Erasing function header from '%s': %i lines" % (op, jj - ii - len(reinstated_lines)))
     self.__content[ii:jj] = reinstated_lines
示例#5
0
 def add_symbol_und(self, name):
     """Add a symbol to satisfy UND from external source."""
     label_name = "symtab_" + name
     if osarch_is_32_bit():
         self.add_data(("st_name", 4, "strtab_%s - strtab" % (name)))
         self.add_data(("st_value", PlatformVar("addr"), label_name, label_name))
         self.add_data(("st_size", PlatformVar("addr"), PlatformVar("addr")))
         self.add_data(("st_info", 1, 17))
         self.add_data(("st_other", 1, 0))
         self.add_data(("st_shndx", 2, 1))
     elif osarch_is_64_bit():
         self.add_data(("st_name", 4, "strtab_%s - strtab" % (name)))
         self.add_data(("st_info", 1, 17))
         self.add_data(("st_other", 1, 0))
         self.add_data(("st_shndx", 2, 1))
         self.add_data(("st_value", PlatformVar("addr"), label_name, label_name))
         self.add_data(("st_size", PlatformVar("addr"), PlatformVar("addr")))
     else:
         raise_unknown_address_size()
示例#6
0
 def add_symbol_und(self, name):
   """Add a symbol to satisfy UND from external source."""
   label_name = "symtab_" + name
   if osarch_is_32_bit():
     self.add_data(("st_name", 4, "strtab_%s - strtab" % (name)))
     self.add_data(("st_value", PlatformVar("addr"), label_name, label_name))
     self.add_data(("st_size", PlatformVar("addr"), PlatformVar("addr")))
     self.add_data(("st_info", 1, 17))
     self.add_data(("st_other", 1, 0))
     self.add_data(("st_shndx", 2, 1))
   elif osarch_is_64_bit():
     self.add_data(("st_name", 4, "strtab_%s - strtab" % (name)))
     self.add_data(("st_info", 1, 17))
     self.add_data(("st_other", 1, 0))
     self.add_data(("st_shndx", 2, 1))
     self.add_data(("st_value", PlatformVar("addr"), label_name, label_name))
     self.add_data(("st_size", PlatformVar("addr"), PlatformVar("addr")))
   else:
     raise_unknown_address_size()