示例#1
0
def BuildIdFromElf(elf_path, tool_prefix):
    """Returns the Build ID for the given binary."""
    args = [path_util.GetReadElfPath(tool_prefix), '-n', elf_path]
    stdout = subprocess.check_output(args, encoding='ascii')
    match = re.search(r'Build ID: (\w+)', stdout)
    assert match, 'Build ID not found from running: ' + ' '.join(args)
    return match.group(1)
示例#2
0
def CollectRelocationAddresses(elf_path, tool_prefix):
    """Returns the list of addresses that are targets for relative relocations."""
    cmd = [path_util.GetReadElfPath(tool_prefix), '--relocs', elf_path]
    ret = subprocess.check_output(cmd, encoding='ascii').splitlines()
    # Grab first column from (sample output) '02de6d5c  00000017 R_ARM_RELATIVE'
    return [
        int(l.split(maxsplit=1)[0], 16) for l in ret if 'R_ARM_RELATIVE' in l
    ]
示例#3
0
def _SectionSizesFromElf(elf_path, tool_prefix):
  args = [path_util.GetReadElfPath(tool_prefix), '-S', '--wide', elf_path]
  stdout = subprocess.check_output(args)
  section_sizes = {}
  # Matches  [ 2] .hash HASH 00000000006681f0 0001f0 003154 04   A  3   0  8
  for match in re.finditer(r'\[[\s\d]+\] (\..*)$', stdout, re.MULTILINE):
    items = match.group(1).split()
    section_sizes[items[0]] = int(items[4], 16)
  return section_sizes
示例#4
0
def LookupElfRodataInfo(elf_path, tool_prefix):
    """Returns (address, offset, size) for the .rodata section."""
    args = [path_util.GetReadElfPath(tool_prefix), '-S', '--wide', elf_path]
    output = subprocess.check_output(args)
    lines = output.splitlines()
    for line in lines:
        # [Nr] Name           Type        Addr     Off     Size   ES Flg Lk Inf Al
        # [07] .rodata        PROGBITS    025e7000 237c000 5ec4f6 00   A  0   0 256
        if '.rodata ' in line:
            fields = line[line.index(models.SECTION_RODATA):].split()
            return int(fields[2], 16), int(fields[3], 16), int(fields[4], 16)
    raise AssertionError('No .rodata for command: ' + repr(args))
示例#5
0
def _ArchFromElf(elf_path, tool_prefix):
  args = [path_util.GetReadElfPath(tool_prefix), '-h', elf_path]
  stdout = subprocess.check_output(args)
  machine = re.search('Machine:\s*(.+)', stdout).group(1)
  if machine == 'Intel 80386':
    return 'x86'
  if machine == 'Advanced Micro Devices X86-64':
    return 'x64'
  elif machine == 'ARM':
    return 'arm'
  elif machine == 'AArch64':
    return 'arm64'
  return machine
示例#6
0
def SectionInfoFromElf(elf_path, tool_prefix):
    """Finds the address and size of all ELF sections

  Returns:
    A dict of section_name->(start_address, size).
  """
    args = [path_util.GetReadElfPath(tool_prefix), '-S', '--wide', elf_path]
    stdout = subprocess.check_output(args, encoding='ascii')
    section_ranges = {}
    # Matches  [ 2] .hash HASH 00000000006681f0 0001f0 003154 04   A  3   0  8
    for match in re.finditer(r'\[[\s\d]+\] (\..*)$', stdout, re.MULTILINE):
        items = match.group(1).split()
        section_ranges[items[0]] = (int(items[2], 16), int(items[4], 16))
    return section_ranges
示例#7
0
def ArchFromElf(elf_path, tool_prefix):
    """Returns the GN architecture for the given binary."""
    args = [path_util.GetReadElfPath(tool_prefix), '-h', elf_path]
    stdout = subprocess.check_output(args, encoding='ascii')
    machine = re.search('Machine:\s*(.+)', stdout).group(1)
    if machine == 'Intel 80386':
        return 'x86'
    if machine == 'Advanced Micro Devices X86-64':
        return 'x64'
    elif machine == 'ARM':
        return 'arm'
    elif machine == 'AArch64':
        return 'arm64'
    return machine
def _LookupStringSectionPositions(target, tool_prefix, output_directory):
    """Returns a dict of object_path -> [(offset, size)...] of .rodata sections.

  Args:
    target: An archive path string (e.g., "foo.a") or a list of object paths.
  """
    is_archive = isinstance(target, str)
    args = [path_util.GetReadElfPath(tool_prefix), '-S', '--wide']
    if is_archive:
        args.append(target)
    else:
        # Assign path for when len(target) == 1, (no File: line exists).
        path = target[0]
        args.extend(target)

    output = subprocess.check_output(args,
                                     cwd=output_directory).decode('ascii')
    lines = output.splitlines()
    section_positions_by_path = {}
    cur_offsets = []
    for line in lines:
        # File: base/third_party/libevent/libevent.a(buffer.o)
        # [Nr] Name              Type        Addr     Off    Size   ES Flg Lk Inf Al
        # [11] .rodata.str1.1    PROGBITS    00000000 0000b4 000004 01 AMS  0   0  1
        # [11] .rodata.str4.4    PROGBITS    00000000 0000b4 000004 01 AMS  0   0  4
        # [11] .rodata.str8.8    PROGBITS    00000000 0000b4 000004 01 AMS  0   0  8
        # [80] .rodata..L.str    PROGBITS    00000000 000530 000002 00   A  0   0  1
        # The various string sections differ by alignment.
        # The presence of a wchar_t literal (L"asdf") seems to make a str4 section.
        # When multiple sections exist, nm gives us no indication as to which
        # section each string corresponds to.
        if line.startswith('File: '):
            if cur_offsets:
                section_positions_by_path[path] = cur_offsets
                cur_offsets = []
            path = line[6:]
        elif '.rodata.' in line:
            progbits_idx = line.find('PROGBITS ')
            if progbits_idx != -1:
                fields = line[progbits_idx:].split()
                position = (int(fields[2], 16), int(fields[3], 16))
                # The heuristics in _IterStringLiterals rely on str1 coming first.
                if fields[-1] == '1':
                    cur_offsets.insert(0, position)
                else:
                    cur_offsets.append(position)
    if cur_offsets:
        section_positions_by_path[path] = cur_offsets
    return section_positions_by_path
示例#9
0
def BuildIdFromElf(elf_path, tool_prefix):
  args = [path_util.GetReadElfPath(tool_prefix), '-n', elf_path]
  stdout = subprocess.check_output(args)
  match = re.search(r'Build ID: (\w+)', stdout)
  assert match, 'Build ID not found from running: ' + ' '.join(args)
  return match.group(1)