def memToLvl(address, levelId = None): refTableAddr = idc.LocByName("levelReferenceTable") if refTableAddr == BADADDR: print("Can't get level reference table address. Make sure its name is levelReferenceTable.") return if levelId == None: endTableAddr = idc.LocByName("levelEndTable") if endTableAddr == BADADDR: print("Can't get level end table address. Make sure its name is levelEndTable.") return lvl0StartAddr = idc.Dword(refTableAddr) lvl1StartAddr = idc.Dword(refTableAddr + 4) lvl0EndAddr = idc.Dword(endTableAddr) lvl1EndAddr = idc.Dword(endTableAddr + 4) if address >= lvl0StartAddr and address <= lvl0EndAddr: fileRelativeAddr = address - lvl0StartAddr idc.Message("Fix.lvl relative address: 0x" + format(fileRelativeAddr, '02X') + "\n") return if address >= lvl1StartAddr and address <= lvl1EndAddr: fileRelativeAddr = address - lvl1StartAddr idc.Message("Actual level relative address: 0x" + format(fileRelativeAddr, '02X') + "\n") return idc.Message("ERROR: This address does not belong to any level file.") else: lvlStartAddr = idc.Dword(refTableAddr + levelId * 4) fileRelativeAddr = address - lvlStartAddr idc.Message("Address relative to file: 0x" + format(fileRelativeAddr, '02X') + "\n")
def toggle_auto_rebase_push(self, *args): if self.repo_manager.repo_auto_sync: self.repo_manager.repo_auto_sync = False idc.Message('Auto rebase/push disabled') else: self.repo_manager.repo_auto_sync = True idc.Message('Auto rebase/push enabled')
def _do_run(self): try: super(BapIda, self).run() BapIda.instances.append(self) idaapi.register_timer(self.poll_interval_ms, self.update) idc.SetStatus(idc.IDA_STATUS_THINKING) self.run_handlers('instance_created') idc.Message("BAP> created new instance with PID {0}\n".format( self.proc.pid)) except: # pylint: disable=bare-except idc.Message("BAP> failed to create instance\nError: {0}\n".format( str(sys.exc_info()[1]))) traceback.print_exc()
def __init__(self, symbols=True): try: check_and_configure_bap() except: idc.Message('BAP> configuration failed\n{0}\n'.format( str(sys.exc_info()))) traceback.print_exc() raise BapIdaError() bap = config.get('bap_executable_path') if bap is None or not os.access(bap, os.X_OK): idc.Warning(''' The bap application is either not found or is not an executable. Please install bap or, if it is installed, provide a path to it. Installation instructions are available at: http://bap.ece.cmu.edu. ''') raise BapNotFound() binary = idaapi.get_input_file_path() super(BapIda, self).__init__(bap, binary) # if you run IDA inside IDA you will crash IDA self.args.append('--no-ida') self._on_finish = [] self._on_cancel = [] self._on_failed = [] if symbols: self._setup_symbols() headers = config.is_set('ida_api.enabled') if headers: self._setup_headers(bap)
def ida_main(): import idc filepath = idc.AskFile(0, "*.map", "Load a Dolphin emulator symbol map") if filepath is None: return symbol_map = load_dolphin_map(filepath) for symbol in symbol_map: addr = int(symbol.vaddr, 16) size = int(symbol.size, 16) idc.MakeUnknown(addr, size, 0) if symbol.section in [".init", ".text"]: idc.MakeCode(addr) success = idc.MakeFunction( addr, idc.BADADDR if not size else (addr + size)) else: success = idc.MakeData(addr, idc.FF_BYTE, size, 0) if not success: idc.Message("Can't apply properties for symbol:" " {0.vaddr} - {0.name}\n".format(symbol)) flags = idc.SN_NOCHECK | idc.SN_PUBLIC if symbol.name.startswith("zz_"): flags |= idc.SN_AUTO | idc.SN_WEAK else: flags |= idc.SN_NON_AUTO idc.MakeNameEx(addr, symbol.name, flags)
def _launch(self, debug): start = time.time() idc.Message('Launching %s/%s... ' % (self.packageName, self.launchActivity)) args = [ 'shell', 'am', 'start', '-n', self.packageName + '/' + self.launchActivity, '-W' ] if debug: args.append("-D") proc = self.adb.call(args, stderr=subprocess.PIPE, async=True, preexec_fn=utils.androidServerPreExec) def watchdog(): time.sleep(15) if proc.poll() is None: # still running proc.terminate() (threading.Thread(target=watchdog)).start() for _ in range(50): pid, _ = self._getPid(with_service=False) if pid is not None: break time.sleep(0.2) print "Done in %s seconds" % (time.time() - start)
def emit(self, record): """Emit a log record into IDA's output window. Args: record (LogRecord): a logging.LogRecord instance """ idc.Message("%s\n" % (super(IdaLogHandler, self).format(record)))
def export_single_cache(self, *args): logger.info("Exporting database using one core") if not os.path.isdir("database"): os.mkdir("database") exporter = ya.MakeFlatBufferExporter() ya.MakeModel(self.hash_provider).accept(exporter) with open("database/database.yadb", "wb") as fh: fh.write(exporter.GetBuffer()) idc.Message("Export complete.")
def install_callback(cls, callback_fn): """ Install callback to be run when the user calls for BAP execution. Callback must take a dict and must return nothing. Dict is guaranteed to get the following keys: 'ea': The value of EA at point where user propagated taint from. """ idc.Message('a callback is installed\n') cls._callbacks.append(callback_fn)
def update(self): if all(bap.finished() for bap in BapIda.instances): idc.SetStatus(idc.IDA_STATUS_READY) if self.finished(): if self.proc.returncode == 0: self.run_handlers('instance_finished') self.close() idc.Message("BAP> finished " + self.action + '\n') elif self.proc.returncode > 0: self.run_handlers('instance_failed') self.close() idc.Message("BAP> an error has occured while {0}\n".format( self.action)) else: if not self.closed: self.run_handlers('instance_canceled') idc.Message("BAP> was killed by signal {0}\n".format( -self.proc.returncode)) return -1 else: self.run_handlers('instance_updated') return self.poll_interval_ms
def run(self): "run BAP instance" if len(BapIda.instances) > 0: answer = idaapi.askyn_c( idaapi.ASKBTN_YES, "Previous instances of BAP didn't finish yet.\ Do you really want to start a new one?".format( len(BapIda.instances))) if answer == idaapi.ASKBTN_YES: self._do_run() else: self._do_run() idc.Message("BAP> total number of running instances: {0}\n".format( len(BapIda.instances)))
def print_stats(bb_coverage): total_bbs = bb_coverage['stats']['total_basic_blocks'] covered_bbs = bb_coverage['stats']['covered_basic_blocks'] # Calculate the coverage percentage to avoid divide-by-zero if total_bbs: percent_str = '{:.1%}'.format(covered_bbs / total_bbs) else: percent_str = '-%' idc.Message( COVERAGE_MESSAGE.format(num_bbs=total_bbs, num_covered_bbs=covered_bbs, percent=percent_str))
def init(self): architecture = utils.getIdaArchitecture() if architecture != "arm": print "%s unsupported architecture: %s" % (self.wanted_name, architecture) return idaapi.PLUGIN_SKIP idc.Message("Initializing %s\n" % self.wanted_name) from aaf import adb wrapper = adb.AdbWrapper(ADB_PATH) from aaf import AndroidAttacher utilsJar = os.path.join(get_plugin_home(), "aaf", "utils.jar") config_file = os.path.splitext(idc.GetIdbPath())[0] + ".aaf.conf" self.androidAttacher = AndroidAttacher(wrapper, utilsJar, config_file) return idaapi.PLUGIN_KEEP
def run(self, arg): comms = {} for addr in ida.addresses(): comm = idaapi.get_cmt(addr, 0) if comm: try: parsed = bap_comment.parse(comm) if parsed: for (name, data) in parsed.items(): comms[(addr, name)] = data except: idc.Message("BAP> failed to parse string {0}\n{1}".format( comm, str(sys.exc_info()[1]))) comms = [(name, addr, data) for ((addr, name), data) in comms.items()] attrs = Attributes(comms) choice = attrs.Show(modal=True) if choice >= 0: idc.Jump(comms[choice][1])
def ReadString(ea): """ Interprets ea as either an address or an ordinal and loads the string it points to accordingly. :param ea: address or ordinal of the string to be read :return: a string if the address or ordinal was valid """ # Check if the address is within the module bounds. if ea == 0: return "" elif ea > g_BaseAddress: # The string is located in the module, read a null terminated string. return idc.GetString(ea) else: # The string is located in the h2alang.dll module. string = ctypes.create_string_buffer(500) if g_user32Dll.LoadStringA(g_h2langDll._handle, ea, string, 500) is 0: # Failed to load the string from the dll. idc.Message("Failed to load string %d from h2lang module!" % ea) # Return the string buffer. return string.value
def run_handlers(self, event): assert event in self.observers handlers = [] instance_handlers = { 'instance_canceled': self._on_cancel, 'instance_failed': self._on_failed, 'instance_finished': self._on_finish, } handlers += self.observers[event] handlers += instance_handlers.get(event, []) failures = 0 for handler in handlers: try: handler(self) except: # pylint: disable=bare-except failures += 1 idc.Message("BAP> {0} failed because {1}\n".format( self.action, str(sys.exc_info()[1]))) traceback.print_exc() if failures != 0: idc.Warning("Some BAP handlers failed")
def main(): #print('INF_VERSION: %s' % (str(idc.GetLongPrm(idc.INF_VERSION)))) #print('INF_PROCNAME: %s' % (str(idc.GetLongPrm(idc.INF_PROCNAME)))) #print('INF_COMPILER: %s' % (str(idc.GetLongPrm(idc.INF_COMPILER)))) #print('INF_FILETYPE: %s' % (str(idc.GetLongPrm(idc.INF_FILETYPE)))) processor = str(idc.GetLongPrm(idc.INF_PROCNAME)) is_x86 = processor == 'metapc' is_ARM = processor == 'ARM' if not is_x86: idc.Message('*** Sorry, currently only supported x86.\n') return def_struct() load_metadata() #return code_reg, meta_reg = analyze_reg() if code_reg != idc.BADADDR: analyze_code_reg(code_reg) if meta_reg != idc.BADADDR: analyze_meta_reg(meta_reg, code_reg) init_array = analyze_init_array() analyze_invoke_unityengine() analyze_invoke_library() print('%X: INIT_IL2CPP' % (idc.LocByName('INIT_IL2CPP'))) print('%X: %s' % (code_reg, idc.Name(code_reg))) print('%X: %s' % (meta_reg, idc.Name(meta_reg))) print('%X: .init_array' % (init_array))
def log(string, *argv): '''idc.Message(formatstring, ...)''' return idc.Message('>' + string % argv + '\n')
idc.Message('as non-root... ') androidServerArgs = ['shell', 'run-as', pkg, androidServerPath] androidServerArgs.extend(args) (androidServerProc, port, androidServerRunAsOut) = runAndroidServer(androidServerArgs) if not androidServerProc: idc.Message('in pkg dir... ') pkgAndroidServerPath = '/data/data/' + pkg + '/files/android_server' self.adb.call(['shell', 'run-as', pkg, 'cp', androidServerPath, pkgAndroidServerPath]) self.adb.call(['shell', 'run-as', pkg, 'chmod', '755', pkgAndroidServerPath]) androidServerArgs = ['shell', 'run-as', pkg, pkgAndroidServerPath] + args (androidServerProc, port, androidServerPkgRunAsOut) = runAndroidServer(androidServerArgs) ''' if not androidServerProc: idc.Message('as root... ') (androidServerProc, port, androidServerSuOut) = runAndroidServer([ 'shell', 'su', '-c', '"' + " ".join([androidServerPath] + args) + '"' ]) ''' if not androidServerProc: idc.Message('in pkg dir... ') (androidServerProc, port, androidServerPkgSuOut) = runAndroidServer(['shell', 'su', '-c', '"' + " ".join([pkgAndroidServerPath] + args) + '"']) ''' if not androidServerProc: ''' print '' print '"run-as" output:' print ' ' + '\n '.join([s for s in androidServerRunAsOut if s]).replace('\0', '')
class AndroidAttacher(object): def __init__(self, wrapper, utilsJar, config_file): self.packageName = None self.launchActivity = None self.android_server = None self.device = None self.adb = wrapper self.utilsJar = utilsJar self.config_file = config_file if hasattr(idc, "idadir"): # ida 7.0 self.bindir = os.path.abspath(idc.idadir() + "/dbgsrv") else: import idaapi self.bindir = os.path.abspath(idaapi.get_idcpath() + "/../dbgsrv") def load_config(self): try: with open(self.config_file, "r") as f: return json.load(f, encoding="UTF-8") except: return {} def save_config(self, obj): try: with open(self.config_file, "w") as f: json.dump(obj, f, encoding="UTF-8", ensure_ascii=False) except: pass @fn_timer def _chooseDevice(self): self.device = self.adb.chooseDevice(self.device) print 'Using device %s' % self.device @fn_timer def _getPid(self): ps = self.adb.call(['shell', 'ps']).splitlines() for x in ps: xs = x.split() if self.packageName in xs and ('S' in xs or 'T' in xs): g = (col for col in xs if col.isdigit()) return int(next(g)) @fn_timer def _launch(self, debug): start = time.time() idc.Message('Launching %s/%s... ' % (self.packageName, self.launchActivity)) args = ['shell', 'am', 'start', '-n', self.packageName + '/' + self.launchActivity, '-W'] if debug: args.append("-D") proc = self.adb.call(args, stderr=subprocess.PIPE, async=True, preexec_fn=utils.androidServerPreExec) def watchdog(): time.sleep(15) if proc.poll() is None: # still running proc.terminate() (threading.Thread(target=watchdog)).start() for _ in range(50): time.sleep(0.2) if self._getPid(): break print "Done in %s seconds" % (time.time() - start) @fn_timer def _attach(self, debug): pid = self._getPid() if not pid: self._launch(debug) for _ in range(10): pid = self._getPid() if pid: break time.sleep(0.5) if not pid: raise StandardError("Error attach %s/%s." % (self.packageName, self.launchActivity)) self.attach_app(pid) @fn_timer def attach_app(self, pid): idc.LoadDebugger("armlinux", 1) idc.SetRemoteDebugger("localhost", "", self.port) status = idc.AttachProcess(pid, -1) if status == 1: print 'Attaching to pid %s... Done' % pid else: print 'Attaching to pid %s... Failed: %s' % (pid, status) def _chooseLaunchActivity(self, packageName): ''' packageApk = self.device.getApkPath(packageName) if not packageApk: raise StandardError("Error find package apk: %s." % packageName) ''' aaf_utils = "/data/local/tmp/aaf_utils.jar" # print "Pushing utils.jar to device: %s" % aaf_utils self.adb.push(self.utilsJar, aaf_utils) out = self.adb.call(['shell', 'su', '-c', '"dalvikvm -cp ' + aaf_utils + ' com.android.internal.util.WithFramework com.fuzhu8.aaf.GetMainActivity ' + packageName + '"']) resp = json.loads(out) if resp["code"] != 0: raise StandardError(resp["msg"]) main = utils.decode_list(resp["main"]) if len(main) == 1: return main[0] activities = utils.decode_list(resp["activities"]) if len(activities) == 1: return activities[0] return utils.ChooserForm("Choose activity", activities).choose() @fn_timer def _startAndroidServer(self, skipShell=False, redirectOut=False): global androidServerSuOut global port ida_port = '-p' + str(self.android_server_port) ps = self.adb.call(['shell', 'ps']).splitlines() for proc in [x.split() for x in ps if 'android_server' in x]: pid = next((col for col in proc if col.isdigit())) cmdline = self.adb.call(['shell', 'cat', '/proc/' + pid + '/cmdline']).split('\0') if ida_port not in cmdline: continue self.adb.call(['shell', 'su', '-c', '"kill -9 ' + pid + '"']) localServerPath = os.path.join(self.bindir, 'android_server') androidServerPath = '/data/local/tmp/android_server' remote = self.adb.call(["shell", "md5", androidServerPath]).split()[0] md5 = hashlib.md5() with open(localServerPath, "r") as f: while True: strRead = f.read(1024) if not strRead: break md5.update(strRead) if md5.hexdigest() != remote: print "Pushing android_server to device: %s" % androidServerPath self.adb.push(localServerPath, androidServerPath) self.adb.call(['shell', 'chmod', '755', androidServerPath]) args = [ida_port] @fn_timer def runAndroidServer(args): # returns (proc, port, stdout) # print "runAndroidServer:", args proc = self.adb.call(args, stderr=subprocess.PIPE, async=True, preexec_fn=utils.androidServerPreExec) need_watchdog = True def watchdog(): time.sleep(180) if need_watchdog and proc.poll() is None: # still running proc.terminate() (threading.Thread(target=watchdog)).start() # we have to find the port used by android_server from stdout # while this complicates things a little, it allows us to # have multiple android_servers running # Listening on port #23946... # Listening on 0.0.0.0:23946... out = [] line = ' ' while line: try: line = proc.stdout.readline() # words = line.split() # print "line:", line, "words:", words out.append(line.rstrip()) if 'android_server terminated by' in line: break if 'Listening' not in line: continue if '#' in line: start_index = line.index("#") elif ':' in line: start_index = line.index(":") else: print "parse line failed: ", line continue end_index = line.index("...") port = line[start_index + 1: end_index] if not port.isdigit(): print "parse failed: port=", port, ", line=", line continue need_watchdog = False return (proc, port, out) except BaseException, e: print e # not found, error? need_watchdog = False return (None, None, out) # can we run as root? androidServerProc = None ''' if not androidServerProc: idc.Message('as non-root... ') androidServerArgs = ['shell', 'run-as', pkg, androidServerPath] androidServerArgs.extend(args) (androidServerProc, port, androidServerRunAsOut) = runAndroidServer(androidServerArgs) if not androidServerProc: idc.Message('in pkg dir... ') pkgAndroidServerPath = '/data/data/' + pkg + '/files/android_server' self.adb.call(['shell', 'run-as', pkg, 'cp', androidServerPath, pkgAndroidServerPath]) self.adb.call(['shell', 'run-as', pkg, 'chmod', '755', pkgAndroidServerPath]) androidServerArgs = ['shell', 'run-as', pkg, pkgAndroidServerPath] + args (androidServerProc, port, androidServerPkgRunAsOut) = runAndroidServer(androidServerArgs) ''' if not androidServerProc: idc.Message('as root... ') (androidServerProc, port, androidServerSuOut) = runAndroidServer( ['shell', 'su', '-c', '"' + " ".join([androidServerPath] + args) + '"']) ''' if not androidServerProc: idc.Message('in pkg dir... ') (androidServerProc, port, androidServerPkgSuOut) = runAndroidServer(['shell', 'su', '-c', '"' + " ".join([pkgAndroidServerPath] + args) + '"']) ''' if not androidServerProc: ''' print '' print '"run-as" output:' print ' ' + '\n '.join([s for s in androidServerRunAsOut if s]).replace('\0', '') print '"run-as pkg" output:' print ' ' + '\n '.join([s for s in androidServerPkgRunAsOut if s]).replace('\0', '') ''' print '"su -c" output:' print ' ' + '\n '.join([s for s in androidServerSuOut if s]).replace('\0', '') ''' print '"su -c pkg" output:' print ' ' + '\n '.join([s for s in androidServerPkgSuOut if s]).replace('\0', '') if any('not executable: magic' in s for s in (androidServerRunAsOut + androidServerPkgRunAsOut + androidServerSuOut + androidServerPkgSuOut)): print '\n********' print '* Your device platform is not supported by this android_server' print '********\n' ''' raise StandardError('failed to run android_server') self.port = int(port) self.android_server = androidServerProc # forward the port that android_server gave us self.adb.forward('tcp:' + port, 'tcp:' + port) print 'Done'
import os import sys import shutil from glob import glob try: import epydoc.apidoc import epydoc.cli except ImportError as e: import idc import traceback idc.Message("Couldn't import module %s\n" % traceback.format_exc()) idc.Exit(-1) # -------------------------------------------------------------------------- DOC_DIR = 'hr-html' # -------------------------------------------------------------------------- def log(msg): #print msg pass # -------------------------------------------------------------------------- def add_footer(lines): S1 = 'Generated by Epydoc' S2 = '</table>' p = lines.find(S1) if p == -1:
def _check_input_file(self): if (self.machine_type == IMAGE_FILE_MACHINE_IA64): return True else: idc.Message("File format is not supported") return False
for ea, name in idautils.Names(): flag = idc.GetFlags(ea) if not idc.hasUserName(flag): continue seg_ea = idc.SegStart(ea) seg_name = idc.SegName(ea) if seg_name not in self.sections: continue sym_type = 'function' if idc.isCode(flag) else 'object' self.symbols[name] = (seg_name, ea - seg_ea, sym_type) def run(self): self.load_symbols_from_ida() err, err_msg = self.objcopy() return err, err_msg if is_ida: inp_file = idc.GetInputFilePath() if not os.path.isfile(inp_file): inp_file = idc.AskFile(0, '', 'Input ELF file') out_file = idc.AskFile(1, '', 'Output file') a = AddSym(inp_file, out_file) err, err_msg = a.run() if err != 0: idc.Warning(err_msg) if out_file != inp_file: os.remove(out_file) else: idc.Message('Saved to {}\n'.format(out_file))
# This script adds a function - memToLvl - which allows you to convert memory addresses to file addresses for LVL files. # You need to have my IDA database for this script to work. import idc idc.Message("Initializing Rayman 3 extension for IDA!\n") def memToLvl(address, levelId = None): refTableAddr = idc.LocByName("levelReferenceTable") if refTableAddr == BADADDR: print("Can't get level reference table address. Make sure its name is levelReferenceTable.") return if levelId == None: endTableAddr = idc.LocByName("levelEndTable") if endTableAddr == BADADDR: print("Can't get level end table address. Make sure its name is levelEndTable.") return lvl0StartAddr = idc.Dword(refTableAddr) lvl1StartAddr = idc.Dword(refTableAddr + 4) lvl0EndAddr = idc.Dword(endTableAddr) lvl1EndAddr = idc.Dword(endTableAddr + 4) if address >= lvl0StartAddr and address <= lvl0EndAddr: fileRelativeAddr = address - lvl0StartAddr idc.Message("Fix.lvl relative address: 0x" + format(fileRelativeAddr, '02X') + "\n") return if address >= lvl1StartAddr and address <= lvl1EndAddr: