예제 #1
0
def get_info():
    res = gdb.execute("maintenance info sections ?", to_string=True)
    bin_name = os.path.basename(h.build_bin_name(res))
    if not bin_name:
        raise("get_info: failed to find bin name")
    return bin_name
예제 #2
0
def hunt(symbols, dbname, merge=True, replace=False, bin_name="lina"):
    if bin_name == "lina":
        base_name = "lina_imagebase"
        addr_name = "addresses"
    elif bin_name == "lina_monitor":
        base_name = "lm_imagebase"
        addr_name = "lm_addresses"
    elif bin_name == "libc.so":
        base_name = "libc_imagebase"
        addr_name = "libc_addresses"
    else:
        logmsg("ERROR: bad elf name in hunt()")
        return None

    # parse version/fw from directory name
    idbdir = idautils.GetIdbDir()
    version = helper.build_version(idbdir)
    if not version:
        logmsg("Can't parse version in %s" % idbdir)
        sys.exit()
    fw = helper.build_bin_name(idbdir)
    if not fw:
        logmsg("Can't parse fw in %s" % idbdir)
        sys.exit()

    new_target = {}
    new_target["fw"] = fw
    new_target["arch"] = ida_helper.ARCHITECTURE
    # by default we don't know the imagebase so we will save
    # absolute addresses in new_target[addr_name]
    new_target[base_name] = 0
    # XXX - add fw md5 to db?

    prevtime = time.time()
    lock = filelock.FileLock("asadb.json")
    with lock.acquire():
        newtime = time.time()
        logmsg("Acquired lock after %d seconds" % int(newtime - prevtime))

        # load old targets
        targets = []
        if os.path.isfile(dbname):
            targets = helper.load_targets(dbname)
        else:
            logmsg("Creating new db: %s" % dbname)
        #logmsg("Existing targets:")
        #logmsg(targets)

        # Building new entry
        new_target["version"] = version
        addresses = {}
        for s, func in symbols.items():
            if not s:
                continue
            name = s
            if name.startswith("instruction_"):
                name = s[len("instruction_"):]
            # addr can actually be an address but also an offset we need
            # (e.g. tls->default_channel)...
            logmsg("Looking up %s" % s)
            addr = func(s)
            # we check both as we never want to add a -1 symbol and sometimes
            # the architecture detected is wrong and we ended up saving -1 :|
            if addr == 0xffffffffffffffff or addr == 0xffffffff or addr == None:
                logmsg("[x] Impossible to get '%s' symbol" % name)
                continue
            #logmsg("%s = 0x%x (%s)" % (name, addr, type(addr)))
            addresses[name] = addr
        #logmsg(addresses)
        new_target[addr_name] = addresses

        if helper.is_new(targets, new_target):
            logmsg("New target: %s (%s)" % (version, fw))
            logmsg(addresses)
            targets.append(new_target)
        elif merge == True:
            logmsg("Merging target: %s (%s)" % (version, fw))
            i = helper.merge_target(new_target, targets, bin_name=bin_name)
            if i != None:
                print(json.dumps(targets[i], indent=2))


#               print(targets[i])
            else:
                logmsg(
                    "Skipping target: %s (%s) as helper.merge_target() failed"
                    % (version, fw))
        elif replace == True:
            logmsg("Replacing target: %s (%s)" % (version, fw))
            helper.replace_target(new_target, targets)
            logmsg(new_target)
        else:
            logmsg("Skipping target: %s (%s)" % (version, fw))
        # sort targets by version. Drawback: index changes each time we add
        # a new firmware but it should not anymore once we have them all
        targets = sorted(targets,
                         key=lambda k: map(int, k["version"].split(".")))

        logmsg("Writing to %s" % dbname)
        open(dbname, "wb").write(json.dumps(targets, indent=4))