undll32 0.2.0 → 0.3.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 +4 -4
- data/lib/undll32.rb +149 -21
- data/lib/undll32/version.rb +1 -1
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: dc86272423576ea01bf2666535b63302cfabd49e12b672c168d49b84fadaa814
         | 
| 4 | 
            +
              data.tar.gz: 1f92550e71c6429d1fdd4ce75fffd759888fddd1a9f127c93424605fd38de2ce
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 4a9bc8bbbd5a4e597ce2847892552b4dc3a7b149aac05658bf0d68c9270e4d151a6af4f6557a314682ae90c5c9d11fa07b013dc067b0b8bb9b5ddc03d9192c02
         | 
| 7 | 
            +
              data.tar.gz: '0692dddf565e76242e9c4bcb5e18d6f4bac407fe9bfb33ac1565e8fe9dfb87de6fb707cd7621f5695feae8eb24998d9e7205ae77235b41cc75c265feb8b91d0e'
         | 
    
        data/lib/undll32.rb
    CHANGED
    
    | @@ -15,6 +15,8 @@ module Undll32 | |
| 15 15 | 
             
              # buffer.buffer => "\0\0\0\0"
         | 
| 16 16 | 
             
              # buffer.unpack => 0
         | 
| 17 17 | 
             
              class Buffer
         | 
| 18 | 
            +
                attr_accessor :struct
         | 
| 19 | 
            +
             | 
| 18 20 | 
             
                def initialize struct
         | 
| 19 21 | 
             
                  case struct
         | 
| 20 22 | 
             
                  when Hash, Array, Symbol, Integer
         | 
| @@ -33,22 +35,63 @@ module Undll32 | |
| 33 35 | 
             
                  _unpack @struct
         | 
| 34 36 | 
             
                end
         | 
| 35 37 |  | 
| 36 | 
            -
                def  | 
| 38 | 
            +
                def load v
         | 
| 39 | 
            +
                  @_i = 0
         | 
| 40 | 
            +
                  _load @struct, v
         | 
| 41 | 
            +
                  unpack
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                def _load x, v
         | 
| 37 45 | 
             
                  case x
         | 
| 38 46 | 
             
                  when Integer
         | 
| 39 | 
            -
                     | 
| 47 | 
            +
                    return @_i += x if v.nil?
         | 
| 48 | 
            +
                    unless String === v
         | 
| 49 | 
            +
                      raise ArgumentError, "expected str, got #{v}"
         | 
| 50 | 
            +
                    end
         | 
| 51 | 
            +
                    x = [x, v.length].min
         | 
| 52 | 
            +
                    buffer[(@_i += x) - x, x] = v[0, x]
         | 
| 40 53 | 
             
                  when Symbol
         | 
| 41 54 | 
             
                    n = { C: 1, S: 2, L: 4, Q: 8 }[x]
         | 
| 42 55 | 
             
                    if n.nil?
         | 
| 43 56 | 
             
                      raise ArgumentError, "expected CSLQ, got #{x}"
         | 
| 44 57 | 
             
                    end
         | 
| 58 | 
            +
                    return @_i += n if v.nil?
         | 
| 59 | 
            +
                    unless Integer === v
         | 
| 60 | 
            +
                      raise ArgumentError, "expected int, got #{v}"
         | 
| 61 | 
            +
                    end
         | 
| 62 | 
            +
                    buffer[(@_i += n) - n, n] = [v].pack("#{x}")
         | 
| 63 | 
            +
                  when Array
         | 
| 64 | 
            +
                    return x.each { |a| _load a, nil } if v.nil?
         | 
| 65 | 
            +
                    unless Array === v and v.size == x.size
         | 
| 66 | 
            +
                      raise ArgumentError, "expected array[#{x.size}], got #{v}"
         | 
| 67 | 
            +
                    end
         | 
| 68 | 
            +
                    x.zip(v) { |a, b| _load a, b }
         | 
| 69 | 
            +
                  when Hash
         | 
| 70 | 
            +
                    return x.each { |k, y| _load y, nil } if v.nil?
         | 
| 71 | 
            +
                    unless Hash === v
         | 
| 72 | 
            +
                      raise ArgumentError, "expected hash, got #{v}"
         | 
| 73 | 
            +
                    end
         | 
| 74 | 
            +
                    x.each { |k, y| _load y, v[k] }
         | 
| 75 | 
            +
                  else
         | 
| 76 | 
            +
                    raise ArgumentError, "expected hash, array, sym, int, got #{x}"
         | 
| 77 | 
            +
                  end
         | 
| 78 | 
            +
                ensure
         | 
| 79 | 
            +
                  $@.shift if $@
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                def _unpack x
         | 
| 83 | 
            +
                  case x
         | 
| 84 | 
            +
                  when Integer
         | 
| 85 | 
            +
                    buffer[(@_i += x) - x, x].sub(/\0+$/, '')
         | 
| 86 | 
            +
                  when Symbol
         | 
| 87 | 
            +
                    n = { C: 1, S: 2, L: 4, Q: 8 }[x]
         | 
| 45 88 | 
             
                    buffer[(@_i += n) - n, n].unpack1("#{x}")
         | 
| 46 89 | 
             
                  when Array
         | 
| 47 90 | 
             
                    x.map { |e| _unpack e }
         | 
| 48 91 | 
             
                  when Hash
         | 
| 49 92 | 
             
                    Hash[x.map { |k, v| [k, _unpack(v)] }]
         | 
| 50 93 | 
             
                  else
         | 
| 51 | 
            -
                    raise ArgumentError, "expected hash, array, sym, int, got #{ | 
| 94 | 
            +
                    raise ArgumentError, "expected hash, array, sym, int, got #{x}"
         | 
| 52 95 | 
             
                  end
         | 
| 53 96 | 
             
                ensure
         | 
| 54 97 | 
             
                  $@.shift if $@
         | 
| @@ -69,50 +112,132 @@ module Undll32 | |
| 69 112 | 
             
                  when Hash
         | 
| 70 113 | 
             
                    _buffer x.values
         | 
| 71 114 | 
             
                  else
         | 
| 72 | 
            -
                    raise ArgumentError, "expected hash, array, sym, int, got #{ | 
| 115 | 
            +
                    raise ArgumentError, "expected hash, array, sym, int, got #{x}"
         | 
| 73 116 | 
             
                  end
         | 
| 74 117 | 
             
                ensure
         | 
| 75 118 | 
             
                  $@.shift if $@
         | 
| 76 119 | 
             
                end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                def self.from_array code
         | 
| 122 | 
            +
                  unless code =~ /^\[[CSLQ]+\]$/
         | 
| 123 | 
            +
                    raise ArgumentError, "expected [CSLQ], got #{code}"
         | 
| 124 | 
            +
                  end
         | 
| 125 | 
            +
                  return new(code[1..-2].chars.map(&:to_sym))
         | 
| 126 | 
            +
                end
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                def self.from_size code
         | 
| 129 | 
            +
                  m = code.match(/^\:(?<size>[^=]+)=?(?<value>.+)?$/)
         | 
| 130 | 
            +
                  if m.nil?
         | 
| 131 | 
            +
                    raise ArgumentError, "expected <number> or CSLQ, got #{code}"
         | 
| 132 | 
            +
                  end
         | 
| 133 | 
            +
                  if m[:size] =~ /^[CSLQ]+$/
         | 
| 134 | 
            +
                    s = m[:size].chars.map(&:to_sym)
         | 
| 135 | 
            +
                    if s.size == 1
         | 
| 136 | 
            +
                      return new(s[0]).tap { |b| b.load(m[:value].to_i) if m[:value] }
         | 
| 137 | 
            +
                    else
         | 
| 138 | 
            +
                      b = new(s)
         | 
| 139 | 
            +
                      b.load(m[:value].split(':').map(&:to_i)) if m[:value]
         | 
| 140 | 
            +
                      return b
         | 
| 141 | 
            +
                    end
         | 
| 142 | 
            +
                  end
         | 
| 143 | 
            +
                  if (n = m[:size].to_i)
         | 
| 144 | 
            +
                    return new(n).tap { |b| b.load(m[:value]) if m[:value] }
         | 
| 145 | 
            +
                  end
         | 
| 146 | 
            +
                  raise ArgumentError, "expected <number> or CSLQ, got #{code}"
         | 
| 147 | 
            +
                end
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                def self.next_placeholder
         | 
| 150 | 
            +
                  @_placeholder_counter ||= 0
         | 
| 151 | 
            +
                  "__#{@_placeholder_counter += 1}__"
         | 
| 152 | 
            +
                end
         | 
| 153 | 
            +
             | 
| 154 | 
            +
                def self.from_struct code
         | 
| 155 | 
            +
                  default = {}
         | 
| 156 | 
            +
                  # code := '{' [name] [:type] [=value] [,...] '}'
         | 
| 157 | 
            +
                  env, keys, key = [], [], ''
         | 
| 158 | 
            +
                  seq = code.scan /\w+|\:[[:digit:]]+|\:[CSLQ:]+|=[^,\}]+|./
         | 
| 159 | 
            +
                  ret = while (token = seq.shift)
         | 
| 160 | 
            +
                    case token[0]
         | 
| 161 | 
            +
                    when '{'
         | 
| 162 | 
            +
                      keys.push(key.to_sym) unless key.empty?
         | 
| 163 | 
            +
                      env.push({})
         | 
| 164 | 
            +
                      key = ''
         | 
| 165 | 
            +
                    when '}'
         | 
| 166 | 
            +
                      env[-1][key.to_sym] = :L unless key.empty?
         | 
| 167 | 
            +
                      x = env.pop
         | 
| 168 | 
            +
                      break x if env.empty?
         | 
| 169 | 
            +
                      env[-1][keys.pop] = x
         | 
| 170 | 
            +
                      key = ''
         | 
| 171 | 
            +
                    when ':'
         | 
| 172 | 
            +
                      token << seq.shift if seq.first&.start_with?('=')
         | 
| 173 | 
            +
                      b = from_size(token)
         | 
| 174 | 
            +
                      key = next_placeholder if key.empty?
         | 
| 175 | 
            +
                      env[-1][key.to_sym] = b.struct
         | 
| 176 | 
            +
                      d = default
         | 
| 177 | 
            +
                      keys.each { |k| d[k] ||= {}; d = d[k] }
         | 
| 178 | 
            +
                      d[key.to_sym] = b.unpack
         | 
| 179 | 
            +
                      key = ''
         | 
| 180 | 
            +
                    when '='
         | 
| 181 | 
            +
                      e = token[1..-1]
         | 
| 182 | 
            +
                      e = Integer(e) rescue nil
         | 
| 183 | 
            +
                      type = Integer === e ? :L : (e.length + 1)
         | 
| 184 | 
            +
                      env[-1][key.to_sym] = type
         | 
| 185 | 
            +
                      d = default
         | 
| 186 | 
            +
                      keys.each { |k| d[k] ||= {}; d = d[k] }
         | 
| 187 | 
            +
                      if Integer === type
         | 
| 188 | 
            +
                        e = "\"#{e}\"".undump rescue e.undump
         | 
| 189 | 
            +
                      end
         | 
| 190 | 
            +
                      d[key.to_sym] = e
         | 
| 191 | 
            +
                      key = ''
         | 
| 192 | 
            +
                    when ','
         | 
| 193 | 
            +
                      next if key.empty?
         | 
| 194 | 
            +
                      env[-1][key.to_sym] = :L
         | 
| 195 | 
            +
                      key = ''
         | 
| 196 | 
            +
                    else
         | 
| 197 | 
            +
                      key << token
         | 
| 198 | 
            +
                    end
         | 
| 199 | 
            +
                  end
         | 
| 200 | 
            +
                  if ret.nil?
         | 
| 201 | 
            +
                    raise ArgumentError, 'expected }, got end-of-input'
         | 
| 202 | 
            +
                  end
         | 
| 203 | 
            +
                  new(ret).tap { |b| b.load(default) }
         | 
| 204 | 
            +
                end
         | 
| 205 | 
            +
             | 
| 206 | 
            +
                def self.from code
         | 
| 207 | 
            +
                  return from_array(code) if code.start_with?('[')
         | 
| 208 | 
            +
                  return from_size(code) if code.start_with?(':')
         | 
| 209 | 
            +
                  code = "{#{code}}" unless code.start_with?('{')
         | 
| 210 | 
            +
                  return from_struct(code)
         | 
| 211 | 
            +
                end
         | 
| 77 212 | 
             
              end
         | 
| 78 213 |  | 
| 79 214 | 
             
              # Undll32.run 'user32', 'MessageBox', 0, 'hello', 'world', 0
         | 
| 215 | 
            +
              # Undll32.run 'user32', 'GetCursorPos', Buffer.new({:x => :L, :y => :L})
         | 
| 216 | 
            +
              # Undll32.run 'user32', 'GetCursorPos', Buffer.from('x,y')
         | 
| 80 217 | 
             
              def self.run(dll, func, *args)
         | 
| 81 218 | 
             
                types = args.map { |e| Integer === e ? 'L' : 'p' }
         | 
| 82 219 | 
             
                input = args.map { |e| Buffer === e ? e.buffer : e }
         | 
| 83 220 | 
             
                Win32API.new(dll, func, types, 'i').call(*input)
         | 
| 84 221 | 
             
              end
         | 
| 85 222 |  | 
| 86 | 
            -
              def self.parse xs
         | 
| 87 | 
            -
                case x = xs.shift
         | 
| 88 | 
            -
                when ':' then Buffer.new xs.shift.to_i
         | 
| 89 | 
            -
                when '[' then Buffer.new xs.shift.chars.map(&:to_sym)
         | 
| 90 | 
            -
                when '{'
         | 
| 91 | 
            -
                  x = Hash[xs.each_slice(4).map { |k, _, v, _| [k.to_sym, v.to_sym] }]
         | 
| 92 | 
            -
                  Buffer.new x
         | 
| 93 | 
            -
                else
         | 
| 94 | 
            -
                  raise ArgumentError, "expected : [ {, got #{x}"
         | 
| 95 | 
            -
                end
         | 
| 96 | 
            -
              end
         | 
| 97 | 
            -
             | 
| 98 223 | 
             
              def self.exe(argv=ARGV)
         | 
| 99 224 | 
             
                return help if ARGV.include? '-h' or ARGV.include? '--help'
         | 
| 100 225 | 
             
                dllfunc, *args = argv
         | 
| 101 226 | 
             
                return help if dllfunc.nil?
         | 
| 102 227 | 
             
                dll, func = dllfunc.split(',')
         | 
| 103 228 | 
             
                return help if func.nil?
         | 
| 104 | 
            -
                args.map!  | 
| 229 | 
            +
                args.map! do |e|
         | 
| 105 230 | 
             
                  e = e.dup
         | 
| 106 231 | 
             
                  if e.start_with?('+')
         | 
| 107 232 | 
             
                    e.slice!(0)
         | 
| 108 233 | 
             
                    next e if e.start_with?('+')
         | 
| 109 | 
            -
                     | 
| 234 | 
            +
                    Buffer.from(e)
         | 
| 110 235 | 
             
                  else
         | 
| 111 236 | 
             
                    n = Integer(e) rescue nil
         | 
| 112 237 | 
             
                    next n if n
         | 
| 113 238 | 
             
                    e
         | 
| 114 239 | 
             
                  end
         | 
| 115 | 
            -
                 | 
| 240 | 
            +
                end
         | 
| 116 241 | 
             
                ret = run(dll, func, *args)
         | 
| 117 242 | 
             
                args.each { |e| pp e.unpack if Buffer === e }
         | 
| 118 243 | 
             
                ret
         | 
| @@ -126,10 +251,10 @@ module Undll32 | |
| 126 251 | 
             
                EXAMPLE
         | 
| 127 252 | 
             
                  undll32 user32,MessageBox 0 hello world 0
         | 
| 128 253 | 
             
                  undll32 user32,GetCursorPos +[LL]
         | 
| 129 | 
            -
                  undll32 user32,GetCursorPos + | 
| 254 | 
            +
                  undll32 user32,GetCursorPos +x,y
         | 
| 130 255 | 
             
                  undll32 user32,GetCursorPos +:8 # will be converted to string
         | 
| 131 256 |  | 
| 132 | 
            -
                 | 
| 257 | 
            +
                ARGUMENTS
         | 
| 133 258 | 
             
                  0   => (Integer) 0
         | 
| 134 259 | 
             
                  str => 'str'
         | 
| 135 260 | 
             
                  +0  => '0'
         | 
| @@ -138,6 +263,9 @@ module Undll32 | |
| 138 263 | 
             
                  +{x:L,y:L} => Buffer.new({:x => :L, :y => :L})
         | 
| 139 264 | 
             
                  +:256      => Buffer.new(256)
         | 
| 140 265 |  | 
| 266 | 
            +
                VERSION
         | 
| 267 | 
            +
                  #{VERSION}
         | 
| 268 | 
            +
             | 
| 141 269 | 
             
                USAGE
         | 
| 142 270 | 
             
              end
         | 
| 143 271 | 
             
            end
         | 
    
        data/lib/undll32/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: undll32
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.3.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - hyrious
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2018-12- | 
| 11 | 
            +
            date: 2018-12-03 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         |