jobfuscator 1.0.6

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,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "base64"
4
+ require "json"
5
+ require "zlib"
6
+
7
+ class JObfuscator
8
+ API_URL = "https://www.pelock.com/api/jobfuscator/v1"
9
+ ERROR_SUCCESS = 0
10
+ ERROR_INPUT_SIZE = 1
11
+ ERROR_INPUT = 2
12
+ ERROR_PARSING = 3
13
+ ERROR_OBFUSCATION = 4
14
+ ERROR_OUTPUT = 5
15
+ USER_AGENT = "PELock JObfuscator"
16
+
17
+ # Defaults match JObfuscator.php (split_strings is false; remove_comments is always on).
18
+ FLAG_PARAMS = {
19
+ array_int_crypt: "array_int_crypt",
20
+ array_char_crypt: "array_char_crypt",
21
+ array_double_crypt: "array_double_crypt",
22
+ array_string_crypt: "array_string_crypt",
23
+ split_strings: "split_strings",
24
+ crypt_strings: "crypt_strings",
25
+ rename_methods: "rename_methods",
26
+ shuffle_methods: "shuffle_methods",
27
+ ints_math_crypt: "ints_math_crypt",
28
+ dbls_math_crypt: "dbls_math_crypt",
29
+ rename_variables: "rename_variables",
30
+ mix_code_flow: "mix_code_flow",
31
+ string_char_vault: "string_char_vault",
32
+ ints_from_double_math: "ints_from_double_math",
33
+ opaque_mixer_chain: "opaque_mixer_chain",
34
+ complexify_booleans: "complexify_booleans",
35
+ try_finally_noise: "try_finally_noise",
36
+ ints_to_arrays: "ints_to_arrays",
37
+ dbls_to_arrays: "dbls_to_arrays"
38
+ }.freeze
39
+
40
+ attr_accessor :enable_compression, *FLAG_PARAMS.keys
41
+
42
+ def initialize(api_key = nil)
43
+ @api_key = api_key
44
+ @enable_compression = true
45
+ @remove_comments = true
46
+ FLAG_PARAMS.each_key { |name| instance_variable_set("@#{name}", true) }
47
+ @split_strings = false
48
+ end
49
+
50
+ def login(return_as_object = true)
51
+ post_request({ "command" => "login" }, return_as_object)
52
+ end
53
+
54
+ def obfuscate_java_file(java_file_path, return_as_object = true)
55
+ source = File.read(java_file_path, encoding: "UTF-8")
56
+ return nil if source.nil? || source.empty?
57
+
58
+ obfuscate_java_source(source, return_as_object)
59
+ rescue StandardError
60
+ nil
61
+ end
62
+
63
+ def obfuscate_java_source(java_source, return_as_object = true)
64
+ post_request({ "command" => "obfuscate", "source" => java_source }, return_as_object)
65
+ end
66
+
67
+ private
68
+
69
+ def post_request(params_array, return_as_object)
70
+ params = params_array.dup
71
+ params["key"] = @api_key unless @api_key.nil? || @api_key.to_s.empty?
72
+
73
+ FLAG_PARAMS.each do |name, key|
74
+ params[key] = "1" if instance_variable_get("@#{name}")
75
+ end
76
+ params["remove_comments"] = "1" if @remove_comments
77
+
78
+ if @enable_compression && params["source"] && !params["source"].to_s.empty?
79
+ params["source"] = Base64.strict_encode64(Zlib::Deflate.deflate(params["source"], 9))
80
+ params["compression"] = "1"
81
+ end
82
+
83
+ body = Http.post_multipart(API_URL, params, user_agent: USER_AGENT)
84
+ return false if body.nil? || body.empty?
85
+
86
+ result = Http.parse_json(body)
87
+ return false if result.nil? || result.empty?
88
+
89
+ depacked = false
90
+ if @enable_compression && result["error"] == ERROR_SUCCESS
91
+ begin
92
+ result["output"] = Zlib::Inflate.inflate(Base64.decode64(result["output"].to_s))
93
+ depacked = true
94
+ rescue StandardError
95
+ # keep packed output
96
+ end
97
+ end
98
+
99
+ return result if return_as_object
100
+ return JSON.generate(result) if depacked
101
+
102
+ body
103
+ end
104
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "net/http"
5
+ require "openssl"
6
+ require "securerandom"
7
+ require "uri"
8
+
9
+ class JObfuscator
10
+ # Stdlib HTTP helper. Multipart for API form posts / file uploads; urlencoded when needed.
11
+ module Http
12
+ class << self
13
+ def post_multipart(url, fields, user_agent:, files: {})
14
+ boundary = "----PELock#{SecureRandom.hex(16)}"
15
+ body = build_multipart(fields, files, boundary)
16
+ request(url, body, user_agent, "multipart/form-data; boundary=#{boundary}")
17
+ end
18
+
19
+ def post_urlencoded(url, fields, user_agent:)
20
+ pairs = []
21
+ fields.each do |key, value|
22
+ next if value.nil?
23
+
24
+ pairs << [key.to_s, normalize_form_value(value)]
25
+ end
26
+ request(url, URI.encode_www_form(pairs), user_agent, "application/x-www-form-urlencoded")
27
+ end
28
+
29
+ def parse_json(body)
30
+ return nil if body.nil? || body.to_s.empty?
31
+
32
+ JSON.parse(body)
33
+ rescue JSON::ParserError
34
+ nil
35
+ end
36
+
37
+ def request(url, body, user_agent, content_type)
38
+ uri = URI.parse(url)
39
+ http = Net::HTTP.new(uri.host, uri.port)
40
+ http.use_ssl = uri.scheme == "https"
41
+ http.open_timeout = 30
42
+ http.read_timeout = 180
43
+ req = Net::HTTP::Post.new(uri.request_uri)
44
+ req["User-Agent"] = user_agent
45
+ req["Content-Type"] = content_type
46
+ req.body = body
47
+ http.request(req).body
48
+ rescue StandardError
49
+ nil
50
+ end
51
+
52
+ def build_multipart(fields, files, boundary)
53
+ body = String.new(encoding: Encoding::ASCII_8BIT)
54
+ fields.each do |name, value|
55
+ next if value.nil?
56
+
57
+ body << "--#{boundary}\r\n"
58
+ body << "Content-Disposition: form-data; name=\"#{name}\"\r\n\r\n"
59
+ body << value.to_s.dup.force_encoding(Encoding::UTF_8).b
60
+ body << "\r\n"
61
+ end
62
+ files.each do |name, file|
63
+ filename = file[:filename] || File.basename(file[:path].to_s)
64
+ content = file[:content] || File.binread(file[:path])
65
+ content_type = file[:content_type] || "application/octet-stream"
66
+ body << "--#{boundary}\r\n"
67
+ body << "Content-Disposition: form-data; name=\"#{name}\"; filename=\"#{filename}\"\r\n"
68
+ body << "Content-Type: #{content_type}\r\n\r\n"
69
+ body << content.b
70
+ body << "\r\n"
71
+ end
72
+ body << "--#{boundary}--\r\n"
73
+ body
74
+ end
75
+
76
+ def normalize_form_value(value)
77
+ case value
78
+ when true then "1"
79
+ when false then "0"
80
+ else value.to_s
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class JObfuscator
4
+ VERSION = "1.0.6"
5
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "jobfuscator/version"
4
+ require_relative "jobfuscator/http"
5
+ require_relative "jobfuscator/client"
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jobfuscator
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.6
5
+ platform: ruby
6
+ authors:
7
+ - Bartosz Wójcik
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ email:
13
+ - support@pelock.com
14
+ executables: []
15
+ extensions: []
16
+ extra_rdoc_files: []
17
+ files:
18
+ - LICENSE
19
+ - README.md
20
+ - lib/jobfuscator.rb
21
+ - lib/jobfuscator/client.rb
22
+ - lib/jobfuscator/http.rb
23
+ - lib/jobfuscator/version.rb
24
+ homepage: https://www.pelock.com/products/jobfuscator
25
+ licenses:
26
+ - Apache-2.0
27
+ metadata:
28
+ homepage_uri: https://www.pelock.com/products/jobfuscator
29
+ source_code_uri: https://github.com/PELock/JObfuscator-Ruby
30
+ bug_tracker_uri: https://www.pelock.com
31
+ rdoc_options: []
32
+ require_paths:
33
+ - lib
34
+ required_ruby_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: 2.7.0
39
+ required_rubygems_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ requirements: []
45
+ rubygems_version: 4.0.20
46
+ specification_version: 4
47
+ summary: JObfuscator (Java Obfuscator) Web API Ruby SDK
48
+ test_files: []