#!/bin/sh # # poedCrack - v2.5 (2009-12-03) -- mod25G # For all devices # # Now includes fat binary support # # Latest version always available at: http://www.roapd.com/uploads/poedCrack.gz # # Heavily based on DeCrypt by FloydianSlip # # Many thanks to: # puy0, SaladFork, Flox, Flawless, FloydianSlip, MadHouse, TDDebug clear echo "poedCrack 2.5 (091203) by poedgirl -- mod25G" if [ ! -e /usr/bin/plutil ]; then echo "Cannot find plutil (Install Erica Utils from Cydia)" exit 1 fi if [ ! -e /usr/bin/gdb ]; then echo "Cannot find gdb (Install GNU Debugger from Cydia)" exit 1 fi if [ ! -e /usr/bin/otool ]; then echo "Cannot find otool (Install toolchain from Cydia)" exit 1 fi if [ ! -e /usr/bin/ldid ]; then echo "Cannot find ldid (Install Link Identity Editor from Cydia)" exit 1 fi #Get and store the whole apps list rm -f /tmp/lsd.tmp ls -d /var/mobile/Applications/*/*.app > /tmp/lsd.tmp if [ $# -lt 1 ]; then echo "Usage: $(basename $0) [ [ []]]" echo cat /tmp/lsd.tmp | cut -f 6 -d '/' | sort -f | sed "s/\\.app/,/" | tr "\n" " " echo -e "\010\010." rm -f /tmp/lsd.tmp exit 1 fi if [ "$1" = "-e" ]; then echo "Encrypted apps list:" ls -d /var/mobile/Applications/*/*.app/SC_Info | sort -f -t \/ -k 6 | while read OneApp do echo -n "$(echo "$OneApp" | cut -f 6 -d '/' | sed "s/\\.app/, /")" done echo -e "\010\010." rm -f /tmp/lsd.tmp exit 1 fi AppInput=$1 CrackerName=$2 CreditFile=$3 if [ ! $CrackerName ]; then CrackerName="Anonymous" fi if [ ! $CreditFile ]; then CreditFile=$CrackerName fi if [ -d "$AppInput" ]; then tempLoc=$AppInput else echo "Locating $AppInput" #Escape the "*" as ".*" AppGrep=$(echo "/$AppInput\.app" | sed "s/\*/\.\*/g") tempLoc=$(grep -i "$AppGrep" /tmp/lsd.tmp) if [ -z "$tempLoc" ]; then echo "Unable to locate $AppInput" rm -f /tmp/lsd.tmp exit 1 fi AppCount=$(echo "$tempLoc" | wc -l) if [ $AppCount -gt 1 ]; then echo "Found $AppCount installation directories:" echo "$tempLoc" rm -f /tmp/lsd.tmp exit 1 fi fi #Apps list not needed anymore rm -f /tmp/lsd.tmp AppPath=$(dirname "$tempLoc") AppName=$(basename "$tempLoc") AppExec=$(plutil -key CFBundleExecutable "$tempLoc/Info.plist" 2>&1) AppVer=$(plutil -key CFBundleVersion "$tempLoc/Info.plist" 2>&1) AppDisplayName=$(plutil -key CFBundleDisplayName "$tempLoc/Info.plist" 2>&1) if [ "${AppDisplayName:0:6}" = "Error:" ]; then echo "Unable to get CFBundleDisplayName" AppDisplayName=$(plutil -key CFBundleName "$tempLoc/Info.plist" 2>&1) if [ "${AppDisplayName:0:6}" = "Error:" ]; then echo "Unable to get CFBundleName" AppDisplayName=$AppExec fi fi MinOS=$(plutil -key MinimumOSVersion "$tempLoc/Info.plist" 2>&1) if [ "${MinOS:0:6}" = "Error:" ]; then echo "Unable to get MinOS" MinOS="0.0.0" fi Patched="" if [ ! -d "$AppPath" ]; then echo "Unable to locate original installation directory" exit 1 fi if [ ! -d "$AppPath/$AppName" ]; then echo "Unable to locate .app directory" exit 1 fi if [ ! -e "$AppPath/$AppName/$AppExec" ]; then echo "Unable to locate executable" exit 1 fi if [ ! "$AppName" = "$AppDisplayName.app" ]; then echo "Found '$AppName' ($AppDisplayName)" else echo "Found '$AppName'" fi echo -n "Creating directories " WorkDir="/tmp/poedCrack-$(date +%Y%m%d-%H%M%S)" NewAppDir="$HOME/Documents/Cracked" if [ -e "$WorkDir" ]; then rm -rf "$WorkDir" fi mkdir -p "$WorkDir" if [ ! -e "$NewAppDir" ]; then mkdir -p "$NewAppDir" fi if [ ! -d "$WorkDir" -o ! -d "$NewAppDir" ]; then echo "failed !" exit 1 fi echo "and copying some files" mkdir -p "$WorkDir/$AppName" cp -a "$AppPath/$AppName/$AppExec" "$WorkDir/$AppName/" cp -a "$AppPath/$AppName/Info.plist" "$WorkDir/$AppName/" if [ ! -e "$WorkDir/$AppName/$AppExec" ]; then echo "Unable to copy application files" rm -fr "$WorkDir" exit 1 fi echo -n "Analyzing application: " LipoFail=$(lipo -info "$WorkDir/$AppName/$AppExec" | grep Architectures | awk '{print $2}') if [ ! $LipoFail ]; then echo "Thin Binary found" Iterations=1 else echo "Fat Binary found" echo "Dumping armv6 section" lipo -thin armv6 "$WorkDir/$AppName/$AppExec" -output "$WorkDir/$AppName/$AppExec-armv6" CPUType=$(sysctl hw.cpusubtype | grep 6 | awk '{print $2}') if [ ! $CPUType ]; then echo "Dumping armv7 section" dd if="$WorkDir/$AppName/$AppExec" of="$WorkDir/$AppName/$AppExec-swapped" bs=1 count=15 >> /dev/null 2>&1> /dev/null echo -en "\011" >> "$WorkDir/$AppName/$AppExec-swapped" dd if="$WorkDir/$AppName/$AppExec" of="$WorkDir/$AppName/$AppExec-swapped" skip=16 bs=1 count=19 oflag=append conv=notrunc >> /dev/null 2>&1> /dev/null echo -en "\006" >> "$WorkDir/$AppName/$AppExec-swapped" dd if="$WorkDir/$AppName/$AppExec" of="$WorkDir/$AppName/$AppExec-swapped" skip=1 bs=36 oflag=append conv=notrunc >> /dev/null 2>&1> /dev/null lipo -thin armv6 "$WorkDir/$AppName/$AppExec-swapped" -output "$WorkDir/$AppName/$AppExec-armv7" rm "$WorkDir/$AppName/$AppExec-swapped" Iterations=2 else echo "Non armv7 compatible CPU: not dumping armv7" Iterations=1 fi fi for (( i=1;i<=$Iterations;i++)); do if [ ! $LipoFail ]; then AppExecCur=$AppExec else if [ $i -eq 1 ];then AppExecCur=$AppExec-armv6 echo "--- Cracking armv6 section ---" # Patched="$Patched arm6" else AppExecCur=$AppExec-armv7 echo "--- Cracking armv7 section ---" # Patched="$Patched arm7" fi fi CryptID=$(otool -l "$WorkDir/$AppName/$AppExecCur" | grep cryptid | awk '{print $2}') if [ $CryptID -ne "1" ]; then echo "Application is not encrypted" rm -fr "$WorkDir" exit 1 fi CryptSize=$(otool -l "$WorkDir/$AppName/$AppExecCur" | grep cryptsize | awk '{print $2}') if [ ! $CryptSize ]; then echo "Unable to find CryptSize" rm -fr "$WorkDir" exit 1 fi CryptOff=$(otool -l "$WorkDir/$AppName/$AppExecCur" | grep cryptoff | awk '{print $2}') if [ ! $CryptOff ]; then echo "Unable to find CryptOff" rm -fr "$WorkDir" exit 1 fi echo "Locating and patching CryptID" # - Take first 4KB of the file, convert to hex on 1 long line # - Find the cryptid command block # - Compute the offset to patch (01 --> 00) dd bs=4096 count=1 if="$WorkDir/$AppName/$AppExecCur" 2> /dev/null | \ od -A n -t x1 -v | \ tr -d ' ','\n' | \ sed "s/0000002100000014......................01.*/ThisIsItThisIsItThisIsItThisIsItHere!!/g" > "$WorkDir/hex.tmp" foo=$(echo -ne "\x00" | dd bs=1 seek=$(expr $(($(stat -c%s "$WorkDir/hex.tmp"))) / 2) conv=notrunc status=noxfer of="$WorkDir/$AppName/$AppExecCur" 2>&1> /dev/null) rm -f "$WorkDir/hex.tmp" cid=$(otool -l "$WorkDir/$AppName/$AppExecCur" | grep cryptid | awk '{print $2}') if [ $cid = "1" ]; then echo "Unable to patch CryptID" rm -fr "$WorkDir" exit 1 fi echo "Dumping unencrypted data from application" echo -e "set sharedlibrary load-rules \".*\" \".*\" none\r\n\ set inferior-auto-start-dyld off\r\n\ set sharedlibrary preload-libraries off\r\n\ set sharedlibrary load-dyld-symbols off\r\n\ handle all nostop\r\n\ rb doModInitFunctions\r\n command 1\r\n\ dump memory $WorkDir/dump.bin 0x2000 $(($CryptSize + 0x2000))\r\n\ kill\r\n\ quit\r\n\ end\r\n\ start" > $WorkDir/batch.gdb foo=$(gdb -q -e "$AppPath/$AppName/$AppExecCur" -x $WorkDir/batch.gdb -batch > /dev/null 2>&1> /dev/null) rm $WorkDir/batch.gdb echo -n "Verifying dump " DumpSize=$(stat -c%s "$WorkDir/dump.bin") if [ "$DumpSize" != "$CryptSize" ]; then echo "failed ! Wrong size ?" rm -fr "$WorkDir" exit 1 fi echo "and replacing encrypted data" foo=$(dd seek=1 count=1 obs=4096 ibs=$DumpSize conv=notrunc if="$WorkDir/dump.bin" of="$WorkDir/$AppName/$AppExecCur" 2>&1> /dev/null) rm "$WorkDir/dump.bin" echo -n "Trying LamerPatcher... " sed --in-place=.BCK \ -e 's=/Cydia.app=/Czdjb.bpp=g' \ -e 's=SignerIdentity=SjgnfrJdfntjtz=g' \ -e 's=PfdkboFabkqfqv=PgdkcoGackqgqw=g' \ -e 's=Sign\d0\d0\d0\d0erId\d0\d0\d0\d0entity=Sjgn\d0\d0\d0\d0frJd\d0\d0\d0\d0fntjtz=g' \ -e 's=/private/var/lib/apt=/prjvbtf/vbr/ljb/bpt=g' \ -e 's=/Applicat\d0\d0\d0ions/dele\d0\d0\d0teme\.txt=/Bppljcbt\d0\d0\d0jpns/dflf\d0\d0\d0tfmf\.txt=g' \ -e 's=/Appl\d0\d0\d0ications/C\d0\d0ydi\d0a\.app=/Bppl\d0\d0\d0jcbtjpns/C\d0\d0zdj\d0b\.bpp=g' \ -e 's=ations/Cy\d0\d0\d0/Applic\d0pp\d0\d0dia.a=btjpns/Cz\d0\d0\d0/Bppljc\d0pp\d0\d0djb.b=g' \ -e 's=ate/va\d0\d0/priv\d0\d0\d0pt/\d0b/a\d0r/li=btf/vb\d0\d0/prjv\d0\d0\d0pt/\d0b/b\d0r/lj=g' \ -e 's=pinchmedia\.com=pjnchmfdjb\.cpm=g' \ -e 's=admob\.com=bdmpb\.cpm=g' \ -e 's=doubleclick\.net=dpvblfcljck\.nft=g' \ -e 's=googlesyndication\.com=gppglfszndjcbtjpn\.cpm=g' \ -e 's=flurry\.com=flvrrz\.cpm=g' \ -e 's=qwapi\.com=qwbpj\.cpm=g' \ -e 's=mobclix\.com=mpbcljx\.cpm=g' \ -e 's=http://ad\.=http://bd/=g' \ -e 's=http://ads\.=http://bds/=g' \ "$WorkDir/$AppName/$AppExecCur" cmp --silent "$WorkDir/$AppName/$AppExecCur.BCK" "$WorkDir/$AppName/$AppExecCur" if [ "$?" -ne "0" ]; then echo "patched something" Patched="$Patched patched" else echo "found nothing" fi rm "$WorkDir/$AppName/$AppExecCur.BCK" echo "Signing the application" foo=$(ldid -s "$WorkDir/$AppName/$AppExecCur" 2>&1> /dev/null) done if [ $LipoFail ]; then if [ -e "$WorkDir/$AppName/$AppExec-armv7" ]; then echo "Combining both parts into a fat binary" lipo -create "$WorkDir/$AppName/$AppExec-armv6" "$WorkDir/$AppName/$AppExec-armv7" -output "$WorkDir/$AppName/$AppExec" chmod 755 "$WorkDir/$AppName/$AppExec" rm "$WorkDir/$AppName/$AppExec-armv6" rm "$WorkDir/$AppName/$AppExec-armv7" else echo mv "$WorkDir/$AppName/$AppExec-armv6" "$WorkDir/$AppName/$AppExec" fi fi # Test MinimumOS version for SignerIdentity needs echo -n "MinOS is '$MinOS': " if [ ${MinOS:0:1} -gt 2 ]; then echo "no SignerIdentity needed" else echo "adding SignerIdentity" cp -a "$WorkDir/$AppName/Info.plist" "$WorkDir/$AppName/Info.backup.plist" plutil -key 'SignerIdentity' -value 'Apple iPhone OS Application Signing' "$WorkDir/$AppName/Info.plist" 2>&1> /dev/null plutil -binary "$WorkDir/$AppName/Info.plist" 2>&1> /dev/null # Timestamp back touch -r "$AppPath/$AppName/Info.plist" "$WorkDir/$AppName/Info.plist" fi # Timestamp back touch -r "$AppPath/$AppName/$AppExec" "$WorkDir/$AppName/$AppExec" if [ ! $CrackerName = "Anonymous" ]; then echo "Adding Credits" echo "Cracked by $CrackerName" >> "$WorkDir/$AppName/$CreditFile" fi echo "Building .ipa (step 1)" mkdir -p "$WorkDir/Payload" if [ ! -e "$WorkDir/Payload" ]; then echo "Failed to create Payload directory" rm -fr "$WorkDir" exit 1 fi mv "$WorkDir/$AppName" "$WorkDir/Payload/" echo -n "Copying Artwork " if [ -e "$AppPath/iTunesArtwork" ]; then cp -a "$AppPath/iTunesArtwork" "$WorkDir/" touch -r "$AppPath/$AppName/Info.plist" "$WorkDir/iTunesArtwork" else echo "failed !" fi echo "and faking Metadata" cp "$AppPath/iTunesMetadata.plist" "$WorkDir/iTunesMetadataSource.plist" plutil -xml "$WorkDir/iTunesMetadataSource.plist" 2>&1> /dev/null echo -e "\n\ \n\ \n\ \tappleId\n\ \tLisa@apple.com\n\ \tpurchaseDate\n\ \t2010-05-05T05:05:05Z" > "$WorkDir/iTunesMetadata.plist" grep -A1 "artistId" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A1 "artistName" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A1 "buy-only" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A1 "buyParams" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A1 "copyright" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A1 "drmVersionNumber" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A1 "fileExtension" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A1 -m1 "genre" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A1 -m1 "genreId" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A1 "itemId" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A1 "itemName" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A1 "kind" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A1 "playlistArtistName" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A1 "playlistName" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A1 "price" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A1 "priceDisplay" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A99 "rating" "$WorkDir/iTunesMetadataSource.plist" | grep -m1 -B99 "" >> "$WorkDir/iTunesMetadata.plist" grep -A1 "releaseDate" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A1 "s" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A1 "softwareIcon57x57URL" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A1 "softwareIconNeedsShine" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A99 "softwareSupportedDeviceIds" "$WorkDir/iTunesMetadataSource.plist" | grep -m1 -B99 "" >> "$WorkDir/iTunesMetadata.plist" grep -A1 "softwareVersionBundleId" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A1 "softwareVersionExternalIdentifier" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A99 "softwareVersionExternalIdentifiers" "$WorkDir/iTunesMetadataSource.plist" | grep -m1 -B99 "" >> "$WorkDir/iTunesMetadata.plist" grep -A99 "subgenres" "$WorkDir/iTunesMetadataSource.plist" | grep -m1 -B99 "" >> "$WorkDir/iTunesMetadata.plist" grep -A1 "vendorId" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" grep -A1 "versionRestrictions" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist" echo -e "\n\ \n" >> "$WorkDir/iTunesMetadata.plist" touch -r "$AppPath/$AppName/Info.plist" "$WorkDir/iTunesMetadata.plist" #Check for possible iTunesMetadata format changes rm -f /tmp/diff.txt diff "$WorkDir/iTunesMetadataSource.plist" "$WorkDir/iTunesMetadata.plist" > /tmp/diff.txt rm -f "$WorkDir/iTunesMetadataSource.plist" NewFields=$(wc -l /tmp/diff.txt | cut -f 1 -d " ") if [ $NewFields -ne "11" ]; then if [ $NewFields -ne "28" ]; then echo "Warning: iTunesMetadata format changed" fi fi rm -f /tmp/diff.txt FirstSize=$(du -k -s "$WorkDir" | cut -f 1) echo "Compressing the .ipa (step 1) [$FirstSize kB]" if [ $CrackerName = "Anonymous" ]; then IPAName=$NewAppDir/$(echo $AppDisplayName | sed -e "s: :_:g")\ \(v$AppVer$Patched\ os$(echo $MinOS | sed -e "s:\.::g")\).ipa else IPAName=$NewAppDir/$(echo $AppDisplayName | sed -e "s: :_:g")\ \(v$AppVer$Patched\ os$(echo $MinOS | sed -e "s:\.::g")\)-$CrackerName.ipa fi cd "$WorkDir" rm -f "$IPAName" zip -m -r "$IPAName" * 2>&1> /dev/null cd - 2>&1> /dev/null if [ ! -e "$IPAName" ]; then echo "Failed to compress the .ipa" rm -fr "$WorkDir" exit 1 fi echo "Building .ipa (step 2)" # Using a SymbolicLink ln -s "$AppPath/" "$WorkDir/Payload" SecondSize=$(du -k -s "$AppPath" | cut -f 1) echo "Compressing the .ipa (step 2) [$(expr $SecondSize - $FirstSize) kB]" cd "$WorkDir" # Zip doesn't move/delete, and excludes some files. zip -y -r "$IPAName" Payload/* -x Payload/iTunesArtwork Payload/iTunesMetadata.plist "Payload/Documents/*" "Payload/Library/*" "Payload/tmp/*" "Payload/$AppName/$AppExec" "Payload/$AppName/Info.plist" "Payload/$AppName/SC_Info/*" "Payload/$AppName/_CodeSignature/*" "Payload/$AppName/CodeResources" "Payload/$AppName/ResourceRules.plist" 2>&1> /dev/null rm "$WorkDir/Payload" cd - 2>&1> /dev/null echo "Removing temporary files" rm -rf "$WorkDir" echo "Created cracked .ipa at $IPAName"