# -*- 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()