有關xcode免認證偵錯工具的文章,在網上有一大堆,但是其中有許多錯誤和以訛傳訛的地方,並且沒有介紹基本原理。
因此我想簡單總結一下,方便新人使用:
背景知識:xcode是開發phone、ipad的必備開發工具,開發的程式可以通過xcode內建的iphone、ipad模擬器運行。但是不能把程式傳到真實的裝置上進行調試和運行。開發人員必須購買99美元/年的開發賬戶,才能再真機上運行和偵錯工具。本文就是講述如何通過破解xcode,使得使用者可以不需要購買99美元開發賬戶,就能在真機上偵錯工具。注意:運行程式的iphone或ipad必須要越獄,而且開發人員如果在appstore上發布程式,那就必須購買開發賬戶。
1、建立個人認證(使用工具 + 生產力-鑰匙串訪問 命令建立,具體步驟在網上有很詳細的介紹,這裡不詳述了)。(非必要步驟)
建立立的個人認證沒有經過蘋果認證,是不可信認證,因此在正常情況下,xcode不可能使用這個認證,所以必須對xcode進行破解才行。不過破解xcode之後,使用不可信的偽認證和不使用認證的效果一樣的,因此這個步驟並不是必須的。
2、修改Xcode的設定檔和二進位檔案,破解xcode。
這是至關重要的步驟,對xcode進行破解,才能讓其不使用認證或使用偽造認證向iphone上傳和調試ios程式。
保證Xcode處於關閉狀態,命令列終端,複製粘貼下面的代碼:
#!/bin/bash
cd /Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Plug-ins/iPhoneOS\ Build\ System\ Support.xcplugin/Contents/MacOS/
dd if=iPhoneOS\ Build\ System\ Support of=working bs=500 count=255
printf “\x8f\x2a\x00\x00″ >> working
dd if=iPhoneOS\ Build\ System\ Support of=working bs=1 skip=127504 seek=127504
/bin/mv -n iPhoneOS\ Build\ System\ Support iPhoneOS\ Build\ System\ Support.original
/bin/mv working iPhoneOS\ Build\ System\ Support
chmod a+x iPhoneOS\ Build\ System\ Support
以上代碼對support.xcplugin檔案進行來修改。
3、修改xcode的設定檔
①cd /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/
新增如下兩項:
PROVISIONING_PROFILE_ALLOWED = NO
PROVISIONING_PROFILE_REQUIRED = NO
②替換“/Developer/Platforms/iPhoneOS.platform/Info.plist”檔案部分單詞:
將所有“XCiPhoneOSCodeSignContext”替換為“XCCodeSignContext”
4、開啟xcode,修改具體項目的配置(此步驟以後在每次建立項目的時候都得進行)
開啟Xcode->然後開啟自己的項目->菜單選擇(Project>>Edit Project Setting)->選擇“Build”面板->找到Code Signing Identity項,並將“Code Signing Identity”更改賦值。兩種方法:
1)如果你建立來偽造的認證“iPhone Developer”(名字可以隨便起),這裡就可以選擇你建立認證的名字。
2)如果沒有建立認證,這裡選擇“Don't Code Sign”
5、建立Code Signing Entitlements檔案。
沒有這個檔案,雖然程式可以上傳到iphone上運行,但是xcode不能調試iphone上的程式。
建立Code Signing Entitlements有兩種方法:
1)方法一:利用指令檔進行建立(注意,此方法我在實驗時,沒有成功,正在尋找原因,添加的指令碼沒有執行)
①串連互連網後執行
mkdir /Developer/iphoneentitlements401
cd /Developer/iphoneentitlements401
curl -O http://www.alexwhittemore.com/iphone/gen_entitlements.txt
mv gen_entitlements.txt gen_entitlements.py
chmod 777 gen_entitlements.py
注意:這裡的建立立的目錄iphoneentitlements401 名稱可以隨便起,但在後面指令檔使用時需注意目錄名稱統一。
②添加自訂的產生指令碼
在Build Phases中添加一個Phase,右下角的Add Build Phase,然後單擊Add Run Script,輸入以下指令碼
export CODESIGN_ALLOCATE=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate
if [ "${PLATFORM_NAME}" == "iphoneos" ] || [ "${PLATFORM_NAME}" == "ipados" ]; then
/Applications/Xcode.app/Contents/Developer/iphoneentitlements/gen_entitlements.py "my.company.${PROJECT_NAME}" "${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/${PROJECT_NAME}.xcent";
codesign -f -s "iPhone Developer" --entitlements "${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/${PROJECT_NAME}.xcent" "${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/"
fi
2)方法二:手工添加檔案
①在工程中按照這個執行建立一個名為:Entitlement.plist 檔案,具體方法是:開啟 File Menu, 選擇 New File -> iPhone OS -> Code Signing -> Entitlements. Name the file “Entitlements.plist" ,然後點擊 ‘Finish’.
②開啟 這個 “Entitlement.plist"檔案,將 “Can be debugged”屬性值改為 “YES”,將“get-task-allow”屬性值改為“YES”。(建立的時候,預設好像就是YES)
③將Code Signing Entitlements 那項的值改為剛剛建立得“Entitlements.plist".
經過上述5個步驟,就可以在iphone上免認證,偵錯工具了。
這是我自己的總結,請各位批評指正。
附1:產生IPA檔案(本人未測試)
如果我的程式調試好了,怎麼才能發給別人用呢?正常情況下IPA檔案是從Xcode的Organizer中輸出的,但是我們沒有認證,這樣輸出會產生錯誤。我們只能用個小Trick來完成這個操作了。
先將代碼產生為Release目標,然後開啟工程的輸出檔案夾,通常情況下這個目錄是
/Users/你都使用者名稱/Library/Developer/Xcode/DerivedData/以工程名打頭的檔案夾/Build/Products/Release-iphoneos
這個目錄下有個.app的檔案,就是產生的程式了。把這個.app拖到iTunes中,它會出現在應用程式那個列表中,然後再把它從iTunes的那個列表中拖出來(比如拖到案頭),就變成.ipa了。
附2: gen_entitlements.py 檔案具體內容
#!/usr/bin/env python
import sys
import struct
if len(sys.argv) != 3:
print "Usage: %s appname dest_file.xcent" % sys.argv[0]
sys.exit(-1)
APPNAME = sys.argv[1]
DEST = sys.argv[2]
if not DEST.endswith('.xml') and not DEST.endswith('.xcent'):
print "Dest must be .xml (for ldid) or .xcent (for codesign)"
sys.exit(-1)
entitlements = """
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>application-identifier</key>
<string>%s</string>
<key>get-task-allow</key>
<true/>
</dict>
</plist>
""" % APPNAME
f = open(DEST,'w')
if DEST.endswith('.xcent'):
f.write("\xfa\xde\x71\x71")
f.write(struct.pack('>L', len(entitlements) + 8))
f.write(entitlements)
f.close()