Class: JSObfu::Scope
- Inherits:
-
Hash
- Object
- Hash
- JSObfu::Scope
- Defined in:
- lib/jsobfu/scope.rb
Overview
A single Javascript scope, used as a key-value store to maintain uniqueness of members in generated closures. For speed this class is implemented as a subclass of Hash.
Constant Summary
- RESERVED_KEYWORDS =
these keywords should never be used as a random var name source: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Reserved_Words
%w( break case catch continue debugger default delete do else finally for function if in instanceof new return switch this throw try typeof var void while with class enum export extends import super implements interface let package private protected public static yield const let
- BUILTIN_VARS =
these vars should not be shadowed as they in the exploit code, and generating them would cause problems.
%w( String window unescape location chrome document navigator location frames ActiveXObject XMLHttpRequest Function eval Object Math CSS parent opener event frameElement Error TypeError setTimeout setInterval top arguments Array Date
Instance Attribute Summary (collapse)
-
- (JSObfu::Scope) parent
Parent that spawned this scope.
-
- (Hash) renames
Mapping old var names to random ones.
Instance Method Summary (collapse)
-
- (Boolean) empty?
Scope has members.
-
- (Boolean) has_key?(key)
Check if we've used this var before.
-
- (Scope) initialize(opts = {})
constructor
A new instance of Scope.
-
- (Object) pop!
"Consumes" the parent and replaces self with it.
-
- (Object) push!
replaces this Scope in the "parent" chain with a copy, empties current scope, and returns.
-
- (String) random_string(len)
A random string that can be used as a var.
-
- (String) random_var_name
Generates a unique, "safe" random variable.
-
- (String) rename_var(var_name, opts = {})
Re-maps your var_name to a unique, random names in the current scope.
- - (Object) top
-
- (Boolean) top?
Scope has no parent.
Constructor Details
- (Scope) initialize(opts = {})
Returns a new instance of Scope
38 39 40 41 42 43 44 |
# File 'lib/jsobfu/scope.rb', line 38 def initialize(opts={}) @parent = opts[:parent] @first_char_set = opts[:first_char_set] || [*'A'..'Z']+[*'a'..'z']+['_', '$'] @char_set = opts[:first_char_set] || @first_char_set + [*'0'..'9'] @min_len = opts[:min_len] || 1 @renames = {} end |
Instance Attribute Details
- (JSObfu::Scope) parent
Returns parent that spawned this scope
29 30 31 |
# File 'lib/jsobfu/scope.rb', line 29 def parent @parent end |
- (Hash) renames
Returns mapping old var names to random ones
32 33 34 |
# File 'lib/jsobfu/scope.rb', line 32 def renames @renames end |
Instance Method Details
- (Boolean) empty?
Returns scope has members
98 99 100 |
# File 'lib/jsobfu/scope.rb', line 98 def empty? self.keys.empty? and (parent.nil? or parent.empty?) end |
- (Boolean) has_key?(key)
Check if we've used this var before. This will also check any attached parent scopes (and their parents, recursively)
117 118 119 |
# File 'lib/jsobfu/scope.rb', line 117 def has_key?(key) super or (parent and parent.has_key?(key)) end |
- (Object) pop!
"Consumes" the parent and replaces self with it
134 135 136 137 138 139 140 141 |
# File 'lib/jsobfu/scope.rb', line 134 def pop! clear if @parent merge! @parent @renames = @parent.renames @parent = @parent.parent end end |
- (Object) push!
replaces this Scope in the "parent" chain with a copy, empties current scope, and returns. Essentially an in-place push operation
124 125 126 127 128 129 130 131 |
# File 'lib/jsobfu/scope.rb', line 124 def push! replacement = dup replacement.parent = @parent replacement.renames = @renames @renames = {} @parent = replacement clear end |
- (String) random_string(len)
Returns a random string that can be used as a var
144 145 146 |
# File 'lib/jsobfu/scope.rb', line 144 def random_string(len) @first_char_set.sample + (len-1).times.map { @char_set.sample }.join end |
- (String) random_var_name
Generates a unique, "safe" random variable
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/jsobfu/scope.rb', line 48 def random_var_name len = @min_len loop do text = random_string(len) unless has_key?(text) or RESERVED_KEYWORDS.include?(text) or BUILTIN_VARS.include?(text) self[text] = nil return text end len += 1 end end |
- (String) rename_var(var_name, opts = {})
Re-maps your var_name to a unique, random names in the current scope
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/jsobfu/scope.rb', line 76 def rename_var(var_name, opts={}) return var_name if BUILTIN_VARS.include?(var_name) generate = opts.fetch(:generate, true) unresolved = opts.fetch(:unresolved, []) renamed = @renames[var_name] if renamed.nil? and parent renamed = parent.rename_var(var_name, :generate => false) end if renamed.nil? and generate @renames[var_name] = random_var_name renamed = @renames[var_name] end #puts "Mapped #{var_name} => #{renamed}" if renamed renamed end |
- (Object) top
107 108 109 110 111 |
# File 'lib/jsobfu/scope.rb', line 107 def top p = self p = p.parent until p.parent.nil? p end |
- (Boolean) top?
Returns scope has no parent
103 104 105 |
# File 'lib/jsobfu/scope.rb', line 103 def top? parent.nil? end |