neri 0.9.3 → 0.9.7
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/neri/build.rb +70 -18
- data/lib/neri/runtime.rb +76 -60
- data/lib/neri/version.rb +1 -1
- data/neri.gemspec +0 -2
- metadata +3 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54122cb7af8b62506615a9be8916791a0051fd6cfc4ad395727a23714997b019
|
4
|
+
data.tar.gz: c79aa6b985eadfa33888aeb35af6fe70f4b17ec89d38d581bffccbf789de5b3b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a3bf286b9a366b38a4c37749ea48d690724331bd5aa208a435cbff987e160fc501d2617014a05ac047864c6a97f62e3f571ca077857119877d392640ab542fb2
|
7
|
+
data.tar.gz: d1830c564fdbe69c2418936ce86227509292ea0c05af462a5ac886fd8f8ebf5bbc931fb08a99a23dc71685df84d913bbe1b2c669eb31491fe17818b0b2fcf704
|
data/lib/neri/build.rb
CHANGED
@@ -18,7 +18,7 @@ module Neri
|
|
18
18
|
|
19
19
|
enable_gems: false,
|
20
20
|
enable_did_you_mean: false,
|
21
|
-
chdir_first:
|
21
|
+
chdir_first: true,
|
22
22
|
pause_last: nil,
|
23
23
|
pause_text: nil,
|
24
24
|
|
@@ -27,6 +27,7 @@ module Neri
|
|
27
27
|
|
28
28
|
datafile: nil,
|
29
29
|
encryption_key: nil,
|
30
|
+
virtual_directory: nil,
|
30
31
|
|
31
32
|
no_exe: false,
|
32
33
|
use_b2ec: false,
|
@@ -111,7 +112,7 @@ options:
|
|
111
112
|
|
112
113
|
--enable-gems
|
113
114
|
--enable-did-you-mean
|
114
|
-
--chdir
|
115
|
+
--no-chdir
|
115
116
|
--pause-last
|
116
117
|
--no-pause-last
|
117
118
|
--pause-text <text>
|
@@ -155,6 +156,7 @@ options:
|
|
155
156
|
|
156
157
|
--create-recipe <recipefile>
|
157
158
|
--recipe <recipefile>
|
159
|
+
--virtual-directory <string>
|
158
160
|
HELP_MESSAGE
|
159
161
|
end
|
160
162
|
|
@@ -209,7 +211,9 @@ options:
|
|
209
211
|
options[:enable_gems] = true
|
210
212
|
when "--enable-did-you-mean"
|
211
213
|
options[:enable_did_you_mean] = true
|
212
|
-
when "--chdir
|
214
|
+
when "--no-chdir"
|
215
|
+
options[:chdir_first] = false
|
216
|
+
when "--chdir-first" # deprecated
|
213
217
|
options[:chdir_first] = true
|
214
218
|
when "--pause-last"
|
215
219
|
options[:pause_last] = true
|
@@ -292,6 +296,8 @@ options:
|
|
292
296
|
filename = ARGV.shift.encode("utf-8")
|
293
297
|
nputs_v "Loading recipe_file '#{filename}'."
|
294
298
|
load File.expand_path(filename)
|
299
|
+
when "--virtual-directory"
|
300
|
+
options[:virtual_directory] = ARGV.shift.encode("utf-8")
|
295
301
|
when "--"
|
296
302
|
break
|
297
303
|
when /^(--.+)/
|
@@ -317,6 +323,7 @@ options:
|
|
317
323
|
unless options[:enable_did_you_mean] || @rubyopt.index("--disable-did_you_mean")
|
318
324
|
@rubyopt += " --disable-did_you_mean"
|
319
325
|
end
|
326
|
+
@rubyopt.sub!(%r{-r\S+/bundler/setup}, "")
|
320
327
|
if @data_files.size > 1 || options[:encryption_key]
|
321
328
|
options[:datafile] ||= "#{basename}.dat"
|
322
329
|
end
|
@@ -328,27 +335,54 @@ options:
|
|
328
335
|
end
|
329
336
|
|
330
337
|
def dll_dependencies
|
331
|
-
require "
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
338
|
+
require "fiddle/import"
|
339
|
+
|
340
|
+
pointer_type = Fiddle::SIZEOF_VOIDP == Fiddle::SIZEOF_LONG_LONG ? 'q*' : 'l!*'
|
341
|
+
psapi = Fiddle.dlopen("psapi.dll")
|
342
|
+
kernel32 = Fiddle.dlopen("kernel32.dll")
|
343
|
+
enumprocessmodules = Fiddle::Function.new(
|
344
|
+
psapi["EnumProcessModules"],
|
345
|
+
[Fiddle::TYPE_LONG, Fiddle::TYPE_VOIDP, Fiddle::TYPE_LONG, Fiddle::TYPE_VOIDP],
|
346
|
+
Fiddle::TYPE_LONG,
|
347
|
+
Fiddle::Importer.const_get(:CALL_TYPE_TO_ABI)[:stdcall]
|
348
|
+
)
|
349
|
+
getmodulefilename = Fiddle::Function.new(
|
350
|
+
kernel32["GetModuleFileNameW"],
|
351
|
+
[Fiddle::TYPE_LONG, Fiddle::TYPE_VOIDP, Fiddle::TYPE_LONG],
|
352
|
+
Fiddle::TYPE_LONG,
|
353
|
+
Fiddle::Importer.const_get(:CALL_TYPE_TO_ABI)[:stdcall]
|
354
|
+
)
|
355
|
+
getcurrentprocess = Fiddle::Function.new(
|
356
|
+
kernel32["GetCurrentProcess"],
|
357
|
+
[],
|
358
|
+
Fiddle::TYPE_LONG,
|
359
|
+
Fiddle::Importer.const_get(:CALL_TYPE_TO_ABI)[:stdcall]
|
360
|
+
)
|
361
|
+
|
337
362
|
bytes_needed = 4 * 32
|
338
363
|
module_handle_buffer = nil
|
339
364
|
process_handle = getcurrentprocess.call
|
340
365
|
loop do
|
341
366
|
module_handle_buffer = "\x00" * bytes_needed
|
342
367
|
bytes_needed_buffer = [0].pack("I")
|
343
|
-
enumprocessmodules.call(
|
368
|
+
enumprocessmodules.call(
|
369
|
+
[process_handle].pack("I").unpack1("i"),
|
370
|
+
[module_handle_buffer].pack("p").unpack1(pointer_type),
|
371
|
+
[module_handle_buffer.size].pack("I").unpack1("i"),
|
372
|
+
[bytes_needed_buffer].pack("p").unpack1(pointer_type)
|
373
|
+
)
|
344
374
|
bytes_needed = bytes_needed_buffer.unpack1("I")
|
345
375
|
break if bytes_needed <= module_handle_buffer.size
|
346
376
|
end
|
347
|
-
|
377
|
+
|
348
378
|
handles = module_handle_buffer.unpack("I*")
|
349
379
|
dependencies = handles.select { |handle| handle > 0 }.map do |handle|
|
350
380
|
str = "\x00\x00" * 256
|
351
|
-
modulefilename_length = getmodulefilename.call(
|
381
|
+
modulefilename_length = getmodulefilename.call(
|
382
|
+
[handle].pack("I").unpack1("i"),
|
383
|
+
[str].pack("p").unpack1(pointer_type),
|
384
|
+
[str.size].pack("I").unpack1("i")
|
385
|
+
)
|
352
386
|
str[0, modulefilename_length * 2].force_encoding("UTF-16LE").encode("UTF-8")
|
353
387
|
end
|
354
388
|
|
@@ -535,6 +569,20 @@ options:
|
|
535
569
|
@data_files.select { |file| File.directory? file }.each do |dir|
|
536
570
|
data_files += Dir.glob("#{dir}/**/*").select { |file| File.file? file }
|
537
571
|
end
|
572
|
+
data_files.uniq! { |file| File.expand_path(file) }
|
573
|
+
|
574
|
+
unless options[:virtual_directory]
|
575
|
+
dir_pwd = Dir.pwd.encode(Encoding::UTF_8)
|
576
|
+
virtual_directories = Pathname.new(dir_pwd).ascend.to_a.map(&:to_s)
|
577
|
+
data_files.each do |file|
|
578
|
+
fullpath = File.expand_path(file)
|
579
|
+
next if fullpath.start_with?(rubydir) || Pathname.new(file).absolute?
|
580
|
+
virtual_directories.shift until fullpath.start_with?(virtual_directories.first)
|
581
|
+
end
|
582
|
+
options[:virtual_directory] = relative_path(dir_pwd, virtual_directories.first, "/_neri_virtual_directory_/")
|
583
|
+
nputs "virtual_directory: #{options[:virtual_directory]}"
|
584
|
+
end
|
585
|
+
|
538
586
|
if options[:encryption_key]
|
539
587
|
require "digest/sha2"
|
540
588
|
@encryption_key = Digest::SHA2.hexdigest(options[:encryption_key])
|
@@ -542,19 +590,20 @@ options:
|
|
542
590
|
Neri.key = @encryption_key || "0" * 64
|
543
591
|
File.open(datafile, "wb") do |f|
|
544
592
|
pos = 0
|
545
|
-
|
593
|
+
file_informations = data_files.map do |file|
|
546
594
|
fullpath = File.expand_path(file)
|
547
595
|
filename = if fullpath.start_with?(rubydir)
|
548
|
-
relative_path(fullpath, rubydir, "
|
596
|
+
relative_path(fullpath, rubydir, "#{options[:system_dir]}#{File::SEPARATOR}")
|
549
597
|
else
|
550
598
|
file
|
551
599
|
end
|
552
|
-
filedata = [filename, File.size(file), pos]
|
600
|
+
filedata = [filename, File.size(file), pos].join("\t")
|
601
|
+
nputs_v " - #{filename}:#{File.size(file)} bytes"
|
553
602
|
pos += File.size(file)
|
554
603
|
pos += BLOCK_LENGTH - pos % BLOCK_LENGTH unless pos % BLOCK_LENGTH == 0
|
555
|
-
|
556
|
-
|
557
|
-
|
604
|
+
filedata
|
605
|
+
end
|
606
|
+
files_str = file_informations.join("\n").encode(Encoding::UTF_8)
|
558
607
|
|
559
608
|
f.write(format("%#{BLOCK_LENGTH}d", files_str.bytesize))
|
560
609
|
f.write(xor(files_str))
|
@@ -716,6 +765,9 @@ END
|
|
716
765
|
ruby_code = "Neri.key='#{@encryption_key}';" if @encryption_key
|
717
766
|
if options[:datafile]
|
718
767
|
ruby_code += "Neri.datafile='#{system_dir}' + #{unpack_filename(options[:datafile])};"
|
768
|
+
if options[:virtual_directory]
|
769
|
+
ruby_code += "Neri.virtual_directory=#{unpack_filename(options[:virtual_directory])};"
|
770
|
+
end
|
719
771
|
ruby_code += "load #{unpack_filename(File.basename(scriptfile))}"
|
720
772
|
else
|
721
773
|
ruby_code += "load File.expand_path('#{system_dir}' + #{unpack_filename(scriptfile)})"
|
data/lib/neri/runtime.rb
CHANGED
@@ -1,79 +1,91 @@
|
|
1
1
|
require "neri/version"
|
2
|
+
require "pathname"
|
2
3
|
|
3
|
-
|
4
|
-
|
4
|
+
module Kernel
|
5
|
+
unless defined?(neri_original_require)
|
6
|
+
alias neri_original_require require
|
7
|
+
private :neri_original_require
|
8
|
+
end
|
5
9
|
|
6
|
-
|
7
|
-
|
8
|
-
|
10
|
+
unless defined?(neri_original_load)
|
11
|
+
alias neri_original_load load
|
12
|
+
private :neri_original_load
|
13
|
+
end
|
14
|
+
|
15
|
+
def require(feature)
|
16
|
+
Neri.require(feature)
|
17
|
+
end
|
9
18
|
|
10
|
-
def load(file, priv = false)
|
11
|
-
|
19
|
+
def load(file, priv = false)
|
20
|
+
Neri.load(file, priv)
|
21
|
+
end
|
12
22
|
end
|
13
23
|
|
14
24
|
module Neri
|
15
25
|
BLOCK_LENGTH = 32
|
16
26
|
@datafile = nil
|
17
|
-
@
|
18
|
-
@
|
19
|
-
@
|
20
|
-
@
|
27
|
+
@file_informations = {}
|
28
|
+
@fullpath_files = {}
|
29
|
+
@virtual_files = {}
|
30
|
+
@virtual_directory = "."
|
21
31
|
@xor = nil
|
22
32
|
|
23
33
|
class << self
|
24
34
|
def datafile=(datafile)
|
25
35
|
@datafile = datafile.encode(Encoding::UTF_8)
|
26
|
-
@system_dir = File.dirname(File.expand_path(@datafile)) + File::SEPARATOR
|
27
36
|
files_length = File.binread(@datafile, BLOCK_LENGTH).to_i
|
28
37
|
files_str = read(files_length, BLOCK_LENGTH)
|
29
38
|
pos = files_length + BLOCK_LENGTH
|
30
39
|
pos += BLOCK_LENGTH - pos % BLOCK_LENGTH unless pos % BLOCK_LENGTH == 0
|
31
40
|
files_str.force_encoding(Encoding::UTF_8)
|
32
|
-
files_str.
|
41
|
+
files_str.each_line do |line|
|
33
42
|
filename, length, offset = line.split("\t")
|
34
|
-
@
|
43
|
+
@file_informations[filename] = [length.to_i, offset.to_i + pos]
|
35
44
|
end
|
36
|
-
@
|
45
|
+
@fullpath_files = @file_informations.transform_keys { |k| File.expand_path(k) }
|
37
46
|
end
|
38
47
|
|
39
48
|
def key=(key)
|
40
|
-
@xor
|
49
|
+
@xor ||= key.scan(/../).map { |a| a.to_i(16) }.pack("c*")
|
41
50
|
end
|
42
51
|
|
43
|
-
def
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
["", ".rb"].each do |ext|
|
48
|
-
tmp_path = path + feature + ext
|
49
|
-
filepath ||= tmp_path if exist_in_datafile?(tmp_path)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
return _neri_orig_require(feature) unless filepath
|
54
|
-
return false if $LOADED_FEATURES.index(filepath)
|
52
|
+
def virtual_directory=(path)
|
53
|
+
@virtual_directory = path
|
54
|
+
@virtual_files = @file_informations.transform_keys { |k| File.expand_path(k, path) }
|
55
|
+
end
|
55
56
|
|
56
|
-
|
57
|
-
|
58
|
-
|
57
|
+
def require(feature)
|
58
|
+
feature_path = Pathname.new(feature.encode(Encoding::UTF_8))
|
59
|
+
feature_path = feature_path.sub_ext(".rb") if feature_path.extname == ""
|
60
|
+
return neri_original_require(feature) if feature_path.extname == ".so"
|
61
|
+
|
62
|
+
path_str = if feature_path.absolute? || feature.start_with?(".")
|
63
|
+
path_in_datafile(feature_path)
|
64
|
+
else
|
65
|
+
search_in_load_path(feature_path)
|
66
|
+
end
|
67
|
+
|
68
|
+
return neri_original_require(feature) unless path_str
|
69
|
+
return false if $LOADED_FEATURES.index(path_str)
|
70
|
+
|
71
|
+
code = load_code(path_str)
|
72
|
+
eval(code, TOPLEVEL_BINDING, path_str)
|
73
|
+
$LOADED_FEATURES.push(path_str)
|
59
74
|
true
|
60
75
|
end
|
61
76
|
|
62
77
|
def load(file, priv = false)
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
paths.each do |path|
|
67
|
-
filepath ||= path + file if exist_in_datafile?(path + file)
|
68
|
-
end
|
78
|
+
file_path = Pathname.new(file.encode(Encoding::UTF_8))
|
79
|
+
path_str = search_in_load_path(file_path) if file_path.relative? && !file.start_with?(".")
|
80
|
+
path_str ||= path_in_datafile(file_path)
|
69
81
|
|
70
|
-
return
|
82
|
+
return neri_original_load(file, priv) unless path_str
|
71
83
|
|
72
|
-
code = load_code(
|
84
|
+
code = load_code(path_str)
|
73
85
|
if priv
|
74
|
-
Module.new.module_eval(code,
|
86
|
+
Module.new.module_eval(code, path_str)
|
75
87
|
else
|
76
|
-
eval(code, TOPLEVEL_BINDING,
|
88
|
+
eval(code, TOPLEVEL_BINDING, path_str)
|
77
89
|
end
|
78
90
|
true
|
79
91
|
end
|
@@ -84,32 +96,26 @@ module Neri
|
|
84
96
|
|
85
97
|
def file_read(filename, encoding = Encoding::BINARY)
|
86
98
|
filename = filename.encode(Encoding::UTF_8)
|
87
|
-
|
88
|
-
|
89
|
-
length, offset = fullpath_files[File.expand_path(filename)]
|
90
|
-
str = read(length, offset)
|
91
|
-
else
|
92
|
-
str = File.binread(filename)
|
93
|
-
end
|
99
|
+
length, offset = file_information(filename)
|
100
|
+
str = length ? read(length, offset) : File.binread(filename)
|
94
101
|
str.force_encoding(encoding)
|
95
102
|
end
|
96
103
|
|
97
104
|
def files
|
98
|
-
@
|
105
|
+
@file_informations.keys
|
99
106
|
end
|
100
107
|
|
101
108
|
def exist_in_datafile?(filename)
|
102
|
-
|
109
|
+
file_information(filename) != nil
|
103
110
|
end
|
104
111
|
|
105
112
|
private
|
106
113
|
|
107
|
-
def
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
@fullpath_files
|
114
|
+
def file_information(filename)
|
115
|
+
fullpath = File.expand_path(filename)
|
116
|
+
return @fullpath_files[fullpath] if @fullpath_files.key?(fullpath)
|
117
|
+
|
118
|
+
@virtual_files[File.expand_path(filename, @virtual_directory)]
|
113
119
|
end
|
114
120
|
|
115
121
|
def xor(str)
|
@@ -131,11 +137,21 @@ module Neri
|
|
131
137
|
xor(File.binread(@datafile, tmp_length, offset))[0, length]
|
132
138
|
end
|
133
139
|
|
134
|
-
def
|
135
|
-
|
136
|
-
|
140
|
+
def search_in_load_path(file_path)
|
141
|
+
$LOAD_PATH.each do |path_str|
|
142
|
+
load_path = Pathname.new(path_str.encode(Encoding::UTF_8))
|
143
|
+
candidate_path_str = path_in_datafile(load_path + file_path)
|
144
|
+
return candidate_path_str if candidate_path_str
|
145
|
+
end
|
146
|
+
nil
|
147
|
+
end
|
148
|
+
|
149
|
+
def path_in_datafile(file_path)
|
150
|
+
fullpath = File.expand_path(file_path.to_s)
|
151
|
+
return fullpath if exist_in_datafile?(fullpath)
|
137
152
|
|
138
|
-
|
153
|
+
virtual_path = File.expand_path(file_path.to_s, @virtual_directory)
|
154
|
+
exist_in_datafile?(virtual_path) ? virtual_path : nil
|
139
155
|
end
|
140
156
|
|
141
157
|
def load_code(file)
|
data/lib/neri/version.rb
CHANGED
data/neri.gemspec
CHANGED
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: neri
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- nodai2hITC
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
12
|
-
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: win32api
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
11
|
+
date: 2021-12-29 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
27
13
|
description: Neri builds Windows batfile or exefile from Ruby script.
|
28
14
|
email:
|
29
15
|
- nodai2h.itc@gmail.com
|