破解从 AppStore 下载的 IPA

破解从 AppStore 下载的 IPA 主要包括如下步骤:

1、去除可执行文件中的加密数据。

2、重新签名打包。

可以参考:http://tungchingkai.blogspot.com/2009/02/how-to-decrypt-iphone-ipa-file.html

如上的文章中附了一个 shell 脚本文件可以方便破解。

这个脚本文件的使用方法是:

1、通过 scp 或者其他工具,将 DCrypt.sh 拷贝到越狱设备上。

2、给文件增加可执行权限:chmod +x ./DCrypt.sh

3、执行破解:./DCrypt.sh UCBrowserHD

但是文章中附的 DCrypt.sh 比较老,

在最新的越狱系统下执行会出错,出错点:

1、plutil 的参数发生了变化。

2、gdb 断点位置需要改变,在 *0x2000 出断点会导出 gdb 出错,无法完成内存 dump。

针对如上问题,对这个工具进行了修改(https://gist.github.com/Proteas/4720822),亲测可用:

 

#!/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"




posted @ 2013-02-06 14:56  Proteas  阅读(1429)  评论(0编辑  收藏  举报