jsobfu 0.1.9 → 0.2.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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ODI3NGYzZmNkMmU4ZmZmM2M1NzIwMjZjNzBhZDQ0YjhjNzVkYmI4MA==
4
+ OWVkOTRmZDM5ZDZmYzkwOGFhNGM4MDk0ZjQ3NzljZWVkMWI4OWQwMg==
5
5
  data.tar.gz: !binary |-
6
- ZjgxMWE0MDFkZGY1YzFlZmFkYTM0ODE2MzJkMWUxZmUxZjZjZGFlNQ==
6
+ MGQzZGZkMTAxZDUxZmJjZjNhNzc0YzE0NDFkNDQ0MzI4ZjJiYTc4MQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- Yjg0Nzc2MzcyZmUzZWEwNTVjNmYyYmFkMGFmOGM0ODRhNmM3MGVmODUzMjIy
10
- YWRjOTdjNzZiZDFjM2VjZGI2ZDIxNTU4ZWRmN2QxZTEyM2I3NjYxMjI4ODMx
11
- MjdlNTg2Y2U1ZDJmNTVlYTQ1MGExM2Q4NjZlNTViNTE3MDZmNDg=
9
+ ZjA5NzRkNWZmMzQ0MDA0ZTkxZWRjMjYyYzc1NWEwZDE5YzcwMDNlZTZiN2E3
10
+ YTczZmQzZGMxODk1MzBlOTY5NjQwYzIxNTNmZTk5MjdlMzBlZmQ1ZGFiODRm
11
+ YThhYjAyMjhlYzhiZjliNzg2ZGZlOTc2ZmEwNDliZWNlOTg4MzU=
12
12
  data.tar.gz: !binary |-
13
- MjUwZmQ4N2UyYmQwZWFmZGEwYmIxMjdkMTljMWIyY2Q4MGJkZmE0YzM0ODhh
14
- NDJkOTYwZjYyZGU5NDdmYzg2Mzc2NTFmNjlmZDNmMmMxNzRkYTEyN2IyOTkz
15
- NDRiNmU1ODgxMWFkZGFmM2Q2ZmIxOWFmMDMzOWZmMDk4NzFlMTE=
13
+ NzhkYTM0OTRlM2EwYzgwNzQ2NmI2MGNhOTUzMDVmMjYzYzk4YmQyOTk3Y2Y2
14
+ ZmJiMTQyZDAwZGJhZGM2YzhlMzQzODAxMjA1MjlhYjE5NDA2NWEzODI0MWQ2
15
+ M2JmMzEzMjkyMzhjMWJkNWMwMmQyODU1Zjg4MzcyZWU1MTRjMzQ=
@@ -47,6 +47,8 @@ class JSObfu
47
47
  # the output code (true)
48
48
  # @option opts [Integer] :iterations number of times to run the
49
49
  # obfuscator on this code (1)
50
+ # @option opts [String] :global the global object to rewrite unresolved lookups to.
51
+ # Depending on the environment, it may be `window`, `global`, or `this`.
50
52
  # @return [self]
51
53
  def obfuscate(opts={})
52
54
  return self if JSObfu.disabled?
@@ -55,7 +57,7 @@ class JSObfu
55
57
  strip_whitespace = opts.fetch(:strip_whitespace, true)
56
58
 
57
59
  iterations.times do |i|
58
- obfuscator = JSObfu::Obfuscator.new(scope: @scope)
60
+ obfuscator = JSObfu::Obfuscator.new(opts.merge(scope: @scope))
59
61
  @code = obfuscator.accept(ast).to_s
60
62
  if strip_whitespace
61
63
  @code.gsub!(/(^\s+|\s+$)/, '')
@@ -98,8 +100,7 @@ protected
98
100
  # Generate an Abstract Syntax Tree (#ast) for later obfuscation
99
101
  #
100
102
  def parse
101
- parser = RKelly::Parser.new
102
- @ast = parser.parse(@code)
103
+ @ast = RKelly::Parser.new.parse(@code)
103
104
  end
104
105
 
105
106
  end
@@ -5,17 +5,22 @@ class JSObfu::Obfuscator < JSObfu::ECMANoWhitespaceVisitor
5
5
  # @return [JSObfu::Scope] the scope maintained while walking the ast
6
6
  attr_reader :scope
7
7
 
8
- # Note: At a high level #renames is not that useful, because var shadowing can
9
- # cause multiple variables in different contexts to be mapped separately.
10
- # - joev
11
-
12
8
  # @return [Hash] of original var/fn names to our new random neames
13
9
  attr_reader :renames
14
10
 
11
+ # @return [String] the global object in this JS environment
12
+ attr_reader :global
13
+
14
+ # unresolved lookups are rewritten as property lookups on the global object
15
+ DEFAULT_GLOBAL = 'window'
16
+
15
17
  # @param opts [Hash] the options hash
16
18
  # @option opts [JSObfu::Scope] :scope the optional scope to save vars to
19
+ # @option opts [String] :global the global object to rewrite unresolved lookups to.
20
+ # Depending on the environment, it may be `window`, `global`, or `this`.
17
21
  def initialize(opts={})
18
22
  @scope = opts.fetch(:scope, JSObfu::Scope.new)
23
+ @global = opts.fetch(:global, DEFAULT_GLOBAL).to_s
19
24
  @renames = {}
20
25
  super()
21
26
  end
@@ -87,8 +92,14 @@ class JSObfu::Obfuscator < JSObfu::ECMANoWhitespaceVisitor
87
92
  o.value = JSObfu::Utils::random_var_encoding(new_val)
88
93
  super
89
94
  else
90
- # A global is used, at least obfuscate the lookup
91
- "window[#{JSObfu::Utils::transform_string(o.value, scope, :quotes => false)}]"
95
+ if o.value.to_s == global.to_s
96
+ # if the ref is the global object, don't obfuscate it on itself. This helps
97
+ # "shimmed" globals (like `window=this` at the top of the script) work reliably.
98
+ super
99
+ else
100
+ # A global is used, at least obfuscate the lookup
101
+ "#{global}[#{JSObfu::Utils::transform_string(o.value, scope, :quotes => false)}]"
102
+ end
92
103
  end
93
104
  end
94
105
 
@@ -19,7 +19,7 @@ describe 'Integrations' do
19
19
  num = $1.to_i
20
20
  end
21
21
 
22
- # ensure there is a global object to reference.
22
+ # ensure there is a global object to reference, regardless of the JS backend.
23
23
  js = "window=this; #{js}"
24
24
 
25
25
  num.times do
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ require 'rkelly'
3
+
4
+ describe JSObfu::Obfuscator do
5
+ let(:opts) { { } }
6
+ subject(:obfuscator) { described_class.new(opts) }
7
+
8
+ describe 'the :global option' do
9
+ let(:global_str) { 'BLAHBLAH' }
10
+ let(:opts) { { global: global_str } }
11
+ let(:simple_js) { 'x;' }
12
+ let(:simple_ast) { RKelly::Parser.new.parse(simple_js) }
13
+
14
+ it 'rewrites unresolved lookups as property lookups on the specified global object' do
15
+ expect(obfuscator.accept(simple_ast).to_s).to include(global_str)
16
+ end
17
+
18
+ context 'when the code contains `this`' do
19
+ let(:simple_js) { 'this;' }
20
+ it 'never rewrites `this`' do
21
+ expect(obfuscator.accept(simple_ast).to_s).not_to include(global_str)
22
+ end
23
+ end
24
+
25
+ context 'when the global object is specified' do
26
+ let(:global_str) { 'mywindow2' }
27
+ let(:simple_js) { "mywindow2;" }
28
+ it 'never rewrites itself' do
29
+ expect(obfuscator.accept(simple_ast).to_s).to eq(simple_js)
30
+ end
31
+ end
32
+ end
33
+
34
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsobfu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Lee
@@ -114,6 +114,7 @@ files:
114
114
  - spec/integration_spec.rb
115
115
  - spec/jsobfu/disable_spec.rb
116
116
  - spec/jsobfu/hoister_spec.rb
117
+ - spec/jsobfu/obfuscator_spec.rb
117
118
  - spec/jsobfu/scope_spec.rb
118
119
  - spec/jsobfu/utils_spec.rb
119
120
  - spec/jsobfu_spec.rb