├── .gitignore
├── APNS
├── README.md
└── apnsPem.sh
├── B&A&D
├── README.md
├── archive.config
├── build.sh
└── exportOptions
│ ├── ad-hoc.plist
│ ├── app-store.plist
│ ├── development.plist
│ └── enterprise.plist
├── LICENSE
├── README.md
├── autoResign
├── README.md
├── aUtoReSiGn.sh
└── resign
│ ├── EnterPrise_Development.mobileprovision
│ ├── EnterPrise_Distribution.mobileprovision
│ ├── Entitlements
│ ├── developer
│ │ └── Entitlements.plist
│ ├── free
│ │ └── Entitlements.plist
│ └── production
│ │ └── Entitlements.plist
│ ├── Free.mobileprovision
│ ├── certificate.png
│ ├── provisioning profiles.png
│ ├── resign.config
│ └── resign.sh
├── class_dump
├── README.md
├── class-dump
└── dumpdecrypted.dylib
├── crashMe
├── README.md
└── sourcecode.png
├── cydia.md
├── inject_with_jailbreaking
├── AsyncSocket.h
├── AsyncSocket.m
├── Xtrace.h
├── Xtrace.mm
├── build_inject.sh
├── wspx_inject.mm
└── wspx_inject.plist
├── isWKoUI
├── README.md
└── iswkoui.png
├── jailBreak
└── README.md
├── nextDay
└── README.md
└── pRoxY
├── README.md
├── crontabScript.sh
└── proxy_demo.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # https://github.com/MrChens/iOS_Tools
2 |
3 | .DS_Store
4 |
--------------------------------------------------------------------------------
/APNS/README.md:
--------------------------------------------------------------------------------
1 | 推送证书的生成:
2 | ================
3 |
4 | 1. 在identifiers-->App IDs中找到对应的appid
5 | 2. 点击edit-->Create Certificate...
6 | 3. 制作CSR文件:打开钥匙串-->证书助理-->从证书颁发机构请求证书(填写账号的邮箱和存储到磁盘)
7 | 4. 返回到刚才的Create Certificate中点击Choose File选择刚才生成的CSR文件然后点击Continue
8 | 5. 下载证书并双击打开钥匙串访问,在左边的证书中选择刚刚弄的好的证书,右键导出为p12文件
9 | 6. 然后使用apnsPem.sh来创建pem文件。(提示输入密码,输入刚才导出p12时的密码)
10 |
11 | Generate apns pem file
12 | ======================
13 |
14 | 1. Login you apple Developer account in https://developer.apple.com/
15 | 2. In `Identifiers` click `App IDs` then Choose you `iOS App IDs` which you wanna create apns pem file.
16 | 3. Expanding it and click `edit`
17 | 4. Before you click `Create Certificate...`, you need generate CSR file.
18 | 5. In the `Push Notifications` section click `Create Certificate...` then click `Choose File` upload the CSR file which you created a moment ago.
19 | 6. Then click `Continue` and download the `xx.cer` file.
20 | 7. Double click the `xx.cer` file, and then choose the certificates which you just download amoment ago.
21 | 8. Export the `xx.cer` file as p12 file.(important:remember your password, we will use it in the follow steps.)
22 | 9. Then use the tool `apnsPem.sh` to create apns pem file.
23 |
24 | Generate CSR file(CertificateSigningRequest)
25 | ============================================
26 |
27 | 1. open `Keychain Access` > `Certificate Assistant` > `Request a Certificate from a Certificate Authority`.
28 | - In the User Email Address field, enter your email address.
29 | - In the Common Name field, create a name for your private key (e.g., John Doe Dev Key).
30 | - The CA Email Address field should be left empty.
31 | - In the "Request is" group, select the "Saved to disk" option.
32 | 2. Click Continue within Keychain Access to complete the CSR generating process.
33 |
--------------------------------------------------------------------------------
/APNS/apnsPem.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | if [ $# -lt 2 ]; then
3 | echo ""
4 | echo "\t Usage:"
5 | echo "\t\t ./apnsPem.sh xxx.p12 xxx.pem"
6 | echo "\t\t the xxx.p12 is the file which you export from Keychain Access."
7 | echo "\t\t the xxx.pme is the file name which you generate from xxx.p12."
8 | exit 0
9 | fi
10 |
11 | INAPNSCERTP12=$1
12 | OUTANPSCERTPEM=$2
13 | echo "\t Please enter your password when the p12 file is generated."
14 | openssl pkcs12 -in $INAPNSCERTP12 -out $OUTANPSCERTPEM -nodes
15 |
--------------------------------------------------------------------------------
/B&A&D/README.md:
--------------------------------------------------------------------------------
1 | # 环境要求:
2 | 1. OSX 10.8以上.
3 | 2. Xcode8.0以上.
4 |
5 | # 使用方式:
6 | 1. 将`exportOptions`,`build.sh`,`archive.config`放入你项目的根目录
7 | 2. 修改`build.sh`中`ARCHIVE_SCHEME_NAME`,`ARCHIVE_PROJECT_NAME`,`ApplicationLoader_UserName`,`ApplicationLoader_Password`为你对应的
8 | 3. 执行`build.sh archive.config`
9 |
10 |
11 | ### 在使用过程中如果有任何问题或者改良的方案欢迎提issue和pr.
12 |
--------------------------------------------------------------------------------
/B&A&D/archive.config:
--------------------------------------------------------------------------------
1 | # TYPE=enterprise appstore ad-hoc development
2 | # Last RELEASE ENTERPRISE BUILDVERSION 100 TODO: 这里的时间用脚本生成
3 | # Last RELEASE APPSTORE BUILDVERSION 130 TODO: 这里的时间用脚本生成.
4 | # RELEASE: indicate whether is need upload dSYMs and ipa to SVN.
5 | # DELIVER_TO_APPSTORE: indicate whether is need upload to AppStore.
6 |
7 | TYPE=enterprise
8 | VERSION=1
9 | EP_BUILDVERSION=0
10 | AS_BUILDVERSION=0
11 | DE_BUILDVERSION=0
12 | DELIVER_TO_APPSTORE=false
13 | RELEASE=true
14 |
--------------------------------------------------------------------------------
/B&A&D/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # https://developer.apple.com/library/content/technotes/tn2215/_index.html
3 | # https://itunesconnect.apple.com/docs/UsingApplicationLoader.pdf
4 | # http://www.matrixprojects.net/p/xcodebuild-export-options-plist/
5 | # http://www.voidcn.com/blog/potato512/article/p-6165228.html
6 | # http://www.jianshu.com/p/bd4c22952e01
7 | # ``有返回值
8 | # ''不做格式化
9 | # ""做格式化
10 | # 0标准输入(stdin),1标准输出(stdout), 2标准错误(stderr)
11 | # error: exportArchive: No applicable devices found. solution: https://github.com/bitrise-io/steps-xcode-archive/issues/37 rvm use system
12 | # xcodebuild exit code :https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man3/sysexits.3.html#//apple_ref/doc/man/3/sysexits
13 |
14 | ALTOOL_DIR="/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool"
15 | ARCHIVE_SCHEME_NAME="wsyun"
16 | ARCHIVE_PROJECT_NAME="wsyun.xcodeproj"
17 | ApplicationLoader_UserName="zhengluff@chinanetcenter.com"
18 | ApplicationLoader_Password="iTunes Producer: zhengluff@chinanetcenter.com"
19 |
20 |
21 | BUGTRACKER_URL="svn://chenshilong@192.168.24.144:8888/tm/flow_browser/BugTracker"
22 | BUGTRACKER_DIR="$HOME/Documents"
23 | BUGTRACKER="BugTracker"
24 | IPA_PREFIX_APPSTORE="${ARCHIVE_SCHEME_NAME}_AppStore_"
25 | IPA_PREFIX_ENTERPRISE="${ARCHIVE_SCHEME_NAME}_ENT_"
26 | CUR_PATH="$PWD"
27 | PROJECT_DIR="${CUR_PATH}"
28 |
29 | BUILD_TIME=`date "+%m-%d-%y, %l.%M %p"`
30 | BUILD_DATE=`date "+%Y-%m-%d"`
31 | EXPORT_TIME=`date "+%Y%m%d%H_%M"`
32 | APP_VERSION="agvtool what-marketing-version -terse1"
33 |
34 | ARCHIVE_FILE_NAME="$ARCHIVE_SCHEME_NAME $BUILD_TIME.xcarchive"
35 | ARCHIVE_FILE_PATH="$HOME/Library/Developer/Xcode/Archives/${BUILD_DATE}/${ARCHIVE_FILE_NAME}"
36 | ARCHIVE_LOG_FILE_NAME="archive.log"
37 | # ARCHIVE_FILE_PATH="$HOME/Library/Developer/Xcode/Archives/2017-06-06/UOne 06-06-17, 3.56 PM.xcarchive"
38 |
39 |
40 | OUTPUT_IPA_APPSTORE="$HOME/Desktop/ipa/${ARCHIVE_SCHEME_NAME}_AppStore/$ARCHIVE_SCHEME_NAME"
41 | OUTPUT_IPA_ENTERPRISE="$HOME/Desktop/ipa/${ARCHIVE_SCHEME_NAME}_EnterPrise/$ARCHIVE_SCHEME_NAME"
42 |
43 | APPSTORE_RESPONED_FILE_NAME="respon.plist"
44 |
45 | function set_publish_mode() {
46 | echo "set UOneConfig.plist to publish mode ${PROJECT_DIR}"
47 | cd "${PROJECT_DIR}/WSPXBrowser"
48 | plutil -p UOneConfig.plist
49 | plutil -replace PMSServiceType -integer 0 UOneConfig.plist
50 | plutil -replace UOneServiceType -integer 0 UOneConfig.plist
51 | plutil -replace CrashMonitor -bool true UOneConfig.plist
52 | plutil -replace NSLogToFile -bool false UOneConfig.plist
53 | plutil -p UOneConfig.plist
54 | sed -i.bak 's/kWspxTest (1)/kWspxTest (0)/g' WSPXUOneDefine.h
55 | sed -i.bak 's/wspxUILog (1)/wspxUILog (0)/g' WSPXUOneDefine.h
56 | sed -i.bak 's/kWspxCustomPhoneTest (1)/kWspxCustomPhoneTest (0)/g' WSPXUOneDefine.h
57 | sed -i.bak 's/kSwitchToLocalJsFile (1)/kSwitchToLocalJsFile (0)/g' WSPXUOneDefine.h
58 |
59 | rm WSPXUOneDefine.h.bak
60 | echo 'set WSPXUOneDefine.h to RELEASE DONE'
61 | }
62 |
63 | function build_enterprise() {
64 | echo -e "构建企业版${ARCHIVE_SCHEME_NAME} build at: ${BUILD_TIME}"
65 | echo -e ""
66 | set_publish_mode
67 | cd $PROJECT_DIR
68 | echo "arguments $* "
69 | CONFIGURATION_TYPE=$4
70 |
71 | agvtool what-marketing-version # update CFBundleShortVersionString
72 | agvtool new-marketing-version $1
73 |
74 | agvtool what-version # update CFBundleVersion
75 | agvtool new-version -all $[ $2+1 ]
76 | echo 'clear...'
77 | xcodebuild clean -project "$ARCHIVE_PROJECT_NAME" -configuration "$CONFIGURATION_TYPE" -quiet
78 | echo -e "xcodebuild clean exit code:$?"
79 |
80 | echo 'archive...'
81 | if [[ -e "${ARCHIVE_LOG_FILE_NAME}" ]]; then
82 | rm $ARCHIVE_LOG_FILE_NAME
83 | fi
84 | xcodebuild archive -project ./"$ARCHIVE_PROJECT_NAME" -scheme "$ARCHIVE_SCHEME_NAME" -configuration "$CONFIGURATION_TYPE" -archivePath "$ARCHIVE_FILE_PATH" PROVISIONING_PROFILE="Automatic"#CODE_SIGN_IDENTITY="iPhone Developer" -quiet > $ARCHIVE_LOG_FILE_NAME #PROVISIONING_PROFILE="Automatic" #-quiet > /dev/null #貌似不指定provisioning_profile才是真的automatic
85 | checkXcodebuildExitCode
86 | rm -r "build"
87 | echo 'exportArchive...'
88 | xcodebuild -exportArchive -archivePath "$ARCHIVE_FILE_PATH" -exportPath "$CUR_PATH" -exportOptionsPlist ./exportOptions/$3.plist
89 |
90 | echo -e "move ipa file to :$OUTPUT_IPA_ENTERPRISE`$APP_VERSION`/"
91 | if [[ ! -e "$OUTPUT_IPA_ENTERPRISE`$APP_VERSION`" ]]; then
92 | echo -e "create ipa directory.:$OUTPUT_IPA_ENTERPRISE`$APP_VERSION`"
93 | mkdir $OUTPUT_IPA_ENTERPRISE`$APP_VERSION`
94 | fi
95 |
96 | rm -i -f "$OUTPUT_IPA_ENTERPRISE`$APP_VERSION`/"*.ipa
97 |
98 | cp -i "$ARCHIVE_SCHEME_NAME.ipa" "$OUTPUT_IPA_ENTERPRISE`$APP_VERSION`/${IPA_PREFIX_ENTERPRISE}${EXPORT_TIME}.ipa"
99 | if [[ -e "$OUTPUT_IPA_ENTERPRISE`$APP_VERSION`/${IPA_PREFIX_ENTERPRISE}${EXPORT_TIME}.ipa" ]]; then
100 | echo "open directory===>$OUTPUT_IPA_ENTERPRISE`$APP_VERSION`/"
101 | open "$OUTPUT_IPA_ENTERPRISE`$APP_VERSION`/"
102 | fi
103 | }
104 |
105 | function build_appStore() {
106 | echo -e "构建商店版${ARCHIVE_SCHEME_NAME} build at: ${BUILD_TIME}"
107 | echo -e ""
108 | set_publish_mode
109 | cd "$PROJECT_DIR/AppStore"
110 | echo "arguments $*"
111 |
112 | agvtool what-marketing-version
113 | agvtool new-marketing-version $1
114 |
115 | agvtool what-version
116 | agvtool new-version -all $[ $2+2 ]
117 | echo 'clear...'
118 | xcodebuild clean -project "$ARCHIVE_PROJECT_NAME" -configuration Release -quiet
119 | echo -e "xcodebuild clean exit code:$?"
120 |
121 | echo 'archive...'
122 | if [[ -e "${ARCHIVE_LOG_FILE_NAME}" ]]; then
123 | rm $ARCHIVE_LOG_FILE_NAME
124 | fi
125 | xcodebuild archive -project ./"$ARCHIVE_PROJECT_NAME" -scheme "$ARCHIVE_SCHEME_NAME" -configuration Release -archivePath "$ARCHIVE_FILE_PATH" CODE_SIGN_IDENTITY="iPhone Developer" -quiet > $ARCHIVE_LOG_FILE_NAME #PROVISIONING_PROFILE="Automatic" -quiet > /dev/null #貌似不指定provisioning_profile才是真的automatic
126 |
127 | checkXcodebuildExitCode
128 |
129 | rm -r "build"
130 | echo 'exportArchive...'
131 | xcodebuild -exportArchive -archivePath "$ARCHIVE_FILE_PATH" -exportPath "$OUTPUT_IPA_APPSTORE`$APP_VERSION`" -exportOptionsPlist ../exportOptions/$3.plist
132 |
133 | echo -e "move ipa file to :$OUTPUT_IPA_APPSTORE`$APP_VERSION`/"
134 | if [[ ! -e "$OUTPUT_IPA_APPSTORE`$APP_VERSION`" ]]; then
135 | echo -e "create ipa directory.:$OUTPUT_IPA_APPSTORE`$APP_VERSION`"
136 | mkdir $OUTPUT_IPA_APPSTORE`$APP_VERSION`
137 |
138 | fi
139 |
140 | mv -i "$OUTPUT_IPA_APPSTORE`$APP_VERSION`/$ARCHIVE_SCHEME_NAME.ipa" "$OUTPUT_IPA_APPSTORE`$APP_VERSION`/${IPA_PREFIX_APPSTORE}${EXPORT_TIME}.ipa"
141 | if [[ -e "$OUTPUT_IPA_APPSTORE`$APP_VERSION`/${IPA_PREFIX_APPSTORE}${EXPORT_TIME}.ipa" ]]; then
142 | echo "open directory===>$OUTPUT_IPA_APPSTORE`$APP_VERSION`/"
143 | open "$OUTPUT_IPA_APPSTORE`$APP_VERSION`/"
144 | fi
145 | }
146 |
147 | function deliver_appStore() {
148 | echo -e "Uploading Your Application Binary Files with altool..."
149 | "$ALTOOL_DIR" --upload-app -f "$OUTPUT_IPA_APPSTORE`$APP_VERSION`/${IPA_PREFIX_APPSTORE}${EXPORT_TIME}.ipa" -u "$ApplicationLoader_UserName" -p @keychain:"$ApplicationLoader_Password" --output-format xml > $APPSTORE_RESPONED_FILE_NAME
150 | }
151 |
152 | function echoSVNStatus() {
153 | echo -e ""
154 | echo -e "Time:`date "+%m-%d-%y, %l.%M.%S %p"`"
155 | echo -e "SVN STATUS:"
156 | svn status
157 | }
158 |
159 | function bugTracker() {
160 | echo -e "checkout BugTracker..."
161 | svn checkout ${BUGTRACKER_URL} ${BUGTRACKER_DIR}/${BUGTRACKER} 1> /dev/null
162 |
163 | if [[ ! -e "${BUGTRACKER_DIR}/${BUGTRACKER}" ]]; then
164 | echo -e "create BugTracker directory."
165 | mkdir ${BUGTRACKER_DIR}/$BUGTRACKER
166 | svn mkdir -m "create BugTracker directory." ${BUGTRACKER_URL}
167 | svn checkout ${BUGTRACKER_URL} ${BUGTRACKER_DIR}/${BUGTRACKER} 1> /dev/null
168 | fi
169 |
170 | dSYMsFile=`ls "${ARCHIVE_FILE_PATH}"/dSYMs/`
171 | BaseString=`xcrun dwarfdump --uuid "${ARCHIVE_FILE_PATH}/dSYMs/${dSYMsFile}" | sed -n -e '/UUID:/p' | grep "UUID:.*" | awk '{split( $0, a, " "); print a[2]}' `
172 | commitMessage=`echo $BaseString | sed 's/ /;/g'`
173 | UUIDFile=`echo $BaseString | sed 's/-//g' | sed 's/ //g' `
174 | echo -e "UUIDFILE:${UUIDFile}"
175 |
176 | filePath=${BUGTRACKER_DIR}/${BUGTRACKER}/${ARCHIVE_SCHEME_NAME}/`$APP_VERSION`/${UUIDFile}
177 | mkdir -p $filePath
178 |
179 | echo -e "copy dSYMsFile:${dSYMsFile} to BugTracker..."
180 | cp -R "${ARCHIVE_FILE_PATH}/dSYMs/${dSYMsFile}" "${filePath}/${UUIDFile}.dSYM"
181 | if [[ $? -gt 0 ]]; then
182 | echo "cp dSYMsFile:${dSYMsFile} failed"
183 | fi
184 |
185 | if [[ $1 == 'enterprise' ]]; then
186 | echo -e "copy enterprise ipa to BugTracker..."
187 | cp -R "$OUTPUT_IPA_ENTERPRISE`$APP_VERSION`/${IPA_PREFIX_ENTERPRISE}${EXPORT_TIME}.ipa" "${filePath}"
188 | if [[ $? -gt 0 ]]; then
189 | echo -e "copy ipa failed:$OUTPUT_IPA_ENTERPRISE`$APP_VERSION`/${IPA_PREFIX_ENTERPRISE}${EXPORT_TIME}.ipa"
190 | fi
191 | else
192 | echo -e "copy app-store ipa to BugTracker..."
193 | cp -R "$OUTPUT_IPA_APPSTORE`$APP_VERSION`/${IPA_PREFIX_APPSTORE}${EXPORT_TIME}.ipa" "${filePath}"
194 | if [[ $? -gt 0 ]]; then
195 | echo -e "copy ipa failed:$OUTPUT_IPA_APPSTORE`$APP_VERSION`/${IPA_PREFIX_APPSTORE}${EXPORT_TIME}.ipa"
196 | fi
197 | fi
198 |
199 | cd $BUGTRACKER_DIR/$BUGTRACKER
200 | echoSVNStatus
201 |
202 | echo -e "SVN ADD"
203 | svn add ${ARCHIVE_SCHEME_NAME} --force
204 |
205 | echo "SVN COMMIT"
206 | svn commit -m "version:${APP_VERSION} $1=>${commitMessage}"
207 |
208 | echoSVNStatus
209 | }
210 |
211 | SUCCESS_MESSAGE="success-message"
212 | PRODUCT_ERRORS="product-errors"
213 |
214 | function checkResponse() {
215 |
216 | if [[ ! -e $APPSTORE_RESPONED_FILE_NAME ]]; then
217 | echo -e ""
218 | echo -e "file -->$APPSTORE_RESPONED_FILE_NAME not exist!!!"
219 | exit 1
220 | fi
221 |
222 | echo -e "---------------------------->check response<----------------------------"
223 |
224 | RETURN=`plutil -p $1 | grep "$SUCCESS_MESSAGE"`
225 | if [[ $RETURN == *"$SUCCESS_MESSAGE"* ]]; then
226 | STATUS=`plutil -p $1 | sed -n -e "/$SUCCESS_MESSAGE/,/dev-tools/p"`
227 | echo -e "response message:"
228 | echo -e "$STATUS"
229 | rm $1
230 | return 0
231 | fi
232 |
233 | RETURN=`plutil -p $1 | grep "$PRODUCT_ERRORS"`
234 | if [[ $RETURN == *"$PRODUCT_ERRORS"* ]]; then
235 | STATUS=`plutil -p $1 | sed -n -e "/$PRODUCT_ERRORS/,/]/p"`
236 | echo -e "response message:"
237 | echo -e "$STATUS"
238 | return 1
239 | fi
240 |
241 | return 1
242 | }
243 |
244 | function checkXcodebuildExitCode() {
245 | XcodebuildExitCode=$?
246 | echo -e "xcodebuild archive exit code:${XcodebuildExitCode}"
247 |
248 | if [[ $XcodebuildExitCode == 0 ]]; then
249 | echo -e "xcodebuild archive succed!"
250 | rm $ARCHIVE_LOG_FILE_NAME
251 | else
252 | echo -e "xocodebuild archive failed, please see ${ARCHIVE_LOG_FILE_NAME}"
253 | echo -e "open ${ARCHIVE_LOG_FILE_NAME}"
254 | open $ARCHIVE_LOG_FILE_NAME
255 | exit 1
256 | fi
257 | }
258 |
259 | function usage() {
260 | echo -e ""
261 | echo -e "build.sh command"
262 | echo -e "command:"
263 | echo -e " ./build.sh reset reset wscloudConfig.plist,WSPXUOneDefine.h to the publish mode."
264 | echo -e " ./build.sh archive.config reset wscloudConfig.plist,WSPXUOneDefine.h and archive project then output ipa."
265 | echo -e ""
266 | }
267 |
268 | function faq() {
269 | echo -e "系统要求:Xcode 8.1 "
270 | echo -e "使用该脚本之前请确保已经在本机安装了对应的证书和描述文件."
271 | echo -e "error: exportArchive: No applicable devices found. solution: https://github.com/bitrise-io/steps-xcode-archive/issues/37 rvm use system"
272 |
273 | }
274 |
275 | if [ $# != 1 ] ; then
276 | usage
277 | exit 0
278 | fi
279 |
280 | faq
281 |
282 | if [[ $1 == 'reset' ]]; then
283 | set_publish_mode
284 | elif [[ $1 == *"config"* ]]; then
285 | source ./$1
286 | if [[ $TYPE == 'enterprise' ]]; then
287 | build_enterprise $VERSION $EP_BUILDVERSION enterprise Release
288 | if [[ $RELEASE == 'true' ]]; then
289 | bugTracker $TYPE
290 | fi
291 | elif [[ $TYPE == 'appstore' ]]; then
292 | build_appStore $VERSION $AS_BUILDVERSION app-store
293 | if [[ $DELIVER_TO_APPSTORE == 'true' ]]; then
294 | deliver_appStore
295 | checkResponse $APPSTORE_RESPONED_FILE_NAME
296 | result=$?
297 | echo -e "---------------------------- checkResponse return value:$result ----------------------------"
298 | if [[ $result == 0 ]]; then
299 | bugTracker $TYPE
300 | fi
301 | fi
302 |
303 | elif [[ $TYPE == 'ad-hoc' ]]; then
304 | build_appStore $VERSION $BUILDVERSION ad-hoc
305 | elif [[ $TYPE == 'development' ]]; then
306 | build_enterprise $VERSION $DE_BUILDVERSION development Debug
307 | fi
308 | else
309 | usage
310 | fi
311 |
--------------------------------------------------------------------------------
/B&A&D/exportOptions/ad-hoc.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | stripSwiftSymbols
6 |
7 | signingStyle
8 | automatic
9 | thinning
10 | <none>
11 | compileBitcode
12 |
13 | method
14 | ad-hoc
15 | uploadBitcode
16 |
17 | teamID
18 | xxxxxx
19 | uploadSymbols
20 |
21 | manifest
22 |
23 | appURL
24 | http://xxxx/UOne-free-2.2.6.ipa?t=1472549634827
25 | displayImageURL
26 | http://xxxx.UOne_AppIcon_57x57.png
27 | fullSizeImageURL
28 | http://xxxx.UOne_AppIcon_512x512.png
29 | subtitle
30 | XXXX
31 | title
32 | XXXX
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/B&A&D/exportOptions/app-store.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | stripSwiftSymbols
6 |
7 | signingStyle
8 | automatic
9 | thinning
10 | <none>
11 | compileBitcode
12 |
13 | method
14 | app-store
15 | uploadBitcode
16 |
17 | teamID
18 | xxxxxx
19 | uploadSymbols
20 |
21 | manifest
22 |
23 | appURL
24 | http://cache.default.server.matocloud.com:39900/static.server.matocloud.com:8080/staticresource/static/cert/bms/app/package/UOne-free-2.2.6.ipa?t=1472549634827
25 | displayImageURL
26 | http://static.server.matocloud.com:8080/staticresource/static/cert/bms/app/package/com.chinanetcenter.UOne_AppIcon_57x57.png
27 | fullSizeImageURL
28 | http://static.server.matocloud.com:8080/staticresource/static/cert/bms/app/package/com.chinanetcenter.UOne_AppIcon_512x512.png
29 | subtitle
30 | XXXX
31 | title
32 | XXXX
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/B&A&D/exportOptions/development.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | thinning
6 | <none>
7 | signingStyle
8 | automatic
9 | stripSwiftSymbols
10 |
11 | compileBitcode
12 |
13 | method
14 | development
15 | uploadBitcode
16 |
17 | teamID
18 | xxxxxx
19 | provisioningProfiles
20 |
21 | com.xxxx.yyyy
22 | provisioningProfilesName_dev
23 |
24 | manifest
25 |
26 | appURL
27 | http://cache.default.server.matocloud.com:39900/static.server.matocloud.com:8080/staticresource/static/cert/bms/app/package/UOne-free-2.2.6.ipa?t=1472549634827
28 | displayImageURL
29 | http://static.server.matocloud.com:8080/staticresource/static/cert/bms/app/package/com.chinanetcenter.UOne_AppIcon_57x57.png
30 | fullSizeImageURL
31 | http://static.server.matocloud.com:8080/staticresource/static/cert/bms/app/package/com.chinanetcenter.UOne_AppIcon_512x512.png
32 | subtitle
33 | U玩
34 | title
35 | U玩
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/B&A&D/exportOptions/enterprise.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | thinning
6 | <none>
7 | signingStyle
8 | automatic
9 | stripSwiftSymbols
10 |
11 | compileBitcode
12 |
13 | method
14 | enterprise
15 | uploadBitcode
16 |
17 | teamID
18 | xxxxx
19 | provisioningProfiles
20 |
21 | com.xxxx.yyyy
22 | provisioningProfilesName
23 |
24 | manifest
25 |
26 | appURL
27 | http://xxxx/UOne-free-2.2.6.ipa?t=1472549634827
28 | displayImageURL
29 | http://xxxx.UOne_AppIcon_57x57.png
30 | fullSizeImageURL
31 | http://xxxx.UOne_AppIcon_512x512.png
32 | subtitle
33 | XXXX
34 | title
35 | XXXX
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 2-Clause License
2 |
3 | Copyright (c) 2017, ShiLong Chen
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # iOS_Tools
2 |
3 | 放一些在iOS开发中自己写的垃圾脚本工具[传送门][iOS_Tools]
4 |
5 | - `aUtoReSiGn` 是使用企业签名来做ipa包的自动重签名+自动安装重签名后的ipa包到测试设备中[传送门][aUtoReSiGn]
6 | - `inject_with_jailbreaking` 用来在越狱设备中hook某些app做些调研什么的[传送门][jailbreaking]
7 | - `class_dump` 对ipa文件进行头文件的导出[传送门][class_dump]
8 | - `codeObfuscated` 改良版的代码混淆[传送门][codeObfuscated]
9 | - `B&A&D` 构建,打包,并提交Itunesconnect上传dsym文件到svn以供后续Debug使用[传送门][B&A&D]
10 | - `isWKoUI` 检测app内的页面是`WKWebview`还是`UIWebview`[传送门][isWKoUI]
11 | - `crashMe` 演示如何通过`crash`文件排查`app`崩溃的问题[ 传送门][crashMe]
12 | - `nextDay` 演示什么叫做永远没空研究系列[传送门][nextDay]
13 | - `jailBreak` 记录越狱笔记[传送门][jailBreak]
14 |
15 | ### 在使用过程中如果有任何问题或者改良的方案欢迎提issue和pr.
16 |
17 | [jailbreaking]:https://github.com/MrChens/iOS_Tools/tree/master/inject_with_jailbreaking
18 | [class_dump]:https://github.com/MrChens/iOS_Tools/tree/master/class_dump
19 | [codeObfuscated]:https://github.com/MrChens/codeObfuscated
20 | [aUtoReSiGn]:https://github.com/MrChens/iOS_Tools/tree/master/autoResign
21 | [iOS_Tools]:https://github.com/MrChens/iOS_Tools
22 | [B&A&D]:https://github.com/MrChens/iOS_Tools/tree/master/B%26A%26D
23 | [isWKoUI]:https://github.com/MrChens/iOS_Tools/tree/master/isWKoUI
24 | [crashMe]:https://github.com/MrChens/iOS_Tools/tree/master/crashMe
25 | [nextDay]:https://github.com/MrChens/iOS_Tools/tree/master/nextDay
26 | [jailBreak]:https://github.com/MrChens/iOS_Tools/tree/master/jailBreak
27 |
--------------------------------------------------------------------------------
/autoResign/README.md:
--------------------------------------------------------------------------------
1 | # 1. 环境要求:
2 |
3 |
4 | 1. OSX 10.8以上.
5 | 2. Xcode8.0以上.
6 |
7 | # 2. 使用方式:
8 |
9 | 1. 直接在终端运行`aUtoReSiGn.sh`.
10 | 2. 将要需要企业重签名的`ipa`放入`input文件夹`中.
11 | 3. 企业重签名后的`ipa`文件会自动放入`output文件夹`中.
12 | 4. 默认情况下重签名的是Distribution版的,如需重签名`Development`版的请修改`resign.config`中的`GET_TASK_ALLOW`为`true`
13 | 5. 如若不需要自动重签名,请直接运行`resign.sh`脚本
14 | 6. 如若需要自动安装`ipa`到手机上,请修改`resign.config`中的`AUTO_INSTALL_IPA`为`true`
15 |
16 | # 3. 重要的:
17 |
18 | 在使用该脚本前您需要确保做了以下几件事:
19 |
20 | **P.S.:请看完全文后再配置,后面附有文件的详细获取/修改步骤** Development和Distribution的区别在于Development的重签名是可以`get-task-allow`
21 |
22 | ## 3.1.1 Development配置
23 |
24 | - 配置`Development`的企业证书在本地的电脑中(钥匙串中)
25 | - 将您下载的`Development`版的`xx.mobileprovision`放入`resign`目录中并重命名为`EnterPrise_Development.mobileprovision`,文件结构如下图`文件结构`所示
26 | - 修改`resign`中`Entitlements/developer/Entitlements.plist`的配置
27 | - 在`resign.config`文件中修改`CODESIGN_IDENTITIES_DEV`的值为您`Development`版的企业证书名字
28 |
29 | ## 3.1.2 Distribution配置
30 |
31 | - 配置`Distribution`的企业证书在本地的电脑中(钥匙串中)
32 | - 将您下载的`Distribution`版的`yy.mobileprovision`放入`resign`目录中并重命名为`EnterPrise_Distribution.mobileprovision`,文件结构如下图`文件结构`所示
33 | - 修改`resign`中`Entitlements/production/Entitlements.plist`的配置
34 | - 在`resign.config`文件中修改`CODESIGN_IDENTITIES`的值为您`Distribution`版的企业证书名字
35 |
36 | ## 3.1.3 free配置
37 |
38 | - 配置`free`的企业证书在本地的电脑中(钥匙串中)
39 | - 将您下载的`free`版的`yy.mobileprovision`放入`resign`目录中并重命名为`Free.mobileprovision`,文件结构如下图`文件结构`所示
40 | - 修改`resign`中`Entitlements/free/Entitlements.plist`的配置
41 | - 在`resign.config`文件中修改`CODESIGN_IDENTITIES_FREE`的值为您`Free`版的证书名字
42 |
43 | ## 3.2 如何修改对应的`Entitlements.plist`
44 |
45 | - 假设你的`teamID`为:`yourTeamID`
46 | - 假设你的`application-identifier`:为`yourTeamID.com.xxx.xxx`
47 | - 将`application-identifier`中的`yyyy.com.xxx.xxx`改为`yourTeamID.com.xxx.xxx`
48 | - 将`keychain-access-groups`的中的`yyyy.*`改为`yourTeamID.*`
49 |
50 | 如果看不懂上面说的是什么鬼.
51 | - Development配置
52 | - 将`Entitlements/developer/Entitlements.plist`中的`application-identifier`的值,改为`EnterPrise_Development.mobileprovision`文件中`application-identifier`中对应的值
53 | - 将`Entitlements/developer/Entitlements.plist`中的`keychain-access-groups`的值,改为`EnterPrise_Development.mobileprovision`文件中`keychain-access-groups`中对应的值
54 |
55 | - Distribution配置
56 | - 将`Entitlements/production/Entitlements.plist`中的`application-identifier`的值,改为`EnterPrise_Distribution.mobileprovision`文件中`application-identifier`中对应的值
57 | - 将`Entitlements/production/Entitlements.plist`中的`keychain-access-groups`的值,改为`EnterPrise_Distribution.mobileprovision`文件中`keychain-access-groups`中对应的值
58 |
59 | - Free配置
60 | - 将`Entitlements/free/Entitlements.plist`中的`application-identifier`的值,改为`Free.mobileprovision`文件中`application-identifier`中对应的值
61 | - 将`Entitlements/free/Entitlements.plist`中的`keychain-access-groups`的值,改为`Free.mobileprovision`文件中`keychain-access-groups`中对应的值
62 |
63 | ## 3.3 如何获取对应的`xx.mobileprovision`
64 |
65 | - Development
66 | - 登陆你的企业开发者账号,选择`Provisioning Profiles`下的`Development`下载`Type`为`iOS Development`的`Provisioning Profiles`文件(P.S.:没试过`Type`为`iOS UniversalDistribution`的)
67 | - Distribution
68 | - 登陆你的企业开发者账号,选择`Provisioning Profiles`下的`Distribution`下载`Type`为`iOS Distribution`的`Provisioning Profiles`文件(P.S.:没试过`Type`为`iOS UniversalDistribution`的)
69 | - Free
70 | - 在Xcode中登录你的Apple ID,然后利用Xcode下载
71 | - PS:目前处于实验阶段,等有空了再来补充完善free版本的签名文档
72 |
73 | ## 3.4 如何获取您证书的名字
74 | - Development
75 | - 打开电脑中的`Keychain Access`
76 | - 找到您的`Development`企业证书,并双击
77 | - 复制证书`Common Name`中对应的值到`resign.config`的`CODESIGN_IDENTITIES_DEV`
78 | - Distribution
79 | - 打开电脑中的`Keychain Access`
80 | - 找到您的`Distribution`企业证书,并双击
81 | - 复制证书`Common Name`中对应的值到`resign.config`的`CODESIGN_IDENTITIES`
82 | - Free
83 | - 打开电脑中的`Keychain Access`
84 | - 找到您的`Free`证书,并双击
85 | - 复制证书`Common Name`中对应的值到`resign.config`的`CODESIGN_IDENTITIES_FREE`
86 |
87 | ## 3.5 如何使用自动安装重签名后的ipa到手机
88 | - 先使用数据连接线将手机和Mac连接
89 | - 修改`resign.config`中的`AUTO_INSTALL_IPA`为`true`
90 | - 运行`aUtoReSiGn.sh`脚本
91 |
92 | ### 如果不想使用自动重签名,可以将`xx.ipa`放在`resign`目录下,并执行脚本`resign.sh`
93 |
94 | ---
95 |
96 | # 文件结构:
97 |
98 |
99 | ```
100 | autoResign
101 | ├── README.md
102 | ├── aUtoReSiGn.sh
103 | ├── input
104 | ├── output
105 | └── resign
106 | ├── EnterPrise_Development.mobileprovision
107 | ├── EnterPrise_Distribution.mobileprovision
108 | ├── Entitlements
109 | │ ├── developer
110 | │ ├── free
111 | │ └── production
112 | ├── Free.mobileprovision
113 | ├── certificate.png
114 | ├── provisioning\ profiles.png
115 | ├── resign.config
116 | └── resign.sh
117 | ```
118 |
119 | ### 在使用过程中如果有任何问题或者改良的方案欢迎提issue和pr.
120 |
121 | -->
122 |
--------------------------------------------------------------------------------
/autoResign/aUtoReSiGn.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | OUTPUT_DIR="output"
3 | INPUT_DIR="input"
4 | RESIGN_DIR="resign"
5 | MYPATH=$(dirname "$0")
6 | INPUT_PATH="${MYPATH}/${INPUT_DIR}"
7 | OUTPUT_PATH="${MYPATH}/${OUTPUT_DIR}"
8 | RESIGN_PATH="${MYPATH}/${RESIGN_DIR}"
9 | source ./resign/resign.config
10 | PROVISIONING_PROFILE=$NEW_MOBILEPROVISION
11 | CURRENT_TIME_FORMAT="+%m-%d-%y, %l.%M.%S %p"
12 |
13 | WHICH_BREW=`which brew`
14 | WHICH_FSWATCH=`which fswatch`
15 | WHICH_IDEVICEINSTALLER=`which ideviceinstaller`
16 |
17 | SCAN_TITME=1 #扫描文件变化的间隔 1/秒
18 |
19 | function installHomebrew() {
20 | echo "auto install Homebrew:"
21 | echo "if any Error shows, you may need this:"
22 | echo "https://brew.sh"
23 | /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
24 | }
25 |
26 | function checkPathExist() {
27 | if [[ ! -e $INPUT_PATH ]]; then
28 | echo "MKDIR ${INPUT_PATH}"
29 | mkdir $INPUT_PATH
30 | fi
31 |
32 | if [[ ! -e $OUTPUT_PATH ]]; then
33 | echo "MKDIR ${OUTPUT_PATH}"
34 | mkdir $OUTPUT_PATH
35 | fi
36 | }
37 |
38 | function checkFswatch() {
39 | # echo -e "MYPATH:$MYPATH"
40 | # echo -e "INPUT_PATH:$INPUT_PATH"
41 | # exit 1
42 | echo "checking fswatch status ..."
43 | if [[ ${WHICH_FSWATCH} == *"fswatch"* ]]; then
44 | echo "fswatch is installed."
45 | else
46 | if [[ ${WHICH_BREW} == *"brew"* ]]; then
47 | echo "brew has installed."
48 | echo "auto install fswatch, please wait I'm working on:"
49 | brew install fswatch
50 | else
51 | installHomebrew
52 | fi
53 | fi
54 | }
55 |
56 |
57 | function checkIdeviceinstaller() {
58 | echo "checking ideviceinstaller status ..."
59 | if [[ ${WHICH_IDEVICEINSTALLER} == *"ideviceinstaller"* ]]; then
60 | echo "ideviceinstaller is installed."
61 | else
62 | if [[ ${WHICH_BREW} == *"brew"* ]]; then
63 | echo ""
64 | echo "brew has installed."
65 | echo "auto install ideviceinstaller, please wait I'm working on:"
66 | echo "if any Error shows, mybe you can use following command:"
67 | echo "
68 | brew update
69 | brew uninstall --ignore-dependencies libimobiledevice
70 | brew uninstall --ignore-dependencies usbmuxd
71 | brew install --HEAD usbmuxd
72 | brew unlink usbmuxd
73 | brew link usbmuxd
74 | brew install --HEAD libimobiledevice
75 | or
76 | brew uninstall ideviceinstaller
77 | brew uninstall libimobiledevice
78 | brew install --HEAD libimobiledevice
79 | brew link --overwrite libimobiledevice
80 | brew install ideviceinstaller
81 | brew link --overwrite ideviceinstaller
82 | "
83 | brew install ideviceinstaller
84 | else
85 | installHomebrew
86 | fi
87 | fi
88 | }
89 |
90 | function doInstall() {
91 | echo "call doInstall with:$1"
92 | if [[ -f "${OUTPUT_PATH}/${1}" ]]; then
93 | echo "READY TO INSTALL ${1} TO IPHONE"
94 | ideviceinstaller -g "${OUTPUT_PATH}/${1}"
95 | else
96 | echo "${1} NOT EXIST"
97 | fi
98 | }
99 |
100 | function doResignWork() {
101 | echo "call doResignWork with:$1"
102 | if [[ -f "${INPUT_PATH}/${1}" ]]; then
103 | echo "READY TO RESIGN ${1}"
104 | APP_NAME=${1}
105 | # echo "@1CurrentPath:$PWD"
106 | cp "$INPUT_PATH/${APP_NAME}" "${RESIGN_PATH}/"
107 | # echo "@2CurrentPath:$PWD"
108 | cd "${RESIGN_PATH}/"
109 | # echo "@3CurrentPath:$PWD"
110 | "./resign.sh" $APP_NAME $GET_TASK_ALLOW
111 | cd "-"
112 | # echo "@4CurrentPath:$PWD"
113 | rm -rf "${RESIGN_PATH}/${APP_NAME}"
114 | FINAL_FILE=`ls ${RESIGN_PATH} | grep "ipa"`
115 | if [[ -f "${RESIGN_PATH}/${FINAL_FILE}" ]]; then
116 | mv "${RESIGN_PATH}/${FINAL_FILE}" "${OUTPUT_PATH}"
117 | else
118 | echo "failed: file not exist"
119 | fi
120 | echo "TIME:`date "${CURRENT_TIME_FORMAT}"`"
121 | else
122 | echo "${1} NOT EXIST"
123 | fi
124 |
125 | }
126 |
127 | function monitor_ipa() {
128 | fswatch -l $SCAN_TITME -v --monitor=fsevents_monitor -0 "${INPUT_PATH}/" "${OUTPUT_PATH}/" | while read -d "" event
129 | do
130 | echo "FINE HAS CHANGED EVENT:${event}"
131 | if [[ ${event} == *"${INPUT_DIR}"* && ${event} == *"ipa" && ${event} != *"TM.ipa" ]]; then
132 | echo "HANDLE INPUT_DIR EVENT:"
133 | IFS='/' read -ra array <<< ${event}
134 | for i in ${array[@]}; do
135 | if [[ ${i} == *"ipa" ]]; then
136 | doResignWork "${i}"
137 | fi
138 | done
139 | elif [[ ${event} == *"${OUTPUT_DIR}"* ]]; then
140 | echo "HANDLE OUTPUT_DIR EVNET:"
141 | IFS='/' read -ra array <<< ${event}
142 | for i in ${array[@]}; do
143 | if [[ ${i} == *"TM.ipa" ]]; then
144 | doInstall "${i}"
145 | fi
146 | done
147 | fi
148 | done
149 | }
150 |
151 |
152 | checkPathExist
153 | checkFswatch
154 | checkIdeviceinstaller
155 | monitor_ipa
156 |
--------------------------------------------------------------------------------
/autoResign/resign/EnterPrise_Development.mobileprovision:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrChens/iOS_Tools/54715f6e51467838ff6a549bb8f6e5bd44a1d72e/autoResign/resign/EnterPrise_Development.mobileprovision
--------------------------------------------------------------------------------
/autoResign/resign/EnterPrise_Distribution.mobileprovision:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrChens/iOS_Tools/54715f6e51467838ff6a549bb8f6e5bd44a1d72e/autoResign/resign/EnterPrise_Distribution.mobileprovision
--------------------------------------------------------------------------------
/autoResign/resign/Entitlements/developer/Entitlements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | application-identifier
6 | yyyy.com.xxx.xxx
7 | com.apple.developer.team-identifier
8 | yyyy
9 | com.apple.developer.associated-domains
10 | *
11 | aps-environment
12 | development
13 | get-task-allow
14 |
15 | keychain-access-groups
16 |
17 | yyyy.*
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/autoResign/resign/Entitlements/free/Entitlements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | application-identifier
6 | yyyy.com.xxx.xxx
7 | com.apple.developer.team-identifier
8 | yyyy
9 | aps-environment
10 | development
11 | com.apple.developer.associated-domains
12 | *
13 | get-task-allow
14 |
15 | keychain-access-groups
16 |
17 | yyyy.*
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/autoResign/resign/Entitlements/production/Entitlements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | application-identifier
6 | yyyy.com.xxx.xxx
7 | aps-environment
8 | production
9 | get-task-allow
10 |
11 | keychain-access-groups
12 |
13 | yyyy.*
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/autoResign/resign/Free.mobileprovision:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrChens/iOS_Tools/54715f6e51467838ff6a549bb8f6e5bd44a1d72e/autoResign/resign/Free.mobileprovision
--------------------------------------------------------------------------------
/autoResign/resign/certificate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrChens/iOS_Tools/54715f6e51467838ff6a549bb8f6e5bd44a1d72e/autoResign/resign/certificate.png
--------------------------------------------------------------------------------
/autoResign/resign/provisioning profiles.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrChens/iOS_Tools/54715f6e51467838ff6a549bb8f6e5bd44a1d72e/autoResign/resign/provisioning profiles.png
--------------------------------------------------------------------------------
/autoResign/resign/resign.config:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | NEW_MOBILEPROVISION="EnterPrise_Distribution.mobileprovision" # Distribution配置文件
3 | CODESIGN_IDENTITIES="iPhone Distribution: xxxx yyyy & Technology Co., Ltd." # Distribution版证书的名字
4 | ENTITLEMENTS="Entitlements/production/Entitlements.plist" # 授权文件 不需要修改该字段
5 |
6 | NEW_MOBILEPROVISION_DEV="EnterPrise_Development.mobileprovision" # Developer配置文件
7 | CODESIGN_IDENTITIES_DEV="iPhone Developer: xxxx Funny (KxxxxxFP)" # Developer版证书的名字
8 | ENTITLEMENTS_DEV="Entitlements/developer/Entitlements.plist" # 授权文件 不需要修改该字段
9 | GET_TASK_ALLOW=false #是否打包Developer true重签名为Developer的包 false重签名为Distribution的包
10 | AUTO_INSTALL_IPA=false #是否自动将重签名后的app安装到手机上
11 |
12 | NEW_MOBILEPROVISION_FREE="person.mobileprovision" # Distribution配置文件
13 | CODESIGN_IDENTITIES_FREE="Apple Development: 13777726110@139.com (R3X24X6L99)" # 个人版证书的名字
14 | ENTITLEMENTS_FREE="Entitlements/free/Entitlements.plist" # 授权文件 不需要修改该字段
15 |
16 |
17 | MINIMUMOSVERSION="10.0" #ipa最低支持的iOS版本
18 |
--------------------------------------------------------------------------------
/autoResign/resign/resign.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 |
4 | if [ $# -lt 1 ]; then
5 | echo ""
6 | echo "resign.sh Usage:"
7 | echo "\t required: ./resign.sh APP_NAME.ipa true/free"
8 | echo "\t true is optional feature which allow you set get-task-allow to true"
9 | echo "\t free is optional feature which allow you codesign ipa with free apple id"
10 |
11 | exit 0
12 | fi
13 |
14 | echo "read cofig from resign.config"
15 | source resign.config
16 |
17 |
18 | TARGET_IPA_PACKAGE_NAME=$1
19 | TM_IPA_PACKAGE_NAME="${TARGET_IPA_PACKAGE_NAME%.*}_MC.ipa" # resigned ipa name
20 | PAYLOAD_DIR="Payload"
21 | APP_DIR=""
22 | PROVISION_FILE=$NEW_MOBILEPROVISION
23 | CODESIGN_KEY=$CODESIGN_IDENTITIES
24 | ENTITLEMENTS_FILE=$ENTITLEMENTS
25 |
26 |
27 | if [[ $2 == 'true' ]]; then
28 | echo "resign with development type"
29 | PROVISION_FILE=$NEW_MOBILEPROVISION_DEV
30 | CODESIGN_KEY=$CODESIGN_IDENTITIES_DEV
31 | ENTITLEMENTS_FILE=$ENTITLEMENTS_DEV
32 | fi
33 |
34 | if [[ $2 == 'free' ]]; then
35 | echo "resign with free developer type"
36 | PROVISION_FILE=$NEW_MOBILEPROVISION_FREE
37 | CODESIGN_KEY=$CODESIGN_IDENTITIES_FREE
38 | ENTITLEMENTS_FILE=$ENTITLEMENTS_FREE
39 | fi
40 |
41 | echo -e ""
42 | echo -e "the new ipa named:${TM_IPA_PACKAGE_NAME}"
43 | echo -e "use provision file:${PROVISION_FILE}"
44 | echo -e "use entitlements file:${ENTITLEMENTS_FILE}"
45 | echo -e "use codesign:${CODESIGN_KEY}"
46 |
47 | OLD_MOBILEPROVISION="embedded.mobileprovision"
48 | DEVELOPER=`xcode-select -print-path`
49 | TARGET_APP_FRAMEWORKS_PATH=""
50 |
51 | SDK_DIR="${DEVELOPER}/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk"
52 | echo -e "SDK_DIR*$SDK_DIR"
53 |
54 | if [ ! -e $TARGET_IPA_PACKAGE_NAME ]; then
55 | echo "ipa file ($TARGET_IPA_PACKAGE_NAME) not exist"
56 | exit 0
57 | fi
58 |
59 | if [ ! -e $PROVISION_FILE ]; then
60 | echo "provision file ($PROVISION_FILE) not exist"
61 | exit 0
62 | fi
63 |
64 | if [ -e $TM_IPA_PACKAGE_NAME ]; then
65 | echo "rm $TM_IPA_PACKAGE_NAME"
66 | rm $TM_IPA_PACKAGE_NAME
67 | fi
68 |
69 | if [ -d $PAYLOAD_DIR ]; then
70 | echo "delete old ipa:$PAYLOAD_DIR"
71 | rm -rf $PAYLOAD_DIR
72 | fi
73 |
74 | echo ""
75 | echo "1. unzip $TARGET_IPA_PACKAGE_NAME"
76 | unzip $TARGET_IPA_PACKAGE_NAME > /dev/null
77 |
78 | if [ ! -d $PAYLOAD_DIR ]; then
79 | echo "unzip $TARGET_IPA_PACKAGE_NAME fail"
80 | fi
81 |
82 | APP_DIR="Payload/fuck.app"
83 |
84 | FUCK_APP_DIR=$(find ${PAYLOAD_DIR} -type d | grep ".app$" | head -n 1)
85 |
86 | # incase of some app name with white space
87 | # eg. "hello world.app"
88 | echo "rename ${FUCK_APP_DIR} to ${APP_DIR}"
89 | mv -i "$FUCK_APP_DIR" "$APP_DIR"
90 |
91 | echo "set Minimum support os version:${MINIMUMOSVERSION}"
92 | plutil -replace MinimumOSVersion -string $MINIMUMOSVERSION $APP_DIR/Info.plist
93 | # plutil -insert UISupportedDevices.4 -string "iPhone11,6" $APP_DIR/Info.plist
94 | # we don't need the this feature
95 | echo "delete UISupportedDevices keypath in Info.plist"
96 | plutil -remove UISupportedDevices $APP_DIR/Info.plist
97 |
98 | if [ -d "$APP_DIR/_CodeSignature" ]; then
99 | echo ""
100 | echo "rm $APP_DIR/_CodeSignature"
101 | rm -rf $APP_DIR/_CodeSignature
102 |
103 | echo ""
104 | echo "cp $SDK_DIR/ResourceRules.plist $APP_DIR/"
105 | cp $SDK_DIR/ResourceRules.plist $APP_DIR/
106 | echo ""
107 | echo "cp $PROVISION_FILE $APP_DIR/$OLD_MOBILEPROVISION"
108 | cp $PROVISION_FILE $APP_DIR/$OLD_MOBILEPROVISION
109 | echo ""
110 | echo "*************start codesign*************"
111 |
112 | #codesign frameworks
113 | TARGET_APP_FRAMEWORKS_PATH="$APP_DIR/Frameworks"
114 | if [[ -d "$TARGET_APP_FRAMEWORKS_PATH" ]]; then
115 | for FRAMEWORK in "$TARGET_APP_FRAMEWORKS_PATH/"*; do
116 | FILENAME=$(basename $FRAMEWORK)
117 | /usr/bin/codesign -f -s "$CODESIGN_KEY" "$FRAMEWORK"
118 | done
119 | fi
120 | echo "codesign frameworks done."
121 |
122 | #codesign plugins
123 | TARGET_APP_PLUGINS_PATH="$APP_DIR/PlugIns"
124 | if [[ -d "$TARGET_APP_PLUGINS_PATH" ]]; then
125 | for PLUGIN in "$TARGET_APP_PLUGINS_PATH/"*; do
126 | FILENAME=$(basename $PLUGIN)
127 | /usr/bin/codesign -f -s "$CODESIGN_KEY" "$PLUGIN"
128 | done
129 | fi
130 | echo "codesign plugins done."
131 |
132 | #codesign the fuck dylib
133 | for FDYLIB in "$APP_DIR/"*; do
134 | #statements
135 | DYLIB=${FDYLIB##*.}
136 | if [[ $DYLIB == dylib ]]; then
137 | #statements
138 | echo "codesign ${FDYLIB}"
139 | /usr/bin/codesign -f -s "$CODESIGN_KEY" "$FDYLIB"
140 | fi
141 | done
142 | echo "codesign dylibs done."
143 |
144 | echo "codesign ${APP_DIR} with entitlements file"
145 | /usr/bin/codesign -f -s "$CODESIGN_KEY" --entitlements $ENTITLEMENTS_FILE $APP_DIR
146 |
147 | echo "*************end codesign*************"
148 |
149 | if [ -d $APP_DIR/_CodeSignature ]; then
150 | echo ""
151 | echo "zip -r $TARGET_IPA_PACKAGE_NAME $APP_DIR/"
152 | zip -r $TM_IPA_PACKAGE_NAME $APP_DIR/ > /dev/null
153 | echo "delete ${APP_DIR}"
154 | rm -rf $APP_DIR
155 | echo " @@@@@@@ resign success !!! @@@@@@@ "
156 | exit 0
157 | fi
158 | fi
159 |
160 | echo "oops! resign fail !!!"
161 |
--------------------------------------------------------------------------------
/class_dump/README.md:
--------------------------------------------------------------------------------
1 | # 导出头文件操作流程文档
2 |
3 | [class-dump](http://stevenygard.com/projects/class-dump/)
4 |
5 | [砸壳(破解)工具](https://github.com/stefanesser/dumpdecrypted.git)
6 |
7 | ### 砸壳时遇见如下
8 | dyld: could not load inserted library 'dumpdecrypted.dylib' because no suitable image found. Did find:
9 | dumpdecrypted.dylib: required code signature missing for 'dumpdecrypted.dylib'
10 |
11 | security find-identity -v -p codesigning
12 | codesign --force --verify --verbose --sign "iPhone Developer: xxx xxxx (xxxxxxxxxx)" dumpdecrypted.dylib
13 |
14 | ### 本目录下已经预先放置好了需要使用的工具,如果不能使用请从上面的网址去download新的工具来。
15 |
16 | 从App Store下载的ipa是需要先砸壳然后再使用`class-dump`才能导出头文件.
17 | 如果是自己打包的企业app直接把ipa解压后的xx.app用`class-dump`就能导出头文件.
18 |
19 | ### 针对App Store下载的ipa进行的`class-dump`(需要越狱的设备)
20 | - 先从ituness上下载xxx.ipa
21 | - 然后将ipa安装到越狱的手机中
22 | - 将`dumpdecrypted.dylib`拷贝到手机的`(iOS8)/var/mobile/Containers/Data/Application/xxx-xxx/Documents`目录下,在iOS7中是`/var/mobile/Applications/xxx-xxx/Documents`
23 | - iOS8然后再cd到3中的目录下执行:`DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/mobile/Containers/Bundle/Application/xxx-xxx/yyy.app/yyy`
24 | iOS7然后再cd到3中的目录下执行:`DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/mobile/Applications/xxx-xxx/yyy.app/yyy`
25 | - 然后就会生成`yyy.decrypted`
26 | - 使用`scp`将`yyy.decrypted`传输到电脑上
27 | - `./class-dump -H yyy.decrypted -o outputs`
28 | - 然后就能在`outputs`中看到导出的头文件
29 |
30 | ### 针对不需要砸壳的ipa进行的class-dump(不需要越狱的设备)
31 | - 将xxx.ipa解压到`class-dump`同个目录下,然后使用下面的命令将头文件导出到`outputs`目录下:
32 | - `./class-dump -H xx.app -o outputs`
33 | - 然后就能在`outputs`中看到导出的头文件
34 |
35 |
36 | ### 在使用过程中如果有任何问题或者改良的方案欢迎提issue和pr.
37 |
38 |
--------------------------------------------------------------------------------
/class_dump/class-dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrChens/iOS_Tools/54715f6e51467838ff6a549bb8f6e5bd44a1d72e/class_dump/class-dump
--------------------------------------------------------------------------------
/class_dump/dumpdecrypted.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrChens/iOS_Tools/54715f6e51467838ff6a549bb8f6e5bd44a1d72e/class_dump/dumpdecrypted.dylib
--------------------------------------------------------------------------------
/crashMe/README.md:
--------------------------------------------------------------------------------
1 | # app崩溃时排查步骤
2 | > 在app崩溃时所生成的`.crash`文件,默认情况下该文件显示的都是十六进制数无法分析。所以我们需要对这些文件进行分析。
3 | ## 需要的工具:
4 | - `Xcode`
5 | - `app`崩溃时生成的`.crash`文件,可通过`Xcode`--> `Window`--> `Devices and Simulators`--> `View Device Logs`从iPhone中提取出来
6 | - `dsym`文件(符号表文件)
7 | - `symbolicatecrash`(可通过执行`find /Applications/Xcode.app/ -name symbolicatecrash`找到该文件的所在位置)
8 |
9 | ## 使用方式:
10 | 1. 打开`.crash`文件找到其中的`uuid`
11 | 2. 找到对应的`dysm`文件.(可通过`dwarfdump --uuid xxx.dsym`查看`uuid`是否和1的一致)
12 | 3. 将`.crash`,`dysm`,`symbolicatecrash`这3个文件放在同一个文件夹下方便处理
13 | 4. 执行命令`./symbolicatecrash xxxx.crash xxxx.dSYM/ > output.crash`就可以看到符号化以后的崩溃堆栈信息
14 | 5. 若报错`Error: "DEVELOPER_DIR" is not defined at ./symbolicatecrash`,则在终端执行一次后面的命令`export DEVELOPER_DIR="/Applications/XCode.app/Contents/Developer"`,然后再执行一次`4`的命令.
15 |
16 | ps:最后生成的`.crash`文件只会解析当前项目的代码,其余的还是十六进制数据
17 |
18 | ## 实际操作
19 | 1. 从`iPhone`中获取`wspxDemo 2018-11-5, 2-42 PM.crash.crash`文件如下(只保留需要的关键信息)
20 |
21 | ```
22 | Incident Identifier: 211AB31B-F097-47DC-83ED-3AC6B3AC6B05
23 | CrashReporter Key: 991d9b4c57cf7b9c00c2cabc05f20cb4812ea851
24 | Hardware Model: iPhone10,3
25 | Process: wspxDemo [1214]
26 | Path: /private/var/containers/Bundle/Application/DF7AAB28-9FF0-99EC-4EA1-16B5C50EB87C/wspxDemo.app/wspxDemo
27 | Identifier: com.crash.CrashMe
28 | Version: 2222 (22.22.222)
29 | Code Type: ARM-64 (Native)
30 | Role: Foreground
31 | Parent Process: launchd [1]
32 | Coalition: com.crash.CrashMe [738]
33 |
34 | Date/Time: 2018-11-05 14:42:17.6018 +0800
35 | Launch Time: 2018-11-05 14:42:17.3303 +0800
36 | OS Version: iPhone OS 12.1 (16B5089b)
37 | Baseband Version: 3.11.00
38 | Report Version: 104
39 |
40 | Exception Type: EXC_CRASH (SIGABRT)
41 | Exception Codes: 0x0000000000000000, 0x0000000000000000
42 | Exception Note: EXC_CORPSE_NOTIFY
43 | Triggered by Thread: 0
44 |
45 | Application Specific Information:
46 | abort() called
47 |
48 | Last Exception Backtrace:
49 | (0x1dcfcfea0 0x1dc1a1a40 0x1dcede054 0x102ceb9b4 0x209fda3c8 0x209fdbb30 0x209fe157c 0x20987ea18 0x209887698 0x20987e694 0x20987f034 0x20987d134 0x20987cde0 0x209881fa0 0x209882f00 0x209881e58 0x209886d44 0x209fdfa74 0x209bca088 0x1dfa049d4 0x1dfa0f79c 0x1dfa0ee94 0x1dca0a484 0x1dc9e13f0 0x1dfa43a9c 0x1dfa43728 0x1dfa43d44 0x1dcf601cc 0x1dcf6014c 0x1dcf5fa30 0x1dcf5a8fc 0x1dcf5a1cc 0x1df1d1584 0x209fe3328 0x102cebaf0 0x1dca1abb4)
50 |
51 | Thread 0 name: Dispatch queue: com.apple.main-thread
52 | Thread 0 Crashed:
53 | 0 libsystem_kernel.dylib 0x00000001dcb67104 0x1dcb44000 + 143620
54 | 1 libsystem_pthread.dylib 0x00000001dcbe6998 0x1dcbe0000 + 27032
55 | 2 libsystem_c.dylib 0x00000001dcabed78 0x1dca67000 + 359800
56 | 3 libc++abi.dylib 0x00000001dc188f78 0x1dc187000 + 8056
57 | 4 libc++abi.dylib 0x00000001dc189120 0x1dc187000 + 8480
58 | 5 libobjc.A.dylib 0x00000001dc1a1e48 0x1dc19b000 + 28232
59 | 6 libc++abi.dylib 0x00000001dc1950fc 0x1dc187000 + 57596
60 | 7 libc++abi.dylib 0x00000001dc195188 0x1dc187000 + 57736
61 | 8 libdispatch.dylib 0x00000001dca0a498 0x1dc9a9000 + 398488
62 | 9 libdispatch.dylib 0x00000001dc9e13f0 0x1dc9a9000 + 230384
63 | 10 FrontBoardServices 0x00000001dfa43a9c 0x1df9f8000 + 309916
64 | 11 FrontBoardServices 0x00000001dfa43728 0x1df9f8000 + 309032
65 | 12 FrontBoardServices 0x00000001dfa43d44 0x1df9f8000 + 310596
66 | 13 CoreFoundation 0x00000001dcf601cc 0x1dceb4000 + 704972
67 | 14 CoreFoundation 0x00000001dcf6014c 0x1dceb4000 + 704844
68 | 15 CoreFoundation 0x00000001dcf5fa30 0x1dceb4000 + 703024
69 | 16 CoreFoundation 0x00000001dcf5a8fc 0x1dceb4000 + 682236
70 | 17 CoreFoundation 0x00000001dcf5a1cc 0x1dceb4000 + 680396
71 | 18 GraphicsServices 0x00000001df1d1584 0x1df1c6000 + 46468
72 | 19 UIKitCore 0x0000000209fe3328 0x2096fc000 + 9335592
73 | 20 wspxDemo 0x0000000102cebaf0 0x102ce4000 + 31472
74 | 21 libdyld.dylib 0x00000001dca1abb4 0x1dca1a000 + 2996
75 |
76 | Thread 1:
77 | 0 libsystem_pthread.dylib 0x00000001dcbeece8 0x1dcbe0000 + 60648
78 |
79 | Thread 2:
80 | 0 libsystem_pthread.dylib 0x00000001dcbeece8 0x1dcbe0000 + 60648
81 |
82 | Thread 3:
83 | 0 libsystem_pthread.dylib 0x00000001dcbeece8 0x1dcbe0000 + 60648
84 |
85 | Thread 4:
86 | 0 libsystem_pthread.dylib 0x00000001dcbeece8 0x1dcbe0000 + 60648
87 |
88 | Thread 5 name: com.apple.uikit.eventfetch-thread
89 | Thread 5:
90 | 0 libsystem_kernel.dylib 0x00000001dcb5bed0 0x1dcb44000 + 98000
91 | 1 libsystem_kernel.dylib 0x00000001dcb5b3a8 0x1dcb44000 + 95144
92 | 2 CoreFoundation 0x00000001dcf5fbc4 0x1dceb4000 + 703428
93 | 3 CoreFoundation 0x00000001dcf5aa60 0x1dceb4000 + 682592
94 | 4 CoreFoundation 0x00000001dcf5a1cc 0x1dceb4000 + 680396
95 | 5 Foundation 0x00000001dd94f404 0x1dd947000 + 33796
96 | 6 Foundation 0x00000001dd94f2b0 0x1dd947000 + 33456
97 | 7 UIKitCore 0x000000020a0d0430 0x2096fc000 + 10306608
98 | 8 Foundation 0x00000001dda821ac 0x1dd947000 + 1290668
99 | 9 libsystem_pthread.dylib 0x00000001dcbeb2ac 0x1dcbe0000 + 45740
100 | 10 libsystem_pthread.dylib 0x00000001dcbeb20c 0x1dcbe0000 + 45580
101 | 11 libsystem_pthread.dylib 0x00000001dcbeecf4 0x1dcbe0000 + 60660
102 |
103 | Thread 0 crashed with ARM Thread State (64-bit):
104 | x0: 0x0000000000000000 x1: 0x0000000000000000 x2: 0x0000000000000000 x3: 0x000000028248b4b7
105 | x4: 0x00000001dc198b81 x5: 0x000000016d11a570 x6: 0x000000000000006e x7: 0xffffffff00000500
106 | x8: 0x0000000000000800 x9: 0x00000001dcbe6870 x10: 0x00000001dcbe1ef4 x11: 0x0000000000000003
107 | x12: 0x0000000000000069 x13: 0x0000000000000000 x14: 0x0000000000000010 x15: 0x0000000000000016
108 | x16: 0x0000000000000148 x17: 0x0000000000000000 x18: 0x0000000000000000 x19: 0x0000000000000006
109 | x20: 0x00000001030aeb80 x21: 0x000000016d11a570 x22: 0x0000000000000303 x23: 0x00000001030aec60
110 | x24: 0x0000000000001903 x25: 0x0000000000002103 x26: 0x0000000000000000 x27: 0x0000000000000000
111 | x28: 0x00000002836bc408 fp: 0x000000016d11a4d0 lr: 0x00000001dcbe6998
112 | sp: 0x000000016d11a4a0 pc: 0x00000001dcb67104 cpsr: 0x00000000
113 |
114 | Binary Images:
115 | 0x102ce4000 - 0x102ceffff wspxDemo arm64 /var/containers/Bundle/Application/DF7AAB28-9FF0-99EC-4EA1-16B5C50EB87C/wspxDemo.app/wspxDemo```
116 |
117 | 2. 从`Binary Images:
118 | 0x102ce4000 - 0x102ceffff wspxDemo arm64 /var/containers/Bundle/Application/DF7AAB28-9FF0-99EC-4EA1-16B5C50EB87C/wspxDemo.app/wspxDemo`中我们拿到`b0ffd72fc5c33a59bf97c79556430202`
119 | 3. 在终端执行`dwarfdump --uuid wspxDemo.app.dSYM/`后得到如下的输出:
120 |
121 |
122 | ```Mero:wspxDemo 2018-11-05 12-56-20 dc$ dwarfdump --uuid wspxDemo.app.dSYM/
123 | UUID: 43C734F8-405F-3970-8B8D-D58575672912 (armv7) wspxDemo.app.dSYM/Contents/Resources/DWARF/wspxDemo
124 | UUID: B0FFD72F-C5C3-3A59-BF97-C79556430202 (arm64) wspxDemo.app.dSYM/Contents/Resources/DWARF/wspxDemo```
125 |
126 | 4. 对比步骤2和3的结果会发现:`b0ffd72fc5c33a59bf97c79556430202`和`B0FFD72F-C5C3-3A59-BF97-C79556430202`是一致的,所以该`wspxDemo 2018-11-5, 2-42 PM.crash.crash`对应的`dysm`就是`wspxDemo.app.dSYM`
127 | 5. 在终端执行命令:`./symbolicatecrash wspxDemo\ \ 2018-11-5\,\ 2-42\ PM.crash wspxDemo.app.dSYM/ > output.crash`得到如下的输出:
128 |
129 | ```
130 | Mero:wspxDemo 2018-11-05 12-56-20 dc$ ./symbolicatecrash wspxDemo\ \ 2018-11-5\,\ 2-42\ PM.crash wspxDemo.app.dSYM/ > output.crash
131 | Error: "DEVELOPER_DIR" is not defined at ./symbolicatecrash line 69.```
132 |
133 | 6. 报错:`Error: "DEVELOPER_DIR" is not defined at ./symbolicatecrash line 69.`
134 | 7. 执行如下命令:`export DEVELOPER_DIR="/Applications/XCode.app/Contents/Developer"`然后再执行`5`的命令.执行结果如下:
135 |
136 | ```
137 | Mero:wspxDemo 2018-11-05 12-56-20 dc$ export DEVELOPER_DIR="/Applications/XCode.app/Contents/Developer"
138 | Mero:wspxDemo 2018-11-05 12-56-20 dc$ ./symbolicatecrash wspxDemo\ \ 2018-11-5\,\ 2-42\ PM.crash wspxDemo.app.dSYM/ > output.crash```
139 |
140 | 8. 如果没有报任何其他错误,则说明你已经成功把`crash`符号了,这时打开`output.crash`开始查看崩溃堆栈吧
141 | 9. 如下是符号化后的`output.crash`文件的内容:
142 |
143 | ```
144 | Incident Identifier: 211AB31B-F097-47DC-83ED-3AC6B3AC6B05
145 | CrashReporter Key: 991d9b4c57cf7b9c00c2cabc05f20cb4812ea851
146 | Hardware Model: iPhone10,3
147 | Process: wspxDemo [1214]
148 | Path: /private/var/containers/Bundle/Application/DF7AAB28-9FF0-99EC-4EA1-16B5C50EB87C/wspxDemo.app/wspxDemo
149 | Identifier: com.crash.CrashMe
150 | Version: 2222 (22.22.222)
151 | Code Type: ARM-64 (Native)
152 | Role: Foreground
153 | Parent Process: launchd [1]
154 | Coalition: com.crash.CrashMe [738]
155 |
156 | Date/Time: 2018-11-05 14:42:17.6018 +0800
157 | Launch Time: 2018-11-05 14:42:17.3303 +0800
158 | OS Version: iPhone OS 12.1 (16B5089b)
159 | Baseband Version: 3.11.00
160 | Report Version: 104
161 |
162 | Exception Type: EXC_CRASH (SIGABRT)
163 | Exception Codes: 0x0000000000000000, 0x0000000000000000
164 | Exception Note: EXC_CORPSE_NOTIFY
165 | Triggered by Thread: 0
166 |
167 | Application Specific Information:
168 | abort() called
169 |
170 | Last Exception Backtrace:
171 | 0 CoreFoundation 0x1dcfcfea0 __exceptionPreprocess + 228
172 | 1 libobjc.A.dylib 0x1dc1a1a40 objc_exception_throw + 55
173 | 2 CoreFoundation 0x1dcede054 -[__NSSingleObjectArrayI objectAtIndex:] + 127
174 | 3 wspxDemo 0x102ceb9b4 -[AppDelegate application:didFinishLaunchingWithOptions:] + 31156 (AppDelegate.m:150)
175 | 4 UIKitCore 0x209fda3c8 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 411
176 | 5 UIKitCore 0x209fdbb30 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 3339
177 | 6 UIKitCore 0x209fe157c -[UIApplication _runWithMainScene:transitionContext:completion:] + 1551
178 | 7 UIKitCore 0x20987ea18 __111-[__UICanvasLifecycleMonitor_Compatability _scheduleFirstCommitForScene:transition:firstActivation:completion:]_block_invoke + 783
179 | 8 UIKitCore 0x209887698 +[_UICanvas _enqueuePostSettingUpdateTransactionBlock:] + 159
180 | 9 UIKitCore 0x20987e694 -[__UICanvasLifecycleMonitor_Compatability _scheduleFirstCommitForScene:transition:firstActivation:completion:] + 239
181 | 10 UIKitCore 0x20987f034 -[__UICanvasLifecycleMonitor_Compatability activateEventsOnly:withContext:completion:] + 1075
182 | 11 UIKitCore 0x20987d134 __82-[_UIApplicationCanvas _transitionLifecycleStateWithTransitionContext:completion:]_block_invoke + 771
183 | 12 UIKitCore 0x20987cde0 -[_UIApplicationCanvas _transitionLifecycleStateWithTransitionContext:completion:] + 431
184 | 13 UIKitCore 0x209881fa0 __125-[_UICanvasLifecycleSettingsDiffAction performActionsForCanvas:withUpdatedScene:settingsDiff:fromSettings:transitionContext:]_block_invoke + 219
185 | 14 UIKitCore 0x209882f00 _performActionsWithDelayForTransitionContext + 111
186 | 15 UIKitCore 0x209881e58 -[_UICanvasLifecycleSettingsDiffAction performActionsForCanvas:withUpdatedScene:settingsDiff:fromSettings:transitionContext:] + 247
187 | 16 UIKitCore 0x209886d44 -[_UICanvas scene:didUpdateWithDiff:transitionContext:completion:] + 367
188 | 17 UIKitCore 0x209fdfa74 -[UIApplication workspace:didCreateScene:withTransitionContext:completion:] + 539
189 | 18 UIKitCore 0x209bca088 -[UIApplicationSceneClientAgent scene:didInitializeWithEvent:completion:] + 363
190 | 19 FrontBoardServices 0x1dfa049d4 -[FBSSceneImpl _didCreateWithTransitionContext:completion:] + 443
191 | 20 FrontBoardServices 0x1dfa0f79c __56-[FBSWorkspace client:handleCreateScene:withCompletion:]_block_invoke_2 + 259
192 | 21 FrontBoardServices 0x1dfa0ee94 __40-[FBSWorkspace _performDelegateCallOut:]_block_invoke + 63
193 | 22 libdispatch.dylib 0x1dca0a484 _dispatch_client_callout + 15
194 | 23 libdispatch.dylib 0x1dc9e13f0 _dispatch_block_invoke_direct$VARIANT$armv81 + 215
195 | 24 FrontBoardServices 0x1dfa43a9c __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 39
196 | 25 FrontBoardServices 0x1dfa43728 -[FBSSerialQueue _performNext] + 415
197 | 26 FrontBoardServices 0x1dfa43d44 -[FBSSerialQueue _performNextFromRunLoopSource] + 55
198 | 27 CoreFoundation 0x1dcf601cc __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 23
199 | 28 CoreFoundation 0x1dcf6014c __CFRunLoopDoSource0 + 87
200 | 29 CoreFoundation 0x1dcf5fa30 __CFRunLoopDoSources0 + 175
201 | 30 CoreFoundation 0x1dcf5a8fc __CFRunLoopRun + 1039
202 | 31 CoreFoundation 0x1dcf5a1cc CFRunLoopRunSpecific + 435
203 | 32 GraphicsServices 0x1df1d1584 GSEventRunModal + 99
204 | 33 UIKitCore 0x209fe3328 UIApplicationMain + 211
205 | 34 wspxDemo 0x102cebaf0 main + 31472 (main.m:14)
206 | 35 libdyld.dylib 0x1dca1abb4 start + 3
207 |
208 |
209 | Thread 0 name: Dispatch queue: com.apple.main-thread
210 | Thread 0 Crashed:
211 | 0 libsystem_kernel.dylib 0x00000001dcb67104 __pthread_kill + 8
212 | 1 libsystem_pthread.dylib 0x00000001dcbe6998 pthread_kill$VARIANT$armv81 + 296
213 | 2 libsystem_c.dylib 0x00000001dcabed78 abort + 140
214 | 3 libc++abi.dylib 0x00000001dc188f78 __cxa_bad_cast + 0
215 | 4 libc++abi.dylib 0x00000001dc189120 default_unexpected_handler+ 8480 () + 0
216 | 5 libobjc.A.dylib 0x00000001dc1a1e48 _objc_terminate+ 28232 () + 124
217 | 6 libc++abi.dylib 0x00000001dc1950fc std::__terminate(void (*)+ 57596 ()) + 16
218 | 7 libc++abi.dylib 0x00000001dc195188 std::terminate+ 57736 () + 84
219 | 8 libdispatch.dylib 0x00000001dca0a498 _dispatch_client_callout + 36
220 | 9 libdispatch.dylib 0x00000001dc9e13f0 _dispatch_block_invoke_direct$VARIANT$armv81 + 216
221 | 10 FrontBoardServices 0x00000001dfa43a9c __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 40
222 | 11 FrontBoardServices 0x00000001dfa43728 -[FBSSerialQueue _performNext] + 416
223 | 12 FrontBoardServices 0x00000001dfa43d44 -[FBSSerialQueue _performNextFromRunLoopSource] + 56
224 | 13 CoreFoundation 0x00000001dcf601cc __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
225 | 14 CoreFoundation 0x00000001dcf6014c __CFRunLoopDoSource0 + 88
226 | 15 CoreFoundation 0x00000001dcf5fa30 __CFRunLoopDoSources0 + 176
227 | 16 CoreFoundation 0x00000001dcf5a8fc __CFRunLoopRun + 1040
228 | 17 CoreFoundation 0x00000001dcf5a1cc CFRunLoopRunSpecific + 436
229 | 18 GraphicsServices 0x00000001df1d1584 GSEventRunModal + 100
230 | 19 UIKitCore 0x0000000209fe3328 UIApplicationMain + 212
231 | 20 wspxDemo 0x0000000102cebaf0 main + 31472 (main.m:14)
232 | 21 libdyld.dylib 0x00000001dca1abb4 start + 4
233 |
234 | Thread 1:
235 | 0 libsystem_pthread.dylib 0x00000001dcbeece8 start_wqthread + 0
236 |
237 | Thread 2:
238 | 0 libsystem_pthread.dylib 0x00000001dcbeece8 start_wqthread + 0
239 |
240 | Thread 3:
241 | 0 libsystem_pthread.dylib 0x00000001dcbeece8 start_wqthread + 0
242 |
243 | Thread 4:
244 | 0 libsystem_pthread.dylib 0x00000001dcbeece8 start_wqthread + 0
245 |
246 | Thread 5 name: com.apple.uikit.eventfetch-thread
247 | Thread 5:
248 | 0 libsystem_kernel.dylib 0x00000001dcb5bed0 mach_msg_trap + 8
249 | 1 libsystem_kernel.dylib 0x00000001dcb5b3a8 mach_msg + 72
250 | 2 CoreFoundation 0x00000001dcf5fbc4 __CFRunLoopServiceMachPort + 236
251 | 3 CoreFoundation 0x00000001dcf5aa60 __CFRunLoopRun + 1396
252 | 4 CoreFoundation 0x00000001dcf5a1cc CFRunLoopRunSpecific + 436
253 | 5 Foundation 0x00000001dd94f404 -[NSRunLoop+ 33796 (NSRunLoop) runMode:beforeDate:] + 300
254 | 6 Foundation 0x00000001dd94f2b0 -[NSRunLoop+ 33456 (NSRunLoop) runUntilDate:] + 148
255 | 7 UIKitCore 0x000000020a0d0430 -[UIEventFetcher threadMain] + 136
256 | 8 Foundation 0x00000001dda821ac __NSThread__start__ + 1040
257 | 9 libsystem_pthread.dylib 0x00000001dcbeb2ac _pthread_body + 128
258 | 10 libsystem_pthread.dylib 0x00000001dcbeb20c _pthread_start + 48
259 | 11 libsystem_pthread.dylib 0x00000001dcbeecf4 thread_start + 4
260 |
261 | Thread 0 crashed with ARM Thread State (64-bit):
262 | x0: 0x0000000000000000 x1: 0x0000000000000000 x2: 0x0000000000000000 x3: 0x000000028248b4b7
263 | x4: 0x00000001dc198b81 x5: 0x000000016d11a570 x6: 0x000000000000006e x7: 0xffffffff00000500
264 | x8: 0x0000000000000800 x9: 0x00000001dcbe6870 x10: 0x00000001dcbe1ef4 x11: 0x0000000000000003
265 | x12: 0x0000000000000069 x13: 0x0000000000000000 x14: 0x0000000000000010 x15: 0x0000000000000016
266 | x16: 0x0000000000000148 x17: 0x0000000000000000 x18: 0x0000000000000000 x19: 0x0000000000000006
267 | x20: 0x00000001030aeb80 x21: 0x000000016d11a570 x22: 0x0000000000000303 x23: 0x00000001030aec60
268 | x24: 0x0000000000001903 x25: 0x0000000000002103 x26: 0x0000000000000000 x27: 0x0000000000000000
269 | x28: 0x00000002836bc408 fp: 0x000000016d11a4d0 lr: 0x00000001dcbe6998
270 | sp: 0x000000016d11a4a0 pc: 0x00000001dcb67104 cpsr: 0x00000000
271 |
272 | Binary Images:
273 | 0x102ce4000 - 0x102ceffff wspxDemo arm64 /var/containers/Bundle/Application/DF7AAB28-9FF0-99EC-4EA1-16B5C50EB87C/wspxDemo.app/wspxDemo```
274 |
275 | 10. 从`crash`文件中我们很容易定位到`app`挂在了`AppDelegate.m`文件中的`第150行`这里.并且可能是因为数组越界导致崩溃。从源码截图中看确实是在`AppDelegate.m`的`150行`有问题.
276 | 11. 得到符号化`crash`文件后就可以进一步排查问题,之前有写过相关的博客[传送门][debug-with-crashlog]在这里就不再详细说明.
277 |
278 | ![源码][sourceCode]
279 |
280 | [debug-with-crashlog]:https://mrchens.github.io/2018/07/26/debug-with-crashlog
281 | [sourceCode]:https://github.com/MrChens/iOS_Tools/blob/master/crashMe/sourcecode.png
282 |
--------------------------------------------------------------------------------
/crashMe/sourcecode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrChens/iOS_Tools/54715f6e51467838ff6a549bb8f6e5bd44a1d72e/crashMe/sourcecode.png
--------------------------------------------------------------------------------
/cydia.md:
--------------------------------------------------------------------------------
1 | # 越狱开发中有用的软件
2 | - OpenSSH:建立ssh连接,记得修改默认root密码(alpine)
3 | - 安装后可以使用scp
4 | - APT 0.6 Transitional: apt-get包管理工具
5 | - Gawk: 支持awk编程,awk是一种强大的文本处理及模式匹配语言
6 | - Core Utilities (/bin):提供了dirname,kill,mktemp,su
7 | - top:动态查看系统状态,如CPU负载
8 | - inetutils: ping, ftp客户端/服务端
9 | - cURL:
10 | - ReRpovision:app自动续签
11 | - tcpdump: 抓包工具
12 | - network Commands: 网络管理工具, ifconfig, netstat, arp, route, traceroute
13 | - readline: 方便命令行移动
14 | - `ctrl+r` 搜索
15 | - `ctrl+a/e` 移动到行首/尾
16 | - `ctrl+u/k` 删除到行首/尾
17 | - `ctrl+l` 清屏
18 | - open:通过命令行打开应用
19 | - ipainstaller: 通过命令行安装ipa应用
20 | - plutil (com.Erica.Utilities): 支持设备上对plist文件进行操作
21 | - strings(Binutils): 打印某个文件的可打印字符串,便于了解一些非文本文件的内容。比如可用来查找浏览器Cokkies内容
22 | - cycript: TBD 通过`ctrl+d`退出
23 | - AppSync: 安装未经过认证的软件
24 | # 命令示例子
25 | - APT 0.6 Transitional
26 | - apt-cache search 查找软件包
27 | - apt-cache show 显示软件包信息
28 | - apt-get update 从APT源更新软件包列表
29 | - apt-get updrade 更新软件包
30 | - apt-get remove 删除已安装的软件包
31 | - apt-get purge 删除已安装的软件包及配置文件
32 | - apt-get autoremove 删除不需要的软件包(通常是由于依赖关系而安装)
33 | - apt-get autoclean 删除已卸载的软件包的.deb档
34 | - dpkg --get-selections | grep 搜索已安装的软件包
35 | - dpkg -s/-L 查看已安装的包信息/路径
36 |
37 |
38 |
39 | # 常用命令行
40 | - `python tcprelay.py -t 2222:2244`
41 | - `uicache //refresh ui`
42 | - `ssh root@ip -p 2222`
43 | - `scp -P root@: `
44 | - `tcpdump -i lo0 -s0 -w xxxx.pcapng //抓lo0接口的包`
45 | - `ifconfig lo0`
46 | - `rvictl -s uuid [Getting a Packet Trace]:https://developer.apple.com/library/content/qa/qa1176/_index.html#//apple_ref/doc/uid/DTS10001707-CH1-SECRVI`
47 | - `defaults write ~/Desktop/config_Xcode/plistfiletst key value`
48 | - `sudo xcode-select -s /Applications/Xcode.app/Contents/Developer`
49 | - `curl - I "http://ssxxx/hhh.txt"`
50 | - `wget -c "http://sssxxx/hhh.txt"`
51 | - `nscurl --ats-diagnostics --verbose https://127.0.0.1:443 //诊断app对于https的plist设置是否正确`
52 | - `dig cache.default.server.matocloud.com`
53 | - `telnet 123.103.23.219`
54 | - `nm //display name list (symbol table)`
55 | - `dpkg -i xxxx.deb (use apt-get install -f command tries to fix this broken package by installing the missing dependency)`
56 | - `https://unix.stackexchange.com/questions/159094/how-to-install-a-deb-file-by-dpkg-i-or-by-apt`
57 | - `grep -rnw headOutPuts -e 'requestByRemovingPostCheckKey' //查找指定字符串的文件`
58 | - `otool -l xxxx | grep crypt // 0为脱过壳`
59 | - `codesign -d --ent :- /path/to/the.app //Inspect the entitlements of a built app`
60 | # 常用文件路径
61 | - `host文件 /private/etc/`
62 | - `cydia下载的deb文件 /private/var/cache/apt/archives 2014年11月,iOS8越狱后的deb包的变化: /User/Library/Caches/com.saurik.Cydia/archives/`
63 |
64 | # 自动安装deb文件
65 | - 将deb文件放入/private/var/root/Media/Cydia/AutoInstall,然后重启设备
66 |
67 | # 常用的源
68 | - http://apt.saurik.com/
69 | - http://apt.thebigboss.org/repofiles/cydia/
70 | - https://cydia.angelxwind.net/
71 | - http://rpetri.ch/repo/
72 | - applist
73 | - http://www.saurik.com/id/1
74 | - http://xsf1re.github.io
75 | -flyjb
76 |
77 | # iPhone相关的网站
78 | - https://www.theiphonewiki.com/wiki/Models
79 | # 越狱可用的网站
80 | 1. https://checkra.in
81 | 2. https://frida.re/docs/installation/
82 | 3.
83 | # 忘记ssh的密码
84 | 1. 使用iFiles或者Filza打开'/private/etc/master.password',找到下面这行
85 |
86 | root:xxxxxxxxxxxxx:0:0::0:0:System Administrator:/var/root:/bin/sh
87 | mobile:xxxxxxxxxxxxx:501:501::0:0:Mobile User:/var/mobile:/bin/sh
88 |
89 | 2. 将root:及mobile:后面的13个x字符处修改成
90 |
91 | root:/smx7MYTQIi2M:0:0::0:0:System Administrator:/var/root:/bin/sh
92 | mobile:/smx7MYTQIi2M:501:501::0:0:Mobile User:/var/mobile:/bin/sh
93 | 3. 修改后保存此文件,你越狱机的ssh密码就重新回到默认的:'alpine'
94 |
95 | # cydia can't access network
96 | 1. cd /var/preferences
97 | 2. backup
98 | 3. rm -rf com.apple.networkextension.plist
99 | 4. rm -rf com.apple.networkextension.cache.plist
100 | 5. rm -rf com.apple.networkextension.necp.plist
101 | 6. 提醒: 如果你是第一次使用的同学cydia启用网络之后 会搜索到cydia的更新 更新之后 的cydia又会无法联网.请再去删一次 3个文件然后再重启 即可.
102 |
103 | # Reveal V4 fix "The operation couldn’t be completed. The app is linked against an older version of the Reveal library. You may need to update the Reveal library in your app."
104 | 0. `install Reveal2Loader_1.0-3_iphoneos-arm.deb or put deb in Device/var/root`
105 | 1. `copy RevealServer.framework to /Library/Frameworks`
106 | 2. `killall SpringBoard`
107 |
108 | # ifunbox can see root
109 | 1. install "Apple File Conduit "2" (64位)"
110 |
111 | # 方便的调试他人app的工具
112 | - flexible
113 | - woodpecker
114 | - lookin
115 |
116 | # IPA2Deb
117 | - mkdir tmp
118 | - cd tmp
119 | - mkdir DEBIAN Applications
120 | - touch DEBIAN/control
121 | - vim DEBIAN/control
122 | - 输入如下的文本:
123 | Package: com.sharedream.test
124 | Name: test
125 | Version: 0.1
126 | Description: test
127 | Section: test
128 | Depends: firmware (>= 4.3)
129 | Priority: optional
130 | Architecture: iphoneos-arm
131 | Author: test
132 | Homepage: test
133 | Maintainer: test
134 | - cp text.app Applications
135 | - cd ..
136 | - dpkg-deb -b tmp test.deb
137 | - dpkg-scanpackages -m debs >Packages
138 | - bzip2 -zkf Packages
139 |
140 | # homebrew
141 | ## 中科大镜像
142 | 替换brew.git:
143 | cd "$(brew --repo)"
144 | git remote set-url origin https://mirrors.ustc.edu.cn/brew.git
145 |
146 | 替换homebrew-core.git:
147 | cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core"
148 | git remote set-url origin https://mirrors.ustc.edu.cn/homebrew-core.git
149 |
150 | ## 阿里镜像
151 |
152 | - cd "$(brew --repo)"
153 |
154 | - git remote set-url origin https://mirrors.aliyun.com/homebrew/brew.git
155 |
156 | - cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core"
157 |
158 | - git remote set-url origin https://mirrors.aliyun.com/homebrew/homebrew-core.git
159 |
160 | ## 更新
161 |
162 | - brew update
163 | - brew config
164 |
165 | ## 重置
166 | - cd "$(brew --repo)"
167 | - git remote set-url origin https://github.com/Homebrew/brew.git
168 |
169 | - cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core"
170 | - git remote set-url origin https://github.com/Homebrew/homebrew-core.git
171 |
172 | ## 更换 homebrew-bottles
173 | - echo $SHELL
174 |
175 | - echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.aliyun.com/homebrew/homebrew-bottles' >> ~/.zshrc
176 |
177 | - source ~/.zshrc
178 |
179 | - echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.aliyun.com/homebrew/homebrew-bottles' >> ~/.bash_profile
180 |
181 | - source ~/.bash_profile
182 |
183 |
184 |
--------------------------------------------------------------------------------
/inject_with_jailbreaking/AsyncSocket.h:
--------------------------------------------------------------------------------
1 | //
2 | // AsyncSocket.h
3 | //
4 | // This class is in the public domain.
5 | // Originally created by Dustin Voss on Wed Jan 29 2003.
6 | // Updated and maintained by Deusty Designs and the Mac development community.
7 | //
8 | // http://code.google.com/p/cocoaasyncsocket/
9 | //
10 |
11 | #import
12 |
13 | @class AsyncSocket;
14 | @class AsyncReadPacket;
15 | @class AsyncWritePacket;
16 |
17 | extern NSString *const AsyncSocketException;
18 | extern NSString *const AsyncSocketErrorDomain;
19 |
20 | enum AsyncSocketError
21 | {
22 | AsyncSocketCFSocketError = kCFSocketError, // From CFSocketError enum.
23 | AsyncSocketNoError = 0, // Never used.
24 | AsyncSocketCanceledError, // onSocketWillConnect: returned NO.
25 | AsyncSocketConnectTimeoutError,
26 | AsyncSocketReadMaxedOutError, // Reached set maxLength without completing
27 | AsyncSocketReadTimeoutError,
28 | AsyncSocketWriteTimeoutError
29 | };
30 | typedef enum AsyncSocketError AsyncSocketError;
31 |
32 | @interface NSObject (AsyncSocketDelegate)
33 |
34 | /**
35 | * In the event of an error, the socket is closed.
36 | * You may call "unreadData" during this call-back to get the last bit of data off the socket.
37 | * When connecting, this delegate method may be called
38 | * before"onSocket:didAcceptNewSocket:" or "onSocket:didConnectToHost:".
39 | **/
40 | - (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err;
41 |
42 | /**
43 | * Called when a socket disconnects with or without error. If you want to release a socket after it disconnects,
44 | * do so here. It is not safe to do that during "onSocket:willDisconnectWithError:".
45 | *
46 | * If you call the disconnect method, and the socket wasn't already disconnected,
47 | * this delegate method will be called before the disconnect method returns.
48 | **/
49 | - (void)onSocketDidDisconnect:(AsyncSocket *)sock;
50 |
51 | /**
52 | * Called when a socket accepts a connection. Another socket is spawned to handle it. The new socket will have
53 | * the same delegate and will call "onSocket:didConnectToHost:port:".
54 | **/
55 | - (void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket;
56 |
57 | /**
58 | * Called when a new socket is spawned to handle a connection. This method should return the run-loop of the
59 | * thread on which the new socket and its delegate should operate. If omitted, [NSRunLoop currentRunLoop] is used.
60 | **/
61 | - (NSRunLoop *)onSocket:(AsyncSocket *)sock wantsRunLoopForNewSocket:(AsyncSocket *)newSocket;
62 |
63 | /**
64 | * Called when a socket is about to connect. This method should return YES to continue, or NO to abort.
65 | * If aborted, will result in AsyncSocketCanceledError.
66 | *
67 | * If the connectToHost:onPort:error: method was called, the delegate will be able to access and configure the
68 | * CFReadStream and CFWriteStream as desired prior to connection.
69 | *
70 | * If the connectToAddress:error: method was called, the delegate will be able to access and configure the
71 | * CFSocket and CFSocketNativeHandle (BSD socket) as desired prior to connection. You will be able to access and
72 | * configure the CFReadStream and CFWriteStream in the onSocket:didConnectToHost:port: method.
73 | **/
74 | - (BOOL)onSocketWillConnect:(AsyncSocket *)sock;
75 |
76 | /**
77 | * Called when a socket connects and is ready for reading and writing.
78 | * The host parameter will be an IP address, not a DNS name.
79 | **/
80 | - (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port;
81 |
82 | /**
83 | * Called when a socket has completed reading the requested data into memory.
84 | * Not called if there is an error.
85 | **/
86 | - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag;
87 |
88 | /**
89 | * Called when a socket has read in data, but has not yet completed the read.
90 | * This would occur if using readToData: or readToLength: methods.
91 | * It may be used to for things such as updating progress bars.
92 | **/
93 | - (void)onSocket:(AsyncSocket *)sock didReadPartialDataOfLength:(CFIndex)partialLength tag:(long)tag;
94 |
95 | /**
96 | * Called when a socket has completed writing the requested data. Not called if there is an error.
97 | **/
98 | - (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag;
99 |
100 | /**
101 | * Called when a socket has written some data, but has not yet completed the entire write.
102 | * It may be used to for things such as updating progress bars.
103 | **/
104 | - (void)onSocket:(AsyncSocket *)sock didWritePartialDataOfLength:(CFIndex)partialLength tag:(long)tag;
105 |
106 | /**
107 | * Called if a read operation has reached its timeout without completing.
108 | * This method allows you to optionally extend the timeout.
109 | * If you return a positive time interval (> 0) the read's timeout will be extended by the given amount.
110 | * If you don't implement this method, or return a non-positive time interval (<= 0) the read will timeout as usual.
111 | *
112 | * The elapsed parameter is the sum of the original timeout, plus any additions previously added via this method.
113 | * The length parameter is the number of bytes that have been read so far for the read operation.
114 | *
115 | * Note that this method may be called multiple times for a single read if you return positive numbers.
116 | **/
117 | - (NSTimeInterval)onSocket:(AsyncSocket *)sock
118 | shouldTimeoutReadWithTag:(long)tag
119 | elapsed:(NSTimeInterval)elapsed
120 | bytesDone:(CFIndex)length;
121 |
122 | /**
123 | * Called if a write operation has reached its timeout without completing.
124 | * This method allows you to optionally extend the timeout.
125 | * If you return a positive time interval (> 0) the write's timeout will be extended by the given amount.
126 | * If you don't implement this method, or return a non-positive time interval (<= 0) the write will timeout as usual.
127 | *
128 | * The elapsed parameter is the sum of the original timeout, plus any additions previously added via this method.
129 | * The length parameter is the number of bytes that have been written so far for the write operation.
130 | *
131 | * Note that this method may be called multiple times for a single write if you return positive numbers.
132 | **/
133 | - (NSTimeInterval)onSocket:(AsyncSocket *)sock
134 | shouldTimeoutWriteWithTag:(long)tag
135 | elapsed:(NSTimeInterval)elapsed
136 | bytesDone:(CFIndex)length;
137 |
138 | /**
139 | * Called after the socket has successfully completed SSL/TLS negotiation.
140 | * This method is not called unless you use the provided startTLS method.
141 | *
142 | * If a SSL/TLS negotiation fails (invalid certificate, etc) then the socket will immediately close,
143 | * and the onSocket:willDisconnectWithError: delegate method will be called with the specific SSL error code.
144 | **/
145 | - (void)onSocketDidSecure:(AsyncSocket *)sock;
146 |
147 | @end
148 |
149 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
150 | #pragma mark -
151 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
152 |
153 | @interface AsyncSocket : NSObject
154 | {
155 | CFSocketNativeHandle theNativeSocket4;
156 | CFSocketNativeHandle theNativeSocket6;
157 |
158 | CFSocketRef theSocket4; // IPv4 accept or connect socket
159 | CFSocketRef theSocket6; // IPv6 accept or connect socket
160 |
161 | CFReadStreamRef theReadStream;
162 | CFWriteStreamRef theWriteStream;
163 |
164 | CFRunLoopSourceRef theSource4; // For theSocket4
165 | CFRunLoopSourceRef theSource6; // For theSocket6
166 | CFRunLoopRef theRunLoop;
167 | CFSocketContext theContext;
168 | NSArray *theRunLoopModes;
169 |
170 | NSTimer *theConnectTimer;
171 |
172 | NSMutableArray *theReadQueue;
173 | AsyncReadPacket *theCurrentRead;
174 | NSTimer *theReadTimer;
175 | NSMutableData *partialReadBuffer;
176 |
177 | NSMutableArray *theWriteQueue;
178 | AsyncWritePacket *theCurrentWrite;
179 | NSTimer *theWriteTimer;
180 |
181 | id theDelegate;
182 | UInt16 theFlags;
183 |
184 | long theUserData;
185 | }
186 |
187 | - (id)init;
188 | - (id)initWithDelegate:(id)delegate;
189 | - (id)initWithDelegate:(id)delegate userData:(long)userData;
190 |
191 | /* String representation is long but has no "\n". */
192 | - (NSString *)description;
193 |
194 | /**
195 | * Use "canSafelySetDelegate" to see if there is any pending business (reads and writes) with the current delegate
196 | * before changing it. It is, of course, safe to change the delegate before connecting or accepting connections.
197 | **/
198 | - (id)delegate;
199 | - (BOOL)canSafelySetDelegate;
200 | - (void)setDelegate:(id)delegate;
201 |
202 | /* User data can be a long, or an id or void * cast to a long. */
203 | - (long)userData;
204 | - (void)setUserData:(long)userData;
205 |
206 | /* Don't use these to read or write. And don't close them either! */
207 | - (CFSocketRef)getCFSocket;
208 | - (CFReadStreamRef)getCFReadStream;
209 | - (CFWriteStreamRef)getCFWriteStream;
210 |
211 | // Once one of the accept or connect methods are called, the AsyncSocket instance is locked in
212 | // and the other accept/connect methods can't be called without disconnecting the socket first.
213 | // If the attempt fails or times out, these methods either return NO or
214 | // call "onSocket:willDisconnectWithError:" and "onSockedDidDisconnect:".
215 |
216 | // When an incoming connection is accepted, AsyncSocket invokes several delegate methods.
217 | // These methods are (in chronological order):
218 | // 1. onSocket:didAcceptNewSocket:
219 | // 2. onSocket:wantsRunLoopForNewSocket:
220 | // 3. onSocketWillConnect:
221 | //
222 | // Your server code will need to retain the accepted socket (if you want to accept it).
223 | // The best place to do this is probably in the onSocket:didAcceptNewSocket: method.
224 | //
225 | // After the read and write streams have been setup for the newly accepted socket,
226 | // the onSocket:didConnectToHost:port: method will be called on the proper run loop.
227 | //
228 | // Multithreading Note: If you're going to be moving the newly accepted socket to another run
229 | // loop by implementing onSocket:wantsRunLoopForNewSocket:, then you should wait until the
230 | // onSocket:didConnectToHost:port: method before calling read, write, or startTLS methods.
231 | // Otherwise read/write events are scheduled on the incorrect runloop, and chaos may ensue.
232 |
233 | /**
234 | * Tells the socket to begin listening and accepting connections on the given port.
235 | * When a connection comes in, the AsyncSocket instance will call the various delegate methods (see above).
236 | * The socket will listen on all available interfaces (e.g. wifi, ethernet, etc)
237 | **/
238 | - (BOOL)acceptOnPort:(UInt16)port error:(NSError **)errPtr;
239 |
240 | /**
241 | * This method is the same as acceptOnPort:error: with the additional option
242 | * of specifying which interface to listen on. So, for example, if you were writing code for a server that
243 | * has multiple IP addresses, you could specify which address you wanted to listen on. Or you could use it
244 | * to specify that the socket should only accept connections over ethernet, and not other interfaces such as wifi.
245 | * You may also use the special strings "localhost" or "loopback" to specify that
246 | * the socket only accept connections from the local machine.
247 | *
248 | * To accept connections on any interface pass nil, or simply use the acceptOnPort:error: method.
249 | **/
250 | - (BOOL)acceptOnInterface:(NSString *)interface port:(UInt16)port error:(NSError **)errPtr;
251 |
252 | /**
253 | * Connects to the given host and port.
254 | * The host may be a domain name (e.g. "deusty.com") or an IP address string (e.g. "192.168.0.2")
255 | **/
256 | - (BOOL)connectToHost:(NSString *)hostname onPort:(UInt16)port error:(NSError **)errPtr;
257 |
258 | /**
259 | * This method is the same as connectToHost:onPort:error: with an additional timeout option.
260 | * To not time out use a negative time interval, or simply use the connectToHost:onPort:error: method.
261 | **/
262 | - (BOOL)connectToHost:(NSString *)hostname
263 | onPort:(UInt16)port
264 | withTimeout:(NSTimeInterval)timeout
265 | error:(NSError **)errPtr;
266 |
267 | /**
268 | * Connects to the given address, specified as a sockaddr structure wrapped in a NSData object.
269 | * For example, a NSData object returned from NSNetservice's addresses method.
270 | *
271 | * If you have an existing struct sockaddr you can convert it to a NSData object like so:
272 | * struct sockaddr sa -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len];
273 | * struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len];
274 | **/
275 | - (BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError **)errPtr;
276 |
277 | /**
278 | * This method is the same as connectToAddress:error: with an additional timeout option.
279 | * To not time out use a negative time interval, or simply use the connectToAddress:error: method.
280 | **/
281 | - (BOOL)connectToAddress:(NSData *)remoteAddr withTimeout:(NSTimeInterval)timeout error:(NSError **)errPtr;
282 |
283 | /**
284 | * Disconnects immediately. Any pending reads or writes are dropped.
285 | * If the socket is not already disconnected, the onSocketDidDisconnect delegate method
286 | * will be called immediately, before this method returns.
287 | *
288 | * Please note the recommended way of releasing an AsyncSocket instance (e.g. in a dealloc method)
289 | * [asyncSocket setDelegate:nil];
290 | * [asyncSocket disconnect];
291 | * [asyncSocket release];
292 | **/
293 | - (void)disconnect;
294 |
295 | /**
296 | * Disconnects after all pending reads have completed.
297 | * After calling this, the read and write methods will do nothing.
298 | * The socket will disconnect even if there are still pending writes.
299 | **/
300 | - (void)disconnectAfterReading;
301 |
302 | /**
303 | * Disconnects after all pending writes have completed.
304 | * After calling this, the read and write methods will do nothing.
305 | * The socket will disconnect even if there are still pending reads.
306 | **/
307 | - (void)disconnectAfterWriting;
308 |
309 | /**
310 | * Disconnects after all pending reads and writes have completed.
311 | * After calling this, the read and write methods will do nothing.
312 | **/
313 | - (void)disconnectAfterReadingAndWriting;
314 |
315 | /* Returns YES if the socket and streams are open, connected, and ready for reading and writing. */
316 | - (BOOL)isConnected;
317 |
318 | /**
319 | * Returns the local or remote host and port to which this socket is connected, or nil and 0 if not connected.
320 | * The host will be an IP address.
321 | **/
322 | - (NSString *)connectedHost;
323 | - (UInt16)connectedPort;
324 |
325 | - (NSString *)localHost;
326 | - (UInt16)localPort;
327 |
328 | /**
329 | * Returns the local or remote address to which this socket is connected,
330 | * specified as a sockaddr structure wrapped in a NSData object.
331 | *
332 | * See also the connectedHost, connectedPort, localHost and localPort methods.
333 | **/
334 | - (NSData *)connectedAddress;
335 | - (NSData *)localAddress;
336 |
337 | /**
338 | * Returns whether the socket is IPv4 or IPv6.
339 | * An accepting socket may be both.
340 | **/
341 | - (BOOL)isIPv4;
342 | - (BOOL)isIPv6;
343 |
344 | // The readData and writeData methods won't block.
345 | //
346 | // You may optionally set a timeout for any read/write operation. (To not timeout, use a negative time interval.)
347 | // If a read/write opertion times out, the corresponding "onSocket:shouldTimeout..." delegate method
348 | // is called to optionally allow you to extend the timeout.
349 | // Upon a timeout, the "onSocket:willDisconnectWithError:" method is called, followed by "onSocketDidDisconnect".
350 | //
351 | // The tag is for your convenience.
352 | // You can use it as an array index, step number, state id, pointer, etc., just like the socket's user data.
353 |
354 | /**
355 | * This will read a certain number of bytes into memory, and call the delegate method when those bytes have been read.
356 | *
357 | * If the length is 0, this method does nothing and the delegate is not called.
358 | * If the timeout value is negative, the read operation will not use a timeout.
359 | **/
360 | - (void)readDataToLength:(CFIndex)length withTimeout:(NSTimeInterval)timeout tag:(long)tag;
361 |
362 | /**
363 | * This reads bytes until (and including) the passed "data" parameter, which acts as a separator.
364 | * The bytes and the separator are returned by the delegate method.
365 | *
366 | * If you pass nil or zero-length data as the "data" parameter,
367 | * the method will do nothing, and the delegate will not be called.
368 | * If the timeout value is negative, the read operation will not use a timeout.
369 | *
370 | * To read a line from the socket, use the line separator (e.g. CRLF for HTTP, see below) as the "data" parameter.
371 | * Note that this method is not character-set aware, so if a separator can occur naturally as part of the encoding for
372 | * a character, the read will prematurely end.
373 | **/
374 | - (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
375 |
376 | /**
377 | * Same as readDataToData:withTimeout:tag, with the additional restriction that the amount of data read
378 | * may not surpass the given maxLength (specified in bytes).
379 | *
380 | * If you pass a maxLength parameter that is less than the length of the data parameter,
381 | * the method will do nothing, and the delegate will not be called.
382 | *
383 | * If the max length is surpassed, it is treated the same as a timeout - the socket is closed.
384 | *
385 | * Pass -1 as maxLength if no length restriction is desired, or simply use the readDataToData:withTimeout:tag method.
386 | **/
387 | - (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout maxLength:(CFIndex)length tag:(long)tag;
388 |
389 | /**
390 | * Reads the first available bytes that become available on the socket.
391 | *
392 | * If the timeout value is negative, the read operation will not use a timeout.
393 | **/
394 | - (void)readDataWithTimeout:(NSTimeInterval)timeout tag:(long)tag;
395 |
396 | /**
397 | * Writes data to the socket, and calls the delegate when finished.
398 | *
399 | * If you pass in nil or zero-length data, this method does nothing and the delegate will not be called.
400 | * If the timeout value is negative, the write operation will not use a timeout.
401 | **/
402 | - (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
403 |
404 | /**
405 | * Returns progress of current read or write, from 0.0 to 1.0, or NaN if no read/write (use isnan() to check).
406 | * "tag", "done" and "total" will be filled in if they aren't NULL.
407 | **/
408 | - (float)progressOfReadReturningTag:(long *)tag bytesDone:(CFIndex *)done total:(CFIndex *)total;
409 | - (float)progressOfWriteReturningTag:(long *)tag bytesDone:(CFIndex *)done total:(CFIndex *)total;
410 |
411 | /**
412 | * Secures the connection using SSL/TLS.
413 | *
414 | * This method may be called at any time, and the TLS handshake will occur after all pending reads and writes
415 | * are finished. This allows one the option of sending a protocol dependent StartTLS message, and queuing
416 | * the upgrade to TLS at the same time, without having to wait for the write to finish.
417 | * Any reads or writes scheduled after this method is called will occur over the secured connection.
418 | *
419 | * The possible keys and values for the TLS settings are well documented.
420 | * Some possible keys are:
421 | * - kCFStreamSSLLevel
422 | * - kCFStreamSSLAllowsExpiredCertificates
423 | * - kCFStreamSSLAllowsExpiredRoots
424 | * - kCFStreamSSLAllowsAnyRoot
425 | * - kCFStreamSSLValidatesCertificateChain
426 | * - kCFStreamSSLPeerName
427 | * - kCFStreamSSLCertificates
428 | * - kCFStreamSSLIsServer
429 | *
430 | * Please refer to Apple's documentation for associated values, as well as other possible keys.
431 | *
432 | * If you pass in nil or an empty dictionary, the default settings will be used.
433 | *
434 | * The default settings will check to make sure the remote party's certificate is signed by a
435 | * trusted 3rd party certificate agency (e.g. verisign) and that the certificate is not expired.
436 | * However it will not verify the name on the certificate unless you
437 | * give it a name to verify against via the kCFStreamSSLPeerName key.
438 | * The security implications of this are important to understand.
439 | * Imagine you are attempting to create a secure connection to MySecureServer.com,
440 | * but your socket gets directed to MaliciousServer.com because of a hacked DNS server.
441 | * If you simply use the default settings, and MaliciousServer.com has a valid certificate,
442 | * the default settings will not detect any problems since the certificate is valid.
443 | * To properly secure your connection in this particular scenario you
444 | * should set the kCFStreamSSLPeerName property to "MySecureServer.com".
445 | * If you do not know the peer name of the remote host in advance (for example, you're not sure
446 | * if it will be "domain.com" or "www.domain.com"), then you can use the default settings to validate the
447 | * certificate, and then use the X509Certificate class to verify the issuer after the socket has been secured.
448 | * The X509Certificate class is part of the CocoaAsyncSocket open source project.
449 | **/
450 | - (void)startTLS:(NSDictionary *)tlsSettings;
451 |
452 | /**
453 | * For handling readDataToData requests, data is necessarily read from the socket in small increments.
454 | * The performance can be much improved by allowing AsyncSocket to read larger chunks at a time and
455 | * store any overflow in a small internal buffer.
456 | * This is termed pre-buffering, as some data may be read for you before you ask for it.
457 | * If you use readDataToData a lot, enabling pre-buffering will result in better performance, especially on the iPhone.
458 | *
459 | * The default pre-buffering state is controlled by the DEFAULT_PREBUFFERING definition.
460 | * It is highly recommended one leave this set to YES.
461 | *
462 | * This method exists in case pre-buffering needs to be disabled by default for some unforeseen reason.
463 | * In that case, this method exists to allow one to easily enable pre-buffering when ready.
464 | **/
465 | - (void)enablePreBuffering;
466 |
467 | /**
468 | * When you create an AsyncSocket, it is added to the runloop of the current thread.
469 | * So for manually created sockets, it is easiest to simply create the socket on the thread you intend to use it.
470 | *
471 | * If a new socket is accepted, the delegate method onSocket:wantsRunLoopForNewSocket: is called to
472 | * allow you to place the socket on a separate thread. This works best in conjunction with a thread pool design.
473 | *
474 | * If, however, you need to move the socket to a separate thread at a later time, this
475 | * method may be used to accomplish the task.
476 | *
477 | * This method must be called from the thread/runloop the socket is currently running on.
478 | *
479 | * Note: After calling this method, all further method calls to this object should be done from the given runloop.
480 | * Also, all delegate calls will be sent on the given runloop.
481 | **/
482 | - (BOOL)moveToRunLoop:(NSRunLoop *)runLoop;
483 |
484 | /**
485 | * Allows you to configure which run loop modes the socket uses.
486 | * The default set of run loop modes is NSDefaultRunLoopMode.
487 | *
488 | * If you'd like your socket to continue operation during other modes, you may want to add modes such as
489 | * NSModalPanelRunLoopMode or NSEventTrackingRunLoopMode. Or you may simply want to use NSRunLoopCommonModes.
490 | *
491 | * Accepted sockets will automatically inherit the same run loop modes as the listening socket.
492 | *
493 | * Note: NSRunLoopCommonModes is defined in 10.5. For previous versions one can use kCFRunLoopCommonModes.
494 | **/
495 | - (BOOL)setRunLoopModes:(NSArray *)runLoopModes;
496 |
497 | /**
498 | * Returns the current run loop modes the AsyncSocket instance is operating in.
499 | * The default set of run loop modes is NSDefaultRunLoopMode.
500 | **/
501 | - (NSArray *)runLoopModes;
502 |
503 | /**
504 | * In the event of an error, this method may be called during onSocket:willDisconnectWithError: to read
505 | * any data that's left on the socket.
506 | **/
507 | - (NSData *)unreadData;
508 |
509 | /* A few common line separators, for use with the readDataToData:... methods. */
510 | + (NSData *)CRLFData; // 0x0D0A
511 | + (NSData *)CRData; // 0x0D
512 | + (NSData *)LFData; // 0x0A
513 | + (NSData *)ZeroData; // 0x00
514 |
515 | @end
516 |
--------------------------------------------------------------------------------
/inject_with_jailbreaking/Xtrace.h:
--------------------------------------------------------------------------------
1 | //
2 | // Xtrace.h
3 | // Xtrace
4 | //
5 | // Created by John Holdsworth on 28/02/2014.
6 | // Copyright (c) 2014 John Holdsworth. All rights reserved.
7 | //
8 | // Repo: https://github.com/johnno1962/Xtrace
9 | //
10 | // $Id: //depot/Xtrace/Xtrace.h#2 $
11 | //
12 | // Class to intercept messages sent to a class or object.
13 | // Swizzles generic logging implemntation in place of the
14 | // original which is called after logging the message.
15 | //
16 | // Implemented as category on NSObject so message the
17 | // class or instance you want to log for example:
18 | //
19 | // Log all messages of the navigation controller class
20 | // and it's superclasses:
21 | // [UINavigationController xtrace]
22 | //
23 | // Log all messages sent to objects instance1/2
24 | // [instance1 xtrace];
25 | // [instance2 xtrace];
26 | //
27 | // Instance tracing takes priority.
28 | //
29 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
32 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
33 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
37 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 | //
40 |
41 | #ifdef DEBUG
42 | #ifdef __OBJC__
43 | #import
44 | #import
45 |
46 | #ifdef __clang__
47 | #if __has_feature(objc_arc)
48 | #define XTRACE_ISARC
49 | #endif
50 | #endif
51 |
52 | #ifdef XTRACE_ISARC
53 | #define XTRACE_UNSAFE __unsafe_unretained
54 | #define XTRACE_BRIDGE(_type) (__bridge _type)
55 | #define XTRACE_RETAINED __attribute((ns_returns_retained))
56 | #else
57 | #define XTRACE_UNSAFE
58 | #define XTRACE_BRIDGE(_type) (_type)
59 | #define XTRACE_RETAINED
60 | #endif
61 |
62 | #define XTRACE_EXCLUSIONS "^(initWithCoder:|_UIAppearance_|"\
63 | "_(initializeFor|performUpdatesForPossibleChangesOf)Idiom:|"\
64 | "timeIntervalSinceReferenceDate)|(WithObjects(AndKeys)?|Format):$"
65 |
66 | // for use with "XcodeColours" plugin
67 | // https://github.com/robbiehanson/XcodeColors
68 |
69 | #define XTRACE_FG "\033[fg"
70 | #define XTRACE_BG "\033[bg"
71 |
72 | #define XTRACE_RED XTRACE_FG"255,0,0;"
73 | #define XTRACE_GREEN XTRACE_FG"0,255,0;"
74 | #define XTRACE_BLUE XTRACE_FG"0,0,255;"
75 |
76 | // internal information
77 | #define XTRACE_ARGS_SUPPORTED 10
78 |
79 | typedef void (*XTRACE_VIMP)( XTRACE_UNSAFE id obj, SEL sel, ... );
80 | typedef void (^XTRACE_BIMP)( XTRACE_UNSAFE id obj, SEL sel, ... );
81 |
82 | struct _xtrace_arg {
83 | const char *name, *type;
84 | int stackOffset;
85 | };
86 |
87 | // information about original implementations
88 | struct _xtrace_info {
89 | int depth;
90 | void *caller;
91 | void *lastObj;
92 | const char *color;
93 |
94 | XTRACE_VIMP before, original, after;
95 | XTRACE_UNSAFE XTRACE_BIMP beforeBlock, afterBlock;
96 |
97 | Method method;
98 | const char *name, *type, *mtype;
99 | struct _xtrace_arg args[XTRACE_ARGS_SUPPORTED+1];
100 |
101 | struct _stats {
102 | NSTimeInterval entered, elapsed;
103 | unsigned callCount;
104 | } stats;
105 | BOOL callingBack;
106 | };
107 |
108 | @interface NSObject(Xtrace)
109 |
110 | // dump class
111 | + (void)xdump;
112 |
113 | // intercept before method is called
114 | + (void)beforeSelector:(SEL)sel callBlock:callback;
115 |
116 | // after intercept block replaces return value
117 | + (void)afterSelector:(SEL)sel callBlock:callback;
118 |
119 | // avoid a class
120 | + (void)notrace;
121 |
122 | // trace class or..
123 | + (void)xtrace;
124 |
125 | // trace instance
126 | - (void)xtrace;
127 |
128 | // stop tacing ""
129 | - (void)notrace;
130 |
131 | @end
132 |
133 | // logging delegate
134 | @protocol XtraceDelegate
135 | - (void)xtrace:(NSString *)trace forInstance:(void *)obj indent:(int)indent;
136 | @end
137 |
138 | // implementing class
139 | @interface Xtrace : NSObject {
140 | @public
141 | Class aClass;
142 | struct _xtrace_info *info;
143 | NSTimeInterval elapsed;
144 | int callCount;
145 | }
146 |
147 | // delegate for callbacks
148 | + (void)setDelegate:delegate;
149 |
150 | // show caller on entry
151 | + (void)showCaller:(BOOL)show;
152 |
153 | // show class implementing
154 | + (void)showActual:(BOOL)show;
155 |
156 | // show log of return values
157 | + (void)showReturns:(BOOL)show;
158 |
159 | // attempt log of call arguments
160 | + (void)showArguments:(BOOL)show;
161 |
162 | // log values's "description"
163 | + (void)describeValues:(BOOL)desc;
164 |
165 | // property methods filtered out by default
166 | + (void)includeProperties:(BOOL)include;
167 |
168 | // include/exclude methods matching pattern
169 | + (BOOL)includeMethods:(NSString *)pattern;
170 | + (BOOL)excludeMethods:(NSString *)pattern;
171 | + (BOOL)excludeTypes:(NSString *)pattern;
172 |
173 | // color subsequent traces
174 | + (void)useColor:(const char *)color;
175 |
176 | // finer grain control of color
177 | + (void)useColor:(const char *)color forSelector:(SEL)sel;
178 | + (void)useColor:(const char *)color forClass:(Class)aClass;
179 |
180 | // don't trace this class e.g. [UIView notrace]
181 | + (void)dontTrace:(Class)aClass;
182 |
183 | // trace class down to NSObject
184 | + (void)traceClass:(Class)aClass;
185 |
186 | // trace class down to "levels" of superclases
187 | + (void)traceClass:(Class)aClass levels:(int)levels;
188 |
189 | // trace all classes in app/bundle/framework
190 | + (void)traceBundleContainingClass:(Class)aClass;
191 |
192 | // "kitchen sink" trace all classes matching pattern
193 | + (void)traceClassPattern:(NSString *)pattern excluding:(NSString *)exclusions;
194 |
195 | // trace instance but only for methods in aClass
196 | + (void)traceInstance:(id)instance class:(Class)aClass;
197 |
198 | // trace all messages sent to an instance
199 | + (void)traceInstance:(id)instance;
200 |
201 | // stop tracing messages to instance
202 | + (void)notrace:(id)instance;
203 |
204 | // dump runtime class info
205 | + (void)dumpClass:(Class)aClass;
206 |
207 | // before, replacement and after callbacks to delegate
208 | + (void)forClass:(Class)aClass before:(SEL)sel callback:(SEL)callback;
209 | + (void)forClass:(Class)aClass replace:(SEL)sel callback:(SEL)callback;
210 | + (void)forClass:(Class)aClass after:(SEL)sel callback:(SEL)callback;
211 |
212 | // block based callbacks as an alternative
213 | + (void)forClass:(Class)aClass before:(SEL)sel callbackBlock:callback;
214 | + (void)forClass:(Class)aClass after:(SEL)sel callbackBlock:callback;
215 |
216 | // get parsed argument info and recorded stats
217 | + (struct _xtrace_info *)infoFor:(Class)aClass sel:(SEL)sel;
218 |
219 | // name the caller of the specified method
220 | + (const char *)callerFor:(Class)aClass sel:(SEL)sel;
221 |
222 | // simple profiling interface
223 | + (NSArray *)profile;
224 | + (void)dumpProfile:(unsigned)count dp:(int)decimalPlaces;
225 |
226 | @end
227 | #endif
228 | #endif
229 |
--------------------------------------------------------------------------------
/inject_with_jailbreaking/Xtrace.mm:
--------------------------------------------------------------------------------
1 | //
2 | // Xtrace.mm
3 | // Xtrace
4 | //
5 | // Created by John Holdsworth on 28/02/2014.
6 | // Copyright (c) 2014 John Holdsworth. All rights reserved.
7 | //
8 | // Repo: https://github.com/johnno1962/Xtrace
9 | //
10 | // $Id: //depot/Xtrace/Xtrace.mm#8 $
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // Your milage will vary.. This is definitely a case of:
16 | //
17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 |
29 | #ifdef DEBUG
30 |
31 | #pragma clang diagnostic push
32 | #pragma clang diagnostic ignored "-Wold-style-cast"
33 | #pragma clang diagnostic ignored "-Wcstring-format-directive"
34 | #pragma clang diagnostic ignored "-Wgnu-conditional-omitted-operand"
35 | #pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
36 | #pragma clang diagnostic ignored "-Wobjc-interface-ivars"
37 | #pragma clang diagnostic ignored "-Wglobal-constructors"
38 | #pragma clang diagnostic ignored "-Wdirect-ivar-access"
39 | #pragma clang diagnostic ignored "-Wclass-varargs"
40 | #pragma clang diagnostic ignored "-Wc++98-compat"
41 | #pragma clang diagnostic ignored "-Wfloat-equal"
42 | #pragma clang diagnostic ignored "-Wpadded"
43 |
44 | #import "Xtrace.h"
45 | #import