cocoapods-privacy 0.5.3 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,506 @@
1
+ require 'json'
2
+ require 'cocoapods-privacy/command'
3
+ require 'securerandom'
4
+ require 'active_support/core_ext/module/attribute_accessors'
5
+
6
+ ##
7
+ # 功能介绍:
8
+ # 1、检索到的混淆内容转换成加密议格式写入 混淆文件
9
+ ##
10
+ module Confuse
11
+ class Hunter
12
+
13
+ # 类变量,用于缓存版本号
14
+ def initialize(version)
15
+ @version = version
16
+ end
17
+
18
+ def search_need_confuse_apis(source_folders,exclude_folders=[])
19
+ apis_define_map, swift_extension_funcBody_map = search_files(source_folders, exclude_folders)
20
+ return apis_define_map, swift_extension_funcBody_map
21
+ end
22
+
23
+ def insert_encrypted_apis_to_confuse_header(apis_define_map,confuse_header_path,flag = "")
24
+ # 存储已生成的随机字符串以确保唯一性
25
+ generated_strings = {}
26
+
27
+ # 生成 #define 语句
28
+ defines = apis_define_map.map { |key, value|
29
+ " #define #{key} #{value}"
30
+ }.join("\n")
31
+
32
+ confuse_header_content = ConfuseUtils.confuse_content(defines,File.basename(confuse_header_path))
33
+ puts "混淆(宏):\n 文件:#{confuse_header_path}\n 内容👇:\n#{confuse_header_content}"
34
+
35
+ # 保存文件
36
+ File.write(confuse_header_path, confuse_header_content)
37
+ end
38
+
39
+ def insert_encrypted_apis_to_confuse_swift(swift_extension_funcBody_map,swift_confuse_file_path,flag = "")
40
+ # 存储已生成的随机字符串以确保唯一性
41
+ generated_strings = {}
42
+
43
+ # 生成 #define 语句
44
+ funcs = swift_extension_funcBody_map.map { |key, values|
45
+ func = "public extension #{key} {\n" + values.map { |value|
46
+ value.split("\n").map { |line| " #{line}" }.join("\n") # 每行前加四个空格
47
+ }.join("\n\n") + "\n}"
48
+ }.join("\n")
49
+ confuse_func_content = funcs
50
+ puts "混淆(扩展):\n 文件:#{swift_confuse_file_path}\n 内容👇:\n#{confuse_func_content}"
51
+
52
+ # # 保存文件
53
+ File.write(swift_confuse_file_path, confuse_func_content)
54
+ end
55
+
56
+ private
57
+
58
+ # # 获取podspec的版本号,如果有缓存则返回缓存值
59
+ # def self.get_version(podspec_file_path)
60
+ # # 如果已经缓存了版本号,直接返回缓存
61
+ # return @cached_version if @cached_version
62
+
63
+ # # 读取podspec文件
64
+ # podspec = Pod::Specification.from_file(podspec_file_path)
65
+ # version = podspec.version.to_s
66
+ # version = version.gsub('.', '_') # Replace dots with underscores
67
+
68
+ # # 缓存版本号
69
+ # @cached_version = version
70
+
71
+ # return version
72
+ # end
73
+
74
+ def extend_version(str)
75
+ return "#{str}_V#{@version}"
76
+ end
77
+
78
+ #💡💡💡以下是 invalid byte sequence in UTF-8 错误复现 的数据代码
79
+ # File.write("/Users/xxx/.cache/cocoapods-privacy/privacy/file.txt", "vandflyver \xC5rhus \n
80
+
81
+ # \n
82
+
83
+ # \\n
84
+
85
+ # vandflyver
86
+ # \xC5rhus
87
+ # ")
88
+ # 文件是否包含内容
89
+ def extract_annotated_attributes?(file_path)
90
+
91
+ #使用UTF-8 读取,无法读取的会被默认处理,修复 https://github.com/ymoyao/cocoapods-privacy/issues/7
92
+ file_content = File.read(file_path, encoding: 'UTF-8', invalid: :replace, undef: :replace)
93
+
94
+ #核心文件检查段落注释 /* */
95
+ file_extension = File.extname(file_path).downcase
96
+ need_check_paragraph_comment = ['.m', '.c', '.swift', '.mm', '.h', '.hap', '.hpp', '.cpp'].include?(file_extension)
97
+
98
+ apis_define_map, swift_extension_funcBody_map = contains_apis_ignore_all_comment(file_content.lines,file_path)
99
+ return apis_define_map, swift_extension_funcBody_map
100
+ end
101
+
102
+ def contains_apis_ignore_all_comment(lines,file_path)
103
+ apis_define_map = {}
104
+ swift_extension_funcBody_map = {}
105
+
106
+ #oc 暴露给swift 的扩展名称
107
+ swift_extension = ""
108
+
109
+ # 段注释和单行注释标志
110
+ in_block_comment = false
111
+ in_line_comment = false
112
+
113
+ # 是否可以触发注释标识,当为true 时可以触发 /*段注释 或者 //单行注释
114
+ can_trigger_comments_flag = true
115
+
116
+ # 统计计数器
117
+ count_comments = 0
118
+ modified = false
119
+
120
+ last_line_scrub = ""
121
+ need_delete_line_map = {} #{删除行下标:行内容line}
122
+ encrypted_lines = lines.map.with_index do |line, line_index|
123
+
124
+ line_scrub = line.scrub("")
125
+ if line_scrub.strip.empty? #忽略空行
126
+ next line
127
+ end
128
+ if line_scrub.strip.start_with?('//') && !in_block_comment #忽略注释 // 和 /**/
129
+ next line
130
+ end
131
+
132
+ chars = line_scrub.chars
133
+ index = 0
134
+ while index < chars.size
135
+ char = chars[index]
136
+
137
+ if char == '/'
138
+ if chars[index + 1] == '*'
139
+ # 检测到 /* 且can_trigger_comments_flag标识为true时,判定为进入 段注释
140
+ if can_trigger_comments_flag
141
+ in_line_comment = false #重置行标识
142
+ in_block_comment = true #标记正在段注释中
143
+ can_trigger_comments_flag = false #回收头部重置标识
144
+ end
145
+
146
+ #段注释每次 遇到 /* 都累加1
147
+ if in_block_comment
148
+ count_comments += 1
149
+ end
150
+
151
+ #跳过当前 /* 两个字符
152
+ index += 2
153
+ next
154
+ end
155
+ # 检测到段注释的end 标识 */
156
+ elsif in_block_comment && char == '*' && chars[index + 1] == '/'
157
+
158
+ #段注释每次 遇到 */ 都累减1
159
+ count_comments -= 1
160
+
161
+ #当/* */ 配对时,说明当前段注释结束了
162
+ if count_comments == 0
163
+ in_line_comment = false
164
+ in_block_comment = false
165
+ can_trigger_comments_flag = true
166
+ end
167
+
168
+ #跳过当前 */ 两个字符
169
+ index += 2
170
+ next
171
+ end
172
+
173
+ # 其他情况,前进一个字符
174
+ index += 1
175
+ end
176
+
177
+ if !in_block_comment && !in_line_comment
178
+
179
+ ###----- 处理oc ------
180
+ # 查找并处理注解:__attribute__((annotate("BB_?Confuse:xxx")))
181
+ #.*?: 匹配任意字符(包括冒号),但它会尽量少匹配直到遇到冒号为止。
182
+ #.*? 匹配冒号后面的一些字符(任意字符,直到遇到下一个双引号)。
183
+ #这样可以确保匹配的字符串中至少包含一个冒号。
184
+ line_scrub.scan(/__attribute__\(\(annotate\("(.*?:.*?)"\)\)\)/) do |match|
185
+ # # 将注解内容按逗号分割功能,并去重
186
+ commands = match.first.split(',').map(&:strip)
187
+ commands.map do |commandInfo|
188
+ puts commandInfo
189
+ commandKeyAndValue = commandInfo.split(':')
190
+ commandKey = commandKeyAndValue.first
191
+ commandValue = commandKeyAndValue.last
192
+ if commandKey && commandKey =~ /BB_?Confuse/
193
+ swift_extension = commandValue
194
+ end
195
+ end
196
+
197
+ # new_parts = encrypted_api(apis)
198
+
199
+ # apis.each_with_index do |seg, index|
200
+ # apis_define_map[seg.strip] = new_parts[index]
201
+ # end
202
+
203
+ # puts "__attribute__ = #{match}"
204
+ end
205
+
206
+ # 查找并处理注解:__attribute__((annotate("xxx")))
207
+ # @regex = /^[+-]\s*\(\s*([^$]+)\s*\**\s*\)\s*(.+)/
208
+ line_scrub.scan(/(^[-+]\s*\(.*?\)\s*(\w+)\s*([\w\s]+))\s*__attribute__\(\(annotate\(/) do |match|
209
+ apis = [match.second]
210
+ new_parts = encrypted_api(apis)
211
+
212
+ funcStr = match.first.sub(';','').sub(/__attribute__\(\(annotate\(["][^"]*["]\)\)\).*/, '')
213
+ swift_method_declaration,params = ObjCMethodAPIConverter.convert(funcStr)
214
+ if !swift_extension.empty? && swift_method_declaration && !swift_method_declaration.empty?
215
+ swift_func_body = SwiftCallAssembly.assembly(new_parts.first,swift_method_declaration,params)
216
+ swift_extension_funcBody_map[swift_extension] ||= []
217
+ swift_extension_funcBody_map[swift_extension].push(swift_func_body)
218
+ end
219
+ apis.each_with_index do |seg, index|
220
+ apis_define_map[seg.strip] = new_parts[index]
221
+ end
222
+ end
223
+
224
+ ###----- 处理swift 类 ------
225
+ #正则解析:
226
+ #1、@BBConfuseMixObjcClass\(" 匹配 @BBConfuseMixObjcClass(" 这一部分 @BBConfuseMixObjcClass("MyClass"
227
+ #2、([a-zA-Z][a-zA-Z0-9]*) 第一个参数:匹配 " 之后的 首字母必须是字母,后面可跟 字母或数字 "MyClass"
228
+ #3、(?:,\s*"([a-zA-Z][a-zA-Z0-9]*)")? 第二个参数(可选):如果有,匹配 , "SecondParam" , "SecondParam"(可选)
229
+ #4、\) 匹配 ") 结束 @BBConfuseMixObjcClass(...) 部分 ")
230
+ #5、(?:.*?@objc\((\S+)\))? 可选的 @objc(...):如果存在,则匹配 @objc(...) 并提取内容 @objc(MyObjCName)(可选)
231
+ #6、.*?class ([a-zA-Z0-9]+) 类名:匹配 class 关键字后面的类名 class MyClass
232
+ #混淆之前的类解析(存在 @objc(xxx) 别名情况 ) 比如 @BBConfuseMixObjcClass("test") @objc(xxxx) public class abc : NSObject {
233
+ confuse_class_pre_literal = "@BBConfuseMixObjcClass"
234
+ line_scrub.gsub!(/#{confuse_class_pre_literal}\("([a-zA-Z][a-zA-Z0-9]*)"(?:,\s*"([a-zA-Z][a-zA-Z0-9]*)")?\)(?:.*?@objc\((\S+)\))?.*?class ([a-zA-Z0-9]+)/) do |match|
235
+ #match = @BBConfuseMixObjcClass("test") @objc(xxxx) public class abc
236
+ #S1 = test
237
+ #S2 = xxxx
238
+ #S3 = abc
239
+ modified = true
240
+ # puts "检测到混淆类标记 = #{match}"
241
+ # puts "$1 = #{$1} $2 = #{$2} $3 = #{$3} $4 = #{$4}"
242
+ origin_swift_class_name = $1
243
+ origin_objc_class_name = $2 || ""
244
+ current_objc_class_name = $3 || ""
245
+ current_swift_class_name = $4
246
+ is_to_objc = match.include?("@objc")
247
+
248
+ encrypted_class_name = encrypted_api([origin_swift_class_name]).first
249
+ confuse_literals = "#{confuse_class_pre_literal}"
250
+ unless origin_objc_class_name.empty?
251
+ confuse_literals += "(\"#{origin_swift_class_name}\",\"#{origin_objc_class_name}\")"
252
+ else
253
+ confuse_literals += "(\"#{origin_swift_class_name}\")"
254
+ end
255
+
256
+ class_literals = match
257
+ .gsub(confuse_literals, "")
258
+ .gsub(/@objc\([^)]*\)|@objc\s+/, "")
259
+ .gsub(current_swift_class_name, encrypted_class_name)
260
+
261
+ #检查上一行是否已经有public typealias origin_class_name = encrypted_class_name, 有的话先标记删除
262
+ swift_typealias = "public typealias #{origin_swift_class_name}"
263
+ if last_line_scrub.delete(" ").include?(swift_typealias.delete(" "))
264
+ need_delete_line_map[line_index - 1] = last_line_scrub
265
+ end
266
+
267
+ #有包含@objc 暴露给oc 才有宏定义的必要
268
+ if is_to_objc
269
+ #添加origin_class_name 和 encrypted_class_name 给字典, 后续插入到宏定义中
270
+ apis_define_map[origin_swift_class_name] = encrypted_class_name unless origin_swift_class_name.empty?
271
+ apis_define_map[origin_objc_class_name] = encrypted_class_name unless origin_objc_class_name.empty?
272
+ end
273
+
274
+ objc_literals = is_to_objc ? " @objc(#{encrypted_class_name.strip}) " : " "
275
+ retult = "#{swift_typealias.strip} = #{encrypted_class_name.strip}\n#{confuse_literals.strip}#{objc_literals}#{class_literals.strip}"
276
+ retult
277
+ end
278
+
279
+ ###----- 处理swift 函数 ------
280
+ confuse_func_pre_literal = "#BBConfuseMixObjcFunc"
281
+ if line_scrub.strip.start_with?(confuse_func_pre_literal)
282
+ #BBConfuseMixObjc("#selector(abcdefg(in:sencName:))"); asdasagwtrqwetr
283
+
284
+
285
+ #selector(.*?)\)
286
+ #解析带参数的
287
+ # line_scrub.gsub!(/#{confuse_func_pre_literal}\(#selector\((.*?)\)\)\);(?:.*?@objc\((\S+)\))?(?:.*?@objc\s*)?/) do |match|
288
+ line_scrub.gsub!(/#{confuse_func_pre_literal}\((?:#selector\((.*?)\)\))?(?:"([^"]*:[^"]*)")?\);(?:.*?@objc\((\S+)\))?(?:.*?@objc\s*)?/) do |match|
289
+ modified = true
290
+ selector_match = $1
291
+ str_match = $2
292
+ # puts "检测到混淆函数标记(带参数) = #{match};$1 = #{$1} $2 = #{$2} $3 = #{$3}"
293
+ is_selector = selector_match && !selector_match.empty?
294
+ if is_selector
295
+ apis = handleObjcInsert(match,selector_match,line)
296
+ else
297
+ apis = str_match.split(':').map(&:strip)
298
+ end
299
+ result,apis_define_map_temp = encrypted_and_combination_api(apis,match)
300
+ apis_define_map = apis_define_map.merge(apis_define_map_temp)
301
+ result
302
+ end
303
+
304
+ #解析不带参数的
305
+ # line_scrub.gsub!(/#{confuse_func_pre_literal}\(#selector\(([^\(]+)\)\);(?:.*?@objc\((\S+)\))?(?:.*?@objc\s*)?/) do |match|
306
+ line_scrub.gsub!(/#{confuse_func_pre_literal}\((?:#selector\(([^\(]+)\))?(?:"([^":]+)")?\);(?:.*?@objc\((\S+)\))?(?:.*?@objc\s*)?/) do |match|
307
+ # line_scrub.gsub!(/#{confuse_func_pre_literal}\((#selector\((.*?)\)|"([^"]+)")\);(?:.*?@objc\((\S+)\))?(?:.*?@objc\s*)?/) do |match|
308
+ modified = true
309
+ selector_match = $1
310
+ str_match = $2
311
+ # puts "检测到混淆函数标记(无参数) = #{match};$1 = #{$1} $2 = #{$2} $3 = #{$3}"
312
+ is_selector = selector_match && !selector_match.empty?
313
+ apis = []
314
+ if is_selector
315
+ apis = handleObjcInsert(match,selector_match,line)
316
+ else
317
+ apis = str_match.split(':').map(&:strip) if str_match
318
+ end
319
+ result,apis_define_map_temp = encrypted_and_combination_api(apis,match)
320
+ apis_define_map = apis_define_map.merge(apis_define_map_temp)
321
+ result
322
+ end
323
+ end
324
+ # puts "line_scrub = #{line_scrub}"
325
+ end
326
+
327
+ #每行结束时,重置行标识
328
+ in_line_comment = false
329
+ last_line_scrub = line_scrub
330
+ line_scrub
331
+ end
332
+ # 写回修改后的文件
333
+ if modified
334
+ encrypted_lines = encrypted_lines.each_with_index.reject { |_, index| need_delete_line_map.keys.include?(index) }.map(&:first)
335
+
336
+ File.write(file_path, encrypted_lines.join)
337
+ # puts "已混淆文件:#{file_path}"
338
+ # File.open('/Users/masterfly/Desktop/babybusGit/common/SafetyProtection/Pod/Classes/ReplaceMe.swift', 'w') do |file|
339
+ # # 逐行写入 rows
340
+ # lines.each do |row|
341
+ # file.puts(row)
342
+ # puts "插入:#{row}"
343
+ # end
344
+ # end
345
+ puts "已混淆文件:#{file_path}"
346
+ end
347
+ return apis_define_map, swift_extension_funcBody_map
348
+ end
349
+
350
+
351
+ def handleObjcInsert(match, suffix,line)
352
+
353
+ #match = #BBConfuseMixObjcFunc(#selector(swiftTestPar(in:sencName:))); @objc(blbbYmRPLbOb:etMLJynbSjJy:)
354
+ #suffix = swiftTestPar(in:sencName:
355
+
356
+ #第一步, 使用;分割,获取关键信息 #BBConfuseMixObjcFunc(#selector(swiftTestPar(in:sencName:)))
357
+ literals = match.split(';').map(&:strip)
358
+ confuse_literals = literals.first
359
+ func_literals = literals[1]
360
+
361
+ #“swiftTestPar(in:sencName:” --》 [“swiftTestPar,“in:sencName:”]
362
+ sepFunc = suffix.split('(').map(&:strip)
363
+
364
+ funcName = sepFunc
365
+ paramSplit = []
366
+ if sepFunc.length > 0
367
+ #““swiftTestPar”
368
+ funcName = sepFunc.first
369
+
370
+ #in:sencName:
371
+ params = sepFunc[1]
372
+
373
+ #in:sencName: --> ["in","sencName"]
374
+ if params
375
+ paramSplit = params.split(':')
376
+
377
+ #特殊情况处理
378
+ #首个参数为 _ 则个参数返回空
379
+ # 其他参数使用With + 参数首字符大写
380
+ paramSplit = paramSplit.map.with_index do |seg, index|
381
+ if index == 0 && seg == "_"
382
+ ""
383
+ elsif index == 0
384
+ "With#{seg.capitalize}"
385
+ else
386
+ seg
387
+ end
388
+ end
389
+
390
+ funcName = funcName + paramSplit.first
391
+ paramSplit.slice!(0)
392
+ end
393
+ end
394
+
395
+ apis = [funcName] + paramSplit
396
+ return apis
397
+ end
398
+
399
+ def encrypted_and_combination_api(apis,match)
400
+ new_parts = encrypted_api(apis)
401
+
402
+ # 构建新注解内容
403
+ new_annotation = "#{new_parts.join(':')}"
404
+ if match.include?(":")
405
+ new_annotation = "#{new_annotation}:"
406
+ end
407
+
408
+ apis_define_map = {}
409
+ # 将未混淆的 API 名称及其对应的混淆字符串添加到字典中
410
+ # apis.each_with_index do |seg, index|
411
+ # apis_define_map[seg.strip] = new_parts[index]
412
+ # end
413
+
414
+ #仅混淆函数名称, 参数可能太过简单,宏定义有风险
415
+ apis_define_map[apis.first] = new_parts.first if apis && !apis.empty?
416
+
417
+ result = match.gsub(";","").gsub(/@objc\([^)]*\)|@objc\s+/, "") # 删除分号 和多余的 @objc
418
+ result = "#{result.strip}; @objc(#{new_annotation})" # 添加新的注解
419
+ # puts "result = #{result}"
420
+ return result, apis_define_map
421
+ end
422
+
423
+
424
+ #搜索所有子文件夹
425
+ def search_files(folder_paths, exclude_folders)
426
+ # 获取文件夹下所有文件(包括子文件夹)
427
+ all_files = []
428
+ folder_paths.each do |folder|
429
+ # 不再做额外格式过滤,避免和podspec中source_files 自带的格式冲突
430
+ # allowed_extensions = ['m', 'c', 'swift', 'mm', 'hap', 'cpp']
431
+ # pattern = File.join(folder, '**', '*.{'+allowed_extensions.join(',')+'}')
432
+ # all_files += Dir.glob(pattern, File::FNM_DOTMATCH).reject { |file| File.directory?(file) }
433
+
434
+ # 使用 Dir.glob 方法直接获取符合条件的文件路径
435
+ files_in_folder = Dir.glob(folder, File::FNM_DOTMATCH)
436
+
437
+ # 过滤掉目录路径,只保留文件路径,并将其添加到 all_files 数组中
438
+ all_files += files_in_folder.reject { |file| File.directory?(file) }
439
+ end
440
+
441
+ # 获取需要排除的文件
442
+ exclude_files = []
443
+ exclude_folders.each do |folder|
444
+ files_in_folder = Dir.glob(folder, File::FNM_DOTMATCH)
445
+ exclude_files += files_in_folder.reject { |file| File.directory?(file) }
446
+ end
447
+
448
+ # 剔除掉需要排除的文件
449
+ all_files = all_files.uniq - exclude_files.uniq
450
+
451
+ # 遍历文件进行检索
452
+ $apis_define_map = {}
453
+ $swift_extension_funcBody_map = {}
454
+
455
+ all_files.each_with_index do |file_path, index|
456
+ api_dict, funcBody_map = extract_annotated_attributes?(file_path)
457
+ $apis_define_map.merge!(api_dict)
458
+ funcBody_map.each do |key, value|
459
+ if $swift_extension_funcBody_map.key?(key)
460
+ # 如果 key 存在于 $swift_extension_funcBody_map 中,合并并去重
461
+ $swift_extension_funcBody_map[key] = (Array($swift_extension_funcBody_map[key]) + Array(value)).uniq
462
+ else
463
+ # 如果 key 不存在,直接添加
464
+ $swift_extension_funcBody_map[key] = value
465
+ end
466
+ end
467
+ end
468
+ return $apis_define_map, $swift_extension_funcBody_map
469
+ end
470
+
471
+
472
+ def encrypted_api(apis)
473
+ encrypted_api = ""
474
+ # 生成 #define 语句
475
+ defines = apis.map do |api|
476
+ if $apis_define_map.key?(api)
477
+ encrypted_api = $apis_define_map[api]
478
+ else
479
+ encrypted_api = generate_safe_api_key()
480
+ end
481
+ end
482
+ defines
483
+ end
484
+
485
+ def generate_safe_api_key
486
+ #需要排除这些连接词,如果有这些连接词,那么转swift时函数会被分割
487
+ forbidden_words = %w[
488
+ With In On To At As Of By For After Before During Alongside Under Through
489
+ ]
490
+
491
+ loop do
492
+ encrypted_api = SecureRandom.alphanumeric(24)
493
+ encrypted_api = encrypted_api.strip
494
+ encrypted_api = encrypted_api.gsub(/\d/, 'b')
495
+ encrypted_api = encrypted_api.sub(/^./, encrypted_api[0].downcase)
496
+ encrypted_api = extend_version(encrypted_api)
497
+
498
+ # 检查是否包含禁用词
499
+ contains_forbidden = forbidden_words.any? { |word| encrypted_api.include?(word) }
500
+
501
+ # 一直循环直到不包含关键词
502
+ return encrypted_api unless contains_forbidden
503
+ end
504
+ end
505
+ end
506
+ end
@@ -0,0 +1,150 @@
1
+ require 'cocoapods-privacy/command'
2
+ require 'cocoapods-core/specification/dsl/attribute_support'
3
+ require 'cocoapods-core/specification/dsl/attribute'
4
+ require 'xcodeproj'
5
+ require 'plist'
6
+ require 'yaml'
7
+
8
+ module ConfuseModule
9
+
10
+ public
11
+
12
+ # 处理组件
13
+ def self.load_module(podspec_file_path)
14
+ # puts "podspec_file_path = #{podspec_file_path}"
15
+ specManager = BB::BBSpecManager.new(KSpecTypeConfuse)
16
+ puts "👇👇👇👇👇👇 Start analysis component confuse 👇👇👇👇👇👇"
17
+ confuse_hash = specManager.check(podspec_file_path)
18
+ confuse_hash.each do |confuse_file_path, hash|
19
+ source_files = hash[KSource_Files_Key]
20
+ exclude_files = hash[KExclude_Files_Key]
21
+ # puts "source_files = #{source_files}"
22
+ # puts "exclude_files = #{exclude_files}"
23
+ # puts "confuse_file_path = #{confuse_file_path}"
24
+ podspec = Pod::Specification.from_file(podspec_file_path)
25
+ version = podspec.version.to_s
26
+ version = version.gsub('.', '_') # Replace dots with underscores
27
+
28
+ hunter = Confuse::Hunter.new(version)
29
+ apis_define_map, swift_extension_funcBody_map = hunter.search_need_confuse_apis(source_files,exclude_files)
30
+ # puts "swift_extension_funcBody_map = #{swift_extension_funcBody_map}"
31
+
32
+ oc_confuse_file_path = "#{confuse_file_path}.h"
33
+ swift_confuse_file_path = "#{confuse_file_path}.swift"
34
+ hunter.insert_encrypted_apis_to_confuse_header(apis_define_map,oc_confuse_file_path,version)
35
+ hunter.insert_encrypted_apis_to_confuse_swift(swift_extension_funcBody_map,swift_confuse_file_path,version)
36
+ end
37
+ puts "👆👆👆👆👆👆 End analysis component confuse 👆👆👆👆👆👆"
38
+ end
39
+
40
+ # # 处理工程
41
+ # def self.load_project(folds,exclude_folds,installer)
42
+ # project_path = ConfuseUtils.project_path()
43
+ # confuse_folder_path = File.join(File.basename(project_path, File.extname(project_path)),ConfuseUtils.confuse_folder)
44
+ # confuse_file_path = File.join(confuse_folder_path,ConfuseUtils.confuse_name)
45
+
46
+ # #创建混淆头文件
47
+ # # 如果混淆头文件不存在,创建混淆文件
48
+ # unless File.exist?(confuse_file_path)
49
+ # puts "#{confuse_file_path}"
50
+ # ConfuseUtils.create_confuse_if_empty(confuse_file_path)
51
+ # end
52
+
53
+ # # 打开 Xcode 项目,在Confuse下 创建
54
+ # project = Xcodeproj::Project.open(File.basename(project_path))
55
+ # main_group = project.main_group
56
+ # resources_group = main_group.find_subpath('Confuse',false)
57
+ # if resources_group.nil?
58
+ # resources_group = main_group.new_group('Confuse',confuse_folder_path)
59
+ # end
60
+
61
+ # target = project.targets.first
62
+ # resources_build_phase = target.resources_build_phase
63
+ # # 如果不存在引用,创建新的引入xcode引用
64
+ # if resources_group.find_file_by_path(ConfuseUtils.confuse_name).nil?
65
+ # confuse_file_ref = resources_group.new_reference(ConfuseUtils.confuse_name,:group)
66
+ # confuse_file_ref.last_known_file_type = 'sourcecode.objc.h'
67
+ # resources_build_phase.add_file_reference(confuse_file_ref) # 将文件引用添加到 resources 构建阶段中
68
+ # end
69
+
70
+ # confuse_pch_file_path = ""
71
+ # # 遍历项目的所有 targets,添加或修改 PCH 文件的设置
72
+ # project.targets.each do |target|
73
+ # target.build_configurations.each do |config|
74
+ # # 获取当前的 Prefix Header 设置
75
+ # current_pch = config.build_settings['GCC_PREFIX_HEADER']
76
+
77
+ # puts "name = #{target.name}"
78
+
79
+ # # 如果当前没有设置 PCH 文件,则添加新的设置
80
+ # if current_pch.nil? || current_pch.empty?
81
+ # # 如果混淆PCH不存在,创建混淆文件
82
+ # confuse_pch_file_path = File.join(confuse_folder_path,ConfuseUtils.confuse_pch_name)
83
+ # unless File.exist?(confuse_pch_file_path)
84
+ # puts "confuse_pch_file_path = #{confuse_pch_file_path}"
85
+ # ConfuseUtils.create_confuse_if_empty(confuse_pch_file_path,ConfuseUtils.confuse_pch_content)
86
+ # end
87
+
88
+ # #pch 添加到xcode 索引
89
+ # if resources_group.find_file_by_path(ConfuseUtils.confuse_pch_name).nil?
90
+ # confuse_pch_file_ref = resources_group.new_reference(ConfuseUtils.confuse_pch_name,:group)
91
+ # confuse_pch_file_ref.last_known_file_type = 'sourcecode.objc.h'
92
+ # resources_build_phase.add_file_reference(confuse_pch_file_ref) # 将文件引用添加到 resources 构建阶段中
93
+ # puts "confuse_pch_file_ref = #{confuse_pch_file_ref}"
94
+ # end
95
+
96
+ # # pch 路径添加到build setting
97
+ # config.build_settings['GCC_PREFIX_HEADER'] = "$(SRCROOT)/#{ConfuseUtils.project_name}/#{ConfuseUtils.confuse_folder}/#{ConfuseUtils.confuse_pch_name}"
98
+ # else
99
+
100
+ # pch_file_name = File.basename(current_pch)
101
+ # confuse_pch_file_path = Dir.glob("**/#{pch_file_name}").first
102
+
103
+ # # 如果 PCH 文件已设置,检查并修改文件内容
104
+ # if File.exist?(confuse_pch_file_path)
105
+ # file_content = File.read(confuse_pch_file_path)
106
+
107
+ # # 检查是否已包含
108
+ # unless file_content.include?("#{ConfuseUtils.confuse_name}")
109
+ # # 找到最后一个 #endif,插入新的 import 语句
110
+ # last_ifdef_index = file_content.rindex('#endif')
111
+
112
+ # if last_ifdef_index
113
+ # inser_content = "\n//混淆需要的头文件,不能删除\n#import \"#{ConfuseUtils.confuse_name}\"\n"
114
+ # puts "检测到已存在pch#{confuse_pch_file_path}, 直接在现在pch 文件中插入混淆头部文件 #{inser_content}"
115
+ # file_content.insert(last_ifdef_index,inser_content)
116
+ # File.write(confuse_pch_file_path, file_content)
117
+ # end
118
+ # end
119
+ # end
120
+ # end
121
+ # end
122
+ # end
123
+
124
+ # version = "" #内部使用随机字符串,不需要版本
125
+ # # #获取工程版本号,用来做动态混淆,每个确保每个版本都不一致
126
+ # # plist_path = target.resolved_build_setting('INFOPLIST_FILE', resolve_against: target).first
127
+ # # plist_path = File.join(File.dirname(project_path), plist_path)
128
+ # # plist = Plist.parse_xml(plist_path)
129
+ # # unless plist.nil?
130
+ # # version = plist['CFBundleShortVersionString']
131
+ # # end
132
+
133
+ # project.save
134
+
135
+
136
+ # # installer.pod_target_subprojects.flat_map { |p| p.targets }.each do |target|
137
+ # # target.build_configurations.each do |config|
138
+ # # puts "name2 = #{target.name}"
139
+ # # config.build_settings['GCC_PREFIX_HEADER'] = "$(SRCROOT)/#{ConfuseUtils.project_name}/#{ConfuseUtils.confuse_folder}/#{ConfuseUtils.confuse_pch_name}"
140
+ # # end
141
+ # # end
142
+
143
+ # # 开始检索api,并返回json 字符串数据
144
+ # hunter = ConfuseHunter.new("")
145
+ # apis = hunter.search_need_confuse_apis(folds,exclude_folds)
146
+
147
+ # # 将数据写入混淆文件
148
+ # hunter.insert_encrypted_apis_to_confuse_header(apis,confuse_file_path,version)
149
+ # end
150
+ end