注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

碳基体

http://weibo.com/tanjiti

 
 
 
 
 

日志

 
 

PoedCrackMod源码  

2012-10-26 13:06:06|  分类: iOS app security |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

#!/bin/sh
#
# poedCrack - v2.5 (2009-12-03) -- mod25H
# For all devices
#
# Now includes fat binary support
#
# Latest genuine 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
# and every helping people !



# ======
# Please, customize the script first !
# Choices are:

# - Should I generate "SignerIdentity" when app is OS2.x ?
# (Nobody cares about OS2.x anymore, except the ones still using it)
PCMsigner="YES"

# - Should I generate fake MetaData or not ?
# (Some people hate them, some love them)
PCMmetadata="YES"

# - Should I try LamerPatcher on the executable ?
# (It won't work 100%, but sometimes it helps)
PCMlamerpatcher="YES"

# - Should I try to crack arm6+arm7 on arm7 devices ?
# (If it freezes during arm7 part, then try "NO")
PCMarm7onarm7="YES"

# DEBUG ONLY: - Should I try to crack arm6+arm7 on arm6 devices ? (It won't work at all)
PCMarm7onarm6="NEVER"
# DEBUG ONLY: - Should I keep unpatched executable ?
PCMkeepunpatched="NEVER"
# DEBUG ONLY: - Force the "this script is running inside a GUI" check ?
PCMinaGUI="NEVER"

PCMwarning="NO"
if [ $PCMwarning = "YES" ]; then
echo "Please, customize this script first !"
exit 1
fi
# Thanks you for testing.
# ======



# Is this script running inside a GUI ?
if [ ! "$(ps -e | grep "$PPID" | grep "/Applications/.*\.app/")" = "" ]; then
PCMinaGUI="YES"
fi

# Initialize progress meter labels
if [ $PCMinaGUI = "YES" ]; then
export TERM=xterm
for ((i=0;i<=100;i++)); do
export Meter$i="$i% "
done
else
clear
fi

echo "${Meter0}poedCrack 2.5 (091203) by poedgirl /mod25H"

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

if [ ! -e /bin/touch ]; then
echo "Cannot find touch"
exit 1
fi

if [ ! -e /usr/bin/lipo ]; then
echo "Cannot find lipo"
exit 1
fi

if [ ! -e /usr/bin/zip ]; then
echo "Cannot find zip"
exit 1
fi

if [ ! -e /usr/sbin/sysctl ]; then
echo "Cannot find sysctl"
exit 1
fi

if [ ! -e /usr/bin/basename ]; then
echo "Cannot find basename"
exit 1
fi

if [ ! -e /usr/bin/cut ]; then
echo "Cannot find cut"
exit 1
fi

if [ ! $PCMinaGUI = "YES" ]; then
# Get and store the encrypted apps list
rm -f /tmp/lsd.tmp
ls -d /var/mobile/Applications/*/*.app/SC_Info 2> /dev/null | sort -f -t \/ -k 6 | while read OneApp
do
echo "$(dirname "$OneApp")" >> /tmp/lsd.tmp
done

if [ "$1" = "-e" ]; then
shift
echo "Note: '-e' is now default."
echo
fi

if [ $# -lt 1 ]; then
echo "Usage: $(basename $0) [<ApplicationName> [<CrackerName> [<CreditFileName>]]]"
echo " or: $(basename $0) for list of encrypted apps"
echo
if [ -e /tmp/lsd.tmp ]; then
cat /tmp/lsd.tmp | cut -f 6 -d '/' | sed "s/\\.app/,/" | tr "\n" " "
echo -e "\010\010."
rm -f /tmp/lsd.tmp
fi
exit 1
fi
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")

if [ $PCMinaGUI = "YES" ]; then
AppExec=$(plutil -key CFBundleExecutable "$tempLoc/Info.plist")
AppVer=$(plutil -key CFBundleVersion "$tempLoc/Info.plist")
AppDisplayName=$(plutil -key CFBundleDisplayName "$tempLoc/Info.plist")
if [ "${AppDisplayName:0:6}" = "Error:" ]; then
echo "${Meter6}Unable to get CFBundleDisplayName"
AppDisplayName=$(plutil -key CFBundleName "$tempLoc/Info.plist")
if [ "${AppDisplayName:0:6}" = "Error:" ]; then
echo "${Meter7}Unable to get CFBundleName"
AppDisplayName=$AppExec
fi
fi
MinOS=$(plutil -key MinimumOSVersion "$tempLoc/Info.plist")
else
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 "${Meter6}Unable to get CFBundleDisplayName"
AppDisplayName=$(plutil -key CFBundleName "$tempLoc/Info.plist" 2>&1)
if [ "${AppDisplayName:0:6}" = "Error:" ]; then
echo "${Meter7}Unable to get CFBundleName"
AppDisplayName=$AppExec
fi
fi
MinOS=$(plutil -key MinimumOSVersion "$tempLoc/Info.plist" 2>&1)
fi
if [ "${MinOS:0:6}" = "Error:" ]; then
echo "${Meter8}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 "${Meter9}Found '$AppName' ($AppDisplayName)"
else
echo "${Meter9}Found '$AppName'"
fi

echo -n "${Meter10}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 "${Meter15}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 "${Meter20}Analyzing application: "

LipoFail=$(lipo -info "$WorkDir/$AppName/$AppExec" | grep Architectures | awk '{print $2}')
if [ ! $LipoFail ]; then
echo "${Meter25}Thin Binary found"
Iterations=1
else
echo "${Meter25}Fat Binary found"

echo "${Meter26}Dumping armv6 section"
lipo -thin armv6 "$WorkDir/$AppName/$AppExec" -output "$WorkDir/$AppName/IWantYourSix"
chmod 777 "$WorkDir/$AppName/IWantYourSix"

# Force armv7 processing on armv6 devices. (It won't work at all; for debug only !)
if [ $PCMarm7onarm6 = "YES" ]; then
echo "${Meter27}Warning: forcing armv7 is stupid !"
CPUType=""
else
CPUType=$(sysctl hw.cpusubtype | grep 6 | awk '{print $2}')
fi

# The iDevice has an arm7 cpu
if [ ! $CPUType ]; then
if [ $PCMarm7onarm7 = "YES" ]; then
echo "${Meter28}Dumping armv7 section"
Iterations=2
# Swapping armv6 and armv7 headers
foo=$(echo -ne "\x09" | dd bs=1 seek=15 conv=notrunc status=noxfer of="$WorkDir/$AppName/$AppExec" 2>&1> /dev/null)
foo=$(echo -ne "\x06" | dd bs=1 seek=35 conv=notrunc status=noxfer of="$WorkDir/$AppName/$AppExec" 2>&1> /dev/null)
# Dumping swapped armv7 part
lipo -thin armv6 "$WorkDir/$AppName/$AppExec" -output "$WorkDir/$AppName/SevenTrumpets"
chmod 777 "$WorkDir/$AppName/SevenTrumpets"
else
echo "${Meter28}Armv7 compatible CPU but not dumping armv7"
Iterations=1
fi
else
echo "${Meter28}Non armv7 compatible CPU: not dumping armv7"
Iterations=1
fi
# (Deleting the fat binary: later)
fi

# Doing one or two parts
for (( i=1;i<=$Iterations;i++)); do
if [ ! $LipoFail ]; then
AppExecCur=$AppExec
else
if [ $i -eq 1 ]; then
AppExecCur="IWantYourSix"
echo "${Meter30}--- Cracking armv6 section ---"
Patched="$Patched arm6"
else
AppExecCur="SevenTrumpets"
echo "${Meter30}--- Cracking armv7 section ---"
Patched="$Patched arm7"
fi
fi

CryptID=$(otool -l "$WorkDir/$AppName/$AppExecCur" | grep cryptid | awk '{print $2}')
if [ $CryptID != "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 "${Meter31}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
# - 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

# Creating GDB script
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

# If first part (arm6) of a fat binary and running an arm7 iDevice, swap trick !
# (The arm7 iDevice always load the arm7 part, but it's swapped with the arm6 part: tricked).
SwapSwapAttack="NO"
if [ $i -eq 1 ]; then
if [ $LipoFail ]; then
if [ ! $CPUType ]; then
echo "${Meter39}Swap Swap Attack !"
SwapSwapAttack="YES"
fi
fi
fi

echo "${Meter40}Dumping unencrypted data from application"

if [ $SwapSwapAttack = "YES" ]; then
# Copying some files
mkdir "$WorkDir/$AppName/SC_Info"
chmod 777 "$WorkDir/$AppName/SC_Info"
cp "$AppPath/$AppName/SC_Info/$AppExec.sinf" "$WorkDir/$AppName/SC_Info/$AppExec.sinf"
chmod 777 "$WorkDir/$AppName/SC_Info/$AppExec.sinf"
cp "$AppPath/$AppName/SC_Info/$AppExec.supp" "$WorkDir/$AppName/SC_Info/$AppExec.supp"
chmod 777 "$WorkDir/$AppName/SC_Info/$AppExec.supp"
cp "$AppPath/$AppName/ResourceRules.plist" "$WorkDir/$AppName/ResourceRules.plist"
chmod 777 "$WorkDir/$AppName/ResourceRules.plist"
mkdir "$WorkDir/$AppName/_CodeSignature"
chmod 777 "$WorkDir/$AppName/_CodeSignature"
cp "$AppPath/$AppName/_CodeSignature/CodeResources" "$WorkDir/$AppName/_CodeSignature/CodeResources"
chmod 777 "$WorkDir/$AppName/_CodeSignature/CodeResources"
ln -s "$WorkDir/$AppName/_CodeSignature/CodeResources" "$WorkDir/$AppName/CodeResources"

# Cracking the previously swapped fat binary in WorkDir
foo=$(gdb -q -e "$WorkDir/$AppName/$AppExec" -x $WorkDir/batch.gdb -batch > /dev/null 2>&1> /dev/null)

# Removing temp files
rm "$WorkDir/$AppName/$AppExec"
rm "$WorkDir/$AppName/SC_Info/$AppExec.sinf"
rm "$WorkDir/$AppName/SC_Info/$AppExec.supp"
rmdir "$WorkDir/$AppName/SC_Info"
rm "$WorkDir/$AppName/ResourceRules.plist"
rm "$WorkDir/$AppName/CodeResources"
rm "$WorkDir/$AppName/_CodeSignature/CodeResources"
rmdir "$WorkDir/$AppName/_CodeSignature"
else
# Cracking genuine executable in AppPath
foo=$(gdb -q -e "$AppPath/$AppName/$AppExec" -x $WorkDir/batch.gdb -batch > /dev/null 2>&1> /dev/null)
fi

# Not needed anymore
rm $WorkDir/batch.gdb

echo -n "${Meter50}Verifying dump "
if [ ! -e "$WorkDir/dump.bin" ]; then
echo "failed ! Can't dump ?"
rm -fr "$WorkDir"
exit 1
fi
DumpSize=$(stat -c%s "$WorkDir/dump.bin")
if [ "$DumpSize" != "$CryptSize" ]; then
echo "failed ! Wrong size ?"
rm -fr "$WorkDir"
exit 1
fi

echo "${Meter54}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"

if [ $PCMlamerpatcher = "YES" ]; then
# MinOs check and Signer check: Lite or Full ?
if [ ${MinOS:0:1} -gt 2 -o $PCMsigner != "YES" ]; then
echo -n "${Meter58}Trying LamerPatcherLite... "
sed --in-place=.BCK \
-e 's=/Cydia\.app=/Czdjb\.bpp=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' \
-e 's=http://ads2\.=http://bds2/=g' \
-e 's=adwhirl\.com=bdwhjrl\.cpm=g' \
-e 's=vdopia\.com=vdppjb\.cpm=g' \
"$WorkDir/$AppName/$AppExecCur"

# "/Applications/Icy\.app"
# "/Applications/SBSettings\.app"
# "/Library/MobileSubstrate"
else
echo -n "${Meter58}Trying LamerPatcherFull... "
sed --in-place=.BCK \
-e 's=SignerIdentity=SjgnfrJdfntjtz=g' \
-e 's=Jdfnuiuy=Kdgnujuz=g' \
-e 's=S\d0\d0\d0h\d0\d0\d0g\d0\d0\d0f\d0\d0\d0e=S\d0\d0\d0i\d0\d0\d0g\d0\d0\d0f\d0\d0\d0f=g' \
-e 's=S\d0\d0\d0i\d0\d0\d0g\d0\d0\d0n\d0\d0\d0e\d0\d0\d0r=S\d0\d0\d0j\d0\d0\d0g\d0\d0\d0n\d0\d0\d0f\d0\d0\d0r=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=S\d0\d0\d0g\d0\d0\d0n\d0\d0\d0e\d0\d0\d0r=S\d0\d0\d0h\d0\d0\d0o\d0\d0\d0f\d0\d0\d0r=g' \
-e 's=/Cydia\.app=/Czdjb\.bpp=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' \
-e 's=http://ads2\.=http://bds2/=g' \
-e 's=adwhirl\.com=bdwhjrl\.cpm=g' \
-e 's=vdopia\.com=vdppjb\.cpm=g' \
"$WorkDir/$AppName/$AppExecCur"

# "/Applications/Icy\.app"
# "/Applications/SBSettings\.app"
# "/Library/MobileSubstrate"
# "%si %sg %sn %se %sr %sI %sd %st %sy"
# "Sig nerId%@%@ ent ity "
# "Si gne rIde ntity"
fi

cmp --silent "$WorkDir/$AppName/$AppExecCur.BCK" "$WorkDir/$AppName/$AppExecCur"
if [ "$?" != "0" ]; then
echo "${Meter59}patched something"
Patched="$Patched patched"
if [ $PCMkeepunpatched != "YES" ]; then
rm "$WorkDir/$AppName/$AppExecCur.BCK"
fi
else
echo "${Meter59}found nothing"
rm "$WorkDir/$AppName/$AppExecCur.BCK"
fi
fi

echo "${Meter60}Signing the application"
foo=$(ldid -s "$WorkDir/$AppName/$AppExecCur" 2>&1> /dev/null)
done

# Unsplitting fat binary
if [ $LipoFail ]; then
rm -f "$WorkDir/$AppName/$AppExec"
echo "${Meter61}---"
if [ -e "$WorkDir/$AppName/SevenTrumpets" ]; then
echo "${Meter62}Combining both parts into a fat binary"
lipo -create "$WorkDir/$AppName/IWantYourSix" "$WorkDir/$AppName/SevenTrumpets" -output "$WorkDir/$AppName/$AppExec"
chmod 777 "$WorkDir/$AppName/$AppExec"

if [ $PCMkeepunpatched != "YES" ]; then
rm "$WorkDir/$AppName/IWantYourSix"
rm "$WorkDir/$AppName/SevenTrumpets"
fi
else
mv "$WorkDir/$AppName/IWantYourSix" "$WorkDir/$AppName/$AppExec"
chmod 777 "$WorkDir/$AppName/$AppExec"
fi
fi

# Timestamp-back executable to defeat checks
touch -r "$AppPath/$AppName/$AppExec" "$WorkDir/$AppName/$AppExec"

# Test MinimumOS version for SignerIdentity needs
echo -n "${Meter63}MinOS is '$MinOS': "
if [ ${MinOS:0:1} -gt 2 ]; then
echo "${Meter64}no SignerIdentity needed"
else
if [ $PCMsigner = "YES" ]; then
echo "${Meter64}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 Info.plist to defeat checks
touch -r "$AppPath/$AppName/Info.plist" "$WorkDir/$AppName/Info.plist"
else
echo "${Meter64}but no SignerIdentity !"
fi
fi

# Adding credits file
if [ ! $CrackerName = "Anonymous" ]; then
echo "${Meter65}Adding Credits"
echo "Cracked by $CrackerName" >> "$WorkDir/$AppName/$CreditFile"
fi

# 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 "${Meter68}Copying Artwork "
if [ -e "$AppPath/iTunesArtwork" ]; then
cp -a "$AppPath/iTunesArtwork" "$WorkDir/"
# Timestamp ArtWork to protect cracker
touch -r "$AppPath/$AppName/Info.plist" "$WorkDir/iTunesArtwork"
else
echo "${Meter68}failed !"
fi

if [ $PCMmetadata = "YES" ]; then
echo "${Meter69}and faking MetaData"
else
echo "${Meter69}and no MetaData"
fi

# Faking MetaData
cp "$AppPath/iTunesMetadata.plist" "$WorkDir/iTunesMetadataSource.plist"
plutil -xml "$WorkDir/iTunesMetadataSource.plist" 2>&1> /dev/null
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" > "$WorkDir/iTunesMetadata.plist"
echo "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" >> "$WorkDir/iTunesMetadata.plist"
echo "<plist version=\"1.0\">" >> "$WorkDir/iTunesMetadata.plist"
echo "<dict>" >> "$WorkDir/iTunesMetadata.plist"
echo -e "\t<key>appleId</key>" >> "$WorkDir/iTunesMetadata.plist"
echo -e "\t<string>ChatMauve@apple.com</string>" >> "$WorkDir/iTunesMetadata.plist"
echo -e "\t<key>purchaseDate</key>" >> "$WorkDir/iTunesMetadata.plist"
echo -e "\t<date>2010-08-08T08:08:08Z</date>" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 "<key>artistId</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 "<key>artistName</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 "<key>buy-only</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 "<key>buyParams</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 "<key>copyright</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 "<key>drmVersionNumber</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 "<key>fileExtension</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 -m1 "<key>genre</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 -m1 "<key>genreId</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 "<key>itemId</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 "<key>itemName</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 "<key>kind</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 "<key>playlistArtistName</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 "<key>playlistName</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 "<key>price</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 "<key>priceDisplay</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A99 "<key>rating</key>" "$WorkDir/iTunesMetadataSource.plist" | grep -m1 -B99 "</dict>" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 "<key>releaseDate</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 "<key>s</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 "<key>softwareIcon57x57URL</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 "<key>softwareIconNeedsShine</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A99 "<key>softwareSupportedDeviceIds</key>" "$WorkDir/iTunesMetadataSource.plist" | grep -m1 -B99 "</array>" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 "<key>softwareVersionBundleId</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 "<key>softwareVersionExternalIdentifier</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A99 "<key>softwareVersionExternalIdentifiers</key>" "$WorkDir/iTunesMetadataSource.plist" | grep -m1 -B99 "</array>" >> "$WorkDir/iTunesMetadata.plist"
grep -A99 "<key>subgenres</key>" "$WorkDir/iTunesMetadataSource.plist" | grep -m1 -B99 "</array>" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 "<key>vendorId</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
grep -A1 "<key>versionRestrictions</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"
echo "</dict>" >> "$WorkDir/iTunesMetadata.plist"
echo -e "</plist>\n" >> "$WorkDir/iTunesMetadata.plist"
# Timestamp Metadata to protect cracker
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 "${Meter70}Warning: iTunesMetadata format changed ?"
#BEGIN DEBUG
#echo "( $NewFields )"
#cat /tmp/diff.txt
#END DEBUG
fi
fi
rm -f /tmp/diff.txt

# Don't want MetaData ?
if [ ! $PCMmetadata = "YES" ]; then
mv "$WorkDir/iTunesMetadata.plist" "$WorkDir/iTunesMetadata.backup.plist"
fi

# Size of first data to compress
FirstSize=$(du -k -s "$WorkDir" | cut -f 1)
echo "${Meter75}Compressing the .ipa (step 1) [$FirstSize kB]"


# Removing unwanted characters, adding AppVersion and MinOsVersion, adding CrackerName
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

# Size of .ipa after step 1
ZipSize=$(stat -c%s "$IPAName")

# Building .ipa (step 2)
# Using a SymbolicLink pointing to App Directory
ln -s "$AppPath/" "$WorkDir/Payload"

# Size of other data to compress
SecondSize=$(du -k -s "$AppPath" | cut -f 1)
echo "${Meter80}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

# It failed because disk is full (zip size after part2 is still the same)
if [ $(stat -c%s "$IPAName") -eq $ZipSize ]; then
echo "Incomplete .ipa ! Disk full ?"
rm -f "$IPAName"
rm -fr "$WorkDir"
exit 1
fi

rm "$WorkDir/Payload"
cd - 2>&1> /dev/null

echo "${Meter99}Removing temporary files"
rm -rf "$WorkDir"

ZipSize=$(du -k -s "$IPAName" | cut -f 1)
echo "${Meter100}Created cracked .ipa at \"$IPAName\" [$ZipSize kB]"


# The truth is I never left you. I kept my promise.

# Thanks and kisses.

关键步骤解说(以

crack arm6+arm7 on arm7 devices的完整过程为例


第一步:提取出mach-o文件中armv6部分
lipo -thin armv6 "$WorkDir/$AppName/$AppExec" -output "$WorkDir/$AppName/IWantYourSix"

第二步:提取出mach-o文件中armv7部分
方法一:交换armv6和armv7 头部
echo -ne "\x09" | dd bs=1 seek=15 conv=notrunc of="$WorkDir/$AppName/$AppExec"
将第16个字节处的06变成09
echo -ne "\x06" | dd bs=1 seek=35 conv=notrunc of="$WorkDir/$AppName/$AppExec"
将第36个字节处的09变成06
如下图所示,右边为原始mach-o文件,经过上面两步,我们发现第16个字节处由06变成09,第36个字节处由09变成06
PoedCrackMod源码 - danqingdani - 碳基体
 提取mach-o中armv7部分
lipo -thin armv6 "$WorkDir/$AppName/$AppExec" -output "$WorkDir/$AppName/SevenTrumpets"

方法二:
 lipo -thin armv7 "$WorkDir/$AppName/$AppExec" -output "$WorkDir/$AppName/SevenTrumpets"

第三步:获得cryptid,cryptsize,cryptoffset等重要数值

    CryptID=$(otool -l "$WorkDir/$AppName/$AppExecCur" | grep cryptid | awk '{print $2}')

    if [ $CryptID != "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

cryptid为加密状态,0表示未加密,1表示解密;
cryptoffset未加密部分的偏移量,单位bytes
cryptsize加密段的大小,单位bytes

第四步:将armv6部分
IWantYourSix
的cryptID修改为0
方法一:
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"

方法二:
也可以直接使用十六进制编辑器例如mac上的0xED打开mach-O文件,搜索2100000014000000,一般会找到2处,如果从21开始第17个字节处为01,则将其改成00

第五步:使用gdb将解密部分导出

方法一:

  # Creating GDB script

    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


    # Cracking the previously swapped fat binary in WorkDir

#注意:要在arm 7的设备上运行arm 6部分,需要swap header处理后的mach-o文件

(If first part (arm6) of a fat binary and running an arm7 iDevice, swap trick)

foo=$(gdb -q -e "$WorkDir/$AppName/$AppExec" -x $WorkDir/batch.gdb -batch > /dev/null 2>&1> /dev/null)

方法二:
danimato-iPod:/private/var/mobile/Applications/CF3BBE01-40FB-48D2-BF6C-FF6D04916E6A/name.app root# gdb -q -e AppName 
Reading symbols for shared libraries .. done
(gdb) set sharedlibrary load-rules .* .* none    
(gdb) set inferior-auto-start-dyld off
(gdb) set sharedlibrary preload-libraries off
(gdb) rb doModInitFunctions                
Breakpoint 1 at 0x2fe0cece
<function, no debug info> __dyld__ZN16ImageLoaderMachO18doModInitFunctionsERKN11ImageLoader11LinkContextE;
(gdb) r
Starting program: /private/var/mobile/Applications/CF3BBE01-40FB-48D2-BF6C-FF6D04916E6A/Mole's World.app/Mole's World 

Breakpoint 1, 0x2fe0cece in __dyld__ZN16ImageLoaderMachO18doModInitFunctionsERKN11ImageLoader11LinkContextE ()

(gdb) x /10i 0x3390   查看是否解密成功 (0x3390为程序加载地址,可以通过otool工具查看加载地址)
0x3af8:  00 00 9d e5                   ldr r0, [sp]
0x3afc:  04 10 8d e2                   add r1, sp, #4 ; 0x4
0x3b00:  01 40 80 e2                   add r4, r0, #1 ; 0x1
0x3b04:  04 21 81 e0                   add r2, r1, r4, lsl #2
0x3b08:  07 d0 cd e3                   bic sp, sp, #7 ; 0x7
0x3b0c:  02 30 a0 e1                   mov r3, r2
0x3b10:  04 40 93 e4                   ldr r4, [r3], #4
0x3b14:  00 00 54 e3                   cmp r4, #0 ; 0x0
0x3b18:  fc ff ff 1a                   bne 0x3b10
0x3b1c:  18 c0 9f e5                   ldr r12, [pc, #24] ; 0x3b3c

(gdb) dump memory AppNamearmv6.bin 0x2000 0x2000+cryptsize 导出解密部分


加载地址(__text __TEXT 专门存放executable machine code
 DANI-LEE-2:name.app$ otool -l appname | grep -i "sectname __text" -A 11 -B 1
Section
  sectname __text
   segname __TEXT
      addr 0x00003390
      size 0x00438b24
    offset 11000
     align 2^3 (8)
    reloff 0
    nreloc 0
     flags 0x80000400
 reserved1 0
 reserved2 0
Section

注意:实际上只有这一步必须在iOS设备上运行,gdb调试时,由于设备可用内存小常常导致中断,所以调试时,最好关闭其他程序

第六步:用第四步中的解密部分替换
IWantYourSix
加密部分

foo=$(dd seek=1 count=1 obs=4096 ibs=$DumpSize conv=notrunc if="$WorkDir/dump.bin" of="$WorkDir/$AppName/$AppExecCur" 2>&1> /dev/null)

第七步:lamerpatcher处理(不一定管用,主要是为了绕过常规的破解检测,常规破解检测一般根据破解前后文件系统的变化作为特征来定位,lamperpatcher做的就是将这些特征字符串替换掉(不是必须的步骤)

if [ $PCMlamerpatcher = "YES" ]; then
# MinOs check and Signer check: Lite or Full ?
if [ ${MinOS:0:1} -gt 2 -o $PCMsigner != "YES" ]; then
echo -n "${Meter58}Trying LamerPatcherLite... "
sed --in-place=.BCK \
-e 's=/Cydia\.app=/Czdjb\.bpp=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' \
-e 's=http://ads2\.=http://bds2/=g' \
-e 's=adwhirl\.com=bdwhjrl\.cpm=g' \
-e 's=vdopia\.com=vdppjb\.cpm=g' \
"$WorkDir/$AppName/$AppExecCur"

# "/Applications/Icy\.app"
# "/Applications/SBSettings\.app"
# "/Library/MobileSubstrate"
else
echo -n "${Meter58}Trying LamerPatcherFull... "
sed --in-place=.BCK \
-e 's=SignerIdentity=SjgnfrJdfntjtz=g' \
-e 's=Jdfnuiuy=Kdgnujuz=g' \
-e 's=S\d0\d0\d0h\d0\d0\d0g\d0\d0\d0f\d0\d0\d0e=S\d0\d0\d0i\d0\d0\d0g\d0\d0\d0f\d0\d0\d0f=g' \
-e 's=S\d0\d0\d0i\d0\d0\d0g\d0\d0\d0n\d0\d0\d0e\d0\d0\d0r=S\d0\d0\d0j\d0\d0\d0g\d0\d0\d0n\d0\d0\d0f\d0\d0\d0r=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=S\d0\d0\d0g\d0\d0\d0n\d0\d0\d0e\d0\d0\d0r=S\d0\d0\d0h\d0\d0\d0o\d0\d0\d0f\d0\d0\d0r=g' \
-e 's=/Cydia\.app=/Czdjb\.bpp=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' \
-e 's=http://ads2\.=http://bds2/=g' \
-e 's=adwhirl\.com=bdwhjrl\.cpm=g' \
-e 's=vdopia\.com=vdppjb\.cpm=g' \
"$WorkDir/$AppName/$AppExecCur"

# "/Applications/Icy\.app"
# "/Applications/SBSettings\.app"
# "/Library/MobileSubstrate"
# "%si %sg %sn %se %sr %sI %sd %st %sy"
# "Sig nerId%@%@ ent ity "
# "Si gne rIde ntity"
fi

cmp --silent "$WorkDir/$AppName/$AppExecCur.BCK" "$WorkDir/$AppName/$AppExecCur"
if [ "$?" != "0" ]; then
echo "${Meter59}patched something"
Patched="$Patched patched"
if [ $PCMkeepunpatched != "YES" ]; then
rm "$WorkDir/$AppName/$AppExecCur.BCK"
fi
else
echo "${Meter59}found nothing"
rm "$WorkDir/$AppName/$AppExecCur.BCK"
fi

fi

第八步:签名IWantYourSix

 foo=$(ldid -s "$WorkDir/$AppName/$AppExecCur" 2>&1> /dev/null

第九步:armv7部分SevenTrumpets的cryptID修改为0(同第四步)
第十步:使用gdb将解密部分导出(同第五步)

   # Cracking genuine executable in AppPath

#注意:对于fat binary,arm 7的设备上是默认按arm 7运行,所以需要使用没有经过swap header处理的原始mach-o文件
foo=$(gdb -q -e "$AppPath/$AppName/$AppExec" -x $WorkDir/batch.gdb -batch > /dev/null 2>&1> /dev/null)

第十一步:用第九步中的解密部分替换SevenTrumpets加密部分(同第六步)
第十二步:使用lamerpatcher处理(不是必须的步骤)(同第七步)
第十三步:签名SevenTrumpets(同第八步)
第十四步:合并IWantYourSix和SevenTrumpets
if [ $LipoFail ]; then
rm -f "$WorkDir/$AppName/$AppExec"
echo "${Meter61}---"
if [ -e "$WorkDir/$AppName/SevenTrumpets" ]; then
echo "${Meter62}Combining both parts into a fat binary"
lipo -create "$WorkDir/$AppName/IWantYourSix" "$WorkDir/$AppName/SevenTrumpets" -output "$WorkDir/$AppName/$AppExec"
chmod 777 "$WorkDir/$AppName/$AppExec"

if [ $PCMkeepunpatched != "YES" ]; then
rm "$WorkDir/$AppName/IWantYourSix"
rm "$WorkDir/$AppName/SevenTrumpets"
fi
else
mv "$WorkDir/$AppName/IWantYourSix" "$WorkDir/$AppName/$AppExec"
chmod 777 "$WorkDir/$AppName/$AppExec"
fi
fi

第十五步:伪造可执行文件的时间戳,以应付破解检测(不是必须的步骤)
touch -r "$AppPath/$AppName/$AppExec" "$WorkDir/$AppName/$AppExec"
第十六步:根据MinOS版本(plutil -key MinimumOSVersion "Info.plist"),伪造SignerIdentity,目前主流是3.0版本,不需要伪造(不是必须的步骤)
echo -n "${Meter63}MinOS is '$MinOS': "
if [ ${MinOS:0:1} -gt 2 ]; then
echo "${Meter64}no SignerIdentity needed"
else
if [ $PCMsigner = "YES" ]; then
echo "${Meter64}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 Info.plist to defeat checks
touch -r "$AppPath/$AppName/Info.plist" "$WorkDir/$AppName/Info.plist"
else
echo "${Meter64}but no SignerIdentity !"
fi
fi
第十七步:伪造iTunesMetadata.plist(不是必须的步骤)

cp "$AppPath/iTunesMetadata.plist" "$WorkDir/iTunesMetadataSource.plist"

plutil -xml "$WorkDir/iTunesMetadataSource.plist" 2>&1> /dev/null

echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" > "$WorkDir/iTunesMetadata.plist"

echo "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" >> "$WorkDir/iTunesMetadata.plist"

echo "<plist version=\"1.0\">" >> "$WorkDir/iTunesMetadata.plist"

echo "<dict>" >> "$WorkDir/iTunesMetadata.plist"

echo -e "\t<key>appleId</key>" >> "$WorkDir/iTunesMetadata.plist"

echo -e "\t<string>ChatMauve@apple.com</string>" >> "$WorkDir/iTunesMetadata.plist"

echo -e "\t<key>purchaseDate</key>" >> "$WorkDir/iTunesMetadata.plist"

echo -e "\t<date>2010-08-08T08:08:08Z</date>" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 "<key>artistId</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 "<key>artistName</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 "<key>buy-only</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 "<key>buyParams</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 "<key>copyright</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 "<key>drmVersionNumber</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 "<key>fileExtension</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 -m1 "<key>genre</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 -m1 "<key>genreId</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 "<key>itemId</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 "<key>itemName</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 "<key>kind</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 "<key>playlistArtistName</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 "<key>playlistName</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 "<key>price</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 "<key>priceDisplay</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A99 "<key>rating</key>" "$WorkDir/iTunesMetadataSource.plist" | grep -m1 -B99 "</dict>" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 "<key>releaseDate</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 "<key>s</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 "<key>softwareIcon57x57URL</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 "<key>softwareIconNeedsShine</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A99 "<key>softwareSupportedDeviceIds</key>" "$WorkDir/iTunesMetadataSource.plist" | grep -m1 -B99 "</array>" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 "<key>softwareVersionBundleId</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 "<key>softwareVersionExternalIdentifier</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A99 "<key>softwareVersionExternalIdentifiers</key>" "$WorkDir/iTunesMetadataSource.plist" | grep -m1 -B99 "</array>" >> "$WorkDir/iTunesMetadata.plist"

grep -A99 "<key>subgenres</key>" "$WorkDir/iTunesMetadataSource.plist" | grep -m1 -B99 "</array>" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 "<key>vendorId</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

grep -A1 "<key>versionRestrictions</key>" "$WorkDir/iTunesMetadataSource.plist" >> "$WorkDir/iTunesMetadata.plist"

echo "</dict>" >> "$WorkDir/iTunesMetadata.plist"

echo -e "</plist>\n" >> "$WorkDir/iTunesMetadata.plist"

# Timestamp Metadata to protect cracker

touch -r "$AppPath/$AppName/Info.plist" "$WorkDir/iTunesMetadata.plist"

第十八步:打包成ipa安装包

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



整个过程,除去前期检测必要工具是否存在(例如ldid,plutil,otool),伪造特征文件,可以总结为以下几步:

第一步. 将fat binary切分为armv6,armv7部分(采用swap header技巧)
第二步:获得cryptid,cryptsize,cryptsize
第三步. 将armv6部分的cryptid修改为0,gdb导出对应的armv6解密部分(对经过swap header处理的Mach-O文件进行操作,使得在arm 7设备上,强制运行arm 6部分),替换掉armv6加密部分,签名
第四步. 将armv7部分的cryptid修改为0,gdb导出对应的armv7解密部分(对原Mach-O文件进行操作),替换掉armv7加密部分,签名
第五步.合并解密过的armv6,armv7
第六步.打包成ipa安装包

注明:第三步和第四步是破解的关键,破解是否成功的关键在于导出的解密部分是否正确完整。
由于binary fat格式的mach-o文件在arm 7设备上默认运行arm 7对应代码,当需要导出arm 6对应的解密部分时,要先经过swap header处理,使其在arm 7 设备上按arm 6运行。
  评论这张
 
阅读(3604)| 评论(0)
推荐

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017