npgrt 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/npgrt.rb +12 -1
- data/lib/npgrt.rb~ +13 -1
- data/lib/npgrt/.version.rb.swp +0 -0
- data/lib/npgrt/algorithm.rb +178 -0
- data/lib/npgrt/algorithm.rb~ +179 -0
- data/lib/npgrt/filesystem.rb +8 -0
- data/lib/npgrt/filesystem.rb~ +9 -0
- data/lib/npgrt/find.rb +31 -0
- data/lib/npgrt/find.rb~ +31 -0
- data/lib/npgrt/message.rb +0 -1
- data/lib/npgrt/message.rb~ +1 -1
- data/lib/npgrt/query.rb +6 -0
- data/lib/npgrt/report.rb +182 -0
- data/lib/npgrt/report.rb~ +183 -0
- data/lib/npgrt/require.rb +23 -1
- data/lib/npgrt/require.rb~ +24 -1
- data/lib/npgrt/version.rb +3 -1
- data/lib/npgrt/version.rb~ +3 -1
- data/lib/npgrt/win32api.rb +335 -16
- data/lib/npgrt/win32api.rb~ +334 -15
- data/lib/test_32.dll +0 -0
- data/lib/test_64.dll +0 -0
- metadata +14 -2
data/lib/npgrt/win32api.rb~
CHANGED
@@ -1,16 +1,32 @@
|
|
1
1
|
module NPGRT
|
2
2
|
require 'Win32API' unless defined? ::Win32API
|
3
3
|
module Win32API
|
4
|
+
|
4
5
|
W = ::Win32API
|
5
6
|
class API
|
6
7
|
def initialize(dll, func, param = nil, ret = "L")
|
7
|
-
@dll, @func, @param, @ret = dll, func, param, ret
|
8
|
-
|
8
|
+
@dll, @func, @param, @ret = dll, func, param, ret
|
9
|
+
end
|
10
|
+
|
11
|
+
def findapi(dll, func, param, ret)
|
12
|
+
[dll, File.basename(dll) + "_" + NPGRT::PlatformWidth.to_s + File.extname(dll)].each{|d|
|
13
|
+
[func, func + "A", func + "W"].each{|f|
|
14
|
+
if (a = begin
|
15
|
+
W.new(d, f, param, ret)
|
16
|
+
rescue LoadError, RuntimeError
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
)
|
20
|
+
return a
|
21
|
+
end
|
22
|
+
}
|
23
|
+
}
|
24
|
+
raise Errno::ENOENT, " NPGRT::API: Can't find a proper DLL for #{dll}!#{func}"
|
9
25
|
end
|
10
26
|
|
11
27
|
def call(*args)
|
12
28
|
param = @param || guess(args)
|
13
|
-
@api ||=
|
29
|
+
@api ||= findapi(@dll, @func, param, @ret)
|
14
30
|
@api.call(*args)
|
15
31
|
end
|
16
32
|
|
@@ -27,13 +43,16 @@ module NPGRT
|
|
27
43
|
API.new dll, func, params, ret
|
28
44
|
end
|
29
45
|
|
46
|
+
def checked_api(dll, func, params = nil, ret = "L", info = "Error!", exclass = RuntimeError)
|
47
|
+
lambda{|*a| raise exclass, info if 0 != API.new(dll, func, params, ret).call(*a)}
|
48
|
+
end
|
30
49
|
def addressof(dll, func)
|
31
50
|
dl = api('kernel32', 'GetModuleHandle').call(dll)
|
32
51
|
dl = (dl == 0) ? dl : api('kernel32', 'LoadLibrary').call(dll)
|
33
52
|
api('kernel32', 'GetProcAddress').call dl, func
|
34
53
|
end
|
35
54
|
|
36
|
-
def memwrite(addr, buf, len = buf.
|
55
|
+
def memwrite(addr, buf, len = buf.length)
|
37
56
|
api('Kernel32', 'RtlMoveMemory').call addr, buf, len
|
38
57
|
end
|
39
58
|
|
@@ -52,13 +71,13 @@ module NPGRT
|
|
52
71
|
memread(grant_all(addr, size), size)
|
53
72
|
end
|
54
73
|
|
55
|
-
def memwrite!(addr, buf, len = buf.
|
56
|
-
|
74
|
+
def memwrite!(addr, buf, len = buf.length)
|
75
|
+
memwrite(grant_all(addr, len), buf, len)
|
57
76
|
end
|
58
77
|
|
59
78
|
CP_UTF8 = {cp: 65001, suffix:"\0", encoding: "utf-8"}
|
60
|
-
CP_ANSI = {cp: 0, suffix:"\0", encoding: "ascii
|
61
|
-
CP_OEM = CP_ANSI
|
79
|
+
CP_ANSI = {cp: 0, suffix:"\0", encoding: "us-ascii"}
|
80
|
+
CP_ACP = CP_OEM = CP_ANSI
|
62
81
|
CP_GBK = {cp: 65001, suffix: "\0", encoding: "gbk"}
|
63
82
|
|
64
83
|
def to_unicode(string, codepage = CP_UTF8)
|
@@ -72,14 +91,13 @@ module NPGRT
|
|
72
91
|
len = api('Kernel32', 'WideCharToMultiByte').call codepage[:cp], 0, string, -1, 0, 0, 0, 0
|
73
92
|
buf = "\0"*len
|
74
93
|
api('Kernel32', 'WideCharToMultiByte').call codepage[:cp], 0, string, -1, buf, len, 0, 0
|
75
|
-
|
76
|
-
|
77
|
-
b.force_encoding(defined?($RGSS_SCRIPTS) ?
|
94
|
+
if buf.respond_to?(:force_encoding)
|
95
|
+
buf.force_encoding(defined?($RGSS_SCRIPTS) ?
|
78
96
|
'utf-8' :
|
79
97
|
codepage[:encoding])
|
80
98
|
else
|
81
|
-
|
82
|
-
end
|
99
|
+
buf
|
100
|
+
end[0..-1].sub(/\0+$/){}
|
83
101
|
end
|
84
102
|
|
85
103
|
def strread(addr)
|
@@ -92,13 +110,314 @@ module NPGRT
|
|
92
110
|
to_codepage(memread(addr, len*2+2))
|
93
111
|
end
|
94
112
|
|
113
|
+
INI_VALUE_MAX = 2048
|
114
|
+
def iniread(app, key, ini = "Game.ini")
|
115
|
+
buf = "\0\0"*INI_VALUE_MAX
|
116
|
+
ini = normalize_pathsep_os ini
|
117
|
+
app, key, ini = [app, key, ini].map{|x| to_unicode(x + "\0\0")+"\0\0"}
|
118
|
+
len = api('kernel32', 'GetPrivateProfileStringW').call(app, key, "", buf, INI_VALUE_MAX, ini)
|
119
|
+
to_codepage buf
|
120
|
+
end
|
121
|
+
|
122
|
+
def iniwrite(app, key, value, ini = "Game.ini")
|
123
|
+
ini = normalize_pathsep_os ini
|
124
|
+
app, key, value, ini = [app, key, value, ini].map{|x| to_unicode(x + "\0\0")+"\0\0"}
|
125
|
+
api('kernel32', 'WritePrivateProfileStringW').call(
|
126
|
+
app, key, value, ini
|
127
|
+
)
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
module REG
|
132
|
+
HKEY_CLASSES_ROOT,
|
133
|
+
HKEY_CURRENT_USER,
|
134
|
+
HKEY_LOCAL_MACHINE,
|
135
|
+
HKEY_USERS,
|
136
|
+
HKEY_PERFORMANCE_DATA,
|
137
|
+
HKEY_CURRENT_CONFIG,
|
138
|
+
HKEY_DYN_DATA = *(0x80000000..0x80000010)
|
139
|
+
|
140
|
+
HKCR = HKEY_CLASSES_ROOT
|
141
|
+
HKCU = HKEY_CURRENT_USER
|
142
|
+
HKLM = HKEY_LOCAL_MACHINE
|
143
|
+
|
144
|
+
REG_NONE = 0
|
145
|
+
REG_SZ = 1
|
146
|
+
REG_EXPAND_SZ = 2
|
147
|
+
REG_BINARY = 3
|
148
|
+
REG_DWORD = 4
|
149
|
+
REG_DWORD_BIG_ENDIAN = 5
|
150
|
+
REG_MULTI_SZ = 7
|
151
|
+
|
152
|
+
|
153
|
+
ESUCCESS = 0
|
154
|
+
EMOREDATA = 234
|
155
|
+
BYTEINC = 4096
|
156
|
+
end
|
157
|
+
|
158
|
+
def regopenkey(path, valuename)
|
159
|
+
path =~ /([^\\]*)\\(.*)/
|
160
|
+
whole, main, child = *$~
|
161
|
+
main = REG.const_get(main)
|
162
|
+
key = [0].pack(NPGRT::PtrType)
|
163
|
+
child = to_unicode(child + "\0\0")+"\0\0"
|
164
|
+
valuename = case valuename
|
165
|
+
when 0, nil
|
166
|
+
0
|
167
|
+
else
|
168
|
+
to_unicode(valuename+"\0\0")+"\0\0"
|
169
|
+
end
|
170
|
+
checked_api(
|
171
|
+
'advapi32', 'RegOpenKeyW', nil, 'L', "Open Key #{path} Error!"
|
172
|
+
).call(
|
173
|
+
main, child, key
|
174
|
+
)
|
175
|
+
key = key.unpack(NPGRT::PtrType).first
|
176
|
+
[key, valuename]
|
177
|
+
end
|
178
|
+
|
179
|
+
def regclosekey(key)
|
180
|
+
api('advapi32', 'RegCloseKey').call key
|
181
|
+
end
|
182
|
+
def regread(path, valuename = 0, type = :REG_SZ)
|
183
|
+
type = REG.const_get(type) if Symbol === type
|
184
|
+
key, valuename = regopenkey(path, valuename)
|
185
|
+
len = REG::BYTEINC
|
186
|
+
plen = [len].pack(NPGRT::PtrType)
|
187
|
+
buf = "\0\0"*len
|
188
|
+
ptype = [type].pack(NPGRT::PtrType)
|
189
|
+
ret = api('advapi32', 'RegQueryValueExW').call(key, valuename, 0, ptype, buf, plen)
|
190
|
+
while ret == REG::EMOREDATA
|
191
|
+
len += REG::BYTEINC
|
192
|
+
plen = [len].pack(NPGRT::PtrType)
|
193
|
+
buf = "\0\0"*len
|
194
|
+
ret = api('advapi32', 'RegQueryValueExW').call(key, valuename, 0, ptype, buf, plen)
|
195
|
+
|
196
|
+
end
|
197
|
+
if ret == REG::ESUCCESS
|
198
|
+
return buf[0, plen.unpack(NPGRT::PtrType).first*2]
|
199
|
+
else
|
200
|
+
raise "Query Key #{path} failed"
|
201
|
+
end
|
202
|
+
ensure
|
203
|
+
regclosekey key
|
204
|
+
end
|
205
|
+
|
206
|
+
def regstrread(type, valuename = "")
|
207
|
+
val = regread(type, valuename)
|
208
|
+
to_codepage val + "\0\0"
|
209
|
+
end
|
210
|
+
|
211
|
+
def regwrite(path, valuename = nil, value = "", type = :REG_SZ)
|
212
|
+
key, valuename = regopenkey(path, valuename)
|
213
|
+
type = REG.const_get(type) if Symbol === type
|
214
|
+
raise "RegWrite #{path} Error!" if 0 != api('advapi32', 'RegSetValueExW').call(
|
215
|
+
key,
|
216
|
+
valuename,
|
217
|
+
0,
|
218
|
+
type,
|
219
|
+
value,
|
220
|
+
value.length
|
221
|
+
)
|
222
|
+
return true
|
223
|
+
ensure
|
224
|
+
regclosekey key
|
225
|
+
end
|
226
|
+
|
227
|
+
def regstrwrite(path, valuename = nil, value = "")
|
228
|
+
regwrite(path, valuename, to_unicode(value+"\0\0")+"\0\0", :REG_SZ)
|
229
|
+
end
|
230
|
+
|
231
|
+
extend self
|
232
|
+
Win32File = Struct.new(:read, :write, :close, :flush)
|
233
|
+
ReadFile = api('kernel32', 'ReadFile')
|
234
|
+
WriteFile = api('kernel32', 'WriteFile')
|
235
|
+
CloseFile = api('Kernel32', 'CloseHandle')
|
236
|
+
TYPE_VOIDP = NPGRT::PtrType
|
237
|
+
OS64 = TYPE_VOIDP == "Q"
|
238
|
+
PTRLEN = OS64 ? 8 : 4
|
239
|
+
|
240
|
+
def hfileread(handle, len)
|
241
|
+
buf = "\0"*len
|
242
|
+
llen = [0].pack(TYPE_VOIDP)
|
243
|
+
ret = ReadFile.call(handle, buf, len, llen, 0)
|
244
|
+
outlen = llen.unpack(TYPE_VOIDP).first
|
245
|
+
ret != 0 ? buf[0, outlen] : nil
|
246
|
+
end
|
247
|
+
|
248
|
+
def hfilewrite(handle, buf, len = buf.to_str.length)
|
249
|
+
llen = [0].pack(TYPE_VOIDP)
|
250
|
+
ret = WriteFile.call(handle, buf.to_str, len, llen, 0)
|
251
|
+
outlen = llen.unpack(TYPE_VOIDP).first
|
252
|
+
ret != 0 ? outlen : nil
|
253
|
+
end
|
254
|
+
|
255
|
+
def hfilereada(handle, len)
|
256
|
+
ret = hfileread(handle, len)
|
257
|
+
!ret ? ret : to_codepage(to_unicode(ret+"\0\0", CP_ACP)+"\0\0")
|
258
|
+
end
|
259
|
+
|
260
|
+
def hfilereadw(handle, len)
|
261
|
+
ret = hfileread(handle, len)
|
262
|
+
!ret ? ret : to_codepage(ret+"\0\0")
|
263
|
+
end
|
264
|
+
|
265
|
+
|
266
|
+
STARTUPINFOTYPE = {
|
267
|
+
:sizeof => OS64 ? 104 : 68,
|
268
|
+
:show => OS64 ? 64 : 48,
|
269
|
+
:handles => OS64 ? [80, 88, 96] : [56, 60, 64]
|
270
|
+
}
|
271
|
+
|
272
|
+
CreatePipe = api('Kernel32', 'CreatePipe')
|
273
|
+
def winpipe
|
274
|
+
buf = "\0"*(PTRLEN*2)
|
275
|
+
sa = [8+PTRLEN, nil, 1].pack(TYPE_VOIDP + "p" + TYPE_VOIDP)
|
276
|
+
addr = [buf].pack("p").unpack(TYPE_VOIDP).first
|
277
|
+
CreatePipe.call addr, addr+PTRLEN, sa, 1
|
278
|
+
ret = buf.unpack(TYPE_VOIDP*2)
|
279
|
+
{:in => ret[0], :out => ret[1]}
|
280
|
+
end
|
281
|
+
def open3(path, dir = nil, env = nil)
|
282
|
+
si = "\0"*STARTUPINFOTYPE[:sizeof]
|
283
|
+
api('Kernel32', 'GetStartupInfoW').call si
|
284
|
+
si[STARTUPINFOTYPE[:show], 2] = [0].pack("S")
|
285
|
+
stdin, stdout, stderr = winpipe, winpipe, winpipe
|
286
|
+
si[STARTUPINFOTYPE[:handles][0], PTRLEN] = [stdin[:in]].pack(TYPE_VOIDP)
|
287
|
+
si[STARTUPINFOTYPE[:handles][1], PTRLEN] = [stdout[:out]].pack(TYPE_VOIDP)
|
288
|
+
si[STARTUPINFOTYPE[:handles][2], PTRLEN] = [stderr[:out]].pack(TYPE_VOIDP)
|
289
|
+
pi = "\0"*PTRLEN*4
|
290
|
+
path = to_unicode(path + "\0\0")+"\0\0"
|
291
|
+
dir = dir == nil ? nil : to_unicode(dir + "\0\0")+"\0\0"
|
292
|
+
env = env == nil ? nil : to_unicode(env + "\0\0")+"\0\0"
|
293
|
+
api('Kernel32', 'CreateProcessW').call(
|
294
|
+
0,
|
295
|
+
path,
|
296
|
+
0,
|
297
|
+
0,
|
298
|
+
1,
|
299
|
+
0,
|
300
|
+
0,
|
301
|
+
dir,
|
302
|
+
si,
|
303
|
+
pi,
|
304
|
+
)
|
305
|
+
CloseFile.call(stdin[:in])
|
306
|
+
CloseFile.call(stdout[:out])
|
307
|
+
CloseFile.call(stderr[:out])
|
308
|
+
u = pi.unpack(TYPE_VOIDP*4)
|
309
|
+
proc_info = Hash[ [:process, :thread, :pid, :tid].zip(u) ]
|
310
|
+
CloseFile.call(proc_info[:process])
|
311
|
+
CloseFile.call(proc_info[:thread])
|
312
|
+
ret = yield stdin[:out], stdout[:in], stderr[:in], proc_info
|
313
|
+
api('Kernel32', 'TerminateProcess').call proc_info[:process], ret
|
314
|
+
end
|
315
|
+
|
316
|
+
def popen(path, dir = nil, env = nil)
|
317
|
+
open3 path, dir, env do |a, b, c, d|
|
318
|
+
yield a,b
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
CloseSocket = api('ws2_32', 'closesocket')
|
323
|
+
OpenSocket = api('ws2_32', 'socket')
|
324
|
+
Connect = api('ws2_32', 'connect')
|
325
|
+
Send = api('ws2_32', 'send')
|
326
|
+
Recv = api('ws2_32', 'recv')
|
327
|
+
def udpnew(addr = nil)
|
328
|
+
addr = sockaddr(*addr) if Array === addr
|
329
|
+
so = OpenSocket.call 2, 2, 0
|
330
|
+
Connect.call so, addr, addr.size if addr
|
331
|
+
so
|
332
|
+
end
|
333
|
+
|
334
|
+
def tcpnew(addr = nil)
|
335
|
+
addr = sockaddr(*addr) if Array === addr
|
336
|
+
so = OpenSocket.call 2, 1, 6
|
337
|
+
Connect.call so, addr, addr.size if addr
|
338
|
+
so
|
339
|
+
end
|
95
340
|
|
341
|
+
def sockaddr(host, port)
|
342
|
+
[2, port, *host].pack("snCCCCx8")
|
343
|
+
end
|
344
|
+
|
345
|
+
def udpclose(u)
|
346
|
+
CloseSocket.call u
|
347
|
+
end
|
96
348
|
|
349
|
+
def tcpclose(u)
|
350
|
+
CloseSocket.call u
|
351
|
+
end
|
97
352
|
|
353
|
+
def socketwrite(h, buf)
|
354
|
+
Send.call h, buf, buf.length, 0
|
355
|
+
end
|
98
356
|
|
357
|
+
def socketread(h, size)
|
358
|
+
buf = "\0" * size
|
359
|
+
ret = Recv.call h, buf, size, 0
|
360
|
+
case ret
|
361
|
+
when -1, 0
|
362
|
+
nil
|
363
|
+
else
|
364
|
+
buf[0, ret]
|
365
|
+
end
|
366
|
+
end
|
99
367
|
|
100
|
-
|
368
|
+
|
369
|
+
def simplehttpread(addr, hostname = addr[/http:\/\/([^\/]*)/, 1],
|
370
|
+
resource = addr[/http:\/\/([^\/]*)(.*)$/, 2])
|
371
|
+
request = "GET #{resource} HTTP/1.1\r\n"\
|
372
|
+
"host:#{hostname}\r\n"\
|
373
|
+
"\r\n\r\n\r\n\r\n"
|
374
|
+
t = tcpnew
|
375
|
+
if hostname[0][/[0-9]/]
|
376
|
+
u = addr = api('ws2_32', 'inet_addr').call(
|
377
|
+
to_codepage(to_unicode(hostname+"\0\0")+"\0", CP_ANSI)+"\0"
|
378
|
+
)
|
379
|
+
else
|
380
|
+
hostent = api('ws2_32', 'gethostbyname').call(
|
381
|
+
to_codepage(to_unicode(hostname+"\0\0")+"\0", CP_ANSI)+"\0"
|
382
|
+
)
|
383
|
+
|
384
|
+
addr = memread(hostent+PTRLEN*3, PTRLEN)
|
385
|
+
addr = addr.unpack(TYPE_VOIDP).first
|
386
|
+
addr = memread(addr, PTRLEN)
|
387
|
+
addr = addr.unpack(TYPE_VOIDP).first
|
388
|
+
addr = memread(addr, PTRLEN)
|
389
|
+
u = addr.unpack("L").first
|
390
|
+
end
|
391
|
+
uaddr = [2, 0, 0, 80, u].pack("CCCCLx8")
|
392
|
+
|
393
|
+
raise "Can't connect to Server " if -1 == Connect.call(t, uaddr, 16)
|
394
|
+
socketwrite t, request
|
395
|
+
responseheader = ""
|
396
|
+
while v = socketread(t, 20480)
|
397
|
+
responseheader << v
|
398
|
+
if pos = responseheader.index("\r\n\r\n")
|
399
|
+
responsebody = responseheader[pos+4..-1]
|
400
|
+
responseheader = responseheader[0...pos]
|
401
|
+
break
|
402
|
+
end
|
403
|
+
yield responseheader, nil if block_given?
|
404
|
+
end
|
405
|
+
|
406
|
+
if !(length = responseheader[/Content-length:\s*(\d+)/i, 1])
|
407
|
+
length = 1e100
|
408
|
+
else
|
409
|
+
length = length.to_i
|
410
|
+
end
|
411
|
+
|
412
|
+
while responsebody.size < length && (v = socketread(t, 20480))
|
413
|
+
responsebody << v
|
414
|
+
yield responseheader, responsebody if block_given?
|
415
|
+
end
|
416
|
+
tcpclose t
|
417
|
+
true
|
418
|
+
end
|
419
|
+
|
420
|
+
|
101
421
|
end
|
102
422
|
|
103
|
-
extend Win32API
|
104
423
|
end
|
data/lib/test_32.dll
ADDED
Binary file
|
data/lib/test_64.dll
ADDED
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: npgrt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Seiran
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-08-
|
11
|
+
date: 2014-08-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,14 +52,26 @@ files:
|
|
52
52
|
- Rakefile
|
53
53
|
- lib/npgrt.rb
|
54
54
|
- lib/npgrt.rb~
|
55
|
+
- lib/npgrt/.version.rb.swp
|
56
|
+
- lib/npgrt/algorithm.rb
|
57
|
+
- lib/npgrt/algorithm.rb~
|
58
|
+
- lib/npgrt/filesystem.rb
|
59
|
+
- lib/npgrt/filesystem.rb~
|
60
|
+
- lib/npgrt/find.rb
|
61
|
+
- lib/npgrt/find.rb~
|
55
62
|
- lib/npgrt/message.rb
|
56
63
|
- lib/npgrt/message.rb~
|
64
|
+
- lib/npgrt/query.rb
|
65
|
+
- lib/npgrt/report.rb
|
66
|
+
- lib/npgrt/report.rb~
|
57
67
|
- lib/npgrt/require.rb
|
58
68
|
- lib/npgrt/require.rb~
|
59
69
|
- lib/npgrt/version.rb
|
60
70
|
- lib/npgrt/version.rb~
|
61
71
|
- lib/npgrt/win32api.rb
|
62
72
|
- lib/npgrt/win32api.rb~
|
73
|
+
- lib/test_32.dll
|
74
|
+
- lib/test_64.dll
|
63
75
|
- message.rb
|
64
76
|
- npgrt.gemspec
|
65
77
|
- npgrt.gemspec~
|