Class: Ocran::StubBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/ocran/stub_builder.rb

Overview

Utility class that produces the actual executable. Opcodes (create_file, mkdir etc) are added by invoking methods on an instance of OcranBuilder.

Constant Summary collapse

Signature =
[0x41, 0xb6, 0xba, 0x4e].freeze
OP_END =
0
OP_CREATE_DIRECTORY =
1
OP_CREATE_FILE =
2
OP_SETENV =
3
OP_SET_SCRIPT =
4
DEBUG_MODE =
0x01
EXTRACT_TO_EXE_DIR =
0x02
AUTO_CLEAN_INST_DIR =
0x04
CHDIR_BEFORE_SCRIPT =
0x08
DATA_COMPRESSED =
0x10
STUB_PATH =
File.expand_path("stub.exe", base_dir)
STUBW_PATH =
File.expand_path("stubw.exe", base_dir)
LZMA_PATH =
File.expand_path("lzma.exe", base_dir)
EDICON_PATH =
File.expand_path("edicon.exe", base_dir)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, chdir_before: nil, debug_extract: nil, debug_mode: nil, enable_compression: nil, gui_mode: nil, icon_path: nil) ⇒ StubBuilder

chdir_before: When set to true, the working directory is changed to the application’s deployment location at runtime.

debug_mode: When the debug_mode option is set to true, the stub will output debug information when the exe file is executed. Debug mode can also be enabled within the directive code using the enable_debug_mode method. This option is provided to transition to debug mode from the initialization point of the stub.

debug_extract: When set to true, the runtime file is extracted to the directory where the executable resides, and the extracted files remain even after the application exits. When set to false, the runtime file is extracted to the system’s temporary directory, and the extracted files are deleted after the application exits.

gui_mode: When set to true, the stub does not display a console window at startup. Errors are shown in a dialog window. When set to false, the stub reports errors through the console window.

icon_path: Specifies the path to the icon file to be embedded in the stub’s resources.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/ocran/stub_builder.rb', line 54

def initialize(path, chdir_before: nil, debug_extract: nil, debug_mode: nil,
               enable_compression: nil, gui_mode: nil, icon_path: nil)
  @dirs = FilePathSet.new
  @files = FilePathSet.new
  @data_size = 0

  if icon_path && !File.exist?(icon_path)
    raise "Icon file #{icon_path} not found"
  end

  stub = Tempfile.new("", File.dirname(path))
  IO.copy_stream(gui_mode ? STUBW_PATH : STUB_PATH, stub)
  stub.close

  if icon_path
    system(EDICON_PATH, stub.path, icon_path.to_s, exception: true)
  end

  File.open(stub, "ab") do |of|
    @of = of
    @opcode_offset = @of.size

    write_header(debug_mode, debug_extract, chdir_before, enable_compression)

    b = proc {
      yield(self)
      write_opcode(OP_END)
    }

    if enable_compression
      compress(&b)
    else
      b.yield
    end

    write_footer
  end

  File.rename(stub, path)
end

Instance Attribute Details

#data_sizeObject (readonly)

Returns the value of attribute data_size.



29
30
31
# File 'lib/ocran/stub_builder.rb', line 29

def data_size
  @data_size
end

Instance Method Details

#cp(source, target) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
# File 'lib/ocran/stub_builder.rb', line 102

def cp(source, target)
  unless File.exist?(source)
    raise "The file does not exist (#{source})"
  end

  return unless @files.add?(source, target)

  write_opcode(OP_CREATE_FILE)
  write_path(target)
  write_file(source)
end

#exec(image, script, *argv) ⇒ Object

Specifies the final application script to be launched, which can be called from any position in the data stream. It cannot be specified more than once.

You can omit setting OP_SET_SCRIPT without issues, in which case the stub terminates without launching anything after performing other runtime operations.



120
121
122
123
124
125
126
127
128
# File 'lib/ocran/stub_builder.rb', line 120

def exec(image, script, *argv)
  if @script_set
    raise "Script is already set"
  end
  @script_set = true

  write_opcode(OP_SET_SCRIPT)
  write_string_array(convert_to_native(image), convert_to_native(script), *argv)
end

#export(name, value) ⇒ Object



130
131
132
133
134
# File 'lib/ocran/stub_builder.rb', line 130

def export(name, value)
  write_opcode(OP_SETENV)
  write_string(name.to_s)
  write_string(value.to_s)
end

#mkdir(target) ⇒ Object



95
96
97
98
99
100
# File 'lib/ocran/stub_builder.rb', line 95

def mkdir(target)
  return unless @dirs.add?("/", target)

  write_opcode(OP_CREATE_DIRECTORY)
  write_path(target)
end