This commit is contained in:
bluesea 2024-07-23 16:32:32 +08:00
parent 16dbe037b9
commit 9086425c1a
37 changed files with 26795 additions and 41 deletions

View File

@ -2,7 +2,7 @@
<Workspace
version = "1.0">
<FileRef
location = "group:HD wallpaper.xcodeproj">
location = "group:/Users/aaa/Documents/IOS/BZ/723/HDwallpaper/TallPaper.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">

View File

@ -16,7 +16,7 @@
@end
@implementation AWM_AllWallpaperViewController
- (void)backItemEvent{
- (void)backItemEventLove:(id)sender{
__weak typeof(self) weakSelf = self;
[[AWM_WallPapaerADManager shareInstance] showIntersitialAD_Back:^(NSInteger actionType) {
[weakSelf.navigationController popViewControllerAnimated:YES];
@ -46,7 +46,7 @@
NSString *backitem = KLS(@"back", @"A friendly greeting");
UIButton *backItem = [[UIButton alloc] initWithFrame:CGRectMake(20-1,0-1,74-1,44-1)];
[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.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.layer.cornerRadius = 5;
btn.layer.masksToBounds = YES;
[btn addTarget:self action:@selector(headerEvent:) forControlEvents:UIControlEventTouchUpInside];
[btn addTarget:self action:@selector(headerEventLove:) forControlEvents:UIControlEventTouchUpInside];
btn.tag = indexPath.section;
[cell.contentView addSubview:btn];
}
@ -129,7 +129,7 @@
wpdetail.data = self.data[indexPath.section];
[self.navigationController pushViewController:wpdetail animated:YES];
}
- (void)headerEvent:(UIButton *)btn{
- (void)headerEventLove:(UIButton *)btn{
AWM_DetailViewController *wpdetail = [[AWM_DetailViewController alloc] init];
wpdetail.data = self.data[btn.tag];
[self.navigationController pushViewController:wpdetail animated:YES];

View File

@ -16,14 +16,14 @@
@end
@implementation AWM_DetailViewController
- (void)backItemEvent{
- (void)backItemEventLove:(id)sender{
__weak typeof(self) weakSelf = self;
[[AWM_WallPapaerADManager shareInstance] showIntersitialAD_Back:^(NSInteger actionType) {
[weakSelf.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);
AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[app.saveImages addObject:self.data[self.index]];
@ -56,13 +56,13 @@
NSString *backitem = KLS(@"back", @"A friendly greeting");
UIButton *backItem = [[UIButton alloc] initWithFrame:CGRectMake(20-1,0-1,74-1,44-1)];
[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;
UIButton *navImage = [[UIButton alloc] initWithFrame:CGRectMake(WPScreen_w-100-1,2-1,74-1,40-1)];
NSString *save = KLS(@"save", @"A friendly greeting");
[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;
@ -86,17 +86,17 @@
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");
[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];
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");
[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];
}
- (void)shangItemEvent{
- (void)shangItemEventLove:(id)sender{
if (self.index == 0) {
UIAlertView *iconAl = [[UIAlertView alloc] initWithTitle:@"" message:@"It's already the first one" delegate:self cancelButtonTitle:nil otherButtonTitles:@"ok", nil];
[iconAl show];
@ -105,7 +105,7 @@
self.index --;
[self.wpscroll setContentOffset:CGPointMake(self.index*WPScreen_w, 0)];
}
- (void)xiaItemEvent{
- (void)xiaItemEventLove:(id)sender{
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];
[iconAl show];

View File

@ -37,13 +37,13 @@
// btn.layer.cornerRadius = 5;
// btn.layer.masksToBounds = YES;
btn.tag = i;
[btn addTarget:self action:@selector(iconEvent:) forControlEvents:UIControlEventTouchUpInside];
[btn addTarget:self action:@selector(iconEventLove:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
UIButton *pracy_btn = [UIButton new];
[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");
[pracy_btn setTitle:privacy 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];
[self.navigationController pushViewController:vc animated:YES];
}
- (void)iconEvent:(UIButton *)icon{
- (void)iconEventLove:(UIButton *)icon{
if (icon.tag == 0) {
AWM_wallpaperViewController *wpdetail = [[AWM_wallpaperViewController alloc] init];
[self.navigationController pushViewController:wpdetail animated:YES];

View File

@ -37,7 +37,7 @@
UIButton *searchBtn = [[UIButton alloc] initWithFrame:CGRectMake((WPScreen_w-300)/2-1,100-1,300-1,96-1)];
NSString *search = KLS(@"search", @"A friendly greeting");
[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.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.view addSubview:self.table];
}
- (void)searchEvent{
- (void)searchEventLove{
AWM_SearchViewController *vc = [[AWM_SearchViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
}
@ -78,7 +78,7 @@
[btn setImage:[UIImage imageNamed:self.data[indexPath.section][i]] forState:UIControlStateNormal];
btn.layer.cornerRadius = 5;
btn.layer.masksToBounds = YES;
[btn addTarget:self action:@selector(headerEvent) forControlEvents:UIControlEventTouchUpInside];
[btn addTarget:self action:@selector(headerEventLove:) forControlEvents:UIControlEventTouchUpInside];
[bgView addSubview:btn];
}
@ -91,7 +91,7 @@
[bgView addSubview:more];
return cell;
}
- (void)headerEvent{
- (void)headerEventLove:(id)sender{
AWM_AllWallpaperViewController *wpdetail = [[AWM_AllWallpaperViewController alloc] init];
[self.navigationController pushViewController:wpdetail animated:YES];
}

View File

@ -36,7 +36,7 @@
UIButton *searchBtn = [[UIButton alloc] initWithFrame:CGRectMake((WPScreen_w-300)/2-1,100-1,300-1,96-1)];
NSString *search = KLS(@"search", @"A friendly greeting");
[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.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.view addSubview:self.table];
}
- (void)searchEvent{
- (void)searchEventLove:(id)s{
AWM_SearchViewController *vc = [[AWM_SearchViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
}
@ -64,7 +64,7 @@
return 3*(10+space*1.5)+30;
}
}
- (void)headerEvent{
- (void)headerEvent:(id)s{
AWM_AllWallpaperViewController *wpdetail = [[AWM_AllWallpaperViewController alloc] init];
[self.navigationController pushViewController:wpdetail animated:YES];
}
@ -82,7 +82,7 @@
header.userInteractionEnabled = YES;
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];
}
}else{
@ -99,7 +99,7 @@
[btn setImage:[UIImage imageNamed:self.data[indexPath.section][i]] forState:UIControlStateNormal];
btn.layer.cornerRadius = 5;
btn.layer.masksToBounds = YES;
[btn addTarget:self action:@selector(headerEvent) forControlEvents:UIControlEventTouchUpInside];
[btn addTarget:self action:@selector(headerEvent:) forControlEvents:UIControlEventTouchUpInside];
[bgView addSubview:btn];
}
}

View File

@ -13,7 +13,7 @@
@end
@implementation AWM_SearchViewController
- (void)backItemEvent{
- (void)backItemEventLove:(id)sender{
__weak typeof(self) weakSelf = self;
[[AWM_WallPapaerADManager shareInstance] showIntersitialAD_Back:^(NSInteger actionType) {
[weakSelf.navigationController popViewControllerAnimated:YES];
@ -50,7 +50,7 @@
NSString *greeting1 = KLS(@"back", @"A friendly greeting");
UIButton *backItem = [[UIButton alloc] initWithFrame:CGRectMake(20-1,0-1,74-1,44-1)];
[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;
UIImageView *navImage = [[UIImageView alloc] initWithFrame:CGRectMake(WPScreen_w-150-1,8-1,130-1,28-1)];

View File

@ -38,7 +38,7 @@
NSString *greeting = KLS(@"back", @"A friendly greeting");
UIButton *backItem = [[UIButton alloc] initWithFrame:CGRectMake(20-1,0-1,74-1,44-1)];
[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;
// UILabel *titleLabel = [UILabel new];
@ -60,7 +60,7 @@
[webView loadRequest:request];
}
- (void)backItemEvent{
- (void)backItemEventLove:(id)sender{
[self.navigationController popViewControllerAnimated:YES];
}

View File

@ -27,7 +27,7 @@
NSString *addpic = KLS(@"addpic", @"A friendly greeting");
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 addTarget:self action:@selector(selectPhoto) forControlEvents:UIControlEventTouchUpInside];
[addImage addTarget:self action:@selector(selectPhotoLove:) forControlEvents:UIControlEventTouchUpInside];
// addImage.center = self.view.center;
[self.view addSubview:addImage];
self.addImage = addImage;
@ -42,7 +42,7 @@
self.showImage = showImage;
}
- (void)selectPhoto{
- (void)selectPhotoLove:(id)sender{
if (self.isShow) {
__weak typeof(self)weakSelf = self;

View File

@ -18,7 +18,7 @@
@end
@implementation AWM_wallpaperViewController
- (void)backItemEvent{
- (void)backItemEventLove:(id)sender{
__weak typeof(self) weakSelf = self;
[[AWM_WallPapaerADManager shareInstance] showIntersitialAD_Back:^(NSInteger actionType) {
[weakSelf.navigationController popViewControllerAnimated:YES];
@ -59,7 +59,7 @@
NSString *backitem = KLS(@"back", @"A friendly greeting");
UIButton *backItem = [[UIButton alloc] initWithFrame:CGRectMake(20-1,0-1,74-1,44-1)];
[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;
NSString *greeting3 = KLS(@"navmy", @"A friendly greeting");
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.layer.cornerRadius = 5;
btn.layer.masksToBounds = YES;
[btn addTarget:self action:@selector(headerEvent) forControlEvents:UIControlEventTouchUpInside];
[btn addTarget:self action:@selector(headerEventLove:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:btn];
}
return cell;
@ -121,7 +121,7 @@
wpdetail.data = self.data;
[self.navigationController pushViewController:wpdetail animated:YES];
}
- (void)headerEvent{
- (void)headerEventLove:(id)sender{
AWM_DetailViewController *wpdetail = [[AWM_DetailViewController alloc] init];
wpdetail.data = self.data;
[self.navigationController pushViewController:wpdetail animated:YES];

3
HX/.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

9
HX/.idea/HX.iml generated Normal file
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

118
HX/README.md Normal file
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

View File

@ -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";
developmentRegion = en;
hasScannedForEncodings = 0;
@ -652,7 +652,7 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
057AF78B2BF1E86F00078C98 /* Build configuration list for PBXProject "HD wallpaper" */ = {
057AF78B2BF1E86F00078C98 /* Build configuration list for PBXProject "TallPaper" */ = {
isa = XCConfigurationList;
buildConfigurations = (
057AF7A72BF1E87100078C98 /* Debug */,

View File

@ -18,7 +18,7 @@
BlueprintIdentifier = "057AF78F2BF1E86F00078C98"
BuildableName = "TallPaper.app"
BlueprintName = "TallPaper"
ReferencedContainer = "container:HD wallpaper.xcodeproj">
ReferencedContainer = "container:TallPaper.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
@ -47,7 +47,7 @@
BlueprintIdentifier = "057AF78F2BF1E86F00078C98"
BuildableName = "TallPaper.app"
BlueprintName = "TallPaper"
ReferencedContainer = "container:HD wallpaper.xcodeproj">
ReferencedContainer = "container:TallPaper.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
@ -64,7 +64,7 @@
BlueprintIdentifier = "057AF78F2BF1E86F00078C98"
BuildableName = "TallPaper.app"
BlueprintName = "TallPaper"
ReferencedContainer = "container:HD wallpaper.xcodeproj">
ReferencedContainer = "container:TallPaper.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>