def test_indirectcalls(outputFilePath=None, listAll=False): #importDepsTils() modInitFuncs = getAllModInitFuncs() if len(modInitFuncs) == 0: return parseGOTNames() #if not haveSymbol(): # return commonSeg = getSegByName("__common") if not None is commonSeg: for ea in Heads(commonSeg.start_ea, commonSeg.end_ea): deName = getDeNameAtEA(ea) if None is deName: continue if deName.endswith("::gMetaClass"): SetType(ea, deName[:-len("::gMetaClass")] + "::MetaClass") parseKernelHeadersAndSetType() rebuildAllInternalDataWOParseModInitFunc(True) AnalysisUtils.forward_analysis_intra_defined_funcs() solvedIndirectCalls, unsolvedIndirectCalls, allIndirectCalls, solveRate = AnalysisUtils.checkResolutionRate() result = {"solvedIndirectCalls": {x: list(solvedIndirectCalls[x]) for x in solvedIndirectCalls}, "unsolvedIndirectCalls":list(unsolvedIndirectCalls), "allIndirectCalls": list(allIndirectCalls)} if not None is outputFilePath: with open(outputFilePath, "w") as f: json.dump(result, f) print "solved {}, unsolved {}, rate {}".format(len(solvedIndirectCalls), len(unsolvedIndirectCalls), solveRate) if listAll: print ", ".join(["0x{:X}".format(x) for x in unsolvedIndirectCalls]) return solvedIndirectCalls, unsolvedIndirectCalls
def test_userentries(outputFilePath=None): if not containsUserClient(): return rebuildAllInternalDataWOParseModInitFunc(True) AnalysisUtils.forward_analysis_intra_defined_funcs() binPath = getOriginalBinaryPath() outputFile = None if not None is outputFilePath: outputFile = open(outputFilePath, "a") foundEntryPoints = findEntryPoints() if len(foundEntryPoints) == 0: if not None is outputFile: outputFile.write("\n\n************\nNo Entry Points in {}:\n".format(binPath)) else: if not None is outputFile: outputFile.write("\n\n============\nEntry Points in {}:\n".format(binPath) ) for entryType in foundEntryPoints: entries = foundEntryPoints[entryType] for entry in entries: outputStr = "[{}] 0x{:016X}: {}".format(entryType, entry, getName(entry)) print outputStr if not None is outputFile: outputFile.write(outputStr + "\n") if not None is outputFile: outputFile.close()
def analyze_stage4(): ''' resolve indirect calls ''' global isKernel if not isKernel: AnalysisUtils.forward_analysis_intra_defined_funcs() AnalysisUtils.forward_analysis_intra_defined_funcs() keepAllConsistency()
def launchCheckerAtIndex(checkerIdx, kext=None): if checkerIdx >= len(Checkers): print "checkerIdx {} out of {}".format(checkerIdx, len(Checkers)) return checker = Checkers[checkerIdx] if not None is checker: checker_name = checker["name"] checker_launcher = checker["launcher"] allUCInfos = getAllUCInfos() if checker["requireUC"] and len(allUCInfos) == 0: print "[!] {} requires accessible userclient, but kext does not have".format( checker_name) return AnalysisUtils.forward_analysis_intra_defined_funcs(kext) print "[+] Launching checker {}".format(checker_name) checker_launcher("abc", kext)
def test_indirectcalls(kextPrefix=None, outputFilePath=None, listAll=False): loadNecessaryDataFromPersistNode() AnalysisUtils.forward_analysis_intra_defined_funcs(kextPrefix) solvedIndirectCalls, unsolvedIndirectCalls, allIndirectCalls, solveRate = AnalysisUtils.checkResolutionRate( kextPrefix) result = { "solvedIndirectCalls": {x: list(solvedIndirectCalls[x]) for x in solvedIndirectCalls}, "unsolvedIndirectCalls": list(unsolvedIndirectCalls), "allIndirectCalls": allIndirectCalls } if not None is outputFilePath: with open(outputFilePath, "w") as f: json.dump(result, f) print "solved {}, unsolved {}, rate {}".format(len(solvedIndirectCalls), len(unsolvedIndirectCalls), solveRate) if listAll: print ", ".join( ["0x{:X}".format(x) for x in sorted(unsolvedIndirectCalls)]) return solvedIndirectCalls, unsolvedIndirectCalls
def perform_checker_on_kext(kextname, checker_id): if not kextname in getAllKEXTPrefixes(): return AnalysisUtils.forward_analysis_intra_defined_funcs(kextname) PolicyChecker.launchCheckerAtIndex(checker_id, kextname)