예제 #1
0
def runForAllImages(dyldFile: BufferedReader,
                    dyldCtx: DyldContext,
                    statusBar: progressbar.ProgressBar,
                    logger: logging.Logger,
                    startIndex: int = 0,
                    stopIndex: int = -1) -> None:
    total = dyldCtx.header.imagesCount

    for index, imageData in enumerate(dyldCtx.images[startIndex:], startIndex):
        if index == stopIndex:
            break

        # TODO: Imp sub caches
        imageOffset = dyldCtx.convertAddr(imageData.address)
        imagePath = dyldCtx.readString(imageData.pathFileOffset)[0:-1]
        imagePath = imagePath.decode("utf-8")
        imageName = imagePath.split("/")[-1]

        # Make a writable copy of the dyld file
        machoFile = mmap.mmap(dyldFile.fileno(), 0, access=mmap.ACCESS_COPY)
        machoCtx = MachOContext(machoFile, imageOffset)

        extractionCtx = ExtractionContext(dyldCtx, machoCtx, statusBar, logger)

        # Test space start

        slide_info.processSlideInfo(extractionCtx)
        linkedit_optimizer.optimizeLinkedit(extractionCtx)
        stub_fixer.fixStubs(extractionCtx)
        objc_fixer.fixObjC(extractionCtx)
        macho_offset.optimizeOffsets(extractionCtx)

        # Test space end

        logger.info(f"processed: ({index + 1}/{total}): {imageName}")
        pass

    statusBar.update(unit="Extractor", status="Done")
    pass
예제 #2
0
    parser.add_argument(
        "-j",
        "--jobs",
        type=int,
        default=mp.cpu_count(),
        help="Number of jobs to run simultaneously."  # noqa
    )
    args = parser.parse_args(namespace=_DyldExtractorArgs)

    # create a list of images
    images: List[str] = []
    with open(args.dyld_path, "rb") as f:
        dyldCtx = DyldContext(f)

        for index, image in enumerate(dyldCtx.images):
            imagePath = dyldCtx.readString(image.pathFileOffset)[0:-1]
            imagePath = imagePath.decode("utf-8")
            imageName = imagePath.split("/")[-1]

            images.append(imageName)
        pass

    summary = ""
    with mp.Pool(args.jobs, initializer=_workerInitializer) as pool:
        # create jobs for each image
        jobs: List[Tuple[str, mp.pool.AsyncResult]] = []
        for index, imageName in enumerate(images):
            jobs.append((imageName,
                         pool.apply_async(_imageRunner,
                                          (args.dyld_path, index))))
            pass
예제 #3
0
def main():
    args = getArguments()

    # Configure Logging
    level = logging.WARNING  # default option

    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

    progressbar.streams.wrap_stderr()  # needed for logging compatability

    logging.basicConfig(
        format=
        "{asctime}:{msecs:3.0f} [{levelname:^9}] {filename}:{lineno:d} : {message}",  # noqa
        datefmt="%H:%M:%S",
        style="{",
        level=level)

    with open(args.dyld_path, "rb") as f:
        with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as dyldFile:
            dyldCtx = DyldContext(dyldFile)

            # enumerate images, create a map of paths and images
            imageMap = {}
            for imageData in dyldCtx.images:
                path = dyldCtx.readString(imageData.pathFileOffset)
                path = path[0:-1]  # remove null terminator
                path = path.decode("utf-8")

                imageMap[path] = imageData

            # list images option
            if args.list_frameworks:
                imagePaths = imageMap.keys()

                # filter if needed
                if args.filter:
                    filterTerm = args.filter.strip().lower()
                    imagePaths = _filterImages(imagePaths, filterTerm)

                print("Listing Images\n--------------")
                for path in imagePaths:
                    print(path)

                return

            # extract image option
            if args.extract:
                extractionTarget = args.extract.strip()
                targetPaths = _filterImages(imageMap.keys(), extractionTarget)
                if len(targetPaths) == 0:
                    print(f"Unable to find image \"{extractionTarget}\"")
                    return

                outputPath = args.output
                if outputPath is None:
                    outputPath = pathlib.Path("binaries/" + extractionTarget)
                    os.makedirs(outputPath.parent, exist_ok=True)

                print(f"Extracting {targetPaths[0]}")
                _extractImage(f, dyldCtx, imageMap[targetPaths[0]], outputPath)
                return