├── .DS_Store ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj ├── Main_iPad.storyboard └── Main_iPhone.storyboard ├── Binary.sh ├── Database.sh ├── Headers.sh ├── Images.xcassets ├── AppIcon.appiconset │ ├── Contents.json │ └── Icon.png └── LaunchImage.launchimage │ └── Contents.json ├── Keychain.sh ├── Log.sh ├── Menu.sh ├── Plist.sh ├── README.md ├── Screenshot.sh ├── Theos.sh ├── ViewController.h ├── ViewController.m ├── com.jensen.iRE.Startup.plist ├── createTweak.sh ├── en.lproj └── InfoPlist.strings ├── iRE-Info.plist ├── iRE-Prefix.pch ├── iRET.deb ├── iRE_Server.py ├── license.txt └── main.m /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/S3Jensen/iRET/8bfe376e6ccfd4219c9d405dd8f6c0226e2ef26c/.DS_Store -------------------------------------------------------------------------------- /AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // iRE 4 | // 5 | // Created by veracode on 11/8/13. 6 | // Copyright (c) 2013 veracode. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // iRE 4 | // 5 | // Created by veracode on 11/8/13. 6 | // Copyright (c) 2013 veracode. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #include 11 | 12 | @implementation AppDelegate 13 | 14 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 15 | { 16 | return YES; 17 | } 18 | 19 | - (void)applicationWillResignActive:(UIApplication *)application 20 | { 21 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 22 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 23 | } 24 | 25 | - (void)applicationDidEnterBackground:(UIApplication *)application 26 | { 27 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 29 | 30 | } 31 | 32 | - (void)applicationWillEnterForeground:(UIApplication *)application 33 | { 34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application 38 | { 39 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 40 | } 41 | 42 | - (void)applicationWillTerminate:(UIApplication *)application 43 | { 44 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /Base.lproj/Main_iPad.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Base.lproj/Main_iPhone.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Binary.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | AppID=$1 4 | 5 | binFile=$(find /var/mobile/Applications/"$AppID"/*.app -type f -exec file {} \; | grep Mach-O | cut -d":" -f1) 6 | 7 | echo ' 8 | 9 | iRET - iOS Reverse Engineering Toolkit 10 | 11 | 37 | 38 | 117 | 118 | 119 | 120 | 121 |
122 | 123 | 124 | 125 | 126 | 127 |
Welcome to iRET
The iOS Reverse Engineering Toolkit
128 | 139 | 140 |
141 |

Binary Analysis Results

142 |
' 143 | if [ -n "$binFile" ] 144 | then 145 | fHeaders=$(otool -fv "$binFile" | grep architecture | tr '\n' '!' | sed 's/!/
/g' | sed 's/cputype\ (16777228)\ cpusubtype\ (0)/arm64/g') 146 | mHeaders=$(otool -hv "$binFile" | tr '\n' '!' | sed 's/!/
/g') 147 | cryptoInfo=$(otool -lv "$binFile" | grep -A 4 LC_ENCRYPTION_INFO | tr '\n' '!' | sed 's/!/
/g') 148 | stackSmashInfo=$(otool -Iv "$binFile" | grep stack_chk | tr '\n' '!' | sed 's/!/
/g') 149 | arcInfo=$(otool -Iv "$binFile" | grep _objc_release | tr '\n' '!' | sed 's/!/
/g') 150 | 151 | [ -n $fHeaders ] && fatHeaders="No Fat Headers" || fatHeaders=$fHeaders 152 | [ -n $stackSmashInfo ] && stack="No Stack Smashing Protection" || stack=$stackSmashInfo 153 | [ -n $arcInfo ] && arc="No ARC Protection" || arc=$arcInfo 154 | 155 | 156 | echo '

Below are the results of the otool analysis.

157 | 158 | 159 | 251 | 252 |
160 | ' 161 | 162 | if [ -n "$fHeaders" ] 163 | then 164 | 165 | echo 'Fat Headers
166 | 167 | 168 | 173 | 176 | 177 |
169 | 170 | '${fatHeaders}' 171 | 172 |
178 |

' 179 | fi 180 | 181 | echo 'Mach-O Headers
182 | 183 | 184 | 189 | 190 |
185 | 186 | '${mHeaders}' 187 | 188 |
191 |

192 | 193 | 194 | 195 | 207 | 208 | 222 | 236 | 237 |
196 | Encryption Info 197 | 198 | 199 | 204 | 205 |
200 | 201 | '${cryptoInfo}' 202 | 203 |
206 |
209 | 210 | Stack Smashing Info
211 | 212 | 213 | 218 | 219 |
214 | 215 | '${stack}' 216 | 217 |
220 | 221 |
223 | 224 | ARC Info
225 | 226 | 227 | 232 | 233 |
228 | 229 | '${arc}' 230 | 231 |
234 | 235 |
238 | 250 |
' 253 | else 254 | echo "The Binary Appears to be a Symbolic Link" 255 | fi 256 | echo '
257 |
258 | 259 | 260 | ' 261 | -------------------------------------------------------------------------------- /Database.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | AppID=$1 4 | Database=$2 5 | 6 | echo ' 7 | 8 | iRET - iOS Reverse Engineering Toolkit 9 | 10 | 39 | 40 | 126 | 127 | 128 | 129 | 130 |
131 | 132 | 133 | 134 | 135 | 136 |
Welcome to iRET
The iOS Reverse Engineering Toolkit
137 | 148 | 149 | 150 |
151 |

Below are the databases that were found on the device.


' 152 | 153 | databases=$(find /var/mobile/Applications/$AppID -name '*.db' -o -name '*.sqlite' -o -name '*.sqlite3' -type f) 154 | 155 | if [ -n "$databases" ] 156 | then 157 | dropDownList="" 158 | 159 | OIFS="$IFS" 160 | IFS=$'\n' 161 | for i in ${databases} 162 | do 163 | dbName=$(basename $i) 164 | 165 | if [ "$Database" = "$i" ]; then 166 | dropDownList+="" 167 | else 168 | dropDownList+="" 169 | fi 170 | done 171 | IFS="$OIFS" 172 | 173 | echo 'To begin, select an database from the list below:

174 |
175 |
178 |
179 |
' 180 | 181 | if [ -n "$Database" ] 182 | then 183 | 184 | #echo "here to run tables!" 185 | tables=$(sqlite3 "$Database" .tables) 186 | 187 | declare -a columnArray 188 | 189 | preTable="
"
190 | 		postTable="
" 191 | 192 | for i in ${tables} 193 | do 194 | echo "$i TABLE
" 195 | sql=$(sqlite3 -column "$Database" "select * from $i;" | sed 's/No Data$postTable" 198 | echo "

" 199 | done 200 | 201 | die=$(sqlite3 "$Database" .tables .quit) 202 | fi 203 | else 204 | echo "No Databases Found" 205 | fi 206 | echo ' 207 | 218 | 219 | 220 | 221 | ' 222 | -------------------------------------------------------------------------------- /Headers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | AppID=$1 4 | SearchText=$3 5 | HeaderName=$2 6 | 7 | if [ ! -d "$AppID"_headers ]; then 8 | #logic to check if the binfile is encrypted 9 | binFile=$(find /var/mobile/Applications/"$AppID"/*.app -type f -exec file {} \; | grep Mach-O | cut -d":" -f1) 10 | mkdir /Applications/iRE.app/"$AppID"_headers 11 | isEncrypted=$(otool -lv "$binFile" | grep cryptid | sed 's/^ *//g' | tr ' ' ':' | cut -d":" -f4) 12 | classDumpPath=$(grep -F classDumpZ /Applications/iRE.app/toolPaths.txt | cut -d":" -f2) 13 | 14 | if [ $isEncrypted -eq 1 ]; then 15 | #binary is encrypted 16 | dumpPath=$(grep -F dumpdecrypted /Applications/iRE.app/toolPaths.txt | cut -d":" -f2) 17 | newBin=$(echo "$binFile" | sed 's/ /\\ /g') 18 | dumpit="DYLD_INSERT_LIBRARIES=$dumpPath " 19 | dumpit2=$dumpit$newBin 20 | eval $dumpit2 21 | binFile2=$(basename "$newBin") 22 | 23 | fileLoc=$(find / -name "$binFile2".decrypted -type f) 24 | nFile=$( echo "$fileLoc" | sed 's/ /\\ /g' ) 25 | eval mv "$nFile" "/Applications/iRE.app/" 26 | eval $classDumpPath /Applications/iRE.app/"$binFile2".decrypted -H -o /Applications/iRE.app/"$AppID"_headers 27 | else 28 | eval $classDumpPath "$binFile" -H -o /Applications/iRE.app/"$AppID"_headers 29 | fi 30 | fi 31 | 32 | 33 | echo ' 34 | 35 | iRET - iOS Reverse Engineering Toolkit 36 | 37 | 66 | 67 | 152 | 153 | 154 | 155 | 156 |
157 | 158 | 159 | 160 | 161 | 162 |
Welcome to iRET
The iOS Reverse Engineering Toolkit
163 | 174 | 175 | 176 |
177 |
178 | 179 | 180 |

Below are the header files that were dumped for the selected application.


' 181 | 182 | 183 | Headers=$(ls /Applications/iRE.app/"$AppID"_headers) 184 | 185 | if [ -n "$Headers" ] 186 | then 187 | dropDownList="" 188 | 189 | OIFS="$IFS" 190 | IFS=$'\n' 191 | for i in ${Headers} 192 | do 193 | fName="/Applications/iRE.app/"$AppID"_headers/"$i 194 | 195 | if [ "$HeaderName" = "$fName" ]; then 196 | dropDownList+="" 197 | else 198 | dropDownList+="" 199 | fi 200 | done 201 | IFS="$OIFS" 202 | 203 | echo 'To begin, select a header file from the list below:

204 |
205 |
208 |
209 |
' 210 | 211 | if [ -n "$HeaderName" ] 212 | then 213 | #Use theos to logify the header 214 | tmpDir="/Applications/iRE.app/tmp/" 215 | file="/Applications/iRE.app/tmp/Tweak.xm" 216 | 217 | #check if tmp directory exists 218 | if [ ! -d "$tmpDir" ]; then 219 | eval mkdir /Applications/iRE.app/tmp 220 | fi 221 | 222 | #check if "Tweak.xm" file exists 223 | if [ -f "$file" ]; then 224 | eval rm "$file" 225 | fi 226 | 227 | #nHeader=$(echo "$HeaderName" | sed 's/\\//g') 228 | #nHeaderName=$(echo "$nHeader" | sed 's/ /\\ /g') 229 | 230 | theosPath=$(grep -F theos /Applications/iRE.app/toolPaths.txt | cut -d":" -f2) 231 | eval "$theosPath/bin/logify.pl $HeaderName > /Applications/iRE.app/tmp/Tweak.xm" 232 | 233 | content=$(cat /Applications/iRE.app/tmp/Tweak.xm | sed 's//g') 234 | 235 | echo '
236 |
237 |
238 |
'
239 | 
240 | 		if [ "$content" != "" ]
241 | 		then
242 | 			echo $content
243 | 		else
244 | 			echo "No Content To Logify"
245 | 		fi
246 | 			echo '
247 |
248 |
249 |
' 250 | fi 251 | fi 252 | echo '
253 |
254 | 255 | 256 | 257 | ' 258 | -------------------------------------------------------------------------------- /Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "57x57", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "57x57", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "size" : "29x29", 25 | "idiom" : "iphone", 26 | "filename" : "Icon.png", 27 | "unassigned" : true, 28 | "scale" : "2x" 29 | } 30 | ], 31 | "info" : { 32 | "version" : 1, 33 | "author" : "xcode" 34 | } 35 | } -------------------------------------------------------------------------------- /Images.xcassets/AppIcon.appiconset/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/S3Jensen/iRET/8bfe376e6ccfd4219c9d405dd8f6c0226e2ef26c/Images.xcassets/AppIcon.appiconset/Icon.png -------------------------------------------------------------------------------- /Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "extent" : "full-screen", 14 | "minimum-system-version" : "7.0", 15 | "subtype" : "retina4", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "orientation" : "portrait", 20 | "idiom" : "ipad", 21 | "extent" : "full-screen", 22 | "minimum-system-version" : "7.0", 23 | "scale" : "1x" 24 | }, 25 | { 26 | "orientation" : "landscape", 27 | "idiom" : "ipad", 28 | "extent" : "full-screen", 29 | "minimum-system-version" : "7.0", 30 | "scale" : "1x" 31 | }, 32 | { 33 | "orientation" : "portrait", 34 | "idiom" : "ipad", 35 | "extent" : "full-screen", 36 | "minimum-system-version" : "7.0", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "orientation" : "landscape", 41 | "idiom" : "ipad", 42 | "extent" : "full-screen", 43 | "minimum-system-version" : "7.0", 44 | "scale" : "2x" 45 | } 46 | ], 47 | "info" : { 48 | "version" : 1, 49 | "author" : "xcode" 50 | } 51 | } -------------------------------------------------------------------------------- /Keychain.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | AppID=$1 4 | 5 | #get keychain path 6 | 7 | keychainPath=$(grep -F keychainDumper /Applications/iRE.app/toolPaths.txt | cut -d":" -f2) 8 | Keys=$($keychainPath -k | tr '\n' '!' | sed 's/!/
/g') 9 | Entitlements=$($keychainPath -e | tr '\n' '!' | sed 's//g') 10 | GPasswords=$($keychainPath -g | tr '\n' '!' | sed 's/!/
/g') 11 | IPasswords=$($keychainPath -n | tr '\n' '!' | sed 's/!/
/g') 12 | Identities=$($keychainPath -i | tr '\n' '!' | sed 's/!/
/g') 13 | Certs=$($keychainPath -c | tr '\n' '!' | sed 's/!/
/g') 14 | 15 | echo ' 16 | 17 | iRET - iOS Reverse Engineering Toolkit 18 | 19 | 45 | 46 | 130 | 131 | 132 | 133 | 134 |
135 | 136 | 137 | 138 | 139 | 140 |
Welcome to iRET
The iOS Reverse Engineering Toolkit
141 | 152 | 153 |
154 |

Below are the contents of the iOS device keychain

155 |
156 | Keychain Keys 157 |

Show/Hide Keychain Keys 158 | 167 |

Show/Hide Keychain Entitlements 168 | 177 |

Show/Hide Keychain Generic Passwords 178 | 187 |

Show/Hide Keychain Internet Passwords 188 | 197 |

Show/Hide Keychain Identities 198 | 207 |

Show/Hide Keychain Certificates 208 | 217 | 227 | 228 | 229 | 230 | ' 231 | -------------------------------------------------------------------------------- /Log.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | AppID=$1 4 | Log=$2 5 | 6 | if [ ! -f /private/var/log/syslog ]; 7 | then 8 | SysLog="SysLog File Does Not Exist" 9 | else 10 | SysLog=$(tail -n 100 /private/var/log/syslog | sed 's//g') 11 | 12 | if [ ! -n "$SysLog" ] 13 | then 14 | SysLog="SysLog is empty" 15 | fi 16 | fi 17 | 18 | 19 | #dropDownList="" 20 | 21 | #for i in ${databases} 22 | #do 23 | #dbName=$(basename $i) 24 | #dropDownList+="" 25 | #done 26 | 27 | echo ' 28 | 29 | iRET - iOS Reverse Engineering Toolkit 30 | 31 | 60 | 61 | 145 | 146 | 147 | 148 | 149 |
150 | 151 | 152 | 153 | 154 | 155 |
Welcome to iRET
The iOS Reverse Engineering Toolkit
156 | 167 | 168 | 169 |
170 |

Below are the first 100 lines of the system log.

171 |
172 | System Log 173 |

Show/Hide System Log 174 | 183 | 184 | 185 |

Below are the log and text files that were found for the selected application.


' 186 | 187 | 188 | logs=$(find /var/mobile/Applications/$AppID -name '*.log' -o -name '*.txt' -type f) 189 | 190 | if [ -n "$logs" ] 191 | then 192 | dropDownList="" 193 | 194 | OIFS="$IFS" 195 | IFS=$'\n' 196 | for i in ${logs} 197 | do 198 | logName=$(basename $i) 199 | 200 | if [ "$Log" = "$i" ]; then 201 | dropDownList+="" 202 | else 203 | dropDownList+="" 204 | fi 205 | done 206 | IFS="$OIFS" 207 | 208 | 209 | echo 'To begin, select a log file from the list below:

210 |
211 |
214 |
215 |
' 216 | 217 | if [ -n "$Log" ] 218 | then 219 | nLog=$(echo "$Log" | sed 's/\\//g') 220 | content=$(cat "$nLog" | sed 's//g') 221 | 222 | echo '
223 |
224 |
225 |
'
226 | 		if [ -n "$content" ]
227 | 		then
228 | 			echo "$content"
229 | 		else
230 | 			echo "No Content"
231 | 		fi
232 | 			echo '
233 |
234 |
235 |
' 236 | fi 237 | else 238 | echo "No Log Files Found" 239 | fi 240 | echo '
241 |
242 | 243 | 244 | 245 | ' 246 | -------------------------------------------------------------------------------- /Menu.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | function checkInstall() 4 | { 5 | local path 6 | 7 | case $1 in 8 | otool) 9 | path=$(which otool) 10 | echo "$path" 11 | ;; 12 | sqlite3) 13 | path=$(which sqlite3) 14 | echo "$path" 15 | ;; 16 | file) 17 | path=$(which file) 18 | echo "$path" 19 | ;; 20 | plutil) 21 | path=$(which plutil) 22 | echo "$path" 23 | ;; 24 | theos) 25 | path=$(find / -name theos -type d) 26 | echo "$path" 27 | ;; 28 | dumpdecrypted) 29 | path=$(find / -name dumpdecrypted.dylib -type f) 30 | echo "$path" 31 | ;; 32 | keychainDumper) 33 | path=$(find / -name keychain_dumper -type f) 34 | echo "$path" 35 | ;; 36 | classDumpZ) 37 | path=$(find / -name class-dump-z -type f) 38 | echo "$path" 39 | ;; 40 | *) break 41 | esac 42 | 43 | } 44 | 45 | 46 | #File that stores paths of tools 47 | file="/Applications/iRE.app/toolPaths.txt" 48 | 49 | #check if "toolPaths.txt" file exists 50 | if [ -f "$file" ] 51 | then 52 | #File already exists. Read it and check if any tool paths are missing 53 | 54 | while IFS=$':' read -r -a myArray 55 | do 56 | toolName=${myArray[0]} 57 | toolPath=${myArray[1]} 58 | 59 | if [ ! -n "$toolPath" ] 60 | then 61 | toolArray+=($toolName) 62 | fi 63 | done < "$file" 64 | 65 | 66 | if [ ${#toolArray[@]} -ge "1" ] 67 | then 68 | #echo "Inside tool array" 69 | for i in "${toolArray[@]}" 70 | do 71 | #echo $i 72 | result=$(checkInstall $i) 73 | #echo "Path: $result" 74 | 75 | if [ "$result" != "" ] 76 | then 77 | sed -i "s,"$i:","$i:$result",g" /Applications/iRE.app/toolPaths.txt 78 | #mv temp.txt toolPaths.txt 79 | fi 80 | done 81 | fi 82 | 83 | else 84 | #First time tool has run, check if tools are installed 85 | 86 | #OTOOL 87 | otoolPath=$(checkInstall otool) 88 | strTools="otool:$otoolPath\n" 89 | 90 | #SQLITE 91 | sqlitePath=$(checkInstall sqlite3) 92 | strTools+="sqlite3:$sqlitePath\n" 93 | 94 | #FILE 95 | fileToolPath=$(checkInstall file) 96 | strTools+="file:$fileToolPath\n" 97 | 98 | #PLUTIL 99 | plutilPath=$(checkInstall plutil) 100 | strTools+="plutil:$plutilPath\n" 101 | 102 | #THEOS 103 | theosPath=$(checkInstall theos) 104 | strTools+="theos:$theosPath\n" 105 | 106 | #DUMPDECRYPTED 107 | dumpPath=$(checkInstall dumpdecrypted) 108 | strTools+="dumpdecrypted:$dumpPath\n" 109 | 110 | #KEYCHAIN 111 | keychainPath=$(checkInstall keychainDumper) 112 | strTools+="keychainDumper:$keychainPath\n" 113 | 114 | #CLASS-DUMP-Z 115 | classDumpPath=$(checkInstall classDumpZ) 116 | strTools+="classDumpZ:$classDumpPath" 117 | 118 | echo -e $strTools > /Applications/iRE.app/toolPaths.txt 119 | fi 120 | 121 | #Read if the paths of the tools and show installed or not 122 | 123 | #check if "toolPaths.txt" file exists 124 | if [ -f "$file" ] 125 | then 126 | 127 | while IFS=':' read -r f1 f2 128 | do 129 | case $f1 in 130 | otool) 131 | if [ "$f2" != "" ] 132 | then 133 | otoolInstalled="Installed" 134 | else 135 | otoolInstalled="Not Installed" 136 | fi 137 | ;; 138 | sqlite3) 139 | if [ "$f2" != "" ] 140 | then 141 | sqliteInstalled="Installed" 142 | else 143 | sqliteInstalled="Not Installed" 144 | fi 145 | ;; 146 | file) 147 | if [ "$f2" != "" ] 148 | then 149 | fileInstalled="Installed" 150 | else 151 | fileInstalled="Not Installed" 152 | fi 153 | ;; 154 | plutil) 155 | if [ "$f2" != "" ] 156 | then 157 | plutilInstalled="Installed" 158 | else 159 | plutilInstalled="Not Installed" 160 | fi 161 | ;; 162 | theos) 163 | if [ "$f2" != "" ] 164 | then 165 | theosInstalled="Installed" 166 | else 167 | theosInstalled="Not Installed" 168 | fi 169 | ;; 170 | dumpdecrypted) 171 | if [ "$f2" != "" ] 172 | then 173 | dumpInstalled="Installed" 174 | else 175 | dumpInstalled="Not Installed" 176 | fi 177 | ;; 178 | keychainDumper) 179 | if [ "$f2" != "" ] 180 | then 181 | keychainInstalled="Installed" 182 | else 183 | keychainInstalled="Not Installed" 184 | fi 185 | ;; 186 | classDumpZ) 187 | if [ "$f2" != "" ] 188 | then 189 | classDumpZInstalled="Installed" 190 | else 191 | classDumpZInstalled="Not Installed" 192 | fi 193 | ;; 194 | *) break 195 | esac 196 | 197 | done < "$file" 198 | 199 | else 200 | echo "/Applications/iRE.app/toolPaths.txt File Does Not Exist" 201 | fi 202 | 203 | 204 | guids=$(ls /var/mobile/Applications/*/*.app/Info.plist |sort | cut -d"/" -f5) 205 | dropDownList="" 206 | 207 | for a in ${guids} 208 | do 209 | name=$( ls /var/mobile/Applications/$a/*.app/Info.plist | cut -d"/" -f6 | cut -d. -f1 ) 210 | dropDownList+="" 211 | done 212 | 213 | echo ' 214 | 215 | 216 | iRET - iOS Reverse Engineering Toolkit 217 | 218 | 226 | 227 | 228 | 229 | 277 | 278 |
230 | 231 | 232 | 233 | 234 | 235 | 274 | 275 |
Welcome to iRET
The iOS Reverse Engineering Toolkit
236 | 237 | 238 | 258 | 271 | 272 |
239 | 240 | 241 | 255 | 256 |
242 |
What is in the toolkit?


243 | 244 | - oTool ('${otoolInstalled}')
245 | - dumpDecrypted ('${dumpInstalled}')
246 | - Sqlite ('${sqliteInstalled}')
247 | - Theos ('${theosInstalled}')
248 | - Keychain_dumper ('${keychainInstalled}')
249 | - file ('${fileInstalled}')
250 | - plutil ('${plutilInstalled}')
251 | - class-dump-z ('${classDumpZInstalled}') 252 |

253 | Note: All tools listed above must be installed.
254 |
257 |
259 | 260 | 261 | 268 | 269 |
262 |
To begin, select an app from the list below:

263 |
264 |
267 |
270 |
273 |
276 |
279 | 280 | ' 281 | -------------------------------------------------------------------------------- /Plist.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | AppID=$1 4 | PList=$2 5 | 6 | echo ' 7 | 8 | iRET - iOS Reverse Engineering Toolkit 9 | 10 | 39 | 40 | 125 | 126 | 127 | 128 | 129 |
130 | 131 | 132 | 133 | 134 | 135 |
Welcome to iRET
The iOS Reverse Engineering Toolkit
136 | 147 | 148 | 149 |
150 |
151 | 152 | 153 |

Below are the plist files that were found for the selected application.


' 154 | 155 | 156 | PLists=$(find /var/mobile/Applications/$AppID -name '*.plist' -type f) 157 | 158 | if [ -n "$PLists" ] 159 | then 160 | dropDownList="" 161 | 162 | OIFS="$IFS" 163 | IFS=$'\n' 164 | for i in ${PLists} 165 | do 166 | PListName=$(basename $i) 167 | 168 | if [ "$PList" = "$i" ]; then 169 | dropDownList+="" 170 | else 171 | dropDownList+="" 172 | fi 173 | done 174 | IFS="$OIFS" 175 | 176 | echo 'To begin, select a plist file from the list below:

177 |
178 |
181 |
182 |
' 183 | 184 | if [ -n "$PList" ] 185 | then 186 | nPList=$(echo "$PList" | sed 's/\\//g') 187 | convert=$(plutil -convert xml1 "$nPList") 188 | content=$(cat "$nPList" | sed 's//g') 189 | 190 | echo '
191 |
192 |
193 |
'
194 | 
195 | 		if [ "$content" != "" ]
196 | 		then
197 | 			echo $content
198 | 		else
199 | 			echo "No Content"
200 | 		fi
201 | 			echo '
202 |
203 |
204 |
' 205 | fi 206 | else 207 | echo "No Log Files Found" 208 | fi 209 | echo '
210 |
211 | 212 | 213 | 214 | ' 215 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | iRET 2 | ==== 3 | The iOS Reverse Engineering Toolkit is a toolkit designed to automate many of the common tasks associated with iOS penetration testing. It automates a many common tasks including: 4 | 5 | - binary analysis using otool 6 | - keychain analysis using keychain_dumper 7 | - reading database content using sqlite 8 | - reading log and plist files 9 | - binary decryption using dumpdecrypted 10 | - dumping binary headers using class_dump_z 11 | - creating, editing, installing theos tweaks 12 | 13 | Installation: 14 | You can download the files and build the debian package yourself or you can simply install the iRET.deb package onto any jailbroken device using dpkg -i on the command line or by using iFile, which is available from Cydia. After it is installed, respring the device and you should see a new "iRET" icon on the device. 15 | 16 | Usage: 17 | Must be connected to a wireless network. Launch the application, click the "Start" button. It will then show the ip address and port number you should navigate to on your computer (computer must be connected to same wireless network as device). On first run, it will take a bit of time for the iRET tool to identify all of the required tools. 18 | 19 | 20 | Dependencies: 21 | The following apps are required to be installed on the device (in addition to the tools required on the main page) 22 | - Python (2.5.1 or 2.7) (Need to be Cydia ‘Developer’) 23 | - coreutils 24 | - Erica Utilities 25 | - file 26 | - adv-cmds 27 | - Bourne-Again Shell 28 | - iOS Toolchain (coolstar version) 29 | - Darwin CC Tools (coolstar version) 30 | - An iOS SDK (presumably iOS 6.1 or 7.x) installed to $THEOS/sdks 31 | 32 | 33 | Known Issues: 34 | - Issue of keeping a selected file in the dropdown, when the name contains a space in it. 35 | 36 | 37 | Troubleshooting: 38 | To troubleshoot any issues. You can manually start the listener. First, ssh into the device, navigate to the /Applications/iRE.app directory and execute the "python iRE_Server.py" command. 39 | 40 | 41 | Credits: 42 | 43 | Special thanks to the following people 44 | 45 | - Bucky Spires (@gigabuck) 46 | - Richard Zuleg 47 | - Dan DeCloss (@wh33lhouse) 48 | - Dustin Howett (theos @DHowett) 49 | - StefanEsser (dumpdecrypted @i0n1c) 50 | - Patrick Toomey (keychain_dumper @patricktoomey) 51 | 52 | All the members on irc.saurik.com #theos channel for their assistance. 53 | 54 | For questions feel free to contact me on Twitter at @S3Jensen or at jensensteve1207@gmail.com. 55 | 56 | Screenshots: 57 | 58 | Landing Page: 59 | 60 | ![ScreenShot](https://cloud.githubusercontent.com/assets/1737324/3407661/cb2a3288-fdb2-11e3-8279-ea50fa634ac8.png) 61 | 62 | Functionality Tabs: 63 | 64 | ![ScreenShot](https://cloud.githubusercontent.com/assets/1737324/3407665/e85dd670-fdb2-11e3-8359-4bb1f120d577.png) 65 | -------------------------------------------------------------------------------- /Screenshot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | AppID=$1 4 | 5 | echo ' 6 | 7 | iRET - iOS Reverse Engineering Toolkit 8 | 9 | 38 | 39 | 125 | 126 | 127 | 128 | 129 |
130 | 131 | 132 | 133 | 134 | 135 |
Welcome to iRET
The iOS Reverse Engineering Toolkit
136 | 147 | 148 | 149 |
150 |

Below is the cached application screenshot.

151 | 152 |
153 |
' 154 | 155 | image=$(find /var/mobile/Applications/"$AppID"/Library/Caches -name '*.png' -type f) 156 | display=$(base64 "$image") 157 | 158 | if [ -n "$image" ]; then 159 | echo "" 160 | else 161 | echo "No Image Found" 162 | fi 163 | 164 | echo '
165 |
166 | 167 | ' 168 | -------------------------------------------------------------------------------- /Theos.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | AppID=$1 4 | Action=$2 5 | 6 | if [ "$Action" == "Create" ]; then 7 | #create the theos tweak 8 | projectName=$3 9 | packageName=$4 10 | author=$5 11 | bundleID=$6 12 | lcprojName=${projectName,,} 13 | create="/Applications/iRE.app/createTweak.sh "5" "$projectName" "$packageName" "$author" "$bundleID"" 14 | eval $create 15 | 16 | if [ ! -d "/Applications/iRE.app/tweaks" ]; then 17 | eval mkdir /Applications/iRE.app/tweaks 18 | fi 19 | 20 | if [ ! -d "/Applications/iRE.app/tweaks/$AppID" ]; then 21 | eval mkdir /Applications/iRE.app/tweaks/$AppID 22 | fi 23 | 24 | projName=$3 25 | pName=${projName,,} 26 | 27 | if [ -d "/$pName" ]; then 28 | moveIt="mv -f /$pName /Applications/iRE.app/tweaks/$AppID/$pName" 29 | elif [ -d "/Applications/iRE.app/$pName" ]; then 30 | moveIt="mv -f /Applications/iRE.app/$pName /Applications/iRE.app/tweaks/$AppID/$pName" 31 | fi 32 | 33 | eval $moveIt 34 | fi 35 | 36 | 37 | echo ' 38 | 39 | iRET - iOS Reverse Engineering Toolkit 40 | 41 | 70 | 71 | 156 | 157 | 158 | 159 | 160 |
161 | 162 | 163 | 164 | 165 | 166 |
Welcome to iRET
The iOS Reverse Engineering Toolkit
167 | 178 | 179 | 180 |
181 |
' 182 | if [ ! -d "/Applications/iRE.app/tweaks/$AppID" ]; then 183 | if [ "$Action" == "New" ]; then 184 | 185 | #Get BundleID for selected Application 186 | InfoFile=$(find /var/mobile/Applications/"$AppID"/*.app -maxdepth 1 -name Info.plist -type f) 187 | BundleID=$(plutil -key CFBundleIdentifier "$InfoFile") 188 | 189 | echo ' 190 |

Below is a form you can use to create a new theos tweak for this application.


191 | 192 |
193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 212 | 213 | 214 | 215 | 216 | 217 |
Project Name:
Package Name:
Author:
Bundle ID: 210 | 211 |
218 |
' 219 | fi 220 | else 221 | 222 | echo 'View/Edit an existing theos file below:

223 |
224 |
' 233 | 234 | if [ "$Action" == "Edit" -o "$Action" == "Build" ]; then 235 | fileName=$3 236 | fileContent=$(cat $fileName) 237 | 238 | echo '
239 | 240 | 241 |
244 | 245 |
246 |
247 | 248 | 249 | 250 |
251 |
' 252 | if [ "$Action" == "Build" ]; then 253 | projName=$(ls /Applications/iRE.app/tweaks/"$AppID"/) 254 | cmd=$(make -C /Applications/iRE.app/tweaks/"$AppID"/"$projName" > /Applications/iRE.app/tweaks/"$AppID"/"$projName"/buildResult.txt) 255 | eval "$cmd" 256 | 257 | #read the buildResult.txt file 258 | result=$(cat /Applications/iRE.app/tweaks/"$AppID"/"$projName"/buildResult.txt | tr '\n' '!' | sed 's/!/
/g') 259 | buildDir="/Applications/iRE.app/tweaks/"$AppID"/"$projName"/obj/" 260 | 261 | if [ -d "$buildDir" ]; then 262 | #copy plist and dylib files 263 | pFile=$(find /Applications/iRE.app/tweaks/"$AppID"/"$projName" -name '*.plist' -type f) 264 | dylibFile=$(find /Applications/iRE.app/tweaks/"$AppID"/"$projName"/obj -name '*.dylib' -type f) 265 | eval cp -f $pFile /Library/MobileSubstrate/DynamicLibraries 266 | eval cp -f $dylibFile /Library/MobileSubstrate/DynamicLibraries 267 | echo "Tweak has been built and installed in /Library/MobileSubstrate/DynamicLibraries." 268 | else 269 | echo "Tweak did not build, check results below." 270 | fi 271 | 272 | echo '
273 |
274 |
' 275 | echo $result 276 | echo '
277 |
278 |
' 279 | fi 280 | 281 | echo '
' 282 | 283 | fi 284 | fi 285 | echo ' 286 | ' 287 | -------------------------------------------------------------------------------- /ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // iRE 4 | // 5 | // Created by veracode on 11/8/13. 6 | // Copyright (c) 2013 veracode. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | { 13 | UILabel*lblHeader; 14 | UILabel*lblMessage; 15 | UILabel*lblIPText; 16 | UILabel*lblIPAddress; 17 | UILabel*lbliRET; 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // iRE 4 | // 5 | // Created by veracode on 11/8/13. 6 | // Copyright (c) 2013 veracode. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #include 11 | #include 12 | 13 | 14 | 15 | @interface ViewController () 16 | 17 | 18 | 19 | @end 20 | 21 | @implementation ViewController 22 | 23 | UIButton*btnStart; 24 | int intButtonState; 25 | 26 | 27 | - (void)viewDidLoad 28 | { 29 | [super viewDidLoad]; 30 | // Do any additional setup after loading the view, typically from a nib. 31 | 32 | float rd = 3.0/255.0; 33 | float gr = 119.0/255.0; 34 | float bl = 204.0/255.0; 35 | 36 | self.view.backgroundColor = [UIColor colorWithRed:rd green:gr blue:bl alpha:1.0]; 37 | 38 | //ADD THE HEADER LABEL 39 | lblHeader = [[UILabel alloc] 40 | initWithFrame:CGRectMake(0,10,320,100)]; 41 | lblHeader.text = @"Welcome to iRET"; 42 | lblHeader.backgroundColor = [UIColor clearColor]; 43 | lblHeader.textColor = [UIColor whiteColor]; 44 | lblHeader.font = [UIFont fontWithName:@"Arial-BoldMT" size:25.0]; 45 | lblHeader.textAlignment = NSTextAlignmentCenter; 46 | 47 | //ADD THE HEADER LABEL 48 | lbliRET = [[UILabel alloc] 49 | initWithFrame:CGRectMake(0,60,320,100)]; 50 | lbliRET.text = @"The iOS Reverse Engineering Toolkit"; 51 | lbliRET.backgroundColor = [UIColor clearColor]; 52 | lbliRET.textColor = [UIColor whiteColor]; 53 | lbliRET.font = [UIFont fontWithName:@"Arial-BoldMT" size:15.0]; 54 | lbliRET.textAlignment = NSTextAlignmentCenter; 55 | 56 | //ADD THE MESSAGE LABEL 57 | lblMessage = [[UILabel alloc] 58 | initWithFrame:CGRectMake(0,100,320,100)]; 59 | lblMessage.numberOfLines = 0; 60 | lblMessage.lineBreakMode = true; 61 | lblMessage.text = @"For on device analysis and reversing."; 62 | lblMessage.backgroundColor = [UIColor clearColor]; 63 | lblMessage.textColor = [UIColor whiteColor]; 64 | lblMessage.font = [UIFont fontWithName:@"Arial-BoldMT" size:10.0]; 65 | lblMessage.textAlignment = NSTextAlignmentCenter; 66 | 67 | //ADD THE BUTTON 68 | UIButton*btnStart = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 69 | btnStart.frame = CGRectMake(105,175,100,35); 70 | btnStart.backgroundColor = [UIColor whiteColor]; 71 | [btnStart.titleLabel setTextColor:[UIColor blackColor]]; 72 | [btnStart.titleLabel setFont:[UIFont boldSystemFontOfSize:20]]; 73 | [btnStart setTitle:@"Start" forState:UIControlStateNormal]; 74 | [btnStart addTarget:self action:@selector(btnStartPressed:) forControlEvents:UIControlEventTouchUpInside]; 75 | 76 | //ADD THE IP Text LABEL 77 | lblIPText = [[UILabel alloc] 78 | initWithFrame:CGRectMake(0,225,320,100)]; 79 | lblIPText.backgroundColor = [UIColor clearColor]; 80 | lblIPText.textColor = [UIColor whiteColor]; 81 | lblIPText.font = [UIFont fontWithName:@"Arial-BoldMT" size:20.0]; 82 | lblIPText.textAlignment = NSTextAlignmentCenter; 83 | 84 | //ADD THE IP Address LABEL 85 | lblIPAddress = [[UILabel alloc] 86 | initWithFrame:CGRectMake(0,275,320,200)]; 87 | lblIPAddress.backgroundColor = [UIColor clearColor]; 88 | lblIPAddress.textColor = [UIColor blackColor]; 89 | lblIPAddress.font = [UIFont fontWithName:@"Arial-BoldMT" size:15.0]; 90 | lblIPAddress.textAlignment = NSTextAlignmentCenter; 91 | 92 | 93 | 94 | [self.view addSubview:lblHeader]; 95 | [self.view addSubview:lblMessage]; 96 | [self.view addSubview:btnStart]; 97 | [self.view addSubview:lblIPText]; 98 | [self.view addSubview:lblIPAddress]; 99 | [self.view addSubview: lbliRET]; 100 | 101 | 102 | 103 | } 104 | 105 | -(void) btnStartPressed:(UIButton *) sender 106 | { 107 | 108 | //START THE LISTENER 109 | NSString *strIP; 110 | 111 | if (intButtonState == 0) 112 | { 113 | intButtonState = 1; 114 | 115 | @try 116 | { 117 | //change the button text to show 'Stop' 118 | [sender setTitle: @"Stop" forState: UIControlStateNormal]; 119 | 120 | int loadResult = system("launchctl load /System/Library/LaunchDaemons/com.jensen.iRE.Startup.plist"); 121 | NSLog(@" Load Startup Result: %i", loadResult); 122 | 123 | if(loadResult == 0) 124 | strIP = [self getIPAddress]; 125 | strIP = [strIP stringByAppendingString:@":5555"]; 126 | lblIPText.text = @"Navigate your browser to:"; 127 | lblIPAddress.text = strIP; 128 | 129 | } 130 | @catch (NSException *exception) 131 | { 132 | NSLog( @"NSException caught "); 133 | NSLog( @"Name: %@", exception.name); 134 | NSLog( @"Reason: %@", exception.reason); 135 | } 136 | @finally 137 | { 138 | NSLog( @"In finally block."); 139 | } 140 | 141 | 142 | } 143 | else if (intButtonState == 1) 144 | { 145 | //STOP THE LISTENER 146 | 147 | intButtonState = 0; 148 | 149 | @try { 150 | //change the button text to show 'Start' 151 | [sender setTitle: @"Start" forState: UIControlStateNormal]; 152 | int unloadStart = system("launchctl unload /System/Library/LaunchDaemons/com.jensen.iRE.Startup.plist"); 153 | NSLog(@"Unload Start Result: %i", unloadStart); 154 | 155 | lblIPText.text = @""; 156 | lblIPAddress.text = @""; 157 | 158 | } 159 | @catch (NSException *exception) { 160 | NSLog( @"NSException caught "); 161 | NSLog( @"Name: %@", exception.name); 162 | NSLog( @"Reason: %@", exception.reason); 163 | } 164 | @finally { 165 | NSLog( @"In finally block."); 166 | } 167 | 168 | } 169 | 170 | } 171 | 172 | 173 | - (void)didReceiveMemoryWarning 174 | { 175 | [super didReceiveMemoryWarning]; 176 | // Dispose of any resources that can be recreated. 177 | } 178 | 179 | -(BOOL)shouldAutorotate 180 | { 181 | return NO; 182 | } 183 | 184 | -(NSUInteger)supportedInterfaceOrientations 185 | { 186 | return UIInterfaceOrientationMaskPortrait; 187 | } 188 | 189 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 190 | { 191 | return (interfaceOrientation == UIInterfaceOrientationPortrait); 192 | } 193 | 194 | - (NSString *)getIPAddress { 195 | 196 | NSString *address = @"error"; 197 | struct ifaddrs *interfaces = NULL; 198 | struct ifaddrs *temp_addr = NULL; 199 | int success = 0; 200 | // retrieve the current interfaces - returns 0 on success 201 | success = getifaddrs(&interfaces); 202 | if (success == 0) { 203 | // Loop through linked list of interfaces 204 | temp_addr = interfaces; 205 | while(temp_addr != NULL) { 206 | if(temp_addr->ifa_addr->sa_family == AF_INET) { 207 | // Check if interface is en0 which is the wifi connection on the iPhone 208 | if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) { 209 | // Get NSString from C String 210 | address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)]; 211 | 212 | } 213 | 214 | } 215 | 216 | temp_addr = temp_addr->ifa_next; 217 | } 218 | } 219 | // Free memory 220 | freeifaddrs(interfaces); 221 | return address; 222 | 223 | } 224 | 225 | 226 | @end 227 | -------------------------------------------------------------------------------- /com.jensen.iRE.Startup.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/S3Jensen/iRET/8bfe376e6ccfd4219c9d405dd8f6c0226e2ef26c/com.jensen.iRE.Startup.plist -------------------------------------------------------------------------------- /createTweak.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | tweak=$1 4 | packageName=$2 5 | projectName=$3 6 | author=$4 7 | bundleID=$5 8 | 9 | /var/theos/bin/nic.pl < 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.jensen.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | LSRequiresIPhoneOS 24 | 25 | UIBackgroundModes 26 | 27 | fetch 28 | 29 | UIMainStoryboardFile 30 | Main_iPhone 31 | UIMainStoryboardFile~ipad 32 | Main_iPad 33 | UIRequiredDeviceCapabilities 34 | 35 | armv7 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /iRE-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /iRET.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/S3Jensen/iRET/8bfe376e6ccfd4219c9d405dd8f6c0226e2ef26c/iRET.deb -------------------------------------------------------------------------------- /iRE_Server.py: -------------------------------------------------------------------------------- 1 | #iRET web server project 2 | #Authors: Richard Zuleg, Steve Jensen 3 | #Version 0.9_1 4 | 5 | import string,cgi,time,os,urllib 6 | from os import curdir, sep 7 | from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer 8 | 9 | applicationPath = "/Applications/iRE.app/" 10 | logFile = applicationPath + "iRE_Server.log" 11 | 12 | class SimpleHandler(BaseHTTPRequestHandler): 13 | 14 | def Menu(self): 15 | try: 16 | import subprocess as sub 17 | 18 | currentPath = applicationPath + "Menu.sh" 19 | p = sub.Popen(["sh", currentPath],stdout=sub.PIPE,stderr=sub.PIPE) 20 | output, errors = p.communicate() 21 | 22 | print errors 23 | f=open(logFile, 'w') 24 | #f.write('Menu.sh was called #1') 25 | f.write(errors) 26 | #f.write(output) 27 | f.close() 28 | 29 | 30 | self.send_response(200) 31 | self.send_header('Content-type', 'text/html') 32 | self.end_headers() 33 | self.wfile.write(output) 34 | return 35 | except: 36 | return 37 | 38 | 39 | def do_GET(self): 40 | try: 41 | print self.path 42 | if ( self.path == "/" ): 43 | import subprocess as sub 44 | currentPath = applicationPath + "Menu.sh" 45 | p = sub.Popen(["sh", currentPath],stdout=sub.PIPE,stderr=sub.PIPE) 46 | output, errors = p.communicate() 47 | 48 | print errors 49 | f=open(logFile, 'w') 50 | #self.wfile.write('Menu.sh was called #2') 51 | f.write(errors) 52 | #f.write(output) 53 | f.close() 54 | 55 | 56 | self.send_response(200) 57 | self.send_header('Content-type', 'text/html') 58 | self.end_headers() 59 | self.wfile.write(output) 60 | return 61 | 62 | #BINARY TAB 63 | 64 | if ( self.path.startswith("/Binary") ): 65 | import subprocess as sub 66 | appTo=urllib.unquote(self.path) 67 | print appTo 68 | appTo=appTo.replace("+",'\\ ') 69 | app=appTo.split("AppID=")[1].split("&EOFname=")[0] 70 | if ( app.startswith("/") ): 71 | app="--direct "+app.rpartition("/")[0]+"/" 72 | command_line=applicationPath+'Binary.sh'+' '+'\''+app+'\'' 73 | command_line='\''+'sh'+'\' '+command_line 74 | import shlex 75 | args = shlex.split(command_line) 76 | #print args 77 | p = sub.Popen(args,stdout=sub.PIPE,stderr=sub.PIPE) 78 | output, errors = p.communicate() 79 | 80 | self.send_response(200) 81 | self.send_header('Content-type', 'text/html') 82 | self.end_headers() 83 | self.wfile.write(output) 84 | 85 | if (errors): 86 | print errors 87 | f=open(logFile, 'w') 88 | f.write(errors) 89 | f.close() 90 | return 91 | 92 | #BINARY TAB 93 | 94 | if ( self.path.startswith("/Screenshot") ): 95 | import subprocess as sub 96 | appTo=urllib.unquote(self.path) 97 | print appTo 98 | appTo=appTo.replace("+",'\\ ') 99 | app=appTo.split("AppID=")[1].split("&EOFname=")[0] 100 | if ( app.startswith("/") ): 101 | app="--direct "+app.rpartition("/")[0]+"/" 102 | command_line=applicationPath+'Screenshot.sh'+' '+'\''+app+'\'' 103 | command_line='\''+'sh'+'\' '+command_line 104 | import shlex 105 | args = shlex.split(command_line) 106 | #print args 107 | p = sub.Popen(args,stdout=sub.PIPE,stderr=sub.PIPE) 108 | output, errors = p.communicate() 109 | 110 | self.send_response(200) 111 | self.send_header('Content-type', 'text/html') 112 | self.end_headers() 113 | self.wfile.write(output) 114 | 115 | if (errors): 116 | print errors 117 | f=open(logFile, 'w') 118 | f.write(errors) 119 | f.close() 120 | return 121 | 122 | #KEYCHAIN TAB 123 | 124 | if ( self.path.startswith("/Keychain") ): 125 | import subprocess as sub 126 | appTo=urllib.unquote(self.path) 127 | #print appTo 128 | appTo=appTo.replace("+",'\\ ') 129 | app=appTo.split("AppID=")[1].split("&EOFname=")[0] 130 | #print app 131 | if ( app.startswith("/") ): 132 | app="--direct "+app.rpartition("/")[0]+"/" 133 | command_line=applicationPath+'Keychain.sh'+' '+'\''+app+'\'' 134 | command_line='\''+'sh'+'\' '+command_line 135 | import shlex 136 | args = shlex.split(command_line) 137 | #print args 138 | p = sub.Popen(args,stdout=sub.PIPE,stderr=sub.PIPE) 139 | output, errors = p.communicate() 140 | 141 | self.send_response(200) 142 | self.send_header('Content-type', 'text/html') 143 | self.end_headers() 144 | self.wfile.write(output) 145 | 146 | if (errors): 147 | print errors 148 | f=open(logFile, 'w') 149 | f.write(errors) 150 | f.close() 151 | return 152 | 153 | #LOG TAB 154 | 155 | if ( self.path.startswith("/Log") ): 156 | import subprocess as sub 157 | appTo=urllib.unquote(self.path) 158 | #print appTo 159 | appTo=appTo.replace("+",'\\ ') 160 | app=appTo.split("AppID=")[1].split("&EOFname=")[0] 161 | #print app 162 | if ( app.startswith("/") ): 163 | app="--direct "+app.rpartition("/")[0]+"/" 164 | command_line=applicationPath+'Log.sh'+' '+'\''+app+'\'' 165 | command_line='\''+'sh'+'\' '+command_line 166 | import shlex 167 | args = shlex.split(command_line) 168 | #print args 169 | p = sub.Popen(args,stdout=sub.PIPE,stderr=sub.PIPE) 170 | output, errors = p.communicate() 171 | 172 | self.send_response(200) 173 | self.send_header('Content-type', 'text/html') 174 | self.end_headers() 175 | self.wfile.write(output) 176 | 177 | if (errors): 178 | print errors 179 | f=open(logFile, 'w') 180 | f.write(errors) 181 | f.close() 182 | return 183 | 184 | #VIEW LOG 185 | 186 | if ( self.path.startswith("/ViewLog") ): 187 | import subprocess as sub 188 | appTo=urllib.unquote(self.path) 189 | print appTo 190 | appTo=appTo.replace("+",'\\ ') 191 | print "about to split" 192 | db=appTo.split("&Log=")[1].split("&EOFname=")[0] 193 | print db 194 | print appTo 195 | print "and again" 196 | app=appTo.split("AppID=")[1].split("&")[0] 197 | print app 198 | if ( app.startswith("/") ): 199 | app="--direct "+app.rpartition("/")[0]+"/" 200 | command_line=applicationPath+'Log.sh'+' '+'\''+app+'\''+' '+'\''+db+'\'' 201 | command_line='\''+'sh'+'\' '+command_line 202 | print command_line 203 | import shlex 204 | args = shlex.split(command_line) 205 | print args 206 | p = sub.Popen(args,stdout=sub.PIPE,stderr=sub.PIPE) 207 | output, errors = p.communicate() 208 | 209 | self.send_response(200) 210 | self.send_header('Content-type', 'text/html') 211 | self.end_headers() 212 | self.wfile.write(output) 213 | 214 | if (errors): 215 | print errors 216 | f=open(logFile, 'w') 217 | f.write(errors) 218 | f.close() 219 | return 220 | 221 | #DATABASE TAB 222 | 223 | if ( self.path.startswith("/Database") ): 224 | import subprocess as sub 225 | appTo=urllib.unquote(self.path) 226 | #print appTo 227 | appTo=appTo.replace("+",'\\ ') 228 | app=appTo.split("AppID=")[1].split("&EOFname=")[0] 229 | #print app 230 | if ( app.startswith("/") ): 231 | app="--direct "+app.rpartition("/")[0]+"/" 232 | command_line=applicationPath+'Database.sh'+' '+'\''+app+'\'' 233 | command_line='\''+'sh'+'\' '+command_line 234 | import shlex 235 | args = shlex.split(command_line) 236 | print args 237 | p = sub.Popen(args,stdout=sub.PIPE,stderr=sub.PIPE) 238 | output, errors = p.communicate() 239 | 240 | self.send_response(200) 241 | self.send_header('Content-type', 'text/html') 242 | self.end_headers() 243 | self.wfile.write(output) 244 | 245 | if (errors): 246 | print errors 247 | f=open(logFile, 'w') 248 | f.write(errors) 249 | f.close() 250 | return 251 | 252 | #SHOW DATABASE 253 | if ( self.path.startswith("/ShowTables") ): 254 | import subprocess as sub 255 | appTo=urllib.unquote(self.path) 256 | print appTo 257 | appTo=appTo.replace("+",'\\ ') 258 | print "about to split" 259 | db=appTo.split("&DB=")[1].split("&EOFname=")[0] 260 | print db 261 | print appTo 262 | print "and again" 263 | app=appTo.split("AppID=")[1].split("&")[0] 264 | print app 265 | if ( app.startswith("/") ): 266 | app="--direct "+app.rpartition("/")[0]+"/" 267 | command_line=applicationPath+'Database.sh'+' '+'\''+app+'\''+' '+'\''+db+'\'' 268 | command_line='\''+'sh'+'\' '+command_line 269 | print command_line 270 | import shlex 271 | args = shlex.split(command_line) 272 | print args 273 | p = sub.Popen(args,stdout=sub.PIPE,stderr=sub.PIPE) 274 | output, errors = p.communicate() 275 | 276 | self.send_response(200) 277 | self.send_header('Content-type', 'text/html') 278 | self.end_headers() 279 | self.wfile.write(output) 280 | 281 | if (errors): 282 | print errors 283 | f=open(logFile, 'w') 284 | f.write(errors) 285 | f.close() 286 | return 287 | 288 | #PLIST TAB 289 | 290 | if ( self.path.startswith("/PList") ): 291 | import subprocess as sub 292 | appTo=urllib.unquote(self.path) 293 | #print appTo 294 | appTo=appTo.replace("+",'\\ ') 295 | app=appTo.split("AppID=")[1].split("&EOFname=")[0] 296 | #print app 297 | if ( app.startswith("/") ): 298 | app="--direct "+app.rpartition("/")[0]+"/" 299 | command_line=applicationPath+'PList.sh'+' '+'\''+app+'\'' 300 | command_line='\''+'sh'+'\' '+command_line 301 | import shlex 302 | args = shlex.split(command_line) 303 | print args 304 | p = sub.Popen(args,stdout=sub.PIPE,stderr=sub.PIPE) 305 | output, errors = p.communicate() 306 | 307 | self.send_response(200) 308 | self.send_header('Content-type', 'text/html') 309 | self.end_headers() 310 | self.wfile.write(output) 311 | 312 | if (errors): 313 | print errors 314 | f=open(logFile, 'w') 315 | f.write(errors) 316 | f.close() 317 | return 318 | 319 | #SHOW PLIST FILE 320 | if ( self.path.startswith("/PFile") ): 321 | import subprocess as sub 322 | appTo=urllib.unquote(self.path) 323 | print appTo 324 | appTo=appTo.replace("+",'\\ ') 325 | print "about to split" 326 | db=appTo.split("&PFile=")[1].split("&EOFname=")[0] 327 | print db 328 | print appTo 329 | print "and again" 330 | app=appTo.split("AppID=")[1].split("&")[0] 331 | print app 332 | if ( app.startswith("/") ): 333 | app="--direct "+app.rpartition("/")[0]+"/" 334 | command_line=applicationPath+'PList.sh'+' '+'\''+app+'\''+' '+'\''+db+'\'' 335 | command_line='\''+'sh'+'\' '+command_line 336 | print command_line 337 | import shlex 338 | args = shlex.split(command_line) 339 | print args 340 | p = sub.Popen(args,stdout=sub.PIPE,stderr=sub.PIPE) 341 | output, errors = p.communicate() 342 | 343 | self.send_response(200) 344 | self.send_header('Content-type', 'text/html') 345 | self.end_headers() 346 | self.wfile.write(output) 347 | 348 | if (errors): 349 | print errors 350 | f=open(logFile, 'w') 351 | f.write(errors) 352 | f.close() 353 | return 354 | 355 | #HEADERS TAB 356 | 357 | if ( self.path.startswith("/Headers") ): 358 | import subprocess as sub 359 | appTo=urllib.unquote(self.path) 360 | #print appTo 361 | appTo=appTo.replace("+",'\\ ') 362 | app=appTo.split("AppID=")[1].split("&EOFname=")[0] 363 | #print app 364 | if ( app.startswith("/") ): 365 | app="--direct "+app.rpartition("/")[0]+"/" 366 | command_line=applicationPath+'Headers.sh'+' '+'\''+app+'\'' 367 | command_line='\''+'sh'+'\' '+command_line 368 | import shlex 369 | args = shlex.split(command_line) 370 | print args 371 | p = sub.Popen(args,stdout=sub.PIPE,stderr=sub.PIPE) 372 | output, errors = p.communicate() 373 | 374 | self.send_response(200) 375 | self.send_header('Content-type', 'text/html') 376 | self.end_headers() 377 | self.wfile.write(output) 378 | 379 | if (errors): 380 | print errors 381 | f=open(logFile, 'w') 382 | f.write(errors) 383 | f.close() 384 | return 385 | 386 | #SEARCH HEADERS 387 | if ( self.path.startswith("/SearchHeaders") ): 388 | import subprocess as sub 389 | appTo=urllib.unquote(self.path) 390 | print appTo 391 | appTo=appTo.replace("+",'\\ ') 392 | print "about to split" 393 | db=appTo.split("&SearchText=")[1].split("&EOFname=")[0] 394 | print db 395 | print appTo 396 | print "and again" 397 | app=appTo.split("AppID=")[1].split("&")[0] 398 | print app 399 | if ( app.startswith("/") ): 400 | app="--direct "+app.rpartition("/")[0]+"/" 401 | command_line=applicationPath+'PList.sh'+' '+'\''+app+'\''+' '+'\''+db+'\'' 402 | command_line='\''+'sh'+'\' '+command_line 403 | print command_line 404 | import shlex 405 | args = shlex.split(command_line) 406 | print args 407 | p = sub.Popen(args,stdout=sub.PIPE,stderr=sub.PIPE) 408 | output, errors = p.communicate() 409 | 410 | self.send_response(200) 411 | self.send_header('Content-type', 'text/html') 412 | self.end_headers() 413 | self.wfile.write(output) 414 | 415 | if (errors): 416 | print errors 417 | f=open(logFile, 'w') 418 | f.write(errors) 419 | f.close() 420 | return 421 | 422 | #SHOW HEADER CONTENT 423 | if ( self.path.startswith("/ShowHeader") ): 424 | import subprocess as sub 425 | appTo=urllib.unquote(self.path) 426 | print appTo 427 | appTo=appTo.replace("+",'\\ ') 428 | print "about to split" 429 | db=appTo.split("&HeaderName=")[1].split("&EOFname=")[0] 430 | print db 431 | print appTo 432 | print "and again" 433 | app=appTo.split("AppID=")[1].split("&")[0] 434 | print app 435 | if ( app.startswith("/") ): 436 | app="--direct "+app.rpartition("/")[0]+"/" 437 | command_line=applicationPath+'Headers.sh'+' '+'\''+app+'\''+' '+'\''+db+'\'' 438 | command_line='\''+'sh'+'\' '+command_line 439 | print command_line 440 | import shlex 441 | args = shlex.split(command_line) 442 | print args 443 | p = sub.Popen(args,stdout=sub.PIPE,stderr=sub.PIPE) 444 | output, errors = p.communicate() 445 | 446 | self.send_response(200) 447 | self.send_header('Content-type', 'text/html') 448 | self.end_headers() 449 | self.wfile.write(output) 450 | 451 | if (errors): 452 | print errors 453 | f=open(logFile, 'w') 454 | f.write(errors) 455 | f.close() 456 | return 457 | 458 | 459 | #THEOS TAB 460 | 461 | if ( self.path.startswith("/Theos") ): 462 | import subprocess as sub 463 | appTo=urllib.unquote(self.path) 464 | #print appTo 465 | appTo=appTo.replace("+",'\\ ') 466 | app=appTo.split("AppID=")[1].split("&EOFname=")[0] 467 | #print app 468 | if ( app.startswith("/") ): 469 | app="--direct "+app.rpartition("/")[0]+"/" 470 | command_line=applicationPath+'Theos.sh'+' '+'\''+app+'\''+' \"New\"' 471 | command_line='\''+'sh'+'\' '+command_line 472 | import shlex 473 | args = shlex.split(command_line) 474 | print args 475 | p = sub.Popen(args,stdout=sub.PIPE,stderr=sub.PIPE) 476 | output, errors = p.communicate() 477 | 478 | self.send_response(200) 479 | self.send_header('Content-type', 'text/html') 480 | self.end_headers() 481 | self.wfile.write(output) 482 | 483 | if (errors): 484 | print errors 485 | f=open(logFile, 'w') 486 | f.write(errors) 487 | f.close() 488 | return 489 | 490 | 491 | #THEOS TWEAK - CREATE 492 | if ( self.path.startswith("/CreateTweak") ): 493 | import subprocess as sub 494 | appTo=urllib.unquote(self.path) 495 | #print appTo 496 | appTo=appTo.replace("+",'\\ ') 497 | bundle=appTo.split("&BundleID=")[1].split("&EOFname=")[0] 498 | auth=appTo.split("&Author=")[1].split("&")[0] 499 | package=appTo.split("&PackageName=")[1].split("&")[0] 500 | project=appTo.split("&ProjectName=")[1].split("&")[0] 501 | app=appTo.split("AppID=")[1].split("&")[0] 502 | if ( app.startswith("/") ): 503 | app="--direct "+app.rpartition("/")[0]+"/" 504 | command_line=applicationPath+'Theos.sh'+' '+'\''+app+'\''+' \"Create\"'+' '+'\''+project+'\''+' '+'\''+package+'\''+' '+'\''+auth+'\''+' '+'\''+bundle+'\'' 505 | command_line='\''+'sh'+'\' '+command_line 506 | #print command_line 507 | import shlex 508 | args = shlex.split(command_line) 509 | #print args 510 | p = sub.Popen(args,stdout=sub.PIPE,stderr=sub.PIPE) 511 | output, errors = p.communicate() 512 | self.send_response(200) 513 | self.send_header('Content-type', 'text/html') 514 | self.end_headers() 515 | self.wfile.write(output) 516 | if (errors): 517 | #print errors 518 | f=open(logFile, 'w') 519 | f.write(errors) 520 | f.close() 521 | return 522 | 523 | #THEOS TWEAK - EDIT 524 | if ( self.path.startswith("/EditTweak") ): 525 | import subprocess as sub 526 | appTo=urllib.unquote(self.path) 527 | print appTo 528 | appTo=appTo.replace("+",'\\ ') 529 | filename=appTo.split("&FileName=")[1].split("&EOFname=")[0] 530 | app=appTo.split("AppID=")[1].split("&")[0] 531 | if ( app.startswith("/") ): 532 | app="--direct "+app.rpartition("/")[0]+"/" 533 | command_line=applicationPath+'Theos.sh'+' '+'\''+app+'\''+' \"Edit\"'+' '+'\''+filename+'\'' 534 | command_line='\''+'sh'+'\' '+command_line 535 | print command_line 536 | import shlex 537 | args = shlex.split(command_line) 538 | print args 539 | p = sub.Popen(args,stdout=sub.PIPE,stderr=sub.PIPE) 540 | output, errors = p.communicate() 541 | self.send_response(200) 542 | self.send_header('Content-type', 'text/html') 543 | self.end_headers() 544 | self.wfile.write(output) 545 | if (errors): 546 | print errors 547 | f=open(logFile, 'w') 548 | f.write(errors) 549 | f.close() 550 | return 551 | 552 | #THEOS TWEAK - SAVE 553 | if ( self.path.startswith("/SaveTweak") ): 554 | import subprocess as sub 555 | appTo=urllib.unquote(self.path) 556 | print appTo 557 | appTo=appTo.replace("+",'\\ ') 558 | filename=appTo.split("&FileName=")[1].split("&EOFname=")[0] 559 | app=appTo.split("AppID=")[1].split("&")[0] 560 | if ( app.startswith("/") ): 561 | app="--direct "+app.rpartition("/")[0]+"/" 562 | command_line=applicationPath+'Theos.sh'+' '+'\''+app+'\''+' \"Save\"'+' '+'\''+filename+'\'' 563 | command_line='\''+'sh'+'\' '+command_line 564 | print command_line 565 | import shlex 566 | args = shlex.split(command_line) 567 | print args 568 | p = sub.Popen(args,stdout=sub.PIPE,stderr=sub.PIPE) 569 | output, errors = p.communicate() 570 | self.send_response(200) 571 | self.send_header('Content-type', 'text/html') 572 | self.end_headers() 573 | self.wfile.write(output) 574 | if (errors): 575 | print errors 576 | f=open(logFile, 'w') 577 | f.write(errors) 578 | f.close() 579 | return 580 | 581 | 582 | #THEOS TWEAK - BUILD 583 | if ( self.path.startswith("/BuildTweak") ): 584 | import subprocess as sub 585 | appTo=urllib.unquote(self.path) 586 | print appTo 587 | appTo=appTo.replace("+",'\\ ') 588 | filename=appTo.split("&FileName=")[1].split("&EOFname=")[0] 589 | app=appTo.split("AppID=")[1].split("&")[0] 590 | if ( app.startswith("/") ): 591 | app="--direct "+app.rpartition("/")[0]+"/" 592 | command_line=applicationPath+'Theos.sh'+' '+'\''+app+'\''+' \"Build\"'+' '+'\''+filename+'\'' 593 | command_line='\''+'sh'+'\' '+command_line 594 | print command_line 595 | import shlex 596 | args = shlex.split(command_line) 597 | print args 598 | p = sub.Popen(args,stdout=sub.PIPE,stderr=sub.PIPE) 599 | output, errors = p.communicate() 600 | self.send_response(200) 601 | self.send_header('Content-type', 'text/html') 602 | self.end_headers() 603 | self.wfile.write(output) 604 | if (errors): 605 | print errors 606 | f=open(logFile, 'w') 607 | f.write(errors) 608 | f.close() 609 | return 610 | except: 611 | return 612 | 613 | def do_POST(self): 614 | try: 615 | if ( self.path.startswith("/SaveTweak") ): 616 | form = cgi.FieldStorage( fp=self.rfile, headers=self.headers, environ={'REQUEST_METHOD':'POST', 'CONTENT_TYPE':self.headers['Content-Type'], }) 617 | app=form["AppID"].value 618 | fileName=form["fileName"].value 619 | content=form["txtContent"].value 620 | d = open(fileName,'w') 621 | d.write(content) 622 | d.close() 623 | self.send_response(301) 624 | self.end_headers() 625 | self.wfile.write("

Changes Saved!

"); 626 | if (errors): 627 | print errors 628 | f=open(logFile, 'w') 629 | f.write(errors) 630 | f.close() 631 | return 632 | except: 633 | return 634 | 635 | def main(): 636 | try: 637 | server = HTTPServer(('', 5555), SimpleHandler) 638 | print 'Starting Server...' 639 | 640 | #f=open(logFile, 'w') 641 | #f.write('START UP! -- \n') 642 | #f.close() 643 | 644 | server.serve_forever() 645 | except KeyboardInterrupt: 646 | print '^C -> stopping server' 647 | server.socket.close() 648 | 649 | if __name__ == '__main__': 650 | main() 651 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | License: GNU General Public License v3 2 | The full license can be found at http://opensource.org/licenses/GPL-3.0 3 | -------------------------------------------------------------------------------- /main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // iRE 4 | // 5 | // Created by veracode on 11/8/13. 6 | // Copyright (c) 2013 veracode. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | setuid(0); 16 | setgid(0); 17 | 18 | @autoreleasepool { 19 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 20 | } 21 | 22 | } 23 | --------------------------------------------------------------------------------