Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 1 addition & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1 @@
- 修复 ZIP 归档中位于子目录的 dylib 文件无法正确导入的问题。
- 新增 “所有应用” 分类。
- 新增免责声明。
- 新增中文名称 “巨魔注入器”。

------

- Fixed an issue where dylib files located in subdirectories in ZIP archives could not be imported correctly.
- Added “All Applications” category.
- Added disclaimer.
- Inject `.bundle` additionally if `.deb` file contains both `.dylib` and `.bundle`
92 changes: 77 additions & 15 deletions TrollFools/InjectorV3+Preprocess.swift
Original file line number Diff line number Diff line change
Expand Up @@ -141,28 +141,90 @@ fileprivate extension InjectorV3 {

var hasAnyDylib = false
var tarReader = TarReader(fileHandle: tarHandle)
var processedBundles = Set<String>()
var bundleContents: [String: [(info: TarEntryInfo, data: Data?)]] = [:]
while let entry = try tarReader.read() {
guard entry.info.type == .regular,
entry.info.name.hasSuffix(".dylib"),
let entryData = entry.data
else {
continue
}

let dylibName = URL(fileURLWithPath: entry.info.name, relativeTo: targetURL).lastPathComponent
guard !dylibName.hasPrefix(".") else {
continue
}
if entry.info.type == .regular && entry.info.name.hasSuffix(".dylib") {
guard let entryData = entry.data else {
continue
}
let dylibName = URL(fileURLWithPath: entry.info.name, relativeTo: targetURL).lastPathComponent
guard !dylibName.hasPrefix(".") else {
continue
}

DDLogWarn("Found dylib \(entry.info.name) name \(dylibName)", ddlog: logger)
DDLogWarn("Found dylib \(entry.info.name) name \(dylibName)", ddlog: logger)

let entryURL = targetURL.appendingPathComponent(dylibName)
try entryData.write(to: entryURL)
hasAnyDylib = true
} else if entry.info.type == .directory && entry.info.name.hasSuffix(".bundle") {
// Extract bundle name
let bundleName = URL(fileURLWithPath: entry.info.name).lastPathComponent
// Avoid processing duplicate or nested bundles
guard !processedBundles.contains(bundleName) else {
continue
}
// Track that we're processing this bundle
processedBundles.insert(bundleName)
// Store bundle entries for later processing
bundleContents[entry.info.name] = []

let entryURL = targetURL.appendingPathComponent(dylibName)
try entryData.write(to: entryURL)
hasAnyDylib = true
DDLogWarn("Found bundle \(entry.info.name) name \(bundleName)", ddlog: logger)
} else {
// Collect contents for all bundles
for (bundlePath, _) in bundleContents {
if entry.info.name.starts(with: bundlePath + "/") {
bundleContents[bundlePath]?.append((entry.info, entry.data))
}
}
}
}

if !hasAnyDylib {
throw Error.generic(NSLocalizedString("No dylib found in the Debian package.", comment: ""))
}
let fileManager = FileManager.default
// Process collected bundle contents
for (bundlePath, contents) in bundleContents {
let bundleName = URL(fileURLWithPath: bundlePath).lastPathComponent

DDLogInfo("Preparing to copy bundle \(bundlePath)", ddlog: logger)

// Destination for the bundle
let destinationBundleURL = targetURL.appendingPathComponent(bundleName)
// Remove existing bundle if it exists
if fileManager.fileExists(atPath: destinationBundleURL.path) {
try fileManager.removeItem(at: destinationBundleURL)
}
// Create destination directory for the bundle
try fileManager.createDirectory(at: destinationBundleURL, withIntermediateDirectories: true)

// Copy bundle contents
for entry in contents {
// Get relative path within the bundle
let relativePath = String(entry.info.name.dropFirst(bundlePath.count + 1))
let destinationPath = destinationBundleURL.appendingPathComponent(relativePath)
// Handle different entry types
switch entry.info.type {
case .directory:
// Create subdirectories
try fileManager.createDirectory(at: destinationPath, withIntermediateDirectories: true)
case .regular:
// Ensure destination directory exists
try fileManager.createDirectory(at: destinationPath.deletingLastPathComponent(), withIntermediateDirectories: true)
// Write file contents
guard let fileData = entry.data else {
DDLogWarn("Unable to read data for \(entry.info.name)", ddlog: logger)
continue
}
try fileData.write(to: destinationPath)
default:
continue
}
}

DDLogInfo("Successfully copied bundle \(bundleName)", ddlog: logger)
}
}
}
Loading