Xcode16.3配置越狱开发环境
首先先在https://developer.apple.com/xcode/resources/ 这里面登陆Apple账号,然后访问url下载 https://download.developer.apple.com/Developer_Tools/Xcode_16.3/Xcode_16.3.xip
1、安装theos
https://theos.dev/docs/installation-macos
会安装到默认位置~/theos
或者直接运行
bash -c "$(curl -fsSL https://raw.githubusercontent.com/theos/theos/master/bin/install-theos)"
软链接放到默认位置
sudo ln -s /Users/kk/theos /opt/theos
2、安装MonkeyDev
参考这个issue解决,不过这个issue原始的脚本还需要进一步修改才可以用于16.3
https://github.com/AloneMonkey/MonkeyDev/issues/365#issuecomment-2726745723
这里放出来最终可用的安装脚本:
#!/bin/bash#set -e表示一旦脚本中有命令的返回值为非0,则脚本立即退出,后续命令不再执行;
#set -o pipefail表示在管道连接的命令序列中,只要有任何一个命令返回非0值,则整个管道返回非0值,即使最后一个命令返回0.
export setCmd="set -eo pipefail"
$setCmd#导出环境变量
export PATH=/opt/MonkeyDev/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin:$PATH#脚本名称和版本
export scriptName="${0##*/}"
export scriptVer="2.0"#本地存储文件的目录
export MonkeyDevPath="/opt/MonkeyDev"
export backupFileExt=".MonkeyDev"#获取用户名、用户组、用户目录、和profile文件
export userName="${SUDO_USER-$USER}"
export userGroup=`id -g $userName`
export userHome=`eval echo ~$userName`#用户可能存在的profile文件
export bashProfileFiles=("$userHome/.zshrc" "$userHome/.bash_profile" "$userHome/.bashrc" "$userHome/.bash_login" "$userHome/.profile")#获取临时文件名
export tempDirsFile="`mktemp -d -t $scriptName`/tempdirs"
touch "$tempDirsFile"#把LANG变量从当前环境中删除
unset LANG#出错退出
function cleanup()
{local exitCode=$?set +etrap - $signalsremoveTempDataexit $exitCode
}function panic()
{local exitCode=$1set +eshift[[ "$@" == "" ]] || echo "$@" >&2exit $exitCode
}export signals="0 1 2 3 15"
#当shell接收到signals指定的信号时,执行cleanup命令
trap cleanup $signalsfunction removeTempData()
{local tempDirsif [[ -f "$tempDirsFile" ]]; thentempDirs=(`cat "$tempDirsFile"`)for td in "${tempDirs[@]}"; dorm -rf "$td" || truedonerm -rf "`dirname $tempDirsFile`" || truefi
}
function getTempDir()
{$setCmdlocal tempDirtempDir=`mktemp -d -t $scriptName` || \panic $? "Failed to create temporary directory"echo "$tempDir" >> "$tempDirsFile" || \panic $? "Failed to echo into $tempDirsFile"echo "$tempDir"
}function copyFile()
{cp -f "$1" "$2" || \panic $? "Failed to copy file $1 to $2"
}#备份原文件
function requireBackup()
{[[ ! -f "$1" || -f "${1}${backupFileExt}" ]] || \copyFile "$1" "${1}${backupFileExt}"
}#获取SDK信息
function getSdkProperty()
{$setCmdlocal sdk="$1"local propertyName="$2"propertyValue=`xcodebuild -version -sdk $sdk $propertyName` || \panic $? "Failed to get $sdk SDK property $propertyName"[[ $propertyValue != "" ]] || \panic 1 "Value of $sdk SDK property $propertyName cannot be empty"# return #echo "$propertyValue"
}#下载文件
function downloadFile() # args: sourceUrl, targetPath
{local sourceUrl="$1"local targetPath="$2"local curlPathmkdir -p "${targetPath%/*}" || \panic $? "Failed to make directory: ${targetPath%/*}"curlPath=`which curl` || \panic $? "Failed to get curl path""$curlPath" --output "$targetPath" "$sourceUrl" || \panic $? "Failed to download $sourceUrl to $targetPath"
}#解压文件
function extractTar() # args: tarPath, outputPath
{local tarPath="$1"local outputPath="$2"tar -C "$outputPath" -zxf "$tarPath" || \panic $? "Failed to extract $tarPath to $outputPath"
}#下载github文件
function downloadGithubTarball() # args: url, outputDir, title
{$setcmdlocal url="$1"local outputDir="$2"local title="$3"local tempDirForTarlocal tempDirForFileslocal untardDirlocal tarFile="file.tar.gz"echo "Downloading $title from Github..."tempDirForTar=`getTempDir`tempDirForFiles=`getTempDir`downloadFile "$url" "$tempDirForTar/$tarFile"extractTar "$tempDirForTar/$tarFile" "$tempDirForFiles"untardDir=`find "$tempDirForFiles/"* -type d -depth 0` || \panic $? "Failed to get untar'ed directory name of $tempDirForTar/$tarFile"mkdir -p "$outputDir" || \panic $? "Failed to make directory: $outputDir"cp -fR "$untardDir/"* "$outputDir/"
}#修改文件权限
function changeMode()
{local mode="$1"local target="$2"local recursive="$3"local options[[ $recursive != "true" ]] || \options="-R"if [[ -e "$target" ]]; thenchmod $options "$mode" "$target" || \panic $? "Failed to change mode to $mode on $target"fi
}#获取用户profile文件
function determineUserBashProfileFile()
{$setCmdlocal flocal filePathfor f in "${bashProfileFiles[@]}"; doif [[ -f "$f" ]]; thenfilePath="$f"echo "" >> "$f" || \panic $? "Failed to echo into $f"breakfidoneif [[ $filePath == "" ]]; thenfilePath="$bashProfileFiles"touch "$filePath" || \panic $? "Failed to touch $filePath"chown "$userName:$userGroup" "$filePath" || \panic $? "Failed to change owner-group of $filePath"changeMode 0600 "$filePath"fi# return #echo "$filePath"
}#验证是否存在文件
function requireFile() # args: filePath [, touchFileIfNotFound]
{local filePath="$1"local touchFileIfNotFound="$2"if [[ ! -f "$filePath" ]]; thenif [[ $touchFileIfNotFound == "true" ]]; thentouch "$filePath" || \panic $? "Failed to touch $filePath"elsepanic 1 "File $filePath not found"fifi
}#增加内容到文件
function addToFileIfMissing() # args: filePath, pattern, value
{local filePath="$1"local pattern="$2"local value="$3"local doesContaindoesContain=`doesFileContain "$filePath" "$pattern"`[[ $doesContain == "true" ]] || \echo "$value" >> "$filePath" || \panic $? "Failed to echo into $filePath"
}#判断文件是否包含内容
function doesFileContain() # args: filePath, pattern
{$setCmdlocal filePath="$1"local pattern="$2"local perlValuelocal funcReturnperlValue=`perl -ne 'if (/'"$pattern"'/) { print "true"; exit; }' "$filePath"` || \panic $? "Failed to perl"if [[ $perlValue == "true" ]]; thenfuncReturn="true"elsefuncReturn="false"fi# return #echo $funcReturn
}#从spec读取内容
function readXcodeSpecificationById(){ #args: filePath, idlocal filePath="$1"local id="$2"content=`/usr/libexec/PlistBuddy -x -c Print "$filePath"` || \panic $? "Failed to get $filePath content"for (( i=0; i<=1; i++)); dodict=`/usr/libexec/PlistBuddy -x -c "Print $i" "$filePath"`if echo $dict | grep -qE "<string>$id</string>"; thenecho "$dict"fidone
}#往spec文件写入内容
function writeDictToSpecification(){ #args: filePath, content# echo $1,$2local filePath="$1"local content="$2"tempfile=`getTempDir`/dictfile# echo $contentecho "$content" >> $tempfile# /usr/libexec/PlistBuddy -x -c 'add 0 dict' "$filePath" > /dev/null# cat $1/usr/libexec/PlistBuddy -x -c "merge $tempfile 0" "$filePath" > /dev/null# cat $1
}# start it
# 创建/opt/MonkeyDev
mkdir -p "$MonkeyDevPath" || \panic $? "Failed to make directory: $MonkeyDevPath"branch="master"if [[ "$1" ]]; thenbranch="$1"
fi#下载一些基础文件和模板文件
downloadGithubTarball "https://codeload.github.com/AloneMonkey/MonkeyDev/tar.gz/$branch" "$MonkeyDevPath" "MonkeyDev base"
downloadGithubTarball "https://codeload.github.com/AloneMonkey/MonkeyDev-Xcode-Templates/tar.gz/$branch" "$MonkeyDevPath/templates" "Xcode templates"#下载frida-ios-dump
echo "Moving frida-ios-dump from Resources..."
downloadFile "https://raw.githubusercontent.com/shadow-boy/MonkeyDev/master/Resource/dump.py" "$MonkeyDevPath/bin/dump.py"
downloadFile "https://raw.githubusercontent.com/shadow-boy/MonkeyDev/master/Resource/dump.js" "$MonkeyDevPath/bin/dump.js"
# cp Resource/dump.js $MonkeyDevPath/bin/dump.js
# cp Resource/dump.py $MonkeyDevPath/bin/dump.py
chmod +x "$MonkeyDevPath/bin/dump.py"#创建符号链接
echo "Creating symlink to Xcode templates..."#$userHome/Library/Developer/Xcode/Templates/MonkeyDev linkto $MonkeyDevPath/templates
userDevDir="$userHome/Library/Developer"
userTemplatesDir="$userDevDir/Xcode/Templates"if [[ ! -d "$userTemplatesDir" ]]; thenmkdir -p "$userTemplatesDir" || \panic $? "Failed to make directory: $userTemplatesDir"chown -R "$userName:$userGroup" "$userDevDir" || \panic $? "Failed to change ownership-group of $userDevDir"
filn -fhs "$MonkeyDevPath/templates" "$userTemplatesDir/MonkeyDev"#修改用户profile文件
echo "Modifying Bash personal initialization file..."userBashProfileFile=`determineUserBashProfileFile`addToFileIfMissing "$userBashProfileFile" "^(export)? *MonkeyDevPath=.*" "export MonkeyDevPath=$MonkeyDevPath"
addToFileIfMissing "$userBashProfileFile" "^(export)? *MonkeyDevDeviceIP=.*" "export MonkeyDevDeviceIP="
addToFileIfMissing "$userBashProfileFile" "^(export)? *PATH=.*(\\\$MonkeyDevPath\\/bin|${MonkeyDevPath//\//\\/}\\/bin).*" "export PATH=$MonkeyDevPath/bin:\$PATH"#支持iphoneos command line tools
iosSdkPlatformPath=`getSdkProperty iphoneos PlatformPath`
macosSdkPlatformPath=`getSdkProperty macosx PlatformPath`# specificationFile="/Applications/Xcode.app/Contents/Developer/Library/Xcode/Plug-ins/XCBSpecifications.ideplugin/Contents/Resources/Embedded-Device.xcspec"# for xcode16
specificationFile=$(find /Applications/Xcode.app -name "Embedded-Device.xcspec" | head -n 1)requireFile "$specificationFile" false# backup
requireBackup "$specificationFile"hasPackageTypeForCommandLineTool=`doesFileContain "$specificationFile" 'com.apple.package-type.mach-o-executable'`
hasProductTypeForCommandLineTool=`doesFileContain "$specificationFile" 'com.apple.product-type.tool'`macosxSDKSpecificationsPath="$(cd $macosSdkPlatformPath/../../.. && pwd)/PlugIns/XCBSpecifications.ideplugin/Contents/Resources"
# echo $macosxSDKSpecificationsPath
packageTypesForMacOSXPath=$(find /Applications/Xcode.app -name "MacOSX Package Types.xcspec" | head -n 1)
productTypesForMacOSXPath=$(find /Applications/Xcode.app -name "MacOSX Product Types.xcspec" | head -n 1)requireFile "$packageTypesForMacOSXPath" false
requireFile "$productTypesForMacOSXPath" falseif [[ $hasPackageTypeForCommandLineTool != "true" ]]; thenmachoDict=`readXcodeSpecificationById "$packageTypesForMacOSXPath" "com.apple.package-type.mach-o-executable"`writeDictToSpecification "$specificationFile" "$machoDict"
fiif [[ $hasProductTypeForCommandLineTool != "true" ]]; thentoolDict=`readXcodeSpecificationById "$productTypesForMacOSXPath" "com.apple.product-type.tool"`writeDictToSpecification "$specificationFile" "$toolDict"
fiexit 0
3、An empty code signing identity is not valid when signing a binary for the 'Dynamic Library' product type.
点击这里的+号
添加 CODE_SIGNING_ALLOWED=NO 选项
4、Can't link a dylib with itself. same install_name as dylib being built in '/Users/........./Package/Library/MobileSubstrate/DynamicLibraries/HookTest.dylib'
这是因为已经编译生成过文件了,删除这个文件之后重新编译即可。
5、with ldid... /opt/MonkeyDev/bin/md: line 326: ldid: command not found 错误解决
这里执行了这个脚本/opt/MonkeyDev/bin/md。往这里面添加brew install 安装文件的目录即可
sudo vim /opt/MonkeyDev/bin/md