Пример #1
0
def save_to_stream(output_stream):
    mod = CFG_pb2.Module()
    num_subs, num_blocks, num_insts = 0, 0, 0

    exclude_blocks = set()
    for sub in program.subroutines():
        num_subs += 1
        if program.Subroutine.VISIBILITY_IMPORTED == sub.visibility:
            exclude_blocks.update(sub.blocks)

    log.debug("Not serializing {} blocks".format(len(exclude_blocks)))

    referenced_blocks = set()
    for block in program.basic_blocks():
        if block in exclude_blocks:
            continue

        if not len(block.instructions):
            referenced_blocks.add(block)
            continue

        num_blocks += 1

        log.info("Serializing block {:08x}.".format(block.ea))
        b = mod.blocks.add()
        b.address = block.ea
        b.is_addressable = block.address_is_taken

        for inst in block:
            i = b.instructions.add()
            i.address = inst.ea
            i.bytes = inst.bytes
            num_insts += 1

    for block in referenced_blocks:
        mod.referenced_blocks.add(block.ea)

    for sub in program.subroutines():
        if not sub.name:
            continue

        if program.Subroutine.VISIBILITY_INTERNAL == sub.visibility:
            continue

        nb = mod.named_blocks.add()
        nb.name = sub.name
        nb.address = sub.ea

        if program.Subroutine.VISIBILITY_IMPORTED == sub.visibility:
            nb.visibility = CFG_pb2.IMPORTED
        elif program.Subroutine.VISIBILITY_EXPORTED == sub.visibility:
            nb.visibility = CFG_pb2.EXPORTED

    log.info("Serializing {} subroutines".format(num_subs))
    log.info("Serializing {} blocks".format(num_blocks))
    log.info("Serializing {} instructions".format(num_insts))
    output_stream.write(mod.SerializeToString())
Пример #2
0
def analyse_function_returns():
    """Find all function call instructions, and mark the blocks associated
  with their return addresses as having their addresses taken."""
    log.info("Analysing targets of function call return instructions")
    for block in program.basic_blocks():
        term_inst = block.terminator
        if not term_inst or not term_inst.is_function_call():
            continue
        return_target_block = program.get_basic_block(term_inst.next_ea)
        return_target_block.address_is_taken = True
Пример #3
0
def analyse_function_returns():
  """Find all function call instructions, and mark the blocks associated
  with their return addresses as having their addresses taken."""
  log.info("Analysing targets of function call return instructions")
  for block in program.basic_blocks():
    term_inst = block.terminator
    if not term_inst or not term_inst.is_function_call():
      continue
    return_target_block = program.get_basic_block(term_inst.next_ea)
    return_target_block.address_is_taken = True
Пример #4
0
def analyse_indirect_jumps():
    """Scan through the code looking for jump tables."""
    log.info("Analysing indirect jump instructions")
    blocks = set(program.basic_blocks())
    seen = set()
    while len(blocks):
        block = blocks.pop()
        if block in seen:
            continue

        seen.add(block)
        term_inst = block.terminator
        if term_inst.is_indirect_jump():
            analyse_indirect_jump(block, term_inst, blocks)
Пример #5
0
def analyse_indirect_jumps():
  """Scan through the code looking for jump tables."""
  log.info("Analysing indirect jump instructions")
  blocks = set(program.basic_blocks())
  seen = set()
  while len(blocks):
    block = blocks.pop()
    if block in seen:
      continue

    seen.add(block)
    term_inst = block.terminator
    if term_inst.is_indirect_jump():
      analyse_indirect_jump(block, term_inst, blocks)
Пример #6
0
def analyse_callbacks():
    """Analyse functions that are used as callbacks."""
    global POSSIBLE_CODE_REFS
    log.info("Analysing callbacks")
    for ea in POSSIBLE_CODE_REFS:
        if program.has_basic_block(ea):
            block = program.get_basic_block(ea)
            if not block.address_is_taken:
                block.address_is_taken = True
                log.info("Block {:08x} is a callback".format(ea))

    for block in program.basic_blocks():
        if not block.address_is_taken:
            if len(tuple(idautils.DataRefsTo(block.ea))):
                block.address_is_taken = True
                log.info("Block {:08x} is a callback".format(block.ea))
Пример #7
0
def analyse_callbacks():
  """Analyse functions that are used as callbacks."""
  global POSSIBLE_CODE_REFS
  log.info("Analysing callbacks")
  for ea in POSSIBLE_CODE_REFS:
    if program.has_basic_block(ea):
      block = program.get_basic_block(ea)
      if not block.address_is_taken:
        block.address_is_taken = True
        log.info("Block {:08x} is a callback (1)".format(ea))

  for block in program.basic_blocks():
    if not block.address_is_taken:
      if len(tuple(idautils.DataRefsTo(block.ea))):
        block.address_is_taken = True
        log.info("Block {:08x} is a callback (2)".format(block.ea))
Пример #8
0
def save_to_stream(output_stream):
  mod = CFG_pb2.Module()
  num_subs, num_blocks, num_insts = 0, 0, 0

  exclude_blocks = set()
  for sub in program.subroutines():
    num_subs += 1
    if program.Subroutine.VISIBILITY_IMPORTED == sub.visibility:
      exclude_blocks.update(sub.blocks)

  log.debug("Not serializing {} blocks".format(len(exclude_blocks)))

  referenced_blocks = set()
  addressed_blocks = set()
  for block in program.basic_blocks():
    if block in exclude_blocks:
      continue

    if not len(block.instructions):
      referenced_blocks.add(block)
      log.error("Block {:08x} has no instructions.".format(block.ea))
      continue

    num_blocks += 1

    log.info("Serializing block {:08x}.".format(block.ea))
    b = mod.blocks.add()
    b.address = block.ea
    
    if block.address_is_taken:
      addressed_blocks.add(block)

    for inst in block:
      i = b.instructions.add()
      i.address = inst.ea
      i.bytes = inst.bytes
      num_insts += 1

  for block in addressed_blocks:
    mod.addressed_blocks.append(block.ea)

  for block in referenced_blocks:
    mod.referenced_blocks.append(block.ea)

  for sub in program.subroutines():
    if not sub.name:
      continue

    if program.Subroutine.VISIBILITY_INTERNAL == sub.visibility:
      continue

    nb = mod.named_blocks.add()
    nb.name = sub.name
    nb.address = sub.ea

    if program.Subroutine.VISIBILITY_IMPORTED == sub.visibility:
      nb.visibility = CFG_pb2.IMPORTED
    elif program.Subroutine.VISIBILITY_EXPORTED == sub.visibility:
      nb.visibility = CFG_pb2.EXPORTED

  log.info("Serializing {} subroutines".format(num_subs))
  log.info("Serializing {} blocks".format(num_blocks))
  log.info("Serializing {} instructions".format(num_insts))
  output_stream.write(mod.SerializeToString())