В чем разница между ... (Type1) и ... (Type2)
blockquote>Ничего:
Исполняемый файл "PE" состоит из некоторых EXE-файл MS-DOS, за которым следует 32- или 64-битная часть.
Если вы запускаете исполняемый файл «PE» в MS-DOS (или в любой другой совместимой операционной системе), DOS игнорирует 32- или 64-битную часть и выполняет исполняемый файл MS-DOS в начале «PE». исполняемый файл.
Несколько программ написаны таким образом, что EXE-файл DOS в начале PE-файла работает так же, как часть Windows, так что вы можете использовать один и тот же EXE-файл как в DOS, так и в Windows.
Однако, в большинстве случаев DOS-часть печатает только сообщение об ошибке, в котором говорится, что программа не может быть запущена под MS-DOS.
То, что вы видите здесь, это две разные программы MS-DOS в начале PE PE-файлов; одна программа печатает сообщение об ошибке
"This program must be run under Win32"
, другая печатает"This program cannot be run in DOS mode."
Кроме того, два двоичных файла различаются по первым символам: MZ и MZP
blockquote>This также не является разницей:
Третий байт файлов MS-DOS является одним из многих байтов, описывающих длину программы MS-DOS. Поскольку у вас разные программы MS-DOS, они также имеют разную длину.
В одном случае байт имеет значение 80, которое отображается как «P» в текстовом редакторе.
В другом случае байт может иметь значение 10 (в качестве примера), которое не отображается как символ в текстовом редакторе.
Почему runPE не работает с исполняемыми файлами определенного типа?
blockquote>Не увидев трояна, я не могу ответить на этот вопрос.
Однако, я видел много троянов, которые не используют правильный формат файла "PE".
(Однако в этих случаях «ошибки» были после «PE L», а не в «MZ» -части.)
Вы хотите Object#method
:
---------------------------------------------------------- Object#method
obj.method(sym) => method
------------------------------------------------------------------------
Looks up the named method as a receiver in obj, returning a Method
object (or raising NameError). The Method object acts as a closure
in obj's object instance, so instance variables and the value of
self remain available.
class Demo
def initialize(n)
@iv = n
end
def hello()
"Hello, @iv = #{@iv}"
end
end
k = Demo.new(99)
m = k.method(:hello)
m.call #=> "Hello, @iv = 99"
l = Demo.new('Fred')
m = l.method("hello")
m.call #=> "Hello, @iv = Fred"
Теперь Ваш код становится:
private
def setup_map
@map = {
'a' => method(:a),
'b' => method(:b),
'c' => method(:c)
}
# or, more succinctly
# @map = Hash.new { |_map,name| _map[name] = method(name.to_sym) }
end
public
def call(arg)
@map["a"][arg] if arg > 10
@map["b"][arg] if arg > 20
@map["c"][arg] if arg > 30
end
Можно сделать это с лямбдами при поддержании способности изменить поведение в подклассах:
class X
def initialize
@map = {}
setup_map
end
private
def setup_map
@map["a"] = lambda { |a| a(a) }
@map["b"] = lambda { |a| b(a) }
@map["c"] = lambda { |a| c(a) }
end
public
def call(a)
@map["a"].call(a) if a > 10
@map["b"].call(a) if a > 20
@map["c"].call(a) if a > 30
end
def a(arg)
puts "a was called with #{arg}"
end
def b(arg)
puts "b was called with #{arg}"
end
def c(arg)
puts "c was called with #{arg}"
end
end
Методы Ruby не являются первоклассными объектами; это реализует OO с передачей сообщений.
class X
def call(a)
self.send(:a, a) if a > 10
self.send(:b, a) if a > 20
self.send(:c, a) if a > 30
end
def a(arg)
puts "a was called with #{arg}"
end
def b(arg)
puts "b was called with #{arg}"
end
def c(arg)
puts "c was called with #{arg}"
end
end
Или просто называют их непосредственно:
def call(a)
self.a(a) if a > 10
self.b(a) if a > 20
self.c(a) if a > 30
end