我正在尝试修改一个梁文件,以便将本地函数调用解释为外部模块调用,即使一个函数可能定义在它被调用的同一模块中。
给定 m 作为模块,我尝试了几种重新编译反汇编梁文件的排列,但无济于事。这是我尝试的一个例子,在长生不老药中:
IO.inspect(:file.write_file("/tmp/disasm.asm", :io_lib.fwrite("~p.\n", [:beam_disasm.file(:code.which m)])))
IO.inspect(:compile.noenv_file("/tmp/disasm.asm", [:from_asm]))
我非常感谢任何关于如何轻松将输出重新编译:beam_disasm.file
回.beam
文件的输入。
谢谢!
编辑:证明更多信息
假设我有一个看起来像这样的 elixir 模块:
defmodule MyApp.IndirectMod do
def value do
1
end
def indirect_value do
value()
end
def indirect_value_2 do
MyApp.IndirectMod.value()
end
end
编译应用程序后,:beam.disasm
提供其光束文件的以下输出:
[ {:attribute, 1, :file, {'lib/temp.ex', 1}}, {:attribute, 1, :module, MyApp.IndirectMod}, {:attribute, 1, :compile, :no_auto_import}, {:attribute, 1, :export, [__info__: 1, indirect_value: 0, indirect_value_2: 0, value: 0]}, {:attribute, 1, :spec, {{:__info__, 1},
[
{:type, 1, :fun,
[
{:type, 1, :product,
[
{:type, 1, :union,
[
{:atom, 1, :attributes},
{:atom, 1, :compile},
{:atom, 1, :functions},
{:atom, 1, :macros},
{:atom, 1, :md5},
{:atom, 1, :module},
{:atom, 1, :deprecated}
]}
]},
{:type, 1, :any, []}
]}
]}}, {:function, 0, :__info__, 1, [
{:clause, 0, [{:atom, 0, :module}], [], [{:atom, 0, MyApp.IndirectMod}]},
{:clause, 0, [{:atom, 0, :functions}], [],
[
{:cons, 0, {:tuple, 0, [{:atom, 0, :indirect_value}, {:integer, 0, 0}]},
{:cons, 0,
{:tuple, 0, [{:atom, 0, :indirect_value_2}, {:integer, 0, 0}]},
{:cons, 0, {:tuple, 0, [{:atom, 0, :value}, {:integer, 0, 0}]},
{nil, 0}}}}
]},
{:clause, 0, [{:atom, 0, :macros}], [], [nil: 0]},
{:clause, 0, [{:atom, 0, :attributes}], [],
[
{:call, 0,
{:remote, 0, {:atom, 0, :erlang}, {:atom, 0, :get_module_info}},
[{:atom, 0, MyApp.IndirectMod}, {:atom, 0, :attributes}]}
]},
{:clause, 0, [{:atom, 0, :compile}], [],
[
{:call, 0,
{:remote, 0, {:atom, 0, :erlang}, {:atom, 0, :get_module_info}},
[{:atom, 0, MyApp.IndirectMod}, {:atom, 0, :compile}]}
]},
{:clause, 0, [{:atom, 0, :md5}], [],
[
{:call, 0,
{:remote, 0, {:atom, 0, :erlang}, {:atom, 0, :get_module_info}},
[{:atom, 0, MyApp.IndirectMod}, {:atom, 0, :md5}]}
]},
{:clause, 0, [{:atom, 0, :deprecated}], [], [nil: 0]} ]}, {:function, 7, :indirect_value, 0, [{:clause, 7, [], [], [{:call, 8, {:atom, 8, :value}, []}]}]}, {:function, 11, :indirect_value_2, 0, [
{:clause, 11, [], [],
[
{:call, 12,
{:remote, 12, {:atom, 0, MyApp.IndirectMod}, {:atom, 12, :value}}, []}
]} ]}, {:function, 3, :value, 0, [{:clause, 3, [], [], [{:integer, 0, 1}]}]} ]
我想提请您注意的特定信息是:
{:function, 7, :indirect_value, 0,
[{:clause, 7, [], [], [{:call, 8, {:atom, 8, :value}, []}]}]},
{:function, 11, :indirect_value_2, 0,
[
{:clause, 11, [], [],
[
{:call, 12,
{:remote, 12, {:atom, 0, MyApp.IndirectMod}, {:atom, 12, :value}}, []}
]}
]},
indirect_value2
是“远程”呼叫,indirect_value
而是“本地”呼叫。我想要实现的是indirect_value
被模仿/视为像indirect_value_2这样的远程调用。
我试图在编译过程中实现这一点。我想到的唯一方法是分解光束文件,适当地改变它并重新组装它。我非常愿意接受其他建议。