iOS無限金幣安裝包實現
在助手大行其道的的同時,另外一個比較火爆的的資源那就是帶各種破解存檔的遊戲的需求。
在itunes12之前的版本,如果要如果app開放了文件共享許可權,那麼可以透過讀寫共享文件的方法來恢復存檔。
但是該方法也僅限於舊版本的itunes,最新的itunes相關已經被徹底的停用了,可以透過愛思助手來檢視共享檔案。
不過使用該方法只能訪問Document目錄,如果要訪問Library目錄會提示沒有相關的許可權。
如果要開放app的檔案共享許可權,需要修改Info。plist將如下屬性設定為yes:UIFileSharingEnabled
不過大多數遊戲的存檔並不是僅僅存在於Document目錄下,那麼對於這類遊戲如果要複製遊戲存檔這種方法就行不通了。
不過要解決這個問題可以使用dylib注入的方式。簡單說來只需要如下幾步:
將遊戲的存檔壓縮到ipa檔案中,如果要減小ipa的體積可以壓縮,如果要提高效率可以直接將目錄下所有的檔案壓縮到ipa目錄下
編寫一個支援將存檔檔案恢復到遊戲的Document、Library、tmp目錄下的dylib,將dylib注入到指定的ipa中
對ipa進行簽名,簽名之後的ipa安裝到裝置上即可,在遊戲首次執行的時候會直接將所有的檔案解壓縮並且恢復到遊戲對應的目錄下。
經過如下幾部之後,就可以實現遊戲存檔或者金幣的無限制恢復了,並且如果要做的更徹底一些,可以在dylib中整合多個存檔,編寫ui介面選擇要恢復的存檔檔案,如果要做的更深入可以透過oss等網路儲存,直接在儲存上上傳存檔,下載並且恢復指定的存檔檔案。
dylib的關鍵程式碼相對來說也比較簡單:
// iOS 存檔恢復工具
// hzm。m
// hzm
//
http://www。
h4ck。org。cn
// Created by obaby on 15/9/22。
// Copyright (c) 2015年 obaby@mars。 All rights reserved。
//
#import “hzm。h”
#import “ZipArchive。h”
@implementation hzm
-(id)init
{
if ((self = [super init]))
{
}
return self;
}
//uncompress ipa file
void UnCompressiPa (NSString * cFileName ,NSString *output);
void UnCompressiPa (NSString * cFileName ,NSString *output)
{
ZipArchive * za = [[ZipArchive alloc]init];
if ([za UnzipOpenFile:cFileName]) {
if ([za UnzipFileTo:output overWrite:YES] != NO) {
//std::cout << ipafileName。UTF8String <<“ have been unziped success\n”;
NSLog(@“%@ have benn unzipped success !\n”,cFileName);
}
[za UnzipCloseFile];
}
//[za release];
}
//檢測檔案目錄是否存在
BOOL isFileExists(NSString * filename)
{
NSFileManager * filemanager;
filemanager = [[NSFileManager alloc]init];
if (![filemanager fileExistsAtPath:filename]) {
return NO;
}
return YES;
}
static void __attribute__((constructor)) initialize(void)
{
NSLog(@“======================= lib注入成功 ========================”);
//無線金幣
NSString *outputdir = [NSHomeDirectory() stringByAppendingString:@“/tmp”] ;
if (!isFileExists(outputdir)) {
[[NSFileManager defaultManager] createDirectoryAtPath:outputdir withIntermediateDirectories:YES attributes:nil error:nil];
NSLog(@“[*]無限金幣:Output dir:%@ created!”,outputdir);
}
NSString *isFirstRunSigFile =[NSHomeDirectory() stringByAppendingString:@“/Documents/isFirst”] ;
if (isFileExists(isFirstRunSigFile)) {
NSLog(@“[*]無限金幣:not first time run nothing do!”);
}else{
NSString *dataFile = [[NSBundle mainBundle] pathForResource:@“coin” ofType:@“zip”];
UnCompressiPa(dataFile, outputdir);
NSLog(@“[*]無限金幣:First time run,file uncompressed and installed”);
NSString *sigeFiledata = @“NO”;
[sigeFiledata writeToFile:isFirstRunSigFile atomically:YES encoding:NSUTF8StringEncoding error:nil];
NSLog(@“[*]無限金幣:Sig file created!”);
NSLog(@“copy all files to documents”);
NSString *dcPath = [outputdir stringByAppendingString:@“/Container/Documents/”];
NSString *dcDest = [NSHomeDirectory() stringByAppendingString:@“/Documents/”];
NSDirectoryEnumerator *dcEnum = [[NSFileManager defaultManager] enumeratorAtPath:dcPath];
NSString *tmpPath ;
sleep(2);
//NSLog(@“%@”,dcEnum);
//[NSTemporaryDirectory() stringByAppendingString:tmpPath]
NSError *err;
while ((tmpPath = [dcEnum nextObject]) != nil) {
NSLog(@“%@”,[dcPath stringByAppendingString:tmpPath]);
[[NSFileManager defaultManager] removeItemAtPath:[dcDest stringByAppendingString:tmpPath] error:nil];
BOOL bStatus = [[NSFileManager defaultManager] copyItemAtPath:[dcPath stringByAppendingString:tmpPath] toPath:[dcDest stringByAppendingString:tmpPath]error:&err];
if (bStatus == NO) {
NSLog(@“%@ copy failed!”,[dcDest stringByAppendingString:tmpPath]);
}
}
NSString *lbPath = [outputdir stringByAppendingString:@“/Container/Library/”];
NSString *lbDest = [NSHomeDirectory() stringByAppendingString:@“/Library/”];
NSDirectoryEnumerator *lbEnum = [[ NSFileManager defaultManager] enumeratorAtPath:lbPath];
while ((tmpPath = [lbEnum nextObject] )!= nil) {
NSLog(@“%@”,[lbPath stringByAppendingString:tmpPath]);
[[NSFileManager defaultManager] removeItemAtPath:[lbDest stringByAppendingString:tmpPath] error:nil];
BOOL bStatus =[[NSFileManager defaultManager] copyItemAtPath:[lbPath stringByAppendingString:tmpPath] toPath:[lbDest stringByAppendingString:tmpPath]error:&err];
if (bStatus == NO) {
NSLog(@“%@ copy failed!”,[lbDest stringByAppendingString:tmpPath]);
}
}
NSString *tmPath = [outputdir stringByAppendingString:@“/Container/tmp”];
NSString *tmDest = [NSHomeDirectory() stringByAppendingString:@“/tmp”];
NSDirectoryEnumerator *tmEnum = [[NSFileManager defaultManager] enumeratorAtPath:tmpPath];
while ((tmpPath = [tmEnum nextObject] )!= nil) {
NSLog(@“%@”,[tmPath stringByAppendingString:tmpPath]);
[[NSFileManager defaultManager] removeItemAtPath:[tmDest stringByAppendingString:tmpPath] error:nil];
BOOL bStatus = [[NSFileManager defaultManager] copyItemAtPath:[tmPath stringByAppendingString:tmpPath] toPath:[tmDest stringByAppendingString:tmpPath] error:&err];
if (bStatus == NO) {
NSLog(@“%@ copy failed!”,[tmDest stringByAppendingString:tmpPath]);
}
}
}
//sleep(5);
NSLog(@“======================= All done ========================”);
}
@end
測試app效果,只有32位架構,無法在最新系統安裝,可以找個舊裝置測試
程式碼:
https://
github。com/obaby/ios_co
de_sign/tree/master/source_codes/coin_lib
原創文章,轉載請註明:
轉載自
obaby@mars
本文標題:
《iOS無限金幣安裝包實現》
本文連結地址:
http://
h4ck。org。cn/2020/11/ios
%e6%97%a0%e9%99%90%e9%87%91%e5%b8%81%e5%ae%89%e8%a3%85%e5%8c%85%e5%ae%9e%e7%8e%b0/