예제 #1
0
def listImages(filterTerm: bytes = b""):
	"""
	Prints all the images in the cache with an optional filter term.
	"""	

	with open(DYLD_PATH, "rb") as dyldFile:
		dyld = Dyld.DyldFile(dyldFile)

		for image in dyld.images:
			dyldFile.seek(image.pathFileOffset)
			path = b""
			while True:
				data = dyldFile.read(1)
				path += data
				if data == b"\x00":
					break

			if filterTerm.lower() in path.lower():
				print(str(path) + ": " + str(dyld.images.index(image)))
예제 #2
0
def runOnce(imageIndex: int, path: str) -> None:
    """
	Decache an image at the imageIndex, and save it to the path.
	"""

    with open(DYLD_PATH, "rb") as dyldFile:
        dyld = Dyld.DyldFile(dyldFile)

        image = dyld.images[imageIndex]

        imageOff = dyld.convertAddr(image.address)
        macho = MachO.MachoFile.parse(dyldFile, imageOff)

        # comment or uncomment lines below to enable or disable modules. Though some do rely on each other.
        # rebuild the linkedit segment, which includes symbols
        print("LinkeditConverter")
        LinkeditConverter(macho, dyld).convert()

        # remove extra data in pointers and generate rebase data
        print("RebaseConverter")
        RebaseConverter(macho, dyld).convert()

        # fix references to selectors
        print("SelectorConverter")
        SelectorConverter(macho, dyld).convert()

        # fix stubs and references to stubs
        print("StubConverter")
        StubConverter(macho, dyld).convert()

        # fix and decache ObjC info
        print("ObjCConverter")
        ObjCConverter(macho, dyld).convert()

        # changes file offsets so that the final MachO file is not GBs big
        print("OffsetConverter")
        OffsetConverter(macho).convert()

        # save the converted image to a file
        print("Writer")
        MachO.Writer(macho).writeToPath(path)
예제 #3
0
def extract(framework: str, out: str):
    with open(DYLD_PATH, "rb") as dyldFile:
        dyld = Dyld.DyldFile(dyldFile)

        for image in dyld.images:
            dyldFile.seek(image.pathFileOffset)
            path = b""
            while True:
                data = dyldFile.read(1)
                if data != b"\x00":
                    path += data
                else:
                    break
            #
            if framework.lower() == str(os.path.basename(
                    path.decode("utf-8"))).lower():
                runOnce(dyld.images.index(image), out)
            elif framework in path.decode("utf-8"):
                pass
            else:
                pass
예제 #4
0
def runAllImages():
    """
	Test a module with all images in the cache	
	"""

    with open(DYLD_PATH, "rb") as dyldFile:
        dyld = Dyld.DyldFile(dyldFile)

        totalImages = len(dyld.images)
        for i in range(1, totalImages):
            image = dyld.images[i]

            imagePath = dyld.readString(image.pathFileOffset)
            imageName = imagePath.split(b"/")[-1].decode("utf-8")

            print("{}/{}: {}".format(i, totalImages, imageName))

            imageOff = dyld.convertAddr(image.address)
            macho = MachO.MachoFile.parse(dyldFile, imageOff)

            # LinkeditConverter(macho, dyld).convert()
            # RebaseConverter(macho, dyld).convert()
            SelectorConverter(macho, dyld).convert()
예제 #5
0
    if args.verbosity == 0:
        # Set the log level so high that it doesn't do anything
        level = 100
    elif args.verbosity == 2:
        level = logging.INFO
    elif args.verbosity == 3:
        level = logging.DEBUG

    logging.basicConfig(
        format=
        "%(asctime)s:%(msecs)03d %(filename)s [%(levelname)-8s] : %(message)s",
        datefmt="%H:%M:%S",
        level=level)

    with open(args.dyld_path, mode="rb") as dyldFileHandle:
        dyldFile = Dyld.DyldFile(dyldFileHandle)
        images = enumerateImages(dyldFile)

        # List Images option
        if args.list_frameworks:
            if args.filter:
                filterTerm = args.filter.lower()
                images = [x for x in images if filterTerm in x[2].lower()]

            print("Listing images")
            print(f"Index| {'Name':40} | Path")
            for image in images:
                print(f"{image[0]:4} | {image[1]:40} | {image[2]}")

        # Extract image Option
        elif args.framework: