Skip to content

Instantly share code, notes, and snippets.

@Proteas
Created February 6, 2013 06:54
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save Proteas/4720822 to your computer and use it in GitHub Desktop.
Save Proteas/4720822 to your computer and use it in GitHub Desktop.
水货一枚半
#!/bin/sh
#
# DeCrypt - v1.2 (2013-02-05)
# - v1.1 (2008-10-21)
# - v1.2 (2013-02-05)
# FloydianSlip, Proteas
#
# Heavily based on xcrack
#
# Many thanks to:
# puy0, SaladFork, Flox, Flawless
#
echo "DeCrypt 1.2 (2013-02-05)"
echo "FloydianSlip, Proteas"
echo
if [ ! -e /usr/bin/plutil ]; then
echo "Cannot find plutil (apt-get install com.ericasadun.utilities)"
exit 1
fi
if [ ! -e /usr/bin/gdb ]; then
echo "Cannot find gdb (apt-get install gdb)"
exit 1
fi
if [ ! -e /usr/bin/otool ]; then
echo "Cannot find otool (apt-get install odcctools)"
exit 1
fi
if [ ! -e /usr/bin/ldid ]; then
echo "Cannot find otool (apt-get install ldid)"
exit 1
fi
if [ ! -e /usr/bin/awk ]; then
echo "Cannot find awk (apt-get install gawk)"
exit 1
fi
if [ ! -e /usr/bin/zip ]; then
echo "Cannot find zip (apt-get install zip)"
exit 1
fi
if [ $# -ne 1 ]; then
echo "Usage: $(basename $0) <ApplicationName>"
echo
exit 1
fi
AppInput=$1
if [ -d "$AppInput" ]; then
tempLoc=$AppInput
else
echo "Locating $AppInput"
tempLoc=$(find /var/mobile/Applications -iname "$AppInput.app")
if [ -z "$tempLoc" ]; then
echo "Unable to locate $AppInput"
exit 1
fi
AppCount=$(find /var/mobile/Applications -iname "$AppInput.app" | wc -l)
if [ $AppCount -gt 1 ]; then
echo "Found two installation directories:"
find /var/mobile/Applications -iname "$AppInput.app"
exit 1
fi
fi
AppPath=$(dirname "$tempLoc")
AppName=$(basename "$tempLoc")
AppExec=$(plutil -key CFBundleExecutable "$tempLoc/Info.plist")
AppVer=$(plutil -key CFBundleVersion "$tempLoc/Info.plist")
AppDisplayName=$(plutil -key CFBundleDisplayName "$tempLoc/Info.plist")
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
echo "Found $AppName"
echo "Creating directories"
WorkDir="/tmp/DecryptApp-$(date +%Y%m%d-%H%M%S)"
NewAppDir="$HOME/Documents/Decrypted"
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 "Unable to create Directories"
exit 1
fi
echo "Copying application files"
cp -a "$AppPath/$AppName/" "$WorkDir/"
if [ ! -e "$WorkDir/$AppName/$AppExec" ]; then
echo "Unable to copy application files"
rm -fr "$WorkDir"
exit 1
fi
echo "Analyzing application"
CryptID=$(otool -l "$WorkDir/$AppName/$AppExec" | 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/$AppExec" | grep cryptsize | awk '{print $2}')
if [ ! $CryptSize ]; then
echo "Unable to find CryptSize"
rm -fr "$WorkDir"
exit 1
fi
CryptOff=$(otool -l "$WorkDir/$AppName/$AppExec" | grep cryptoff | awk '{print $2}')
if [ ! $CryptOff ]; then
echo "Unable to find CryptOff"
rm -fr "$WorkDir"
exit 1
fi
echo "Locating and patching CryptID"
# "/System/Library/Frameworks" in hex
PathAsHex="2f53797374656d2f4c6962726172792f4672616d65776f726b73"
# - Convert to hex on 1 long line, only take stuff before the path string,
# - Convert to 1 byte set per line, find 0x01 (line number is offset in the real file),
# - Strip newlines, reverse the order
oneLocations=($(od -A n -t x1 -v "$WorkDir/$AppName/$AppExec" | \
tr -d ' ','\n' | \
sed "s/$PathAsHex.*\$//" | \
sed "s/../&\n/g" | \
grep -n -s 01 | \
cut -d : -f 1 | \
sort -nr | \
tr "\n" " "))
for TryOffset in "${oneLocations[@]}"; do
cp -a "$WorkDir/$AppName/$AppExec" "$WorkDir/$AppName/$AppExec.trying"
foo=$(echo -ne "\x00" | dd bs=1 seek=$((TryOffset - 1)) conv=notrunc status=noxfer of="$WorkDir/$AppName/$AppExec.trying" 2>&1> /dev/null)
cid=$(otool -l "$WorkDir/$AppName/$AppExec.trying" | grep cryptid | awk '{print $2}')
if [ $cid -eq 0 ]; then
break
fi
rm "$WorkDir/$AppName/$AppExec.trying"
done
if [ ! -e "$WorkDir/$AppName/$AppExec.trying" ]; then
echo "Unable to find CryptID"
rm -fr "$WorkDir"
exit 1
fi
mv "$WorkDir/$AppName/$AppExec.trying" "$WorkDir/$AppName/$AppExec"
echo "Dumping unencrypted data from application"
echo -e "set breakpoint pending on\r\n
break \"UIApplicationMain\"\r\n
commands 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/$AppExec" -x $WorkDir/batch.gdb -batch 2>&1> /dev/null)
rm $WorkDir/batch.gdb
echo "Verifiying data dump"
DumpSize=$(stat -c%s "$WorkDir/dump.bin")
if [ "$DumpSize" != "$CryptSize" ]; then
echo "Memory dump is not the right size or does not exist"
rm -fr "$WorkDir"
exit 1
fi
echo "Replacing encrypted data with data dump"
foo=$(dd seek=4096 bs=1 conv=notrunc if="$WorkDir/dump.bin" of="$WorkDir/$AppName/$AppExec" 2>&1> /dev/null)
rm "$WorkDir/dump.bin"
echo "Signing the application"
foo=$(ldid -s "$WorkDir/$AppName/$AppExec" 2>&1> /dev/null)
plutil -key 'SignerIdentity' -value 'Apple iPhone OS Application Signing' "$WorkDir/$AppName/Info.plist" 2>&1> /dev/null
if [ -e "$WorkDir/$AppName/SC_Info" ]; then
echo "Removing SC_Info"
rm -fr "$WorkDir/$AppName/SC_Info"
fi
if [ -e "$WorkDir/$AppName/_CodeSignature" ]; then
echo "Removing _CodeSignature"
rm -fr "$WorkDir/$AppName/_CodeSignature"
fi
if [ -h "$WorkDir/$AppName/CodeResources" ]; then
echo "Removing CodeResources"
rm -fr "$WorkDir/$AppName/CodeResources"
fi
if [ -e "$WorkDir/$AppName/ResourceRules.plist" ]; then
echo "Removing ResourceRules.plist"
rm -fr "$WorkDir/$AppName/ResourceRules.plist"
fi
echo "Building .ipa"
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 "Copying iTunesArtwork"
if [ -e "$AppPath/iTunesArtwork" ]; then
cp -a "$AppPath/iTunesArtwork" "$WorkDir/"
else
echo "Unable to find iTunesArtwork"
fi
echo "Compressing the .ipa"
IPAName=$NewAppDir/$(echo $AppName | sed -e "s: :_:g")-v$AppVer.ipa
cd "$WorkDir"
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 "Removing temporary files"
rm -rf "$WorkDir"
echo "Done"
echo "Created decrypted .ipa at $IPAName"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment