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