fdsa
This commit is contained in:
parent
16dbe037b9
commit
9086425c1a
@ -2,7 +2,7 @@
|
|||||||
<Workspace
|
<Workspace
|
||||||
version = "1.0">
|
version = "1.0">
|
||||||
<FileRef
|
<FileRef
|
||||||
location = "group:HD wallpaper.xcodeproj">
|
location = "group:/Users/aaa/Documents/IOS/BZ/723/HDwallpaper/TallPaper.xcodeproj">
|
||||||
</FileRef>
|
</FileRef>
|
||||||
<FileRef
|
<FileRef
|
||||||
location = "group:Pods/Pods.xcodeproj">
|
location = "group:Pods/Pods.xcodeproj">
|
||||||
|
|||||||
Binary file not shown.
@ -16,7 +16,7 @@
|
|||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation AWM_AllWallpaperViewController
|
@implementation AWM_AllWallpaperViewController
|
||||||
- (void)backItemEvent{
|
- (void)backItemEventLove:(id)sender{
|
||||||
__weak typeof(self) weakSelf = self;
|
__weak typeof(self) weakSelf = self;
|
||||||
[[AWM_WallPapaerADManager shareInstance] showIntersitialAD_Back:^(NSInteger actionType) {
|
[[AWM_WallPapaerADManager shareInstance] showIntersitialAD_Back:^(NSInteger actionType) {
|
||||||
[weakSelf.navigationController popViewControllerAnimated:YES];
|
[weakSelf.navigationController popViewControllerAnimated:YES];
|
||||||
@ -46,7 +46,7 @@
|
|||||||
NSString *backitem = KLS(@"back", @"A friendly greeting");
|
NSString *backitem = KLS(@"back", @"A friendly greeting");
|
||||||
UIButton *backItem = [[UIButton alloc] initWithFrame:CGRectMake(20-1,0-1,74-1,44-1)];
|
UIButton *backItem = [[UIButton alloc] initWithFrame:CGRectMake(20-1,0-1,74-1,44-1)];
|
||||||
[backItem setImage:[UIImage imageNamed:backitem] forState:UIControlStateNormal];
|
[backItem setImage:[UIImage imageNamed:backitem] forState:UIControlStateNormal];
|
||||||
[backItem addTarget:self action:@selector(backItemEvent) forControlEvents:UIControlEventTouchUpInside];
|
[backItem addTarget:self action:@selector(backItemEventLove:) forControlEvents:UIControlEventTouchUpInside];
|
||||||
self.backItem = backItem;
|
self.backItem = backItem;
|
||||||
|
|
||||||
self.data = @[@[@"fj1",@"fj2",@"fj3",@"fj4",@"fj5",@"fj6",@"fj7",@"fj8",@"fj9",@"fj10"],@[@"mv1",@"mv2",@"mv3",@"mv4",@"mv5",@"mv6",@"mv7",@"mv8",@"mv9",@"mv10"],@[@"kt1",@"kt2",@"kt3",@"kt4",@"kt5",@"kt6",@"kt7",@"kt8",@"kt9"],@[@"rw1",@"rw2",@"rw3",@"rw4",@"rw5",@"rw6",@"rw7",@"rw8",@"rw9",@"rw10",@"rw11",@"rw12",@"rw13",@"rw14",@"rw15",@"rw16",@"rw17",@"rw18",@"rw19"]];
|
self.data = @[@[@"fj1",@"fj2",@"fj3",@"fj4",@"fj5",@"fj6",@"fj7",@"fj8",@"fj9",@"fj10"],@[@"mv1",@"mv2",@"mv3",@"mv4",@"mv5",@"mv6",@"mv7",@"mv8",@"mv9",@"mv10"],@[@"kt1",@"kt2",@"kt3",@"kt4",@"kt5",@"kt6",@"kt7",@"kt8",@"kt9"],@[@"rw1",@"rw2",@"rw3",@"rw4",@"rw5",@"rw6",@"rw7",@"rw8",@"rw9",@"rw10",@"rw11",@"rw12",@"rw13",@"rw14",@"rw15",@"rw16",@"rw17",@"rw18",@"rw19"]];
|
||||||
@ -87,7 +87,7 @@
|
|||||||
[btn setImage:[UIImage imageNamed:self.data[indexPath.section][i]] forState:UIControlStateNormal];
|
[btn setImage:[UIImage imageNamed:self.data[indexPath.section][i]] forState:UIControlStateNormal];
|
||||||
btn.layer.cornerRadius = 5;
|
btn.layer.cornerRadius = 5;
|
||||||
btn.layer.masksToBounds = YES;
|
btn.layer.masksToBounds = YES;
|
||||||
[btn addTarget:self action:@selector(headerEvent:) forControlEvents:UIControlEventTouchUpInside];
|
[btn addTarget:self action:@selector(headerEventLove:) forControlEvents:UIControlEventTouchUpInside];
|
||||||
btn.tag = indexPath.section;
|
btn.tag = indexPath.section;
|
||||||
[cell.contentView addSubview:btn];
|
[cell.contentView addSubview:btn];
|
||||||
}
|
}
|
||||||
@ -129,7 +129,7 @@
|
|||||||
wpdetail.data = self.data[indexPath.section];
|
wpdetail.data = self.data[indexPath.section];
|
||||||
[self.navigationController pushViewController:wpdetail animated:YES];
|
[self.navigationController pushViewController:wpdetail animated:YES];
|
||||||
}
|
}
|
||||||
- (void)headerEvent:(UIButton *)btn{
|
- (void)headerEventLove:(UIButton *)btn{
|
||||||
AWM_DetailViewController *wpdetail = [[AWM_DetailViewController alloc] init];
|
AWM_DetailViewController *wpdetail = [[AWM_DetailViewController alloc] init];
|
||||||
wpdetail.data = self.data[btn.tag];
|
wpdetail.data = self.data[btn.tag];
|
||||||
[self.navigationController pushViewController:wpdetail animated:YES];
|
[self.navigationController pushViewController:wpdetail animated:YES];
|
||||||
|
|||||||
@ -16,14 +16,14 @@
|
|||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation AWM_DetailViewController
|
@implementation AWM_DetailViewController
|
||||||
- (void)backItemEvent{
|
- (void)backItemEventLove:(id)sender{
|
||||||
__weak typeof(self) weakSelf = self;
|
__weak typeof(self) weakSelf = self;
|
||||||
[[AWM_WallPapaerADManager shareInstance] showIntersitialAD_Back:^(NSInteger actionType) {
|
[[AWM_WallPapaerADManager shareInstance] showIntersitialAD_Back:^(NSInteger actionType) {
|
||||||
[weakSelf.navigationController popViewControllerAnimated:YES];
|
[weakSelf.navigationController popViewControllerAnimated:YES];
|
||||||
}];
|
}];
|
||||||
// [self.navigationController popViewControllerAnimated:YES];
|
// [self.navigationController popViewControllerAnimated:YES];
|
||||||
}
|
}
|
||||||
- (void)saveItemEvent{
|
- (void)saveItemEventLove:(id)sender{
|
||||||
UIImageWriteToSavedPhotosAlbum([UIImage imageNamed:self.data[self.index]], self, @selector(imageSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:), nil);
|
UIImageWriteToSavedPhotosAlbum([UIImage imageNamed:self.data[self.index]], self, @selector(imageSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:), nil);
|
||||||
AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate];
|
AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate];
|
||||||
[app.saveImages addObject:self.data[self.index]];
|
[app.saveImages addObject:self.data[self.index]];
|
||||||
@ -56,13 +56,13 @@
|
|||||||
NSString *backitem = KLS(@"back", @"A friendly greeting");
|
NSString *backitem = KLS(@"back", @"A friendly greeting");
|
||||||
UIButton *backItem = [[UIButton alloc] initWithFrame:CGRectMake(20-1,0-1,74-1,44-1)];
|
UIButton *backItem = [[UIButton alloc] initWithFrame:CGRectMake(20-1,0-1,74-1,44-1)];
|
||||||
[backItem setImage:[UIImage imageNamed:backitem] forState:UIControlStateNormal];
|
[backItem setImage:[UIImage imageNamed:backitem] forState:UIControlStateNormal];
|
||||||
[backItem addTarget:self action:@selector(backItemEvent) forControlEvents:UIControlEventTouchUpInside];
|
[backItem addTarget:self action:@selector(backItemEventLove:) forControlEvents:UIControlEventTouchUpInside];
|
||||||
self.backItem = backItem;
|
self.backItem = backItem;
|
||||||
|
|
||||||
UIButton *navImage = [[UIButton alloc] initWithFrame:CGRectMake(WPScreen_w-100-1,2-1,74-1,40-1)];
|
UIButton *navImage = [[UIButton alloc] initWithFrame:CGRectMake(WPScreen_w-100-1,2-1,74-1,40-1)];
|
||||||
NSString *save = KLS(@"save", @"A friendly greeting");
|
NSString *save = KLS(@"save", @"A friendly greeting");
|
||||||
[navImage setImage:[UIImage imageNamed:save] forState:UIControlStateNormal];
|
[navImage setImage:[UIImage imageNamed:save] forState:UIControlStateNormal];
|
||||||
[navImage addTarget:self action:@selector(saveItemEvent) forControlEvents:UIControlEventTouchUpInside];
|
[navImage addTarget:self action:@selector(saveItemEventLove:) forControlEvents:UIControlEventTouchUpInside];
|
||||||
self.navImage = navImage;
|
self.navImage = navImage;
|
||||||
|
|
||||||
|
|
||||||
@ -86,17 +86,17 @@
|
|||||||
UIButton *shangItem = [[UIButton alloc] initWithFrame:CGRectMake((WPScreen_w-240)/3-1,WPScreen_h-170-1,120-1,50-1)];
|
UIButton *shangItem = [[UIButton alloc] initWithFrame:CGRectMake((WPScreen_w-240)/3-1,WPScreen_h-170-1,120-1,50-1)];
|
||||||
NSString *shang = KLS(@"shang", @"A friendly greeting");
|
NSString *shang = KLS(@"shang", @"A friendly greeting");
|
||||||
[shangItem setImage:[UIImage imageNamed:shang] forState:UIControlStateNormal];
|
[shangItem setImage:[UIImage imageNamed:shang] forState:UIControlStateNormal];
|
||||||
[shangItem addTarget:self action:@selector(shangItemEvent) forControlEvents:UIControlEventTouchUpInside];
|
[shangItem addTarget:self action:@selector(shangItemEventLove:) forControlEvents:UIControlEventTouchUpInside];
|
||||||
[self.view addSubview:shangItem];
|
[self.view addSubview:shangItem];
|
||||||
|
|
||||||
UIButton *xiaItem = [[UIButton alloc] initWithFrame:CGRectMake((WPScreen_w-240)/3*2+120-1-1,WPScreen_h-170-1-1,120-1-1,50-1-1)];
|
UIButton *xiaItem = [[UIButton alloc] initWithFrame:CGRectMake((WPScreen_w-240)/3*2+120-1-1,WPScreen_h-170-1-1,120-1-1,50-1-1)];
|
||||||
NSString *xia = KLS(@"xia", @"A friendly greeting");
|
NSString *xia = KLS(@"xia", @"A friendly greeting");
|
||||||
[xiaItem setImage:[UIImage imageNamed:xia] forState:UIControlStateNormal];
|
[xiaItem setImage:[UIImage imageNamed:xia] forState:UIControlStateNormal];
|
||||||
[xiaItem addTarget:self action:@selector(xiaItemEvent) forControlEvents:UIControlEventTouchUpInside];
|
[xiaItem addTarget:self action:@selector(xiaItemEventLove:) forControlEvents:UIControlEventTouchUpInside];
|
||||||
[self.view addSubview:xiaItem];
|
[self.view addSubview:xiaItem];
|
||||||
|
|
||||||
}
|
}
|
||||||
- (void)shangItemEvent{
|
- (void)shangItemEventLove:(id)sender{
|
||||||
if (self.index == 0) {
|
if (self.index == 0) {
|
||||||
UIAlertView *iconAl = [[UIAlertView alloc] initWithTitle:@"" message:@"It's already the first one" delegate:self cancelButtonTitle:nil otherButtonTitles:@"ok", nil];
|
UIAlertView *iconAl = [[UIAlertView alloc] initWithTitle:@"" message:@"It's already the first one" delegate:self cancelButtonTitle:nil otherButtonTitles:@"ok", nil];
|
||||||
[iconAl show];
|
[iconAl show];
|
||||||
@ -105,7 +105,7 @@
|
|||||||
self.index --;
|
self.index --;
|
||||||
[self.wpscroll setContentOffset:CGPointMake(self.index*WPScreen_w, 0)];
|
[self.wpscroll setContentOffset:CGPointMake(self.index*WPScreen_w, 0)];
|
||||||
}
|
}
|
||||||
- (void)xiaItemEvent{
|
- (void)xiaItemEventLove:(id)sender{
|
||||||
if (self.index == self.data.count-1) {
|
if (self.index == self.data.count-1) {
|
||||||
UIAlertView *iconAl = [[UIAlertView alloc] initWithTitle:@"" message:@"It's the last one" delegate:self cancelButtonTitle:nil otherButtonTitles:@"ok", nil];
|
UIAlertView *iconAl = [[UIAlertView alloc] initWithTitle:@"" message:@"It's the last one" delegate:self cancelButtonTitle:nil otherButtonTitles:@"ok", nil];
|
||||||
[iconAl show];
|
[iconAl show];
|
||||||
|
|||||||
@ -37,13 +37,13 @@
|
|||||||
// btn.layer.cornerRadius = 5;
|
// btn.layer.cornerRadius = 5;
|
||||||
// btn.layer.masksToBounds = YES;
|
// btn.layer.masksToBounds = YES;
|
||||||
btn.tag = i;
|
btn.tag = i;
|
||||||
[btn addTarget:self action:@selector(iconEvent:) forControlEvents:UIControlEventTouchUpInside];
|
[btn addTarget:self action:@selector(iconEventLove:) forControlEvents:UIControlEventTouchUpInside];
|
||||||
[self.view addSubview:btn];
|
[self.view addSubview:btn];
|
||||||
}
|
}
|
||||||
|
|
||||||
UIButton *pracy_btn = [UIButton new];
|
UIButton *pracy_btn = [UIButton new];
|
||||||
[self.view addSubview:pracy_btn];
|
[self.view addSubview:pracy_btn];
|
||||||
[pracy_btn addTarget:self action:@selector(showUserPravcy) forControlEvents:UIControlEventTouchUpInside];
|
[pracy_btn addTarget:self action:@selector(showUserPravcyLove:) forControlEvents:UIControlEventTouchUpInside];
|
||||||
NSString *privacy = KLS(@"privacy", @"A friendly greeting");
|
NSString *privacy = KLS(@"privacy", @"A friendly greeting");
|
||||||
[pracy_btn setTitle:privacy forState:UIControlStateNormal];
|
[pracy_btn setTitle:privacy forState:UIControlStateNormal];
|
||||||
[pracy_btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
|
[pracy_btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
|
||||||
@ -55,12 +55,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
//显示用户隐私
|
//显示用户隐私
|
||||||
- (void)showUserPravcy {
|
- (void)showUserPravcyLove:(id)s {
|
||||||
AWM_UserPravcyVC *vc = [AWM_UserPravcyVC new];
|
AWM_UserPravcyVC *vc = [AWM_UserPravcyVC new];
|
||||||
[self.navigationController pushViewController:vc animated:YES];
|
[self.navigationController pushViewController:vc animated:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)iconEvent:(UIButton *)icon{
|
- (void)iconEventLove:(UIButton *)icon{
|
||||||
if (icon.tag == 0) {
|
if (icon.tag == 0) {
|
||||||
AWM_wallpaperViewController *wpdetail = [[AWM_wallpaperViewController alloc] init];
|
AWM_wallpaperViewController *wpdetail = [[AWM_wallpaperViewController alloc] init];
|
||||||
[self.navigationController pushViewController:wpdetail animated:YES];
|
[self.navigationController pushViewController:wpdetail animated:YES];
|
||||||
|
|||||||
@ -37,7 +37,7 @@
|
|||||||
UIButton *searchBtn = [[UIButton alloc] initWithFrame:CGRectMake((WPScreen_w-300)/2-1,100-1,300-1,96-1)];
|
UIButton *searchBtn = [[UIButton alloc] initWithFrame:CGRectMake((WPScreen_w-300)/2-1,100-1,300-1,96-1)];
|
||||||
NSString *search = KLS(@"search", @"A friendly greeting");
|
NSString *search = KLS(@"search", @"A friendly greeting");
|
||||||
[searchBtn setBackgroundImage:[UIImage imageNamed:search] forState:UIControlStateNormal];
|
[searchBtn setBackgroundImage:[UIImage imageNamed:search] forState:UIControlStateNormal];
|
||||||
[searchBtn addTarget:self action:@selector(searchEvent) forControlEvents:UIControlEventTouchUpInside];
|
[searchBtn addTarget:self action:@selector(searchEventLove) forControlEvents:UIControlEventTouchUpInside];
|
||||||
[self.view addSubview:searchBtn];
|
[self.view addSubview:searchBtn];
|
||||||
|
|
||||||
self.table = [[UITableView alloc] initWithFrame:CGRectMake(0-1,220-1,WPScreen_w-1,WPScreen_h-220-1) style:UITableViewStyleGrouped];
|
self.table = [[UITableView alloc] initWithFrame:CGRectMake(0-1,220-1,WPScreen_w-1,WPScreen_h-220-1) style:UITableViewStyleGrouped];
|
||||||
@ -47,7 +47,7 @@
|
|||||||
self.table.separatorColor = [UIColor clearColor];
|
self.table.separatorColor = [UIColor clearColor];
|
||||||
[self.view addSubview:self.table];
|
[self.view addSubview:self.table];
|
||||||
}
|
}
|
||||||
- (void)searchEvent{
|
- (void)searchEventLove{
|
||||||
AWM_SearchViewController *vc = [[AWM_SearchViewController alloc] init];
|
AWM_SearchViewController *vc = [[AWM_SearchViewController alloc] init];
|
||||||
[self.navigationController pushViewController:vc animated:YES];
|
[self.navigationController pushViewController:vc animated:YES];
|
||||||
}
|
}
|
||||||
@ -78,7 +78,7 @@
|
|||||||
[btn setImage:[UIImage imageNamed:self.data[indexPath.section][i]] forState:UIControlStateNormal];
|
[btn setImage:[UIImage imageNamed:self.data[indexPath.section][i]] forState:UIControlStateNormal];
|
||||||
btn.layer.cornerRadius = 5;
|
btn.layer.cornerRadius = 5;
|
||||||
btn.layer.masksToBounds = YES;
|
btn.layer.masksToBounds = YES;
|
||||||
[btn addTarget:self action:@selector(headerEvent) forControlEvents:UIControlEventTouchUpInside];
|
[btn addTarget:self action:@selector(headerEventLove:) forControlEvents:UIControlEventTouchUpInside];
|
||||||
[bgView addSubview:btn];
|
[bgView addSubview:btn];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +91,7 @@
|
|||||||
[bgView addSubview:more];
|
[bgView addSubview:more];
|
||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
- (void)headerEvent{
|
- (void)headerEventLove:(id)sender{
|
||||||
AWM_AllWallpaperViewController *wpdetail = [[AWM_AllWallpaperViewController alloc] init];
|
AWM_AllWallpaperViewController *wpdetail = [[AWM_AllWallpaperViewController alloc] init];
|
||||||
[self.navigationController pushViewController:wpdetail animated:YES];
|
[self.navigationController pushViewController:wpdetail animated:YES];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,7 +36,7 @@
|
|||||||
UIButton *searchBtn = [[UIButton alloc] initWithFrame:CGRectMake((WPScreen_w-300)/2-1,100-1,300-1,96-1)];
|
UIButton *searchBtn = [[UIButton alloc] initWithFrame:CGRectMake((WPScreen_w-300)/2-1,100-1,300-1,96-1)];
|
||||||
NSString *search = KLS(@"search", @"A friendly greeting");
|
NSString *search = KLS(@"search", @"A friendly greeting");
|
||||||
[searchBtn setBackgroundImage:[UIImage imageNamed:search] forState:UIControlStateNormal];
|
[searchBtn setBackgroundImage:[UIImage imageNamed:search] forState:UIControlStateNormal];
|
||||||
[searchBtn addTarget:self action:@selector(searchEvent) forControlEvents:UIControlEventTouchUpInside];
|
[searchBtn addTarget:self action:@selector(searchEventLove:) forControlEvents:UIControlEventTouchUpInside];
|
||||||
[self.view addSubview:searchBtn];
|
[self.view addSubview:searchBtn];
|
||||||
|
|
||||||
self.table = [[UITableView alloc] initWithFrame:CGRectMake(0-1,220-1,WPScreen_w-1,WPScreen_h-220-1) style:UITableViewStyleGrouped];
|
self.table = [[UITableView alloc] initWithFrame:CGRectMake(0-1,220-1,WPScreen_w-1,WPScreen_h-220-1) style:UITableViewStyleGrouped];
|
||||||
@ -46,7 +46,7 @@
|
|||||||
self.table.separatorColor = [UIColor clearColor];
|
self.table.separatorColor = [UIColor clearColor];
|
||||||
[self.view addSubview:self.table];
|
[self.view addSubview:self.table];
|
||||||
}
|
}
|
||||||
- (void)searchEvent{
|
- (void)searchEventLove:(id)s{
|
||||||
AWM_SearchViewController *vc = [[AWM_SearchViewController alloc] init];
|
AWM_SearchViewController *vc = [[AWM_SearchViewController alloc] init];
|
||||||
[self.navigationController pushViewController:vc animated:YES];
|
[self.navigationController pushViewController:vc animated:YES];
|
||||||
}
|
}
|
||||||
@ -64,7 +64,7 @@
|
|||||||
return 3*(10+space*1.5)+30;
|
return 3*(10+space*1.5)+30;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
- (void)headerEvent{
|
- (void)headerEvent:(id)s{
|
||||||
AWM_AllWallpaperViewController *wpdetail = [[AWM_AllWallpaperViewController alloc] init];
|
AWM_AllWallpaperViewController *wpdetail = [[AWM_AllWallpaperViewController alloc] init];
|
||||||
[self.navigationController pushViewController:wpdetail animated:YES];
|
[self.navigationController pushViewController:wpdetail animated:YES];
|
||||||
}
|
}
|
||||||
@ -82,7 +82,7 @@
|
|||||||
header.userInteractionEnabled = YES;
|
header.userInteractionEnabled = YES;
|
||||||
|
|
||||||
UIButton *headerbtn = [[UIButton alloc] initWithFrame:header.bounds];
|
UIButton *headerbtn = [[UIButton alloc] initWithFrame:header.bounds];
|
||||||
[headerbtn addTarget:self action:@selector(headerEvent) forControlEvents:UIControlEventTouchUpInside];
|
[headerbtn addTarget:self action:@selector(headerEvent:) forControlEvents:UIControlEventTouchUpInside];
|
||||||
[cell.contentView addSubview:header];
|
[cell.contentView addSubview:header];
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
@ -99,7 +99,7 @@
|
|||||||
[btn setImage:[UIImage imageNamed:self.data[indexPath.section][i]] forState:UIControlStateNormal];
|
[btn setImage:[UIImage imageNamed:self.data[indexPath.section][i]] forState:UIControlStateNormal];
|
||||||
btn.layer.cornerRadius = 5;
|
btn.layer.cornerRadius = 5;
|
||||||
btn.layer.masksToBounds = YES;
|
btn.layer.masksToBounds = YES;
|
||||||
[btn addTarget:self action:@selector(headerEvent) forControlEvents:UIControlEventTouchUpInside];
|
[btn addTarget:self action:@selector(headerEvent:) forControlEvents:UIControlEventTouchUpInside];
|
||||||
[bgView addSubview:btn];
|
[bgView addSubview:btn];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation AWM_SearchViewController
|
@implementation AWM_SearchViewController
|
||||||
- (void)backItemEvent{
|
- (void)backItemEventLove:(id)sender{
|
||||||
__weak typeof(self) weakSelf = self;
|
__weak typeof(self) weakSelf = self;
|
||||||
[[AWM_WallPapaerADManager shareInstance] showIntersitialAD_Back:^(NSInteger actionType) {
|
[[AWM_WallPapaerADManager shareInstance] showIntersitialAD_Back:^(NSInteger actionType) {
|
||||||
[weakSelf.navigationController popViewControllerAnimated:YES];
|
[weakSelf.navigationController popViewControllerAnimated:YES];
|
||||||
@ -50,7 +50,7 @@
|
|||||||
NSString *greeting1 = KLS(@"back", @"A friendly greeting");
|
NSString *greeting1 = KLS(@"back", @"A friendly greeting");
|
||||||
UIButton *backItem = [[UIButton alloc] initWithFrame:CGRectMake(20-1,0-1,74-1,44-1)];
|
UIButton *backItem = [[UIButton alloc] initWithFrame:CGRectMake(20-1,0-1,74-1,44-1)];
|
||||||
[backItem setImage:[UIImage imageNamed:greeting1] forState:UIControlStateNormal];
|
[backItem setImage:[UIImage imageNamed:greeting1] forState:UIControlStateNormal];
|
||||||
[backItem addTarget:self action:@selector(backItemEvent) forControlEvents:UIControlEventTouchUpInside];
|
[backItem addTarget:self action:@selector(backItemEventLove:) forControlEvents:UIControlEventTouchUpInside];
|
||||||
self.backItem = backItem;
|
self.backItem = backItem;
|
||||||
|
|
||||||
UIImageView *navImage = [[UIImageView alloc] initWithFrame:CGRectMake(WPScreen_w-150-1,8-1,130-1,28-1)];
|
UIImageView *navImage = [[UIImageView alloc] initWithFrame:CGRectMake(WPScreen_w-150-1,8-1,130-1,28-1)];
|
||||||
|
|||||||
@ -38,7 +38,7 @@
|
|||||||
NSString *greeting = KLS(@"back", @"A friendly greeting");
|
NSString *greeting = KLS(@"back", @"A friendly greeting");
|
||||||
UIButton *backItem = [[UIButton alloc] initWithFrame:CGRectMake(20-1,0-1,74-1,44-1)];
|
UIButton *backItem = [[UIButton alloc] initWithFrame:CGRectMake(20-1,0-1,74-1,44-1)];
|
||||||
[backItem setImage:[UIImage imageNamed:greeting] forState:UIControlStateNormal];
|
[backItem setImage:[UIImage imageNamed:greeting] forState:UIControlStateNormal];
|
||||||
[backItem addTarget:self action:@selector(backItemEvent) forControlEvents:UIControlEventTouchUpInside];
|
[backItem addTarget:self action:@selector(backItemEventLove:) forControlEvents:UIControlEventTouchUpInside];
|
||||||
self.backItem = backItem;
|
self.backItem = backItem;
|
||||||
|
|
||||||
// UILabel *titleLabel = [UILabel new];
|
// UILabel *titleLabel = [UILabel new];
|
||||||
@ -60,7 +60,7 @@
|
|||||||
[webView loadRequest:request];
|
[webView loadRequest:request];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)backItemEvent{
|
- (void)backItemEventLove:(id)sender{
|
||||||
[self.navigationController popViewControllerAnimated:YES];
|
[self.navigationController popViewControllerAnimated:YES];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,7 +27,7 @@
|
|||||||
NSString *addpic = KLS(@"addpic", @"A friendly greeting");
|
NSString *addpic = KLS(@"addpic", @"A friendly greeting");
|
||||||
UIButton *addImage = [[UIButton alloc] initWithFrame:CGRectMake((WPScreen_w-150)/2-1,650-1,150-1,75-1)];
|
UIButton *addImage = [[UIButton alloc] initWithFrame:CGRectMake((WPScreen_w-150)/2-1,650-1,150-1,75-1)];
|
||||||
[addImage setImage:[UIImage imageNamed:addpic] forState:UIControlStateNormal];
|
[addImage setImage:[UIImage imageNamed:addpic] forState:UIControlStateNormal];
|
||||||
[addImage addTarget:self action:@selector(selectPhoto) forControlEvents:UIControlEventTouchUpInside];
|
[addImage addTarget:self action:@selector(selectPhotoLove:) forControlEvents:UIControlEventTouchUpInside];
|
||||||
// addImage.center = self.view.center;
|
// addImage.center = self.view.center;
|
||||||
[self.view addSubview:addImage];
|
[self.view addSubview:addImage];
|
||||||
self.addImage = addImage;
|
self.addImage = addImage;
|
||||||
@ -42,7 +42,7 @@
|
|||||||
self.showImage = showImage;
|
self.showImage = showImage;
|
||||||
|
|
||||||
}
|
}
|
||||||
- (void)selectPhoto{
|
- (void)selectPhotoLove:(id)sender{
|
||||||
if (self.isShow) {
|
if (self.isShow) {
|
||||||
__weak typeof(self)weakSelf = self;
|
__weak typeof(self)weakSelf = self;
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation AWM_wallpaperViewController
|
@implementation AWM_wallpaperViewController
|
||||||
- (void)backItemEvent{
|
- (void)backItemEventLove:(id)sender{
|
||||||
__weak typeof(self) weakSelf = self;
|
__weak typeof(self) weakSelf = self;
|
||||||
[[AWM_WallPapaerADManager shareInstance] showIntersitialAD_Back:^(NSInteger actionType) {
|
[[AWM_WallPapaerADManager shareInstance] showIntersitialAD_Back:^(NSInteger actionType) {
|
||||||
[weakSelf.navigationController popViewControllerAnimated:YES];
|
[weakSelf.navigationController popViewControllerAnimated:YES];
|
||||||
@ -59,7 +59,7 @@
|
|||||||
NSString *backitem = KLS(@"back", @"A friendly greeting");
|
NSString *backitem = KLS(@"back", @"A friendly greeting");
|
||||||
UIButton *backItem = [[UIButton alloc] initWithFrame:CGRectMake(20-1,0-1,74-1,44-1)];
|
UIButton *backItem = [[UIButton alloc] initWithFrame:CGRectMake(20-1,0-1,74-1,44-1)];
|
||||||
[backItem setImage:[UIImage imageNamed:backitem] forState:UIControlStateNormal];
|
[backItem setImage:[UIImage imageNamed:backitem] forState:UIControlStateNormal];
|
||||||
[backItem addTarget:self action:@selector(backItemEvent) forControlEvents:UIControlEventTouchUpInside];
|
[backItem addTarget:self action:@selector(backItemEventLove:) forControlEvents:UIControlEventTouchUpInside];
|
||||||
self.backItem = backItem;
|
self.backItem = backItem;
|
||||||
NSString *greeting3 = KLS(@"navmy", @"A friendly greeting");
|
NSString *greeting3 = KLS(@"navmy", @"A friendly greeting");
|
||||||
UIImageView *navImage = [[UIImageView alloc] initWithFrame:CGRectMake(WPScreen_w-150-1,8-1,130-1,28-1)];
|
UIImageView *navImage = [[UIImageView alloc] initWithFrame:CGRectMake(WPScreen_w-150-1,8-1,130-1,28-1)];
|
||||||
@ -94,7 +94,7 @@
|
|||||||
[btn setImage:[UIImage imageNamed:self.data[i]] forState:UIControlStateNormal];
|
[btn setImage:[UIImage imageNamed:self.data[i]] forState:UIControlStateNormal];
|
||||||
btn.layer.cornerRadius = 5;
|
btn.layer.cornerRadius = 5;
|
||||||
btn.layer.masksToBounds = YES;
|
btn.layer.masksToBounds = YES;
|
||||||
[btn addTarget:self action:@selector(headerEvent) forControlEvents:UIControlEventTouchUpInside];
|
[btn addTarget:self action:@selector(headerEventLove:) forControlEvents:UIControlEventTouchUpInside];
|
||||||
[cell.contentView addSubview:btn];
|
[cell.contentView addSubview:btn];
|
||||||
}
|
}
|
||||||
return cell;
|
return cell;
|
||||||
@ -121,7 +121,7 @@
|
|||||||
wpdetail.data = self.data;
|
wpdetail.data = self.data;
|
||||||
[self.navigationController pushViewController:wpdetail animated:YES];
|
[self.navigationController pushViewController:wpdetail animated:YES];
|
||||||
}
|
}
|
||||||
- (void)headerEvent{
|
- (void)headerEventLove:(id)sender{
|
||||||
AWM_DetailViewController *wpdetail = [[AWM_DetailViewController alloc] init];
|
AWM_DetailViewController *wpdetail = [[AWM_DetailViewController alloc] init];
|
||||||
wpdetail.data = self.data;
|
wpdetail.data = self.data;
|
||||||
[self.navigationController pushViewController:wpdetail animated:YES];
|
[self.navigationController pushViewController:wpdetail animated:YES];
|
||||||
|
|||||||
3
HX/.idea/.gitignore
generated
vendored
Normal file
3
HX/.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
9
HX/.idea/HX.iml
generated
Normal file
9
HX/.idea/HX.iml
generated
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
6
HX/.idea/misc.xml
generated
Normal file
6
HX/.idea/misc.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
8
HX/.idea/modules.xml
generated
Normal file
8
HX/.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/HX.iml" filepath="$PROJECT_DIR$/.idea/HX.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
HX/.idea/vcs.xml
generated
Normal file
6
HX/.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
197
HX/AddClashCodeToFile.py
Normal file
197
HX/AddClashCodeToFile.py
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
# -*- coding: UTF-8 -*-
|
||||||
|
import os,sys
|
||||||
|
import random
|
||||||
|
import string
|
||||||
|
import re
|
||||||
|
import time
|
||||||
|
import json
|
||||||
|
import shutil
|
||||||
|
import hashlib
|
||||||
|
import time
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
script_path = os.path.split(os.path.realpath(sys.argv[0]))[0]
|
||||||
|
|
||||||
|
swiftFunPattern = "func.*?\\{"
|
||||||
|
|
||||||
|
#目前oc只向对象实例方法注入垃圾代码
|
||||||
|
ocFunPattern = "-.*?\\{"
|
||||||
|
|
||||||
|
#需要忽略的文件,写入这里后,这些文件将不会被添加垃圾代码
|
||||||
|
ignore_files = ["ZHAuthorSetVC.m", "DownloadManager.swift"]
|
||||||
|
|
||||||
|
#用于匹配 // 注释 的文本信息,在插入函数垃圾代码前,需要清除掉注释,避免在被注释的函数中添加垃圾代码而导致编译不过
|
||||||
|
explanatoryPattern = "(^//.*)"
|
||||||
|
|
||||||
|
#判断是否应该被忽略插入垃圾代码
|
||||||
|
def isNeedIgnore(fileName):
|
||||||
|
global ignore_files
|
||||||
|
for file in ignore_files:
|
||||||
|
if fileName.find(file) != -1:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
#单词列表,用以随机名称
|
||||||
|
with open(os.path.join(script_path, "./word_list.json"), "r") as fileObj:
|
||||||
|
word_name_list = json.load(fileObj)
|
||||||
|
|
||||||
|
# 随机获取一个字符
|
||||||
|
def get_random_char():
|
||||||
|
# 可以根据需要更改字符的范围
|
||||||
|
ascii_uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||||
|
ascii_lowercase = 'abcdefghijklmnopqrstuvwxyz'
|
||||||
|
digits = '0123456789'
|
||||||
|
# 这里可以选择不同的字符集合进行随机选择
|
||||||
|
char_sets = [ascii_uppercase, ascii_lowercase, digits]
|
||||||
|
char_set = random.choice(char_sets)
|
||||||
|
return random.choice(char_set)
|
||||||
|
|
||||||
|
#获取一个随机变量名称
|
||||||
|
def getVeriableName():
|
||||||
|
global word_name_list
|
||||||
|
return random.choice(word_name_list) + "_" + get_random_char()
|
||||||
|
|
||||||
|
|
||||||
|
#向OC文件的既有函数添加垃圾代码
|
||||||
|
def addClashCode2OC(filePath):
|
||||||
|
global ocFunPattern
|
||||||
|
print("\n开始向:\n%s\n添加垃圾代码\n" %filePath)
|
||||||
|
with open(filePath,"r",errors="ignore") as fileObj:
|
||||||
|
fileContent_text = fileObj.read()
|
||||||
|
fileObj.close()
|
||||||
|
matches = re.finditer(ocFunPattern,fileContent_text)
|
||||||
|
#倒序遍历匹配的结果
|
||||||
|
for match in reversed(list(matches)):
|
||||||
|
firstPart_text = fileContent_text[:match.end()]
|
||||||
|
firstPart_text = firstPart_text +"\n" + " " + getOCFakeCode() + "\n"
|
||||||
|
fileContent_text = firstPart_text + fileContent_text[match.end():]
|
||||||
|
#print("match position:",match.end())
|
||||||
|
with open(filePath,"w",errors="ignore") as fileObj:
|
||||||
|
fileObj.write(fileContent_text)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#获取OC垃圾伪装代码
|
||||||
|
def getOCFakeCode():
|
||||||
|
random_number = random.randint(1, 2)
|
||||||
|
if random_number == 1:
|
||||||
|
return getOCFakeCode_1()
|
||||||
|
else:
|
||||||
|
return getOCFakeCode_2()
|
||||||
|
|
||||||
|
#oc代码格式1
|
||||||
|
def getOCFakeCode_1():
|
||||||
|
vn1 = getVeriableName()
|
||||||
|
vn2 = getVeriableName()
|
||||||
|
vn_key = getVeriableName()
|
||||||
|
resultText = "\nNSDateFormatter *%s = [NSDateFormatter new];\n[%s setDateFormat:@\"yyyy-MM-dd HH:mm\"];\nNSString *%s = [%s stringFromDate:[NSDate date]];\n[[NSUserDefaults standardUserDefaults] setObject:%s forKey:@\"%s\"];\n" %(vn1,vn1,vn2,vn1,vn2,vn_key)
|
||||||
|
return resultText
|
||||||
|
|
||||||
|
#oc代码格式2
|
||||||
|
def getOCFakeCode_2():
|
||||||
|
digits = '0123456789'
|
||||||
|
value1 = random.choice(digits)
|
||||||
|
|
||||||
|
vn1 = getVeriableName()
|
||||||
|
vn2 = getVeriableName()
|
||||||
|
vn_key = getVeriableName()
|
||||||
|
resultText = "\nNSInteger %s = %s;\nNSInteger %s = [[NSUserDefaults standardUserDefaults] integerForKey:@\"%s\"];\n%s *= %s;\n[[NSUserDefaults standardUserDefaults] setInteger:%s forKey:@\"%s\"];\n" %(vn1,value1,vn2,vn_key,vn2,vn1,vn2,vn_key)
|
||||||
|
return resultText
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#向Swift文件的既有函数添加垃圾代码
|
||||||
|
def addClashCode2Swift(filePath):
|
||||||
|
global swiftFunPattern
|
||||||
|
print("\n开始向:\n%s\n添加垃圾代码\n" %filePath)
|
||||||
|
with open(filePath,"r",errors="ignore") as fileObj:
|
||||||
|
fileContent_text = fileObj.read()
|
||||||
|
fileObj.close()
|
||||||
|
matches = re.finditer(swiftFunPattern,fileContent_text)
|
||||||
|
#倒序遍历匹配的结果
|
||||||
|
for match in reversed(list(matches)):
|
||||||
|
firstPart_text = fileContent_text[:match.end()]
|
||||||
|
firstPart_text = firstPart_text +"\n" + " " + getSwiftFakeCode() + "\n"
|
||||||
|
fileContent_text = firstPart_text + fileContent_text[match.end():]
|
||||||
|
#print("match position:",match.end())
|
||||||
|
with open(filePath,"w",errors="ignore") as fileObj:
|
||||||
|
fileObj.write(fileContent_text)
|
||||||
|
|
||||||
|
#获取swift垃圾伪装代码
|
||||||
|
def getSwiftFakeCode():
|
||||||
|
random_number = random.randint(1, 2)
|
||||||
|
if random_number == 1:
|
||||||
|
return getSwiftFakeCode_1()
|
||||||
|
else:
|
||||||
|
return getSwiftFakeCode_2()
|
||||||
|
|
||||||
|
#swift代码格式1
|
||||||
|
def getSwiftFakeCode_1():
|
||||||
|
vn1 = getVeriableName()
|
||||||
|
digits = '0123456789'
|
||||||
|
value1 = random.choice(digits)
|
||||||
|
|
||||||
|
vn2 = getVeriableName()
|
||||||
|
vn2_key = getVeriableName()
|
||||||
|
|
||||||
|
vn3 = getVeriableName()
|
||||||
|
|
||||||
|
resultText = "\nlet %s:Int = %s\nlet %s:Int = UserDefaults.standard.integer(forKey: \"%s\")\nvar %s = %s * %s\nUserDefaults.standard .setValue(%s, forKey: \"%s\")\n" %(vn1,value1,vn2,vn2_key,vn3,vn1,vn2,vn3,vn2_key)
|
||||||
|
return resultText
|
||||||
|
|
||||||
|
#swift代码格式2
|
||||||
|
def getSwiftFakeCode_2():
|
||||||
|
vn1 = getVeriableName()
|
||||||
|
vn2 = getVeriableName()
|
||||||
|
vn_key = getVeriableName()
|
||||||
|
resultText = "\nlet %s = DateFormatter() \n%s.dateStyle = .full\nlet %s = %s.string(from: NSDate.now)\nUserDefaults.standard .setValue(%s, forKey: \"%s\")\n" %(vn1,vn1,vn2,vn1,vn2,vn_key)
|
||||||
|
return resultText
|
||||||
|
|
||||||
|
|
||||||
|
#解析初始化参数
|
||||||
|
def parase_args():
|
||||||
|
global script_path
|
||||||
|
parseParam = argparse.ArgumentParser(description='添加垃圾代码.\n')
|
||||||
|
#存放代码的根路径,即需要 函数 被添加垃圾代码 的根路径,该程序将遍历这个目录下的所有文件(即包含子目录的子文件 执行垃圾代码添加)
|
||||||
|
parseParam.add_argument('--code_dir', dest='code_dir', type=str, required=False, default=script_path, help='需要添加垃圾函数代码的根目录')
|
||||||
|
print("paraseParam:",parseParam)
|
||||||
|
return parseParam.parse_args()
|
||||||
|
|
||||||
|
#进行循环处理目录中的文件
|
||||||
|
def cycleDealDir(need_dealDir):
|
||||||
|
print("开始循环这个目录:",need_dealDir)
|
||||||
|
if not os.path.exists(need_dealDir):
|
||||||
|
print("当前目录不存在:",need_dealDir)
|
||||||
|
#以walk的方式,本身就会遍历完毕当前目录下的所有文件
|
||||||
|
for parent,folders,files in os.walk(need_dealDir):
|
||||||
|
#print("遍历子文件...")
|
||||||
|
for file in files:
|
||||||
|
filePath = os.path.join(parent, file)
|
||||||
|
file_extension = file.split(".")[-1]
|
||||||
|
if file_extension == "swift" and not isNeedIgnore(file):
|
||||||
|
addClashCode2Swift(filePath)
|
||||||
|
elif file_extension == "m" and not isNeedIgnore(file):
|
||||||
|
addClashCode2OC(filePath)
|
||||||
|
else:
|
||||||
|
print("其他类型的文件暂不处理:",file)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
#解析参数
|
||||||
|
parseParam = parase_args()
|
||||||
|
|
||||||
|
#获取只要添加垃圾代码的目标 文件夹
|
||||||
|
cycleDealDir(parseParam.code_dir)
|
||||||
|
|
||||||
|
#遍历获取目标文件夹中的目标文件
|
||||||
|
#过滤 需要忽略的目标文件
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
||||||
|
|
||||||
12604
HX/ClassName_list.json
Normal file
12604
HX/ClassName_list.json
Normal file
File diff suppressed because it is too large
Load Diff
118
HX/README.md
Normal file
118
HX/README.md
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
# iosMixTools
|
||||||
|
ios混淆脚本工具,主要用于游戏类。顺便安利一波: [IOS马甲包混淆](https://blog.csdn.net/lyzz0612/article/details/80390362)
|
||||||
|
有任何问题和建议欢迎联系: email: lyzz0612@qq.com
|
||||||
|
|
||||||
|
## Updated
|
||||||
|
这些工具用完目前还是2.1被拒, 4.3的可以尝试下;第三方加固工具试用版也被拒,目前在打算先用小游戏过审。
|
||||||
|
|
||||||
|
资源混淆感觉应该够了,但还是被4.3。这边用的游戏引擎代码基本没动,准备对它动刀了
|
||||||
|
|
||||||
|
* 定义宏加到代码不同地方,根据行号不同插入不同代码,可引入第三方库
|
||||||
|
```
|
||||||
|
#define MIX_FUNC_1 {SOME CODE}
|
||||||
|
#define MIX_FUNC(__LINE__) MIX_FUNC_##__LINE__
|
||||||
|
```
|
||||||
|
|
||||||
|
* 改写原有宏实现,如cocos引擎的CCASSERT,CCLOG
|
||||||
|
* 替换字符串,改为解密加密字符串
|
||||||
|
|
||||||
|
### Updated 2019/01/17
|
||||||
|
刚用小游戏提审过了,主要改地方是
|
||||||
|
1. 没加垃圾资源,但是把所有资源打成加密zip包+xor加密,启动时再解压执行。这样苹果机审应该不可能扫出重复资源来
|
||||||
|
2. 换iOS类名、函数名。原来只是加了垃圾函数,类名也只是加前缀,这次全换了完全不同的名字
|
||||||
|
3. 换机器打包、提审。本来公司就几台打包机器,提了很多次估计被标记了,一提就封号……这次是自己的电脑打包和提审的
|
||||||
|
4. 去掉热更联网检查,改为固定时间判断。原来是启动会检查更新,虽然提示是改成正在加载资源了,但有可能检测到网络数据了。这次直接固定提审1个月开放热更
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
发现新的混淆工具[https://github.com/zfjsyqk/ZFJObsLib](https://github.com/zfjsyqk/ZFJObsLib),看描述功能很齐全,待试用。
|
||||||
|
|
||||||
|
## 使用说明
|
||||||
|
|
||||||
|
### 1. addNative.py 生成oc垃圾代码工具
|
||||||
|
此脚本会扫描指定目录,给OC文件添加垃圾函数,同时创建垃圾文件到/trash目录。
|
||||||
|
#### 参数说明
|
||||||
|
|
||||||
|
* ` --oc_folder OC_FOLDER` OC_FOLDER为OC代码所在目录
|
||||||
|
* `--replace`替换OC_FOLDER下的原文件,同时原代码会备份到脚本目录下的backup_ios目录。不指定此项垃圾代码只会放到脚本目录下的target_ios/
|
||||||
|
|
||||||
|
addNative.py里还有一些配置可以看需求手动修改,如生成垃圾文件的数量,垃圾函数的数量,忽略文件列表等,具体请查看代码顶部相关注释
|
||||||
|
|
||||||
|
### 2. renameNative.py 修改类名前缀工具
|
||||||
|
类名是引用可能较为复杂的东西,工具批量替换的限制要求会比较多。如果你的项目满足以下条件,那么这个工具会比较适合你:
|
||||||
|
|
||||||
|
* 大部分类名都带相同的前缀,也只准备替换前缀;
|
||||||
|
* 大部分类都只在一个大文件夹下,它们之间相互引用,外部调用的情况较少并且你能很有把握的排除或手动替换它们;
|
||||||
|
* 类名和文件名一致;
|
||||||
|
|
||||||
|
本工具的流程是扫描指定文件夹,找到名称(或者说类名,工具假设两者是一致的)以指定前缀开始的文件;修改替换文件名前缀;并再次遍历此文件夹所有文件,将文件内容中的所有该名称也替换掉;替换xx.xcodeproj/project.pbxproj下的路径,省去在Xcode中手动添加文件(因为文件名修改了,不替换的话Xcode上还保持原来的名称会提示找不到文件);同时为了防止文件夹名称跟文件名相同而导致替换project.pbxproj时将目录名也替换掉的情况,对文件夹名称也进行相同的流程。
|
||||||
|
|
||||||
|
#### 参数说明:
|
||||||
|
|
||||||
|
* `--add_prefix PREFIX` 添加类名前缀,有此项old_prefix和new_prefix将不起作用,此项请提前在renameNative.py文件中ignore_path_text添加不需要前缀的文件或路径
|
||||||
|
* `--old_prefix OLD_PREFIX` 替换前的类名前缀
|
||||||
|
* `--new_prefix NEW_PREFIX` 替换后的类名前缀
|
||||||
|
* `--ios_path IOS_PATH` OC文件目录
|
||||||
|
* `--proj_path PROJ_PATH ` xx.xcodeproj路径
|
||||||
|
|
||||||
|
运行示例:
|
||||||
|
`python renameNative.py --add_prefix ANDROID --ios_path xx/xx/xx/ --proj_path xx/xx/xx.xcodeproj`
|
||||||
|
`python renameNative.py --old_prefix ANDROID --new_prefix IOS --ios_path xx/xx/xx/ --proj_path xx/xx/xx.xcodeproj`
|
||||||
|
|
||||||
|
|
||||||
|
### 3. autoBornCode.py 添加lua和png,修改资源文件MD5
|
||||||
|
此脚本会扫描指定文件夹,在路径包含/res的目录创建png, 其他地方创建lua。根据目录下的文件和文件夹数随机添加文件和子文件夹,创建数量是根据目录下原有文件和文件夹的数量随机。然后会给大部分类型资源文件添加一些无效内容来改变其MD5。
|
||||||
|
|
||||||
|
#### 参数说明
|
||||||
|
|
||||||
|
* `--res RESOURCE_DIR` 资源目录
|
||||||
|
* `--target TARGET_FOLDER` 可选参数,修改后的资源存放目录。不设置为脚本目录下的target_resource
|
||||||
|
|
||||||
|
在代码的最前面有个匹配规则, path_exclude表示必须是不包含该字符串的路径才能创建该类型文件,path_include表示必须是包含该字符串的路径才要创建该类型文件
|
||||||
|
```
|
||||||
|
match_rule = {
|
||||||
|
".png": {
|
||||||
|
"path_include": os.path.sep + "res",
|
||||||
|
},
|
||||||
|
".lua": {
|
||||||
|
# "path_include": "src",
|
||||||
|
"path_exclude": os.path.sep + "res",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**TODO**音效文件修改MD5值
|
||||||
|
|
||||||
|
|
||||||
|
### 4. iOS加固插件
|
||||||
|
[五款iOS加固产品测试与点评](http://telecom.chinabyte.com/300/14570300.shtml)
|
||||||
|
|
||||||
|
[加固产品比较](https://www.codercto.com/a/28193.html)
|
||||||
|
|
||||||
|
1. Obfuscator-LLVM
|
||||||
|
|
||||||
|
[Obfuscator-LLVM在iOS中的实践](https://www.jianshu.com/p/a631b5584de6)
|
||||||
|
[obfuscator-llvm Github Installation](https://github.com/obfuscator-llvm/obfuscator/wiki/Installation)
|
||||||
|
配置了一下,编译了好长时间发现支持的clang版本只到4.0,很多issue都没人管了,而且不支持字符串混淆,优点是开源,有空可以自己折腾一下
|
||||||
|
|
||||||
|
2. 网易的试用需要审核
|
||||||
|
|
||||||
|
[网易易盾](http://dun.163.com/product/ios-reinforce)
|
||||||
|
|
||||||
|
3. 顶象的试用插件有大概半个月的期限,~~只支持30%的加固,不过对我们提审的来说应该够了~~ 经试验试用版提审会被2.3.1拒绝,提示用了代码混淆
|
||||||
|
|
||||||
|
[顶象](https://www.dingxiang-inc.com/business/ios)
|
||||||
|
[顶象文档](https://cdn.dingxiang-inc.com/public-service/docs/compiler-ios/)
|
||||||
|
|
||||||
|
|
||||||
|
4. 几维安全、360都是在线加固的
|
||||||
|
|
||||||
|
[几维安全静态库](https://www.kiwisec.com/product/app-encrypt.html)
|
||||||
|
[加固保iOS](http://jiagu.360.cn/#/app/android)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
240
HX/addNativeCode.py
Normal file
240
HX/addNativeCode.py
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
# -*- coding: UTF-8 -*-
|
||||||
|
# 添加OC垃圾代码
|
||||||
|
import os,sys
|
||||||
|
import random
|
||||||
|
import string
|
||||||
|
import re
|
||||||
|
#import md5
|
||||||
|
import time
|
||||||
|
import json
|
||||||
|
import shutil
|
||||||
|
import hashlib
|
||||||
|
import time
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
#sys.setdefaultencoding("utf-8")
|
||||||
|
|
||||||
|
script_path = os.path.split(os.path.realpath(sys.argv[0]))[0]
|
||||||
|
#垃圾代码临时存放目录
|
||||||
|
target_ios_folder = os.path.join(script_path, "./target_ios")
|
||||||
|
#备份目录
|
||||||
|
backup_ios_folder = os.path.join(script_path, "./backup_ios")
|
||||||
|
|
||||||
|
#忽略文件列表,不给这些文件添加垃圾函数
|
||||||
|
ignore_file_list = ["main.m", "GNative.mm", "MobClickCpp.mm"]
|
||||||
|
#忽略文件夹列表,不处理这些文件夹下的文件
|
||||||
|
ignore_folder_list = ["thirdparty","Support",".svn","paycenter","UMMobClick.framework","UMessage_Sdk_1.5.0a","TencentOpenApi_IOS_Bundle.bundle",
|
||||||
|
"TencentOpenAPI.framework","Bugly.framework","AlipaySDK.framework","AlipaySDK.bundle"]
|
||||||
|
|
||||||
|
#创建函数数量范围
|
||||||
|
create_func_min = 2
|
||||||
|
create_func_max = 10
|
||||||
|
|
||||||
|
#创建垃圾文件数量范围
|
||||||
|
create_file_min = 10
|
||||||
|
create_file_max = 100
|
||||||
|
|
||||||
|
#oc代码目录
|
||||||
|
ios_src_path = ""
|
||||||
|
|
||||||
|
#确保添加的函数不重名
|
||||||
|
funcname_set = set()
|
||||||
|
|
||||||
|
#单词列表,用以随机名称
|
||||||
|
with open(os.path.join(script_path, "./word_list.json"), "r") as fileObj:
|
||||||
|
word_name_list = json.load(fileObj)
|
||||||
|
|
||||||
|
#获取一个随机名称
|
||||||
|
def getOneName():
|
||||||
|
global word_name_list
|
||||||
|
return random.choice(word_name_list)
|
||||||
|
|
||||||
|
#oc代码头文件函数声明
|
||||||
|
def getOCHeaderFuncText():
|
||||||
|
funcName = getOneName()
|
||||||
|
text = "\n- (void)%s" %(funcName)
|
||||||
|
return text
|
||||||
|
|
||||||
|
#oc代码函数实现模板
|
||||||
|
def getOCFuncText(header_text):
|
||||||
|
arg1 = getOneName()
|
||||||
|
arg2 = getOneName()
|
||||||
|
text = [
|
||||||
|
header_text + "\n",
|
||||||
|
"{\n",
|
||||||
|
"\tint %s = 2;\n" %(arg1),
|
||||||
|
"\tint %s = 3;\n" %(arg2),
|
||||||
|
"\t%s += %s ;\n" %(arg2,arg1),
|
||||||
|
"\t[[NSUserDefaults standardUserDefaults] setObject:@(%s) forKey:@\"%s\"];\n" %(arg2,arg1),
|
||||||
|
"\tNSLog(@\"%s\");\n" %(arg1),
|
||||||
|
"}\n"
|
||||||
|
]
|
||||||
|
return "".join(text)
|
||||||
|
|
||||||
|
#oc代码以@end结尾,在其前面添加text
|
||||||
|
def appendTextToOCFile(file_path, text):
|
||||||
|
with open(file_path, "r") as fileObj:
|
||||||
|
old_text = fileObj.read()
|
||||||
|
fileObj.close()
|
||||||
|
end_mark_index = old_text.rfind("@end")
|
||||||
|
if end_mark_index == -1:
|
||||||
|
print("\t非法的结尾格式: " + file_path)
|
||||||
|
return
|
||||||
|
new_text = old_text[:end_mark_index]
|
||||||
|
new_text = new_text + text + "\n"
|
||||||
|
new_text = new_text + old_text[end_mark_index:]
|
||||||
|
|
||||||
|
with open(file_path, "w") as fileObj:
|
||||||
|
fileObj.write(new_text)
|
||||||
|
|
||||||
|
#处理单个OC文件,添加垃圾函数。确保其对应头文件存在于相同目录
|
||||||
|
def dealWithOCFile(filename, file_path):
|
||||||
|
global target_ios_folder,create_func_min,create_func_max,funcname_set
|
||||||
|
funcname_set.clear()
|
||||||
|
end_index = file_path.rfind(".")
|
||||||
|
pre_name = file_path[:end_index]
|
||||||
|
header_path = pre_name + ".h"
|
||||||
|
if not os.path.exists(header_path):
|
||||||
|
print ("\t相应头文件不存在:" + file_path)
|
||||||
|
return
|
||||||
|
|
||||||
|
new_func_num = random.randint(create_func_min, create_func_max)
|
||||||
|
print ("\t给%s添加%d个方法" %(filename, new_func_num))
|
||||||
|
for i in range(new_func_num):
|
||||||
|
header_text = getOCHeaderFuncText()
|
||||||
|
# print "add %s to %s" %(header_text, header_path.replace(target_ios_folder, ""))
|
||||||
|
appendTextToOCFile(header_path, header_text + ";\n")
|
||||||
|
funcText = getOCFuncText(header_text)
|
||||||
|
appendTextToOCFile(file_path, funcText)
|
||||||
|
|
||||||
|
#扫描parent_folder,添加垃圾函数,处理了忽略列表
|
||||||
|
def addOCFunctions(parent_folder):
|
||||||
|
global ignore_file_list
|
||||||
|
for parent, folders, files in os.walk(parent_folder):
|
||||||
|
need_ignore = None
|
||||||
|
for ignore_folder in ignore_folder_list:
|
||||||
|
if parent.find("/" + ignore_folder) != -1:
|
||||||
|
need_ignore = ignore_folder
|
||||||
|
break
|
||||||
|
if need_ignore:
|
||||||
|
print ("\t忽略文件夹" + ignore_folder)
|
||||||
|
continue
|
||||||
|
|
||||||
|
for file in files:
|
||||||
|
if file.endswith(".m") or file.endswith(".mm"):
|
||||||
|
if file in ignore_file_list:
|
||||||
|
continue
|
||||||
|
dealWithOCFile(file, os.path.join(parent, file))
|
||||||
|
|
||||||
|
#新创建的垃圾文件header模板
|
||||||
|
def getOCHeaderFileText(class_name):
|
||||||
|
global funcname_set
|
||||||
|
new_func_name = getOneName()
|
||||||
|
while new_func_name in funcname_set:
|
||||||
|
new_func_name = getOneName()
|
||||||
|
funcname_set.add(new_func_name)
|
||||||
|
|
||||||
|
text = [
|
||||||
|
"#import <Foundation/Foundation.h>\n\n",
|
||||||
|
"@interface %s : NSObject {\n" %(class_name),
|
||||||
|
"\tint %s;\n" %(new_func_name),
|
||||||
|
"\tfloat %s;\n" %(getOneName()),
|
||||||
|
"}\n\n@end"
|
||||||
|
]
|
||||||
|
return "".join(text)
|
||||||
|
|
||||||
|
#新创建的垃圾文件mm模板
|
||||||
|
def getOCMMFileText(class_name):
|
||||||
|
text = [
|
||||||
|
'#import "%s.h"\n\n' %(class_name),
|
||||||
|
"@implementation %s\n" %(class_name),
|
||||||
|
"\n\n@end"
|
||||||
|
]
|
||||||
|
return "".join(text)
|
||||||
|
|
||||||
|
#添加垃圾文件到parent_folder/trash/
|
||||||
|
def addOCFile(parent_folder):
|
||||||
|
global create_file_min, create_file_max
|
||||||
|
file_list = []
|
||||||
|
target_folder = os.path.join(parent_folder, "trash")
|
||||||
|
if os.path.exists(target_folder):
|
||||||
|
shutil.rmtree(target_folder)
|
||||||
|
os.mkdir(target_folder)
|
||||||
|
file_num = random.randint(create_file_min, create_file_max)
|
||||||
|
for i in range(file_num):
|
||||||
|
file_name = getOneName()
|
||||||
|
file_list.append("#import \"" + file_name + ".h\"")
|
||||||
|
print ("\t创建OC文件 trash/" + file_name)
|
||||||
|
header_text = getOCHeaderFileText(file_name)
|
||||||
|
full_path = os.path.join(target_folder, file_name + ".h")
|
||||||
|
with open(full_path, "w") as fileObj:
|
||||||
|
fileObj.write(header_text)
|
||||||
|
fileObj.close()
|
||||||
|
|
||||||
|
mm_text = getOCMMFileText(file_name)
|
||||||
|
full_path = os.path.join(target_folder, file_name + ".mm")
|
||||||
|
with open(full_path, "w") as fileObj:
|
||||||
|
fileObj.write(mm_text)
|
||||||
|
all_header_text = "\n".join(file_list)
|
||||||
|
|
||||||
|
with open(os.path.join(parent_folder, "Trash.h"), "w") as fileObj:
|
||||||
|
fileObj.write(all_header_text)
|
||||||
|
fileObj.close()
|
||||||
|
|
||||||
|
#解析参数
|
||||||
|
def parse_args():
|
||||||
|
parser = argparse.ArgumentParser(description='oc垃圾代码生成工具.')
|
||||||
|
parser.add_argument('--oc_folder', dest='oc_folder', type=str, required=True, help='OC代码所在目录')
|
||||||
|
parser.add_argument('--replace', dest='replace_ios', required=False, help='直接替换oc源代码', action="store_true")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
return args
|
||||||
|
|
||||||
|
def main():
|
||||||
|
app_args = parse_args()
|
||||||
|
global ios_src_path, backup_ios_folder, target_ios_folder
|
||||||
|
ios_src_path = app_args.oc_folder
|
||||||
|
if not os.path.exists(ios_src_path):
|
||||||
|
print ("oc_folder path not exist.")
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
print ("拷贝OC代码到target_ios")
|
||||||
|
if os.path.exists(target_ios_folder):
|
||||||
|
shutil.rmtree(target_ios_folder)
|
||||||
|
shutil.copytree(ios_src_path, target_ios_folder)
|
||||||
|
|
||||||
|
print ("开始创建oc文件到trash目录")
|
||||||
|
addOCFile(target_ios_folder)
|
||||||
|
print ("\n开始添加oc方法")
|
||||||
|
addOCFunctions(target_ios_folder)
|
||||||
|
|
||||||
|
if app_args.replace_ios:
|
||||||
|
print ("\n用target_ios替换原目录")
|
||||||
|
print ("\t备份OC代码到" + os.path.abspath(backup_ios_folder))
|
||||||
|
if os.path.exists(backup_ios_folder):
|
||||||
|
shutil.rmtree(backup_ios_folder)
|
||||||
|
shutil.copytree(ios_src_path, backup_ios_folder)
|
||||||
|
|
||||||
|
print ("\t开始替换")
|
||||||
|
trash_folder = os.path.join(ios_src_path, "trash")
|
||||||
|
if os.path.exists(trash_folder):
|
||||||
|
shutil.rmtree(trash_folder)
|
||||||
|
os.mkdir(trash_folder)
|
||||||
|
|
||||||
|
for parent, folders, files in os.walk(target_ios_folder):
|
||||||
|
for file in files:
|
||||||
|
if file.endswith(".h") or file.endswith(".m") or file.endswith(".mm"):
|
||||||
|
full_path = os.path.join(parent, file)
|
||||||
|
target_path = full_path.replace(target_ios_folder, ios_src_path)
|
||||||
|
shutil.copy(full_path, target_path)
|
||||||
|
print ("替换成功\n需要在Xcode上重新添加trash文件下的oc文件")
|
||||||
|
else:
|
||||||
|
print ("垃圾代码生成完毕,垃圾代码目录:" + os.path.abspath(target_ios_folder))
|
||||||
|
|
||||||
|
print ("\nfinished")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
174
HX/autoBornCode.py
Normal file
174
HX/autoBornCode.py
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
# -*- coding: UTF-8 -*-
|
||||||
|
import os,sys
|
||||||
|
import random
|
||||||
|
import string
|
||||||
|
import re
|
||||||
|
import time
|
||||||
|
import json
|
||||||
|
import shutil
|
||||||
|
import hashlib
|
||||||
|
import time
|
||||||
|
import argparse
|
||||||
|
#该脚本目前只针对Assets.xcassets目录下的文件进行副本、添加;
|
||||||
|
#即:在该脚本执行完毕之后,请将指定的--target 对应目录下的Assets.xcassets拷贝回工程项目替换原有的Assets.xcassets即可
|
||||||
|
#该脚本会修改原来的png图片的sha值,以及随机添加一些无效的且无法预览fake图片
|
||||||
|
script_path = os.path.split(os.path.realpath(sys.argv[0]))[0]
|
||||||
|
|
||||||
|
resource_path = ""
|
||||||
|
target_path = os.path.join(script_path, "target_resource")
|
||||||
|
|
||||||
|
#匹配规则,路径包含path_include且不包含path_exclude的才会创建对应类型的文件 os.path.sep:代表路径分隔符,即 /
|
||||||
|
match_rule = {
|
||||||
|
".png": {
|
||||||
|
# "path_include": os.path.sep + "res",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
#确保添加的函数不重名
|
||||||
|
funcname_set = set()
|
||||||
|
|
||||||
|
#单词列表,用以随机名称
|
||||||
|
with open(os.path.join(script_path, "./ClassName_list.json"), "r") as fileObj:
|
||||||
|
word_name_list = json.load(fileObj)
|
||||||
|
|
||||||
|
#获取一个随机名称
|
||||||
|
def getOneName():
|
||||||
|
global word_name_list
|
||||||
|
return random.choice(word_name_list)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#获取png内容
|
||||||
|
def getPngText():
|
||||||
|
hexbyte = "0000000049454e44ae426082"
|
||||||
|
text = str(random.randint(1, 100)) * random.randint(1024, 10240)
|
||||||
|
text = text + bytes.fromhex(hexbyte).hex()
|
||||||
|
text = text.encode('utf-8')
|
||||||
|
return text
|
||||||
|
|
||||||
|
#添加单个文件
|
||||||
|
def addSingleFile(file_path):
|
||||||
|
global target_path
|
||||||
|
print ("add file " + file_path.replace(target_path, ""))
|
||||||
|
_, file_type = os.path.splitext(file_path)
|
||||||
|
if file_type == ".png":
|
||||||
|
# print("发现png文件,准备在文件末尾追加hex文件操作...")
|
||||||
|
with open(file_path, "wb") as fileObj:
|
||||||
|
fileObj.write(getPngText())
|
||||||
|
fileObj.close()
|
||||||
|
|
||||||
|
def addFileTo(parent_folder, level, min_file_num=0):
|
||||||
|
global match_rule, target_path
|
||||||
|
create_folder_list = []
|
||||||
|
for parent, folders, files in os.walk(parent_folder):
|
||||||
|
target_file_type = ""
|
||||||
|
relative_path = parent.replace(target_path, "")
|
||||||
|
print("relative_path:"+relative_path)
|
||||||
|
for file_type, match_config in match_rule.items():
|
||||||
|
# print("file_type:" + file_type)
|
||||||
|
print("match_config:" + str(match_config))
|
||||||
|
|
||||||
|
if "path_exclude" in match_config and relative_path.find(match_config["path_exclude"]) != -1:
|
||||||
|
continue
|
||||||
|
if "path_include" not in match_config or relative_path.find(match_config["path_include"]) != -1:
|
||||||
|
target_file_type = file_type
|
||||||
|
# print("target_file_type:"+target_file_type)
|
||||||
|
break
|
||||||
|
if not target_file_type:
|
||||||
|
print("不在执行后续的addSingleFile步骤")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Create file count 创建 指定的最小文件数量 + 文件列表长度一半 到 文件列表长度 之间 的数量
|
||||||
|
new_file_num = random.randint(len(files) // 2, len(files)) + min_file_num
|
||||||
|
for i in range(new_file_num):
|
||||||
|
#根据随机的文件名 + 文件后缀类型 拼接为要创建的文件路径
|
||||||
|
file_path = os.path.join(parent, getOneName() + target_file_type)
|
||||||
|
addSingleFile(file_path)
|
||||||
|
print("已经执行addSingleFile步骤...")
|
||||||
|
# Prevent creating too many levels 如果该目录下已经被自动创建目录,则不再继续自动创建
|
||||||
|
if level > 2:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Create folder count
|
||||||
|
new_fold_num = random.randint(len(folders) // 2, len(folders))
|
||||||
|
for i in range(new_fold_num):
|
||||||
|
target_folder = os.path.join(parent, getOneName())
|
||||||
|
# Defer folder creation to avoid interrupting os.walk
|
||||||
|
create_folder_list.append(target_folder)
|
||||||
|
|
||||||
|
for folder_path in create_folder_list:
|
||||||
|
try:
|
||||||
|
print("create folder", folder_path.replace(target_path, ""))
|
||||||
|
os.makedirs(folder_path, exist_ok=True) # Handle existing folders
|
||||||
|
addFileTo(folder_path, level + 1, random.randint(2, 5))
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
#----------------------------------------ended add file----------------------
|
||||||
|
def changeSingleFileMD5(file_path):
|
||||||
|
pre_hash_valaue = calculate_sha256_hash(file_path)
|
||||||
|
# print("pre_hash_value:\n" + pre_hash_valaue)
|
||||||
|
_, file_type = os.path.splitext(file_path)
|
||||||
|
with open(file_path, "ab") as fileObj:
|
||||||
|
if file_type == ".png":
|
||||||
|
text = "".join(random.sample(string.ascii_letters, 11))
|
||||||
|
elif file_type == ".jpg":
|
||||||
|
text = "".join(random.sample(string.ascii_letters, 20))
|
||||||
|
else:
|
||||||
|
text = " "*random.randint(1, 100)
|
||||||
|
fileObj.write(text.encode('utf-8'))
|
||||||
|
fileObj.close()
|
||||||
|
after_hash_valaue = calculate_sha256_hash(file_path)
|
||||||
|
# print("after_hash_valaue:\n" + after_hash_valaue)
|
||||||
|
|
||||||
|
#改变文件md5
|
||||||
|
def changeFolderMD5(target_path):
|
||||||
|
# type_filter = set([".png", ".jpg", ".json", ".plist", ".fnt"])
|
||||||
|
#暂时不处理json、pilist文件
|
||||||
|
type_filter = set([".png", ".jpg"])
|
||||||
|
for parent, folders, files in os.walk(target_path):
|
||||||
|
for file in files:
|
||||||
|
full_path = os.path.join(parent, file)
|
||||||
|
_, file_type = os.path.splitext(full_path)
|
||||||
|
if file_type in type_filter:
|
||||||
|
changeSingleFileMD5(full_path)
|
||||||
|
|
||||||
|
#返回文件的hash值
|
||||||
|
def calculate_sha256_hash(file_path):
|
||||||
|
with open(file_path, 'rb') as f:
|
||||||
|
data = f.read()
|
||||||
|
hasher = hashlib.sha256()
|
||||||
|
hasher.update(data)
|
||||||
|
return hasher.hexdigest()
|
||||||
|
#----------------------------------------------------main------------------------------------------------
|
||||||
|
|
||||||
|
def parse_args():
|
||||||
|
global res_path
|
||||||
|
parser = argparse.ArgumentParser(description='资源变异工具')
|
||||||
|
parser.add_argument('--res', dest='res_dir', type=str, required=True, help='资源目录')
|
||||||
|
parser.add_argument('--target', dest='target_dir', type=str, required=False, default=target_path, help='资源导出目录')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
return args
|
||||||
|
|
||||||
|
def main():
|
||||||
|
global resource_path, target_path
|
||||||
|
app_args = parse_args()
|
||||||
|
resource_path = app_args.res_dir
|
||||||
|
target_path = app_args.target_dir
|
||||||
|
|
||||||
|
if not os.path.exists(resource_path):
|
||||||
|
print ("res path not exists: " + resource_path)
|
||||||
|
exit(0)
|
||||||
|
if target_path != resource_path:
|
||||||
|
if os.path.exists(target_path):
|
||||||
|
shutil.rmtree(target_path)
|
||||||
|
shutil.copytree(resource_path, target_path)
|
||||||
|
#执行png文件的添加、目录的创建
|
||||||
|
addFileTo(target_path, 0)
|
||||||
|
|
||||||
|
print ("\n\nstart modify file md5")
|
||||||
|
changeFolderMD5(target_path)
|
||||||
|
print ("finish!")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
301
HX/confuseAndBuild.sh
Normal file
301
HX/confuseAndBuild.sh
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# confuseAndBuild.sh
|
||||||
|
# ConfuseSwift
|
||||||
|
#
|
||||||
|
|
||||||
|
# ⚠️声明
|
||||||
|
# 1. 请将该脚本放在Xcode的Project工程的根目录。
|
||||||
|
# 2. 当前版本未配置完整Xcode环境变量,仅支持混淆功能,不支持framework编译,若需编译请用Xcode运行该脚本。
|
||||||
|
|
||||||
|
# ⚠️教程
|
||||||
|
# https://www.jianshu.com/p/be751f780d94
|
||||||
|
# 直接在终端cd到confuseAndBuild.sh上一层目录,然后运行./confuseAndBuild.sh -c 即可
|
||||||
|
|
||||||
|
|
||||||
|
if [ -z "$PROJECT_NAME" ]; then
|
||||||
|
CONFUSE_DIR="."
|
||||||
|
else
|
||||||
|
CONFUSE_DIR="${SRCROOT}/${PROJECT_NAME}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ⚠️自己配置自己的前缀
|
||||||
|
CONFUSE_PREFIX="hunxiao_"
|
||||||
|
|
||||||
|
BACKUP_FILE=".backup.log"
|
||||||
|
SYMBOL_FILE=".symbol.log"
|
||||||
|
CONFUSE_FILE=".confuse.log"
|
||||||
|
CONFUSE_FLAG=".confuseFlag"
|
||||||
|
|
||||||
|
SOURCE_ARRAY=( "*.swift"
|
||||||
|
"*.m"
|
||||||
|
"*.h"
|
||||||
|
"*.c"
|
||||||
|
"*.cpp")
|
||||||
|
BACKUP_EXTENSION=".bak"
|
||||||
|
|
||||||
|
|
||||||
|
# 格式:echo -e "\033[背景色;前景色m 打印的字符串 \033[0m"
|
||||||
|
# 颜色:重置=0,黑色=30,红色=31,绿色=32,黄色=33,蓝色=34,洋红=35,青色=36,白色=37。
|
||||||
|
# 示例:echo -e “\033[30m 我是黑色字 \033[0m”
|
||||||
|
# 参考:https://www.cnblogs.com/xiansong1005/p/7221316.html
|
||||||
|
# https://www.cnblogs.com/lr-ting/archive/2013/02/28/2936792.html
|
||||||
|
info() {
|
||||||
|
local green="\033[1;32m"
|
||||||
|
local normal="\033[0m"
|
||||||
|
echo -e "[${green}info${normal}] $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
local red="\033[1;31m"
|
||||||
|
local normal="\033[0m"
|
||||||
|
echo -e "[${red}error${normal}] $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 生成随机字符串 16字
|
||||||
|
randomString() {
|
||||||
|
random_string=$(openssl rand -base64 64 | tr -cd 'a-zA-Z' | head -c 8)
|
||||||
|
prefixed_string="water_$random_string"
|
||||||
|
echo "$prefixed_string"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 获取符号的随机字符串 $1是符号名
|
||||||
|
randomStringWithSymbol() {
|
||||||
|
grep -w $1 $SYMBOL_FILE -h | cut -d \ -f 2
|
||||||
|
}
|
||||||
|
|
||||||
|
removeIfExist() {
|
||||||
|
if [ -f $1 ]; then
|
||||||
|
rm $1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 备份文件 $1:file full path
|
||||||
|
backupFile() {
|
||||||
|
file=$1
|
||||||
|
# 在原文件名前加个.(点符合)用作备份名
|
||||||
|
fileName=${file##*/}
|
||||||
|
backupPath=${file/$fileName/.$fileName$BACKUP_EXTENSION}
|
||||||
|
echo "backup $file to $backupPath"
|
||||||
|
|
||||||
|
if [ ! -f $backupPath ]; then
|
||||||
|
cp $file $backupPath
|
||||||
|
echo $backupPath >>$BACKUP_FILE
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 方案1. 精确备份:用关键字遍历会修改到的source文件,再将其备份 -- 消耗性能
|
||||||
|
# 方案2. 整体备份:备份所有source文件 -- 消耗存储空间
|
||||||
|
# 根据需要,为简单起见,这里选用方案2
|
||||||
|
backupAllSource() {
|
||||||
|
info "backup all swift files"
|
||||||
|
NAMES="-name \"${SOURCE_ARRAY[0]}\""
|
||||||
|
i=1
|
||||||
|
while [ $i -lt ${#SOURCE_ARRAY[@]} ]; do
|
||||||
|
NAMES+=" -or -name \"${SOURCE_ARRAY[$i]}\""
|
||||||
|
let i++
|
||||||
|
done
|
||||||
|
# echo $NAMES
|
||||||
|
|
||||||
|
removeIfExist $BACKUP_FILE
|
||||||
|
touch $BACKUP_FILE
|
||||||
|
|
||||||
|
eval "find $CONFUSE_DIR $NAMES" | while read file; do
|
||||||
|
backupFile $file
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# 混淆工作, ⚠️该函数不会自动备份,要备份请调用safeConfuse函数
|
||||||
|
confuseOnly() {
|
||||||
|
info "confuse start..."
|
||||||
|
|
||||||
|
# 获取要混淆的函数名和变量名
|
||||||
|
INCLUDES="--include=\"${SOURCE_ARRAY[0]}\""
|
||||||
|
i=1
|
||||||
|
while [ $i -lt ${#SOURCE_ARRAY[@]} ]; do
|
||||||
|
INCLUDES+=" --include=\"${SOURCE_ARRAY[$i]}\""
|
||||||
|
let i++
|
||||||
|
done
|
||||||
|
eval "grep $CONFUSE_PREFIX -r $CONFUSE_DIR $INCLUDES -n" >$CONFUSE_FILE
|
||||||
|
|
||||||
|
# cat $CONFUSE_FILE
|
||||||
|
# 绑定随机字符串
|
||||||
|
removeIfExist $SYMBOL_FILE
|
||||||
|
touch $SYMBOL_FILE
|
||||||
|
|
||||||
|
cat $CONFUSE_FILE | egrep -w $CONFUSE_PREFIX"[0-9a-zA-Z_]*" -o | sort | uniq | while read line; do
|
||||||
|
echo $line" `randomString`" >>$SYMBOL_FILE
|
||||||
|
done
|
||||||
|
|
||||||
|
# cat $SYMBOL_FILE
|
||||||
|
|
||||||
|
# 读取备份文件记录
|
||||||
|
# 在这里没使用遍历批量替换,怕文件太多的时候影响性能
|
||||||
|
cat $CONFUSE_FILE | while read line; do
|
||||||
|
# echo "> $line"
|
||||||
|
# 截取行号
|
||||||
|
lineNum=`echo $line | sed 's/.*:\([0-9]*\):.*/\1/g'`
|
||||||
|
# 截取文件路径
|
||||||
|
path=${line%%:*}
|
||||||
|
|
||||||
|
# 一行可能有多个要替换的子串,要循环遍历完
|
||||||
|
# 这里之所以要用`sort -r`倒序是因为有个bug:如有字符串"jjyy abc hello abcde", 现在要替换"abc"为"123"(abcde保持不变),也就是传说中的‘全匹配替换’,
|
||||||
|
# 但不知为何在macOS下单词边界表达式不起作用:\<abc\> 或者 \babc\b都不起作用,Linux下这个正则表达式是没问题的。
|
||||||
|
# 倒序之后有长串优先替换长串,防止短串把长串部分替换掉。但依然存在bug:若是长串不需要替换,则短串替换是依然会将长串部分替换😂
|
||||||
|
# 因此依然还需要寻找macOS下单词边界/全匹配 的正则表达式
|
||||||
|
echo $line | egrep -w $CONFUSE_PREFIX"[0-9a-zA-Z_]*" -o | sort -r | while read -ra symbol; do
|
||||||
|
# 根据名称获取绑定的随机字符串
|
||||||
|
random=`randomStringWithSymbol $symbol`
|
||||||
|
# echo "$path $lineNum $symbol $random"
|
||||||
|
# 随机字符串替换
|
||||||
|
# -i:表示直接在原文件替换,"":表示不要备份
|
||||||
|
sed -i "" "${lineNum}s/$symbol/$random/g" $path
|
||||||
|
|
||||||
|
echo " $symbol => $random"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
info "confuse done"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 编译工作,生成通用framework
|
||||||
|
buildAll() {
|
||||||
|
info "build start..."
|
||||||
|
|
||||||
|
if [ -z "$PROJECT_NAME" ]; then
|
||||||
|
echo -e "\033[1;31mERROR:当前版本未配置完整Xcode环境变量,仅支持混淆功能,不支持framework编译,若需编译请用Xcode运行该脚本\033[0m"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 要build的target名
|
||||||
|
TARGET_NAME=${PROJECT_NAME}
|
||||||
|
UNIVERSAL_OUTPUT_DIR="${SRCROOT}/Framework/"
|
||||||
|
|
||||||
|
# 创建输出目录,并删除之前的framework文件
|
||||||
|
mkdir -p "${UNIVERSAL_OUTPUT_DIR}"
|
||||||
|
rm -rf "${UNIVERSAL_OUTPUT_DIR}/${TARGET_NAME}.framework"
|
||||||
|
|
||||||
|
#分别编译模拟器和真机的Framework
|
||||||
|
xcodebuild -target "${TARGET_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} ARCHS="armv7 armv7s arm64" -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
|
||||||
|
xcodebuild -target "${TARGET_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} ARCHS="i386 x86_64" -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
|
||||||
|
|
||||||
|
#拷贝framework到univer目录
|
||||||
|
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${TARGET_NAME}.framework" "${UNIVERSAL_OUTPUT_DIR}"
|
||||||
|
|
||||||
|
# 合并swiftmodule到univer目录
|
||||||
|
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework/Modules/${TARGET_NAME}.swiftmodule/" "${UNIVERSAL_OUTPUT_DIR}/${TARGET_NAME}.framework/Modules/${TARGET_NAME}.swiftmodule"
|
||||||
|
|
||||||
|
#合并framework,输出最终的framework到build目录
|
||||||
|
lipo -create -output "${UNIVERSAL_OUTPUT_DIR}/${TARGET_NAME}.framework/${TARGET_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework/${TARGET_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${TARGET_NAME}.framework/${TARGET_NAME}"
|
||||||
|
|
||||||
|
#删除编译之后生成的无关的配置文件
|
||||||
|
dir_path="${UNIVERSAL_OUTPUT_DIR}/${TARGET_NAME}.framework/"
|
||||||
|
for file in ls $dir_path; do
|
||||||
|
if [[ ${file} =~ ".xcconfig" ]]; then
|
||||||
|
rm -f "${dir_path}/${file}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
#判断build文件夹是否存在,存在则删除
|
||||||
|
if [ -d "${SRCROOT}/build" ]; then
|
||||||
|
rm -rf "${SRCROOT}/build"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#rm -rf "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator" "${BUILD_DIR}/${CONFIGURATION}-iphoneos"
|
||||||
|
|
||||||
|
#打开合并后的文件夹
|
||||||
|
open "${UNIVERSAL_OUTPUT_DIR}"
|
||||||
|
|
||||||
|
info "build done"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 清理工作,去混淆
|
||||||
|
unconfuse() {
|
||||||
|
info "clean start..."
|
||||||
|
if [ -f $CONFUSE_FLAG ]; then
|
||||||
|
# 恢复混淆的函数名所在source文件的bak内容
|
||||||
|
cat $BACKUP_FILE | while read backup; do
|
||||||
|
backupName=${backup##*/}
|
||||||
|
fileName=`echo $backupName | cut -d "." -f2,3`
|
||||||
|
filePath=${backup/$backupName/$fileName}
|
||||||
|
|
||||||
|
echo "recover $backup to $filePath"
|
||||||
|
|
||||||
|
cp $backup $filePath
|
||||||
|
rm $backup
|
||||||
|
done
|
||||||
|
# 删除修改记录
|
||||||
|
removeIfExist $SYMBOL_FILE
|
||||||
|
removeIfExist $CONFUSE_FILE
|
||||||
|
removeIfExist $BACKUP_FILE
|
||||||
|
removeIfExist $CONFUSE_FLAG
|
||||||
|
else
|
||||||
|
echo "Not confuse yet!"
|
||||||
|
fi
|
||||||
|
info "clean done"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查是否上次未完成
|
||||||
|
precheck() {
|
||||||
|
# 创建一个隐藏文件,仅标记混淆编译的状态
|
||||||
|
# 由于编译过程有可能被中断,因此混淆后的代码可能未恢复,在开始备份前先做判断
|
||||||
|
unconfuse
|
||||||
|
touch $CONFUSE_FLAG
|
||||||
|
}
|
||||||
|
|
||||||
|
# 去混淆->备份->混淆
|
||||||
|
safeConfuse() {
|
||||||
|
precheck
|
||||||
|
backupAllSource
|
||||||
|
confuseOnly
|
||||||
|
}
|
||||||
|
|
||||||
|
# 去混淆->备份->混淆
|
||||||
|
# 编译
|
||||||
|
# 去混淆
|
||||||
|
safeConfuseAndBuild() {
|
||||||
|
info "preparing confuse and build..."
|
||||||
|
|
||||||
|
safeConfuse
|
||||||
|
buildAll
|
||||||
|
unconfuse
|
||||||
|
|
||||||
|
info "all done"
|
||||||
|
}
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo -e "\033[1;31musage: ./confuseAndBuild.sh [-u|c|b|a]"
|
||||||
|
echo -e " -u"
|
||||||
|
echo -e " unconfuse: 清理工作,去混淆"
|
||||||
|
echo -e " -c"
|
||||||
|
echo -e " safeConfuse: 去混淆->备份->混淆"
|
||||||
|
echo -e " -b"
|
||||||
|
echo -e " buildAll: 编译生成通用framework"
|
||||||
|
echo -e " -a"
|
||||||
|
echo -e " safeConfuseAndBuild: 去混淆->备份->混淆->编译->去混淆"
|
||||||
|
echo -e "EXAMPLE:"
|
||||||
|
echo -e " ./confuseAndBuild.sh -u\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
echo "参数个数:$# 参数值:$1"
|
||||||
|
case $1 in
|
||||||
|
"-u" )
|
||||||
|
unconfuse
|
||||||
|
;;
|
||||||
|
"-c" )
|
||||||
|
safeConfuse
|
||||||
|
;;
|
||||||
|
"-b" )
|
||||||
|
buildAll
|
||||||
|
;;
|
||||||
|
"-a" )
|
||||||
|
safeConfuseAndBuild
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
main $@
|
||||||
301
HX/confuseAndBuild.txt
Normal file
301
HX/confuseAndBuild.txt
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# confuseAndBuild.sh
|
||||||
|
# ConfuseSwift
|
||||||
|
#
|
||||||
|
|
||||||
|
# ⚠️声明
|
||||||
|
# 1. 请将该脚本放在Xcode的Project工程的根目录。
|
||||||
|
# 2. 当前版本未配置完整Xcode环境变量,仅支持混淆功能,不支持framework编译,若需编译请用Xcode运行该脚本。
|
||||||
|
|
||||||
|
# ⚠️教程
|
||||||
|
# https://www.jianshu.com/p/be751f780d94
|
||||||
|
# 直接在终端cd到confuseAndBuild.sh上一层目录,然后运行./confuseAndBuild.sh -c 即可
|
||||||
|
|
||||||
|
|
||||||
|
if [ -z "$PROJECT_NAME" ]; then
|
||||||
|
CONFUSE_DIR="."
|
||||||
|
else
|
||||||
|
CONFUSE_DIR="${SRCROOT}/${PROJECT_NAME}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ⚠️自己配置自己的前缀
|
||||||
|
CONFUSE_PREFIX="hunxiao_"
|
||||||
|
|
||||||
|
BACKUP_FILE=".backup.log"
|
||||||
|
SYMBOL_FILE=".symbol.log"
|
||||||
|
CONFUSE_FILE=".confuse.log"
|
||||||
|
CONFUSE_FLAG=".confuseFlag"
|
||||||
|
|
||||||
|
SOURCE_ARRAY=( "*.swift"
|
||||||
|
"*.m"
|
||||||
|
"*.h"
|
||||||
|
"*.c"
|
||||||
|
"*.cpp")
|
||||||
|
BACKUP_EXTENSION=".bak"
|
||||||
|
|
||||||
|
|
||||||
|
# 格式:echo -e "\033[背景色;前景色m 打印的字符串 \033[0m"
|
||||||
|
# 颜色:重置=0,黑色=30,红色=31,绿色=32,黄色=33,蓝色=34,洋红=35,青色=36,白色=37。
|
||||||
|
# 示例:echo -e “\033[30m 我是黑色字 \033[0m”
|
||||||
|
# 参考:https://www.cnblogs.com/xiansong1005/p/7221316.html
|
||||||
|
# https://www.cnblogs.com/lr-ting/archive/2013/02/28/2936792.html
|
||||||
|
info() {
|
||||||
|
local green="\033[1;32m"
|
||||||
|
local normal="\033[0m"
|
||||||
|
echo -e "[${green}info${normal}] $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
local red="\033[1;31m"
|
||||||
|
local normal="\033[0m"
|
||||||
|
echo -e "[${red}error${normal}] $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 生成随机字符串 16字
|
||||||
|
randomString() {
|
||||||
|
random_string=$(openssl rand -base64 64 | tr -cd 'a-zA-Z' | head -c 8)
|
||||||
|
prefixed_string="water_$random_string"
|
||||||
|
echo "$prefixed_string"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 获取符号的随机字符串 $1是符号名
|
||||||
|
randomStringWithSymbol() {
|
||||||
|
grep -w $1 $SYMBOL_FILE -h | cut -d \ -f 2
|
||||||
|
}
|
||||||
|
|
||||||
|
removeIfExist() {
|
||||||
|
if [ -f $1 ]; then
|
||||||
|
rm $1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 备份文件 $1:file full path
|
||||||
|
backupFile() {
|
||||||
|
file=$1
|
||||||
|
# 在原文件名前加个.(点符合)用作备份名
|
||||||
|
fileName=${file##*/}
|
||||||
|
backupPath=${file/$fileName/.$fileName$BACKUP_EXTENSION}
|
||||||
|
echo "backup $file to $backupPath"
|
||||||
|
|
||||||
|
if [ ! -f $backupPath ]; then
|
||||||
|
cp $file $backupPath
|
||||||
|
echo $backupPath >>$BACKUP_FILE
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 方案1. 精确备份:用关键字遍历会修改到的source文件,再将其备份 -- 消耗性能
|
||||||
|
# 方案2. 整体备份:备份所有source文件 -- 消耗存储空间
|
||||||
|
# 根据需要,为简单起见,这里选用方案2
|
||||||
|
backupAllSource() {
|
||||||
|
info "backup all swift files"
|
||||||
|
NAMES="-name \"${SOURCE_ARRAY[0]}\""
|
||||||
|
i=1
|
||||||
|
while [ $i -lt ${#SOURCE_ARRAY[@]} ]; do
|
||||||
|
NAMES+=" -or -name \"${SOURCE_ARRAY[$i]}\""
|
||||||
|
let i++
|
||||||
|
done
|
||||||
|
# echo $NAMES
|
||||||
|
|
||||||
|
removeIfExist $BACKUP_FILE
|
||||||
|
touch $BACKUP_FILE
|
||||||
|
|
||||||
|
eval "find $CONFUSE_DIR $NAMES" | while read file; do
|
||||||
|
backupFile $file
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# 混淆工作, ⚠️该函数不会自动备份,要备份请调用safeConfuse函数
|
||||||
|
confuseOnly() {
|
||||||
|
info "confuse start..."
|
||||||
|
|
||||||
|
# 获取要混淆的函数名和变量名
|
||||||
|
INCLUDES="--include=\"${SOURCE_ARRAY[0]}\""
|
||||||
|
i=1
|
||||||
|
while [ $i -lt ${#SOURCE_ARRAY[@]} ]; do
|
||||||
|
INCLUDES+=" --include=\"${SOURCE_ARRAY[$i]}\""
|
||||||
|
let i++
|
||||||
|
done
|
||||||
|
eval "grep $CONFUSE_PREFIX -r $CONFUSE_DIR $INCLUDES -n" >$CONFUSE_FILE
|
||||||
|
|
||||||
|
# cat $CONFUSE_FILE
|
||||||
|
# 绑定随机字符串
|
||||||
|
removeIfExist $SYMBOL_FILE
|
||||||
|
touch $SYMBOL_FILE
|
||||||
|
|
||||||
|
cat $CONFUSE_FILE | egrep -w $CONFUSE_PREFIX"[0-9a-zA-Z_]*" -o | sort | uniq | while read line; do
|
||||||
|
echo $line" `randomString`" >>$SYMBOL_FILE
|
||||||
|
done
|
||||||
|
|
||||||
|
# cat $SYMBOL_FILE
|
||||||
|
|
||||||
|
# 读取备份文件记录
|
||||||
|
# 在这里没使用遍历批量替换,怕文件太多的时候影响性能
|
||||||
|
cat $CONFUSE_FILE | while read line; do
|
||||||
|
# echo "> $line"
|
||||||
|
# 截取行号
|
||||||
|
lineNum=`echo $line | sed 's/.*:\([0-9]*\):.*/\1/g'`
|
||||||
|
# 截取文件路径
|
||||||
|
path=${line%%:*}
|
||||||
|
|
||||||
|
# 一行可能有多个要替换的子串,要循环遍历完
|
||||||
|
# 这里之所以要用`sort -r`倒序是因为有个bug:如有字符串"jjyy abc hello abcde", 现在要替换"abc"为"123"(abcde保持不变),也就是传说中的‘全匹配替换’,
|
||||||
|
# 但不知为何在macOS下单词边界表达式不起作用:\<abc\> 或者 \babc\b都不起作用,Linux下这个正则表达式是没问题的。
|
||||||
|
# 倒序之后有长串优先替换长串,防止短串把长串部分替换掉。但依然存在bug:若是长串不需要替换,则短串替换是依然会将长串部分替换😂
|
||||||
|
# 因此依然还需要寻找macOS下单词边界/全匹配 的正则表达式
|
||||||
|
echo $line | egrep -w $CONFUSE_PREFIX"[0-9a-zA-Z_]*" -o | sort -r | while read -ra symbol; do
|
||||||
|
# 根据名称获取绑定的随机字符串
|
||||||
|
random=`randomStringWithSymbol $symbol`
|
||||||
|
# echo "$path $lineNum $symbol $random"
|
||||||
|
# 随机字符串替换
|
||||||
|
# -i:表示直接在原文件替换,"":表示不要备份
|
||||||
|
sed -i "" "${lineNum}s/$symbol/$random/g" $path
|
||||||
|
|
||||||
|
echo " $symbol => $random"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
info "confuse done"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 编译工作,生成通用framework
|
||||||
|
buildAll() {
|
||||||
|
info "build start..."
|
||||||
|
|
||||||
|
if [ -z "$PROJECT_NAME" ]; then
|
||||||
|
echo -e "\033[1;31mERROR:当前版本未配置完整Xcode环境变量,仅支持混淆功能,不支持framework编译,若需编译请用Xcode运行该脚本\033[0m"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 要build的target名
|
||||||
|
TARGET_NAME=${PROJECT_NAME}
|
||||||
|
UNIVERSAL_OUTPUT_DIR="${SRCROOT}/Framework/"
|
||||||
|
|
||||||
|
# 创建输出目录,并删除之前的framework文件
|
||||||
|
mkdir -p "${UNIVERSAL_OUTPUT_DIR}"
|
||||||
|
rm -rf "${UNIVERSAL_OUTPUT_DIR}/${TARGET_NAME}.framework"
|
||||||
|
|
||||||
|
#分别编译模拟器和真机的Framework
|
||||||
|
xcodebuild -target "${TARGET_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} ARCHS="armv7 armv7s arm64" -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
|
||||||
|
xcodebuild -target "${TARGET_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} ARCHS="i386 x86_64" -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
|
||||||
|
|
||||||
|
#拷贝framework到univer目录
|
||||||
|
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${TARGET_NAME}.framework" "${UNIVERSAL_OUTPUT_DIR}"
|
||||||
|
|
||||||
|
# 合并swiftmodule到univer目录
|
||||||
|
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework/Modules/${TARGET_NAME}.swiftmodule/" "${UNIVERSAL_OUTPUT_DIR}/${TARGET_NAME}.framework/Modules/${TARGET_NAME}.swiftmodule"
|
||||||
|
|
||||||
|
#合并framework,输出最终的framework到build目录
|
||||||
|
lipo -create -output "${UNIVERSAL_OUTPUT_DIR}/${TARGET_NAME}.framework/${TARGET_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework/${TARGET_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${TARGET_NAME}.framework/${TARGET_NAME}"
|
||||||
|
|
||||||
|
#删除编译之后生成的无关的配置文件
|
||||||
|
dir_path="${UNIVERSAL_OUTPUT_DIR}/${TARGET_NAME}.framework/"
|
||||||
|
for file in ls $dir_path; do
|
||||||
|
if [[ ${file} =~ ".xcconfig" ]]; then
|
||||||
|
rm -f "${dir_path}/${file}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
#判断build文件夹是否存在,存在则删除
|
||||||
|
if [ -d "${SRCROOT}/build" ]; then
|
||||||
|
rm -rf "${SRCROOT}/build"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#rm -rf "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator" "${BUILD_DIR}/${CONFIGURATION}-iphoneos"
|
||||||
|
|
||||||
|
#打开合并后的文件夹
|
||||||
|
open "${UNIVERSAL_OUTPUT_DIR}"
|
||||||
|
|
||||||
|
info "build done"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 清理工作,去混淆
|
||||||
|
unconfuse() {
|
||||||
|
info "clean start..."
|
||||||
|
if [ -f $CONFUSE_FLAG ]; then
|
||||||
|
# 恢复混淆的函数名所在source文件的bak内容
|
||||||
|
cat $BACKUP_FILE | while read backup; do
|
||||||
|
backupName=${backup##*/}
|
||||||
|
fileName=`echo $backupName | cut -d "." -f2,3`
|
||||||
|
filePath=${backup/$backupName/$fileName}
|
||||||
|
|
||||||
|
echo "recover $backup to $filePath"
|
||||||
|
|
||||||
|
cp $backup $filePath
|
||||||
|
rm $backup
|
||||||
|
done
|
||||||
|
# 删除修改记录
|
||||||
|
removeIfExist $SYMBOL_FILE
|
||||||
|
removeIfExist $CONFUSE_FILE
|
||||||
|
removeIfExist $BACKUP_FILE
|
||||||
|
removeIfExist $CONFUSE_FLAG
|
||||||
|
else
|
||||||
|
echo "Not confuse yet!"
|
||||||
|
fi
|
||||||
|
info "clean done"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查是否上次未完成
|
||||||
|
precheck() {
|
||||||
|
# 创建一个隐藏文件,仅标记混淆编译的状态
|
||||||
|
# 由于编译过程有可能被中断,因此混淆后的代码可能未恢复,在开始备份前先做判断
|
||||||
|
unconfuse
|
||||||
|
touch $CONFUSE_FLAG
|
||||||
|
}
|
||||||
|
|
||||||
|
# 去混淆->备份->混淆
|
||||||
|
safeConfuse() {
|
||||||
|
precheck
|
||||||
|
backupAllSource
|
||||||
|
confuseOnly
|
||||||
|
}
|
||||||
|
|
||||||
|
# 去混淆->备份->混淆
|
||||||
|
# 编译
|
||||||
|
# 去混淆
|
||||||
|
safeConfuseAndBuild() {
|
||||||
|
info "preparing confuse and build..."
|
||||||
|
|
||||||
|
safeConfuse
|
||||||
|
buildAll
|
||||||
|
unconfuse
|
||||||
|
|
||||||
|
info "all done"
|
||||||
|
}
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo -e "\033[1;31musage: ./confuseAndBuild.sh [-u|c|b|a]"
|
||||||
|
echo -e " -u"
|
||||||
|
echo -e " unconfuse: 清理工作,去混淆"
|
||||||
|
echo -e " -c"
|
||||||
|
echo -e " safeConfuse: 去混淆->备份->混淆"
|
||||||
|
echo -e " -b"
|
||||||
|
echo -e " buildAll: 编译生成通用framework"
|
||||||
|
echo -e " -a"
|
||||||
|
echo -e " safeConfuseAndBuild: 去混淆->备份->混淆->编译->去混淆"
|
||||||
|
echo -e "EXAMPLE:"
|
||||||
|
echo -e " ./confuseAndBuild.sh -u\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
echo "参数个数:$# 参数值:$1"
|
||||||
|
case $1 in
|
||||||
|
"-u" )
|
||||||
|
unconfuse
|
||||||
|
;;
|
||||||
|
"-c" )
|
||||||
|
safeConfuse
|
||||||
|
;;
|
||||||
|
"-b" )
|
||||||
|
buildAll
|
||||||
|
;;
|
||||||
|
"-a" )
|
||||||
|
safeConfuseAndBuild
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
main $@
|
||||||
183
HX/renameNative.py
Normal file
183
HX/renameNative.py
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
# -*- coding: UTF-8 -*-
|
||||||
|
import os,sys
|
||||||
|
import random
|
||||||
|
import string
|
||||||
|
import re
|
||||||
|
#import md5
|
||||||
|
import time
|
||||||
|
import json
|
||||||
|
import shutil
|
||||||
|
import hashlib
|
||||||
|
import time
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
script_path = os.path.split(os.path.realpath(sys.argv[0]))[0]
|
||||||
|
add_prefix = ""
|
||||||
|
old_prefix = "ZZH_"
|
||||||
|
new_prefix = "BSHighCode"
|
||||||
|
ios_src_path = ""
|
||||||
|
project_file_path = ""
|
||||||
|
|
||||||
|
ignore_path_text = [".a", ".png", ".plist", ".storyboard", ".pch"]
|
||||||
|
|
||||||
|
#首字母大写
|
||||||
|
def isNeedIgnore(file_path):
|
||||||
|
global ignore_path_text
|
||||||
|
for ignore_text in ignore_path_text:
|
||||||
|
if file_path.find(ignore_text) != -1:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def replaceStringInFile(full_path, old_text, new_text):
|
||||||
|
with open(full_path, "r",errors="ignore") as fileObj:
|
||||||
|
all_text = fileObj.read()
|
||||||
|
fileObj.close()
|
||||||
|
|
||||||
|
all_text = all_text.replace(old_text, new_text)
|
||||||
|
with open(full_path, "w",errors="ignore") as fileObj:
|
||||||
|
fileObj.write(all_text)
|
||||||
|
fileObj.close()
|
||||||
|
|
||||||
|
def renameFileInXcodeProj(old_file_name, new_file_name):
|
||||||
|
global project_file_path
|
||||||
|
if os.path.exists(project_file_path):
|
||||||
|
replaceStringInFile(project_file_path, old_file_name, new_file_name)
|
||||||
|
|
||||||
|
#替换文件中的文本内容:匹配到的文本被替换为指定的new_text
|
||||||
|
def renameInAllFile(old_text, new_text):
|
||||||
|
global ios_src_path
|
||||||
|
for parent, folders, files in os.walk(ios_src_path):
|
||||||
|
for file in files:
|
||||||
|
full_path = os.path.join(parent, file)
|
||||||
|
replaceStringInFile(full_path, old_text, new_text)
|
||||||
|
|
||||||
|
#开始重命名类名
|
||||||
|
def dealWithIos(folder_path):
|
||||||
|
print ("开始重命名类名")
|
||||||
|
global old_prefix, new_prefix
|
||||||
|
for parent, folders, files in os.walk(folder_path):
|
||||||
|
#先处理每个文件的名字
|
||||||
|
for file in files:
|
||||||
|
print("\n the file:" + file + "\n")
|
||||||
|
#得到该文件的路径
|
||||||
|
old_full_path = os.path.join(parent, file)
|
||||||
|
#如果该文件名称匹配为需要重命名的类名 名称,并且该文本不属于被忽略的文件,则需要执行重命名操作
|
||||||
|
if file.startswith(old_prefix) and not isNeedIgnore(old_full_path):
|
||||||
|
#将该文件名称中匹配上的文本部分替换为new_prefix,并得到新文件名 名称
|
||||||
|
new_file_name = file.replace(old_prefix, new_prefix)
|
||||||
|
print ("\t重命名文件: %s -> %s" %(file, new_file_name))
|
||||||
|
#合成新文件名对应的文件路径
|
||||||
|
new_full_path = os.path.join(parent, new_file_name)
|
||||||
|
#将原来的文件改命为新的文件名称
|
||||||
|
os.rename(old_full_path, new_full_path)
|
||||||
|
#在项目工程中改名
|
||||||
|
renameFileInXcodeProj(file, new_file_name)
|
||||||
|
|
||||||
|
#在可能引用的地方替换,获取不带文件名后缀的部分
|
||||||
|
old_file_base_name = os.path.splitext(file)[0]
|
||||||
|
print("\n the old_file_base_name:" + old_file_base_name + "\n")
|
||||||
|
new_file_base_name = old_file_base_name.replace(old_prefix, new_prefix)
|
||||||
|
#将ios_src_path 所指定的目录下的所有old_file_base_name文本(主要是指的类名) 替换为新的new_file_base_name文本 (类名)
|
||||||
|
renameInAllFile(old_file_base_name, new_file_base_name)
|
||||||
|
|
||||||
|
for parent, folders, files in os.walk(folder_path):
|
||||||
|
for folder in folders:
|
||||||
|
old_full_path = os.path.join(parent, folder)
|
||||||
|
#递归处理该目录下的内容
|
||||||
|
# dealWithIos(old_full_path)
|
||||||
|
if folder.startswith(old_prefix) and not isNeedIgnore(old_full_path):
|
||||||
|
new_folder_name = folder.replace(old_prefix, new_prefix)
|
||||||
|
print ("\t重命名文件夹: %s -> %s" %(folder, new_folder_name))
|
||||||
|
new_full_path = os.path.join(parent, new_folder_name)
|
||||||
|
os.rename(old_full_path, new_full_path)
|
||||||
|
#在项目工程中改名
|
||||||
|
renameFileInXcodeProj(folder, new_folder_name)
|
||||||
|
print ("finish\n")
|
||||||
|
|
||||||
|
#开始添加前缀
|
||||||
|
def addPreFix():
|
||||||
|
print ("开始添加前缀")
|
||||||
|
global add_prefix, ios_src_path
|
||||||
|
for parent, folders, files in os.walk(ios_src_path):
|
||||||
|
for file in files:
|
||||||
|
old_full_path = os.path.join(parent, file)
|
||||||
|
if not isNeedIgnore(old_full_path):
|
||||||
|
new_file_name = add_prefix + file
|
||||||
|
print ("\t重命名文件: %s -> %s" %(file, new_file_name))
|
||||||
|
|
||||||
|
new_full_path = os.path.join(parent, new_file_name)
|
||||||
|
os.rename(old_full_path, new_full_path)
|
||||||
|
#在项目工程中改名
|
||||||
|
renameFileInXcodeProj(file, new_file_name)
|
||||||
|
|
||||||
|
#在可能引用的地方替换
|
||||||
|
old_file_base_name = os.path.splitext(file)[0]
|
||||||
|
new_file_base_name = os.path.splitext(new_file_name)[0]
|
||||||
|
renameInAllFile(old_file_base_name, new_file_base_name)
|
||||||
|
renameInAllFile(add_prefix+add_prefix, add_prefix)
|
||||||
|
|
||||||
|
for parent, folders, files in os.walk(ios_src_path):
|
||||||
|
for folder in folders:
|
||||||
|
old_full_path = os.path.join(parent, folder)
|
||||||
|
if not isNeedIgnore(old_full_path):
|
||||||
|
new_folder_name = add_prefix + folder
|
||||||
|
print ("\t重命名文件夹: %s -> %s" %(folder, new_folder_name))
|
||||||
|
new_full_path = os.path.join(parent, new_folder_name)
|
||||||
|
os.rename(old_full_path, new_full_path)
|
||||||
|
#在项目工程中改名
|
||||||
|
renameFileInXcodeProj(folder, new_folder_name)
|
||||||
|
print ("finish\n")
|
||||||
|
|
||||||
|
#给方法添加前缀
|
||||||
|
#.....
|
||||||
|
|
||||||
|
|
||||||
|
#修改指定前缀的方法名
|
||||||
|
#....
|
||||||
|
|
||||||
|
#给每个方法的起始行处 添加垃圾代码
|
||||||
|
#......
|
||||||
|
|
||||||
|
#----------------------------------------------------main------------------------------------------------
|
||||||
|
def parse_args():
|
||||||
|
global script_path, proj_ios_path
|
||||||
|
parser = argparse.ArgumentParser(description='修改类名前缀工具.\n')
|
||||||
|
parser.add_argument('--add_prefix', dest='add_prefix', type=str, required=False, default="", help='添加类名前缀')
|
||||||
|
parser.add_argument('--old_prefix', dest='old_prefix', type=str, required=False, help='原类名前缀')
|
||||||
|
parser.add_argument('--new_prefix', dest='new_prefix', type=str, required=False, help='替换后类名前缀')
|
||||||
|
parser.add_argument('--ios_path', dest='ios_path', type=str, required=True, help='OC文件目录')
|
||||||
|
parser.add_argument('--proj_path', dest='proj_path', type=str, required=False, default="", help='xx.xcodeproj路径')
|
||||||
|
args = parser.parse_args()
|
||||||
|
return args
|
||||||
|
|
||||||
|
def main():
|
||||||
|
global old_prefix, new_prefix, ios_src_path, project_file_path, add_prefix
|
||||||
|
app_args = parse_args()
|
||||||
|
|
||||||
|
add_prefix = app_args.add_prefix
|
||||||
|
old_prefix = app_args.old_prefix
|
||||||
|
new_prefix = app_args.new_prefix
|
||||||
|
ios_src_path = app_args.ios_path
|
||||||
|
project_file_path = os.path.join(app_args.proj_path, "project.pbxproj")
|
||||||
|
if not os.path.exists(ios_src_path):
|
||||||
|
print ("ios_path not exists: " + ios_src_path)
|
||||||
|
exit(0)
|
||||||
|
if not os.path.exists(project_file_path):
|
||||||
|
print ("proj_path not exists: " + project_file_path)
|
||||||
|
|
||||||
|
print ("请提前备份文件夹或确认在版本管理软件中")
|
||||||
|
input("回车继续执行")
|
||||||
|
#给类名添加前缀:实际作用是,当以前编写的项目工程中的类名(类名必需和文件名字一致,因为是通过文件名称去依次修改文件名、类名的)没有添加一致的前缀
|
||||||
|
if add_prefix and add_prefix != "":
|
||||||
|
addPreFix()
|
||||||
|
#添加完毕前缀后,就退出程序
|
||||||
|
print("\n添加完毕前缀后,就退出程序\n")
|
||||||
|
exit(0)
|
||||||
|
dealWithIos(ios_src_path)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
12604
HX/word_list.json
Normal file
12604
HX/word_list.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -330,7 +330,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
buildConfigurationList = 057AF78B2BF1E86F00078C98 /* Build configuration list for PBXProject "HD wallpaper" */;
|
buildConfigurationList = 057AF78B2BF1E86F00078C98 /* Build configuration list for PBXProject "TallPaper" */;
|
||||||
compatibilityVersion = "Xcode 14.0";
|
compatibilityVersion = "Xcode 14.0";
|
||||||
developmentRegion = en;
|
developmentRegion = en;
|
||||||
hasScannedForEncodings = 0;
|
hasScannedForEncodings = 0;
|
||||||
@ -652,7 +652,7 @@
|
|||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
/* Begin XCConfigurationList section */
|
||||||
057AF78B2BF1E86F00078C98 /* Build configuration list for PBXProject "HD wallpaper" */ = {
|
057AF78B2BF1E86F00078C98 /* Build configuration list for PBXProject "TallPaper" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
057AF7A72BF1E87100078C98 /* Debug */,
|
057AF7A72BF1E87100078C98 /* Debug */,
|
||||||
@ -18,7 +18,7 @@
|
|||||||
BlueprintIdentifier = "057AF78F2BF1E86F00078C98"
|
BlueprintIdentifier = "057AF78F2BF1E86F00078C98"
|
||||||
BuildableName = "TallPaper.app"
|
BuildableName = "TallPaper.app"
|
||||||
BlueprintName = "TallPaper"
|
BlueprintName = "TallPaper"
|
||||||
ReferencedContainer = "container:HD wallpaper.xcodeproj">
|
ReferencedContainer = "container:TallPaper.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildActionEntry>
|
</BuildActionEntry>
|
||||||
</BuildActionEntries>
|
</BuildActionEntries>
|
||||||
@ -47,7 +47,7 @@
|
|||||||
BlueprintIdentifier = "057AF78F2BF1E86F00078C98"
|
BlueprintIdentifier = "057AF78F2BF1E86F00078C98"
|
||||||
BuildableName = "TallPaper.app"
|
BuildableName = "TallPaper.app"
|
||||||
BlueprintName = "TallPaper"
|
BlueprintName = "TallPaper"
|
||||||
ReferencedContainer = "container:HD wallpaper.xcodeproj">
|
ReferencedContainer = "container:TallPaper.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildableProductRunnable>
|
</BuildableProductRunnable>
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
@ -64,7 +64,7 @@
|
|||||||
BlueprintIdentifier = "057AF78F2BF1E86F00078C98"
|
BlueprintIdentifier = "057AF78F2BF1E86F00078C98"
|
||||||
BuildableName = "TallPaper.app"
|
BuildableName = "TallPaper.app"
|
||||||
BlueprintName = "TallPaper"
|
BlueprintName = "TallPaper"
|
||||||
ReferencedContainer = "container:HD wallpaper.xcodeproj">
|
ReferencedContainer = "container:TallPaper.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildableProductRunnable>
|
</BuildableProductRunnable>
|
||||||
</ProfileAction>
|
</ProfileAction>
|
||||||
Loading…
Reference in New Issue
Block a user