mirror of
https://git-qiuchenly.yltfspace.com/QiuChenly/corepatch
synced 2025-11-25 05:40:27 +08:00
205 lines
6.8 KiB
Ruby
205 lines
6.8 KiB
Ruby
require 'json'
|
||
require 'fileutils'
|
||
require './Utils'
|
||
require 'pathname'
|
||
require 'shellwords'
|
||
|
||
def readPrototypeKey(file, keyName)
|
||
link = Shellwords.escape(file)
|
||
%x{defaults read #{link} #{keyName}}.chomp
|
||
end
|
||
|
||
def parseAppInfo(appBaseLocate, appInfoFile)
|
||
appInfo = {}
|
||
appInfo['appBaseLocate'] = "#{appBaseLocate}"
|
||
appInfo['CFBundleIdentifier'] = readPrototypeKey appInfoFile, 'CFBundleIdentifier'
|
||
appInfo['CFBundleVersion'] = readPrototypeKey appInfoFile, 'CFBundleVersion'
|
||
appInfo['CFBundleShortVersionString'] = readPrototypeKey appInfoFile, 'CFBundleShortVersionString'
|
||
appInfo['CFBundleName'] = readPrototypeKey appInfoFile, 'CFBundleExecutable'
|
||
appInfo
|
||
end
|
||
|
||
def scan_apps
|
||
applist = []
|
||
baseDir = '/Applications'
|
||
lst = Dir.glob("#{baseDir}/*")
|
||
lst.each do |app|
|
||
appInfoFile = "#{app}/Contents/Info.plist"
|
||
next unless File.exist?(appInfoFile)
|
||
begin
|
||
applist.push parseAppInfo app, appInfoFile
|
||
# puts "检查本地App: #{appInfoFile}"
|
||
rescue StandardError
|
||
next
|
||
end
|
||
end
|
||
applist
|
||
end
|
||
|
||
def checkCompatible(compatibleVersionCode, compatibleVersionSubCode, appVersionCode, appSubVersionCode)
|
||
return true if compatibleVersionCode.nil? && compatibleVersionSubCode.nil?
|
||
compatibleVersionCode&.each do |code|
|
||
return true if appVersionCode == code
|
||
end
|
||
|
||
compatibleVersionSubCode&.each do |code|
|
||
return true if appSubVersionCode == code
|
||
end
|
||
false
|
||
end
|
||
|
||
def main
|
||
ret = %x{csrutil status}.chomp
|
||
# System Integrity Protection status: disabled.
|
||
if ret.include?('status: enabled')
|
||
# puts "给老子把你那个b SIP关了先!是不是关SIP犯法?\n要求里写了要先关SIP,能不能认真看看我写的说明?\n如果你看了还没关,说明你确实是SB\n如果你没看说明,那你更SB。\nWhatever,U ARE SB。"
|
||
# return
|
||
end
|
||
|
||
config = File.read('config.json')
|
||
config = JSON.parse config
|
||
basePublicConfig = config['basePublicConfig']
|
||
appList = config['AppList']
|
||
procVersion = config['Version']
|
||
|
||
puts "====\t自动注入开始执行\t====\n"
|
||
puts "====\tVersion(版本号): #{procVersion}\t====\n"
|
||
puts "====\tAutomatic Inject Script Checking... ====\n"
|
||
puts "====\tDesign By QiuChenly(github.com/qiuchenly)"
|
||
puts "注入时请根据提示输入'y' 或者按下回车键跳过这一项。\n"
|
||
puts "When i find useful options, pls follow my prompts enter 'y' or press enter key to jump that item.\n"
|
||
|
||
install_apps = scan_apps
|
||
|
||
# prepare resolve package lst
|
||
appLst = []
|
||
appList.each do |app|
|
||
packageName = app['packageName']
|
||
if packageName.is_a?(Array)
|
||
packageName.each { |name|
|
||
tmp = app.dup
|
||
tmp['packageName'] = name
|
||
appLst.push tmp
|
||
}
|
||
else
|
||
appLst.push app
|
||
end
|
||
end
|
||
|
||
appLst.each { |app|
|
||
packageName = app['packageName']
|
||
appBaseLocate = app['appBaseLocate']
|
||
bridgeFile = app['bridgeFile']
|
||
injectFile = app['injectFile']
|
||
supportVersion = app['supportVersion']
|
||
supportSubVersion = app['supportSubVersion']
|
||
extraShell = app['extraShell']
|
||
needCopy2AppDir = app['needCopyToAppDir']
|
||
deepSignApp = app['deepSignApp']
|
||
disableLibraryValidate = app['disableLibraryValidate']
|
||
entitlements = app['entitlements']
|
||
noSignTarget = app['noSignTarget']
|
||
noDeep = app ['noDeep']
|
||
|
||
localApp = install_apps.select { |_app| _app['CFBundleIdentifier'] == packageName }
|
||
if localApp.empty? && (appBaseLocate.nil? || !Dir.exist?(appBaseLocate))
|
||
next
|
||
end
|
||
|
||
if localApp.empty?
|
||
puts "[🔔] 此App包不是常见类型结构,请注意当前App注入的路径是 #{appBaseLocate}"
|
||
puts "[🔔] This App Folder is not common struct,pls attention now inject into the app path is #{appBaseLocate}"
|
||
# puts "读取的是 #{appBaseLocate + "/Contents/Info.plist"}"
|
||
localApp.push(parseAppInfo appBaseLocate, appBaseLocate + '/Contents/Info.plist')
|
||
end
|
||
|
||
localApp = localApp[0]
|
||
if appBaseLocate.nil?
|
||
appBaseLocate = localApp['appBaseLocate']
|
||
end
|
||
bridgeFile = basePublicConfig['bridgeFile'] if bridgeFile.nil?
|
||
|
||
unless checkCompatible(supportVersion, supportSubVersion, localApp['CFBundleShortVersionString'], localApp['CFBundleVersion'])
|
||
puts "[😅] [#{localApp['CFBundleName']}] - [#{localApp['CFBundleShortVersionString']}] - [#{localApp['CFBundleIdentifier']}]不是受支持的版本,跳过注入😋。\n"
|
||
next
|
||
end
|
||
|
||
puts "[🤔] [#{localApp['CFBundleName']}] - [#{localApp['CFBundleShortVersionString']}] - [#{localApp['CFBundleIdentifier']}]是受支持的版本,是否需要注入?y/n(默认n)\n"
|
||
action = gets.chomp
|
||
next if action != 'y'
|
||
puts "开始注入App: #{packageName}"
|
||
|
||
dest = appBaseLocate + bridgeFile + injectFile
|
||
backup = dest + '_backup'
|
||
|
||
if File.exist? backup
|
||
puts "备份的原始文件已经存在,需要直接用这个文件注入吗?y/n(默认y)\n"
|
||
puts "Find Previous Target File Backup, Are u use it inject?y/n(default is y)\n"
|
||
action = gets.chomp
|
||
# action = 'y'
|
||
if action == 'n'
|
||
FileUtils.remove(backup)
|
||
FileUtils.copy(dest, backup)
|
||
else
|
||
|
||
end
|
||
else
|
||
FileUtils.copy(dest, backup)
|
||
end
|
||
|
||
current = Pathname.new(File.dirname(__FILE__)).realpath
|
||
current = Shellwords.escape(current)
|
||
# set shell +x permission
|
||
sh = "chmod +x #{current}/tool/insert_dylib"
|
||
# puts sh
|
||
system sh
|
||
backup = Shellwords.escape(backup)
|
||
dest = Shellwords.escape(dest)
|
||
|
||
sh = "sudo #{current}/tool/insert_dylib #{current}/tool/libInjectLib.dylib #{backup} #{dest}"
|
||
unless needCopy2AppDir.nil?
|
||
system "sudo cp #{current}/tool/libInjectLib.dylib #{Shellwords.escape(appBaseLocate + bridgeFile)}libInjectLib.dylib"
|
||
sh = "sudo #{current}/tool/insert_dylib #{Shellwords.escape(appBaseLocate + bridgeFile)}libInjectLib.dylib #{backup} #{dest}"
|
||
end
|
||
# puts sh
|
||
system sh
|
||
|
||
# 没搞懂为什么有的人codesign都能冲突
|
||
signPrefix = '/usr/bin/codesign -f -s - --timestamp=none --all-architectures'
|
||
|
||
if noDeep.nil?
|
||
puts 'Need Deep Sign.'
|
||
signPrefix = "#{signPrefix} --deep"
|
||
end
|
||
|
||
unless entitlements.nil?
|
||
signPrefix = "#{signPrefix} --entitlements #{current}/tool/#{entitlements}"
|
||
end
|
||
|
||
# 签名目标文件 如果加了--deep 会导致签名整个app
|
||
if noSignTarget.nil?
|
||
puts '开始签名...'
|
||
system "#{signPrefix} #{dest}"
|
||
end
|
||
|
||
unless disableLibraryValidate.nil?
|
||
sh = 'sudo defaults write /Library/Preferences/com.apple.security.libraryvalidation.plist DisableLibraryValidation -bool true'
|
||
system sh
|
||
end
|
||
|
||
unless extraShell.nil?
|
||
system "sudo sh #{current}/tool/" + extraShell
|
||
end
|
||
|
||
if deepSignApp
|
||
system "#{signPrefix} #{Shellwords.escape(appBaseLocate)}"
|
||
end
|
||
|
||
system "sudo xattr -cr #{dest.match(/(.+\.app)/)}"
|
||
|
||
puts 'App处理完成。'
|
||
}
|
||
end
|
||
|
||
main
|