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
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()
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
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()