codeobscure 0.1.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.
- checksums.yaml +7 -0
- data/bin/codeobscure +3 -0
- data/filtSymbols +0 -0
- data/filtSymbols_standard +0 -0
- data/lib/codeobscure.rb +107 -0
- data/lib/codeobscure/filtsymbols.rb +47 -0
- data/lib/codeobscure/funclist.rb +159 -0
- data/lib/codeobscure/obscure.rb +89 -0
- data/lib/codeobscure/version.rb +3 -0
- data/test/codeobscure_test.rb +50 -0
- data/test/test_helper.rb +4 -0
- metadata +135 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8d45e95289d085a0efdd2c8597a5a5aa2cce266d
|
4
|
+
data.tar.gz: b1ca9ac495f2742f6a0d98629c4e0a6f66147807
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e475da848a16558d2cb66723a10ef58233e9e76a3599a0158fc9907360db5a58c0c84a5f173cb7c511ef4ff39e866b7ddfaf2ac99e5c8887c4b7650585ffc022
|
7
|
+
data.tar.gz: bb113db57be6ab97f88f5cefc3ad1840a8930448a511d0bf9c7b3b9105288fba88de9477874ef4d9e03344807b749551f05449e4607b272e32f9dfeff28ce8af
|
data/bin/codeobscure
ADDED
data/filtSymbols
ADDED
Binary file
|
Binary file
|
data/lib/codeobscure.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
require "codeobscure/version"
|
2
|
+
require "codeobscure/funclist"
|
3
|
+
require "codeobscure/obscure"
|
4
|
+
require "codeobscure/filtsymbols"
|
5
|
+
require "colorize"
|
6
|
+
require 'xcodeproj'
|
7
|
+
require 'fileutils'
|
8
|
+
require 'optparse'
|
9
|
+
|
10
|
+
module Codeobscure
|
11
|
+
|
12
|
+
def self.root
|
13
|
+
File.dirname __dir__
|
14
|
+
end
|
15
|
+
|
16
|
+
#waiting for add optionparse and add class obscure
|
17
|
+
def self.obscure
|
18
|
+
|
19
|
+
options = {}
|
20
|
+
OptionParser.new do |opts|
|
21
|
+
opts.banner = "Usage: obscure code for object-c project"
|
22
|
+
|
23
|
+
opts.on("-o", "--obscure XcodeprojPath", "obscure code") do |v|
|
24
|
+
options[:obscure] = v
|
25
|
+
end
|
26
|
+
|
27
|
+
opts.on("-l", "--load path1,path2,path3",Array,"load filt symbols from path") do |v|
|
28
|
+
options[:load] = v
|
29
|
+
end
|
30
|
+
|
31
|
+
opts.on("-r", "--reset", "reset loaded symbols") do |v|
|
32
|
+
options[:reset] = true
|
33
|
+
end
|
34
|
+
|
35
|
+
opts.on("-f", "--fetch type1,type2,type3", "fetch and replace type,default type is [c,p,f].c for class,p for property,f for function") do |v|
|
36
|
+
options[:fetch] = v
|
37
|
+
end
|
38
|
+
|
39
|
+
end.parse!
|
40
|
+
|
41
|
+
if options[:reset]
|
42
|
+
`rm -f #{root_dir}/filtSymbols`
|
43
|
+
`cp #{root_dir}/filtSymbols_standard #{root_dir}/filtSymbols`
|
44
|
+
end
|
45
|
+
|
46
|
+
#only load, execute load only
|
47
|
+
#only obscure, execute obscure only
|
48
|
+
#load and obscure at same time,load firt,then obscure.That's mean you can get rid of some directoies.
|
49
|
+
load_pathes = options[:load]
|
50
|
+
if load_pathes
|
51
|
+
load_pathes.each do |load_path|
|
52
|
+
if File.exist? load_path
|
53
|
+
FiltSymbols.loadFiltSymbols load_path
|
54
|
+
puts "加载完毕!".colorize(:green)
|
55
|
+
else
|
56
|
+
puts "指定的目录不存在:#{path}".colorize(:red)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
fetch_types = ["p","c","f"]
|
62
|
+
if options[:fetch].length > 0
|
63
|
+
fetch_types = options[:fetch]
|
64
|
+
end
|
65
|
+
|
66
|
+
if options[:obscure]
|
67
|
+
|
68
|
+
xpj_path = options[:obscure]
|
69
|
+
if File.exist? xpj_path
|
70
|
+
root_dir = xpj_path.split("/")[0...-1].join "/"
|
71
|
+
FuncList.genFuncList root_dir , "all", true, fetch_types
|
72
|
+
header_file = Obscure.run root_dir
|
73
|
+
project = Xcodeproj::Project.open xpj_path
|
74
|
+
project_name = xpj_path.split("/").last
|
75
|
+
main_group = project.main_group
|
76
|
+
if !main_group.find_file_by_path("codeObfuscation.h")
|
77
|
+
main_group.new_reference header_file
|
78
|
+
end
|
79
|
+
project.targets.each do |target|
|
80
|
+
if target.name = project_name
|
81
|
+
build_configs = target.build_configurations
|
82
|
+
build_configs.each do |build_config|
|
83
|
+
build_settings = build_config.build_settings
|
84
|
+
prefix_key = "GCC_PREFIX_HEADER"
|
85
|
+
prefix_header = build_settings[prefix_key]
|
86
|
+
if prefix_header.nil? || prefix_header.empty?
|
87
|
+
build_config.build_settings[prefix_key] = "./codeObfuscation.h"
|
88
|
+
elsif prefix_header.include? "codeObfuscation.h"
|
89
|
+
puts "#{target.name}:#{build_config}配置文件已配置完成".colorize(:green)
|
90
|
+
else
|
91
|
+
puts "请在#{prefix_header.class.name}中#import \"codeObfuscation.h\"".colorize(:green)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
project.save
|
97
|
+
puts "配置完成!".colorize(:green)
|
98
|
+
puts "请直接运行项目,如果项目中出现类似: `+[LoremIpsum PyTJvHwWNmeaaVzp:]: unrecognized selector sent to class`。在codeObfuscation.h中查询PyTJvHwWNmeaaVzp并删除它!".colorize(:yellow)
|
99
|
+
else
|
100
|
+
puts "指定的目录不存在:#{path}".colorize(:red)
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require_relative "funclist.rb"
|
2
|
+
require "colorize"
|
3
|
+
module FiltSymbols
|
4
|
+
@@filt_db_path = "#{File.expand_path '../../..', __FILE__}/filtSymbols"
|
5
|
+
@@table_name = "symbols"
|
6
|
+
@@key_words = ["interface","NSInteger","BOOL","Class","free","M_PI_2","abort","change","top","bottom","NSUIntegerMax","intoString"]
|
7
|
+
|
8
|
+
def self.createTable
|
9
|
+
if !File.exist? @@filt_db_path
|
10
|
+
`echo "create table #{@@table_name}(src text,PRIMARY KEY (src));" | sqlite3 #{@@filt_db_path}`
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.insertValue(line)
|
15
|
+
`echo "insert or ignore into #{@@table_name} values('#{line}');" | sqlite3 #{@@filt_db_path}`
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.query(line)
|
19
|
+
`echo "select * from #{@@table_name} where src='#{line}';" | sqlite3 #{@@filt_db_path}`
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.loadFiltSymbols(path)
|
23
|
+
|
24
|
+
createTable
|
25
|
+
|
26
|
+
funclist_path = FuncList.genFuncList path , "h" , false
|
27
|
+
|
28
|
+
puts "处理中,可能需要一段时间,耐心等候...".colorize(:yellow)
|
29
|
+
symbol_file = File.open(funclist_path).read
|
30
|
+
symbol_file.each_line do |line|
|
31
|
+
line_content = line.rstrip.split(":").last
|
32
|
+
insertValue line_content
|
33
|
+
end
|
34
|
+
|
35
|
+
@@key_words.each do |word|
|
36
|
+
insertValue word
|
37
|
+
end
|
38
|
+
|
39
|
+
if File.exist? funclist_path
|
40
|
+
`rm -f #{funclist_path}`
|
41
|
+
end
|
42
|
+
|
43
|
+
`sqlite3 #{@@filt_db_path} .dump`
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
module FuncList
|
2
|
+
|
3
|
+
@@func_regex = /\s*(\w+)\s*:\s*\(\s*\w*\s*\s*\w+\s*\*?\s*\)\s*\w+\s*/
|
4
|
+
@@func_simple_regex = /\s*[-\+]\s*\(\s*\w+\s*\*?\)\s*(\w+)\s*;*/
|
5
|
+
@@hcls_regex = /@interface\s+(\w+)\s*/
|
6
|
+
@@mcls_regex = /@implementation\s+(\w+)\s*/
|
7
|
+
@@property_regex = /\s*@property\s*\(.*?getter=(\w+).*?\)\s*\w+\s*\*?\s*\w+\s*.*;/
|
8
|
+
@@property_regex2 = /\s*@property\s*\(.*?\)\s*\w+\s*\*?\s*(\w+)\s*.*;/
|
9
|
+
@@property_regex3 = /\s*@property\s*\(.*?\)\s*\w+\s*<.*>\s*\*?\s*(\w+)\s*.*;/
|
10
|
+
|
11
|
+
def self.to_utf8(str)
|
12
|
+
str = str.force_encoding('UTF-8')
|
13
|
+
return str if str.valid_encoding?
|
14
|
+
str.encode("UTF-8", 'binary', invalid: :replace, undef: :replace, replace: '')
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.capture(content_str,type = "m",fetch_types=["p","f","c"])
|
18
|
+
results = []
|
19
|
+
str = to_utf8 content_str
|
20
|
+
if fetch_types.include? "f"
|
21
|
+
str.scan @@func_regex do |curr_match|
|
22
|
+
md = Regexp.last_match
|
23
|
+
whole_match = md[0]
|
24
|
+
captures = md.captures
|
25
|
+
|
26
|
+
captures.each do |capture|
|
27
|
+
results << "f:#{capture}"
|
28
|
+
#p [whole_match, capture]
|
29
|
+
p "f:[#{capture}]"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
#no arguments function
|
33
|
+
str.scan @@func_simple_regex do |curr_match|
|
34
|
+
md = Regexp.last_match
|
35
|
+
whole_match = md[0]
|
36
|
+
captures = md.captures
|
37
|
+
|
38
|
+
captures.each do |capture|
|
39
|
+
results << "f:#{capture}"
|
40
|
+
#p [whole_match, capture]
|
41
|
+
p "f:[#{capture}]"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
cls_regex = ""
|
46
|
+
if type == "h"
|
47
|
+
cls_regex = @@hcls_regex
|
48
|
+
else
|
49
|
+
cls_regex = @@mcls_regex
|
50
|
+
end
|
51
|
+
if fetch_types.include? "c"
|
52
|
+
str.scan cls_regex do |curr_match|
|
53
|
+
md = Regexp.last_match
|
54
|
+
whole_match = md[0]
|
55
|
+
captures = md.captures
|
56
|
+
|
57
|
+
captures.each do |capture|
|
58
|
+
results << "c:#{capture}"
|
59
|
+
#p [whole_match, capture]
|
60
|
+
p "c:[#{capture}]"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
if fetch_types.include? "p"
|
65
|
+
str.scan @@property_regex do |curr_match|
|
66
|
+
md = Regexp.last_match
|
67
|
+
whole_match = md[0]
|
68
|
+
captures = md.captures
|
69
|
+
|
70
|
+
captures.each do |capture|
|
71
|
+
results << "p:#{capture}"
|
72
|
+
#p [whole_match, capture]
|
73
|
+
p "p:[#{capture}]"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
str.scan @@property_regex2 do |curr_match|
|
77
|
+
md = Regexp.last_match
|
78
|
+
whole_match = md[0]
|
79
|
+
captures = md.captures
|
80
|
+
|
81
|
+
captures.each do |capture|
|
82
|
+
results << "p:#{capture}"
|
83
|
+
#p [whole_match, capture]
|
84
|
+
p "p:[#{capture}]"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
str.scan @@property_regex3 do |curr_match|
|
88
|
+
md = Regexp.last_match
|
89
|
+
whole_match = md[0]
|
90
|
+
captures = md.captures
|
91
|
+
|
92
|
+
captures.each do |capture|
|
93
|
+
results << "p:#{capture}"
|
94
|
+
#p [whole_match, capture]
|
95
|
+
p "p:[#{capture}]"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
results
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.genFuncList(path,type = "m",need_filt=true,fetch_types=["p","f","c"])
|
104
|
+
puts "#######################{fetch_types}"
|
105
|
+
capture_methods = []
|
106
|
+
p_methods = []
|
107
|
+
funclist_path = "#{path}/func.list"
|
108
|
+
file = File.open(funclist_path, "w")
|
109
|
+
file_pathes = []
|
110
|
+
if type == "h" || type == "m"
|
111
|
+
file_pathes = `find #{path} -name "*.#{type}" -d`.split "\n"
|
112
|
+
elsif type == "all"
|
113
|
+
file_pathes += `find #{path} -name "*.h" -d`.split "\n"
|
114
|
+
file_pathes += `find #{path} -name "*.m" -d`.split "\n"
|
115
|
+
end
|
116
|
+
file_pathes.each do |file_path|
|
117
|
+
content = File.read file_path
|
118
|
+
captures = capture content , type , fetch_types
|
119
|
+
captures.each do |capture_method|
|
120
|
+
method_type = capture_method.split(":").first
|
121
|
+
method_content = capture_method.split(":").last
|
122
|
+
if !(method_content.start_with?("init") || method_content.start_with?("set") || method_content.start_with?("_") || method_content.length < 4) || !need_filt
|
123
|
+
if method_type == "c" || method_type == "f"
|
124
|
+
if !capture_methods.include? capture_method
|
125
|
+
capture_methods << capture_method
|
126
|
+
end
|
127
|
+
elsif method_type == "p"
|
128
|
+
if !p_methods.include? capture_method
|
129
|
+
p_methods << capture_method
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
p_methods.each do |capture_method|
|
137
|
+
method_type = capture_method.split(":").first
|
138
|
+
method_content = capture_method.split(":").last
|
139
|
+
c_method = "c:#{method_content}"
|
140
|
+
f_method = "f:#{method_content}"
|
141
|
+
if capture_methods.include? c_method
|
142
|
+
capture_methods.delete c_method
|
143
|
+
end
|
144
|
+
if capture_methods.include? f_method
|
145
|
+
capture_methods.delete f_method
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
capture_methods += p_methods
|
150
|
+
|
151
|
+
if capture_methods.length > 0
|
152
|
+
file.write(capture_methods.join "\n")
|
153
|
+
end
|
154
|
+
file.close
|
155
|
+
funclist_path
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require_relative 'filtsymbols.rb'
|
2
|
+
|
3
|
+
class String
|
4
|
+
def upcase_first_letter
|
5
|
+
self.slice(0,1).capitalize + self.slice(1..-1)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
module Obscure
|
10
|
+
|
11
|
+
|
12
|
+
@@TABLENAME="symbols"
|
13
|
+
@@SYMBOL_DB_FILE="symbols"
|
14
|
+
@@STRING_SYMBOL_FILE="func.list"
|
15
|
+
|
16
|
+
#维护数据库方便日后作排重
|
17
|
+
def self.createTable
|
18
|
+
if !File.exist? @@SYMBOL_DB_FILE
|
19
|
+
`echo "create table #{@@TABLENAME}(src text, des text,PRIMARY KEY (src));" | sqlite3 #{@@SYMBOL_DB_FILE}`
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.insertValue(line,ramdom)
|
24
|
+
`echo "insert or ignore into #{@@TABLENAME} values('#{line}' ,'#{ramdom}');" | sqlite3 #{@@SYMBOL_DB_FILE}`
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.query(line)
|
28
|
+
`echo "select * from #{@@TABLENAME} where src='#{line}';" | sqlite3 #{@@SYMBOL_DB_FILE}`
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.ramdomString
|
32
|
+
`openssl rand -base64 64 | tr -cd 'a-zA-Z' |head -c 16`
|
33
|
+
end
|
34
|
+
|
35
|
+
#有define重复的问题等待解决
|
36
|
+
def self.run(root_dir)
|
37
|
+
|
38
|
+
@@HEAD_FILE="#{root_dir}/codeObfuscation.h"
|
39
|
+
@@SYMBOL_DB_FILE = "#{root_dir}/#{@@SYMBOL_DB_FILE}"
|
40
|
+
@@STRING_SYMBOL_FILE = "#{root_dir}/#{@@STRING_SYMBOL_FILE}"
|
41
|
+
|
42
|
+
if File.exist? @@SYMBOL_DB_FILE
|
43
|
+
`rm -f #{@@SYMBOL_DB_FILE}`
|
44
|
+
end
|
45
|
+
if File.exists? @@HEAD_FILE
|
46
|
+
`rm -f #{@@HEAD_FILE}`
|
47
|
+
end
|
48
|
+
createTable
|
49
|
+
|
50
|
+
date = `date`
|
51
|
+
file = File.new @@HEAD_FILE , 'w'
|
52
|
+
file.puts "#ifndef co_codeObfuscation_h"
|
53
|
+
file.puts "#define co_codeObfuscation_h"
|
54
|
+
file.puts "//confuse string at #{date.to_s}"
|
55
|
+
|
56
|
+
symbol_file = File.open(@@STRING_SYMBOL_FILE).read
|
57
|
+
symbol_file.each_line do |line|
|
58
|
+
line_type = line.rstrip.split(":").first
|
59
|
+
line_content = line.rstrip.split(":").last
|
60
|
+
result = FiltSymbols.query(line_content)
|
61
|
+
if result.nil? || result.empty?
|
62
|
+
ramdom = ramdomString
|
63
|
+
insertValue line_content , ramdom
|
64
|
+
if line_type == "p"
|
65
|
+
result = FiltSymbols.query("set#{line_content.upcase_first_letter}")
|
66
|
+
if result.nil? || result.empty?
|
67
|
+
file.puts "#define #{line_content} #{ramdom}"
|
68
|
+
file.puts "#define _#{line_content} _#{ramdom}"
|
69
|
+
file.puts "#define set#{line_content.upcase_first_letter} set#{ramdom.upcase_first_letter}"
|
70
|
+
end
|
71
|
+
else
|
72
|
+
file.puts "#define #{line_content} #{ramdom}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
file.puts "#endif"
|
78
|
+
file.close
|
79
|
+
|
80
|
+
`sqlite3 #{@@SYMBOL_DB_FILE} .dump`
|
81
|
+
if File.exist? @@SYMBOL_DB_FILE
|
82
|
+
`rm -f #{@@SYMBOL_DB_FILE}`
|
83
|
+
end
|
84
|
+
if File.exist? @@STRING_SYMBOL_FILE
|
85
|
+
`rm -f #{@@STRING_SYMBOL_FILE}`
|
86
|
+
end
|
87
|
+
@@HEAD_FILE
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class CodeobscureTest < Minitest::Test
|
4
|
+
def test_that_it_has_a_version_number
|
5
|
+
refute_nil ::Codeobscure::VERSION
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_it_funclist_capture
|
9
|
+
result = FuncList.capture '+ (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view'
|
10
|
+
#因为没有去重
|
11
|
+
assert_equal result , ['f:pickerView','f:viewForRow','f:forComponent','f:reusingView','f:pickerView']
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_it_funclist_genFuncList
|
15
|
+
test_dir = "#{File.dirname(__FILE__)}/objcTemple"
|
16
|
+
funclist_path = "#{test_dir}/func.list"
|
17
|
+
if File.exist? funclist_path
|
18
|
+
File.delete funclist_path
|
19
|
+
end
|
20
|
+
FuncList.genFuncList(test_dir)
|
21
|
+
is_exist = File.exist? funclist_path
|
22
|
+
assert is_exist , "generate func.list file failed"
|
23
|
+
|
24
|
+
content = File.read funclist_path
|
25
|
+
puts "=========#{content.split "\n"}"
|
26
|
+
expect_result = "f:addItem\nf:getClusters\nf:getRectWithPt\nf:Span\nf:getDistanceSquared\nf:point\nf:clearItems\nc:BMKClusterAlgorithm"
|
27
|
+
assert_equal expect_result , content
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_it_obscure_run
|
31
|
+
test_dir = "#{File.dirname(__FILE__)}/objcTemple"
|
32
|
+
FuncList.genFuncList(test_dir)
|
33
|
+
path = "#{test_dir}/codeObfuscation.h"
|
34
|
+
if File.exist? path
|
35
|
+
File.delete path
|
36
|
+
end
|
37
|
+
Obscure.run test_dir
|
38
|
+
is_exist = File.exist? path
|
39
|
+
assert is_exist , "generate codeObfuscation.h failed"
|
40
|
+
end
|
41
|
+
|
42
|
+
#def test_it_filtsymbols_load
|
43
|
+
#test_dir = "#{File.dirname(__FILE__)}/objcTemple"
|
44
|
+
#FiltSymbols.loadFiltSymbols test_dir
|
45
|
+
#path = "#{File.expand_path '../..', __FILE__}/filtSymbols"
|
46
|
+
#is_exist = File.exist? path
|
47
|
+
#assert is_exist , "generate filtSymbols failed"
|
48
|
+
#end
|
49
|
+
|
50
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: codeobscure
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- kaich
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-08-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.12'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.12'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: colorize
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.7'
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: 0.7.7
|
65
|
+
type: :runtime
|
66
|
+
prerelease: false
|
67
|
+
version_requirements: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - "~>"
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0.7'
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 0.7.7
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: xcodeproj
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 1.0.0
|
82
|
+
type: :runtime
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 1.0.0
|
89
|
+
description: Code Obscure Tool.You can use it simplely
|
90
|
+
email:
|
91
|
+
- chengkai1853@163.com
|
92
|
+
executables:
|
93
|
+
- codeobscure
|
94
|
+
extensions: []
|
95
|
+
extra_rdoc_files: []
|
96
|
+
files:
|
97
|
+
- bin/codeobscure
|
98
|
+
- filtSymbols
|
99
|
+
- filtSymbols_standard
|
100
|
+
- lib/codeobscure.rb
|
101
|
+
- lib/codeobscure/filtsymbols.rb
|
102
|
+
- lib/codeobscure/funclist.rb
|
103
|
+
- lib/codeobscure/obscure.rb
|
104
|
+
- lib/codeobscure/version.rb
|
105
|
+
- test/codeobscure_test.rb
|
106
|
+
- test/test_helper.rb
|
107
|
+
homepage: https://github.com/kaich/codeobscure
|
108
|
+
licenses:
|
109
|
+
- MIT
|
110
|
+
metadata:
|
111
|
+
allowed_push_host: https://rubygems.org
|
112
|
+
post_install_message:
|
113
|
+
rdoc_options: []
|
114
|
+
require_paths:
|
115
|
+
- lib
|
116
|
+
- bin
|
117
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
requirements: []
|
128
|
+
rubyforge_project:
|
129
|
+
rubygems_version: 2.4.5
|
130
|
+
signing_key:
|
131
|
+
specification_version: 4
|
132
|
+
summary: Code Obscure For Xcode Project
|
133
|
+
test_files:
|
134
|
+
- test/codeobscure_test.rb
|
135
|
+
- test/test_helper.rb
|