jsobfu 0.1.9 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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